@kky42/pievo-server 2.3.0 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/MachinesModal-CSbnrUER.js +1 -0
  3. package/.output/public/assets/SignIn-0Tjqs-Ma.js +1 -0
  4. package/.output/public/assets/actionUi-DpwGIGpw.js +1 -0
  5. package/.output/public/assets/app-CaZpuwOS.css +2 -0
  6. package/.output/public/assets/index-CaS_SmDq.js +10 -0
  7. package/.output/public/assets/invite._token-Btg_0aLp.js +1 -0
  8. package/.output/public/assets/invite._token-KMD2JAgE.js +1 -0
  9. package/.output/public/assets/lifecycleUi-C7dwHtbw.js +1 -0
  10. package/.output/public/assets/loops._loopId-D5usF3DO.js +67 -0
  11. package/.output/public/assets/loops._loopId_.runs._runId-DRCgXaCq.js +3 -0
  12. package/.output/public/assets/preload-helper-DsxECZIS.js +5 -0
  13. package/.output/public/assets/routes-CtFgwdgW.js +1 -0
  14. package/.output/public/assets/routes-LDbnnQ3f.js +1 -0
  15. package/.output/public/assets/t._teamId-D41xcbsF.js +1 -0
  16. package/.output/public/assets/t._teamId-DUena1pV.js +1 -0
  17. package/.output/public/assets/ui-Do4gqMyP.js +1 -0
  18. package/.output/server/_libs/@base-ui/react+[...].mjs +4130 -4130
  19. package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
  20. package/.output/server/_libs/drizzle-orm+postgres.mjs +28 -1
  21. package/.output/server/_ssr/DashboardView-C2LdV6J0.mjs +914 -0
  22. package/.output/server/_ssr/{notifyFns-DuPR1zd7.mjs → MachinesModal-BjkcVjjx.mjs} +55 -35
  23. package/.output/server/_ssr/{SignIn-RmpWm9uy.mjs → SignIn-DEGrvJvb.mjs} +10 -24
  24. package/.output/server/_ssr/SocialLinks-Cm4H8pUJ.mjs +1044 -0
  25. package/.output/server/_ssr/{actionUi-BN55TNYE.mjs → actionUi-DJBWuNwr.mjs} +3 -3
  26. package/.output/server/_ssr/{artifactFiles-BCaIIrrT.mjs → artifactFiles-DtpRidFZ.mjs} +7 -8
  27. package/.output/server/_ssr/{artifactKind-BW0isV8L.mjs → artifactKind-FBYbgSuf.mjs} +27 -2
  28. package/.output/server/_ssr/artifacts-BR3jj0NC.mjs +2 -0
  29. package/.output/server/_ssr/{auth-30Z4lV1w.mjs → auth-C0zoZCGe.mjs} +16 -19
  30. package/.output/server/_ssr/boot-CdOO4xOo.mjs +2 -0
  31. package/.output/server/_ssr/{boot-3BNKujyp.mjs → boot-sNlIkoLe.mjs} +1331 -3927
  32. package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-_7tfuNRi.mjs → bun-sqlite-dialect-BW9W1_Ps-DmlZWqO7.mjs} +2 -2
  33. package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-ucDUbeBk.mjs → d1-sqlite-dialect-BLC8LXE6-CCNzqZwZ.mjs} +2 -2
  34. package/.output/server/_ssr/db-CwLD-5w1.mjs +2 -0
  35. package/.output/server/_ssr/{dist-Cd6nlLlO.mjs → dist-B3SxDOpW.mjs} +2 -2
  36. package/.output/server/_ssr/{factory-CWWwV7XZ.mjs → factory-Dv3Zopis.mjs} +2 -2
  37. package/.output/server/_ssr/invite._token-CJ6-H-s3.mjs +20 -0
  38. package/.output/server/_ssr/{invite._token-SdWXemIc.mjs → invite._token-dLKDJKVs.mjs} +9 -17
  39. package/.output/server/_ssr/{invite._token-BKlz0R2f.mjs → invite._token-l1SjouDz.mjs} +6 -15
  40. package/.output/server/_ssr/{kysely-adapter-C8iS51DB.mjs → kysely-adapter-nL7WKSgw.mjs} +1 -1
  41. package/.output/server/_ssr/{lifecycleUi-DgBQAYzp.mjs → lifecycleUi-Dad3hvhm.mjs} +11 -11
  42. package/.output/server/_ssr/logger-B8m8F1Qu.mjs +2 -0
  43. package/.output/server/_ssr/loopApi-BKyFB4KM.mjs +342 -0
  44. package/.output/server/_ssr/{adapters-BoLkOf1T.mjs → loopProjection-B8a829ij.mjs} +25 -55
  45. package/.output/server/_ssr/loops._loopId-DS16Phmq.mjs +1271 -0
  46. package/.output/server/_ssr/{loops._loopId_.runs._runId-PUGBrD5q.mjs → loops._loopId_.runs._runId-BEJI6iK5.mjs} +23 -74
  47. package/.output/server/_ssr/{loops._loopId_.runs._runId-Ymy4lwee.mjs → loops._loopId_.runs._runId-CduETLqH.mjs} +4 -5
  48. package/.output/server/_ssr/{machineFns-BZ9puxDt.mjs → machineFns-ByMsgG12.mjs} +3 -5
  49. package/.output/server/_ssr/{node-sqlite-dialect-D_3JmkMo.mjs → node-sqlite-dialect-CjNineno.mjs} +2 -2
  50. package/.output/server/_ssr/router-CXyrnvx-.mjs +565 -0
  51. package/.output/server/_ssr/{routes-ClZEdsnB.mjs → routes-BulNEUEE.mjs} +6 -10
  52. package/.output/server/_ssr/{routes-ComqHvCL.mjs → routes-DD94baie.mjs} +3 -3
  53. package/.output/server/_ssr/{routes-D5jJJ-30.mjs → routes-Wjexi35W.mjs} +6 -6
  54. package/.output/server/_ssr/runDiff-Ba8Lg1vg.mjs +2 -0
  55. package/.output/server/_ssr/ssr.mjs +60 -100
  56. package/.output/server/_ssr/store-Cujtg2QE.mjs +2 -0
  57. package/.output/server/_ssr/{t._teamId-BgHV_KFP.mjs → t._teamId-1CreIlPV.mjs} +7 -11
  58. package/.output/server/_ssr/{t._teamId-DDERNgfn.mjs → t._teamId-Bd6-zZsy.mjs} +4 -4
  59. package/.output/server/_ssr/{t._teamId-DRJvKHZn.mjs → t._teamId-COuMKQ4r.mjs} +7 -7
  60. package/.output/server/_ssr/{teamFns-Bp81UO-x.mjs → teamFns-H438WnZC.mjs} +12 -30
  61. package/.output/server/_ssr/{teamFns-bm82twd5.mjs → teamFns-j2JKjorZ.mjs} +2 -2
  62. package/.output/server/_ssr/tokens-DgG_Syq3.mjs +2 -0
  63. package/.output/server/_ssr/{ui-Ww2tTM2u.mjs → ui-D5KWstlb.mjs} +26 -48
  64. package/.output/server/{_tanstack-start-manifest_v-DwKENYCN.mjs → _tanstack-start-manifest_v-3H7yBKLz.mjs} +25 -35
  65. package/{drizzle/0000_round_marauders.sql → .output/server/drizzle/0000_baseline.sql} +102 -44
  66. package/.output/server/drizzle/meta/_journal.json +3 -115
  67. package/.output/server/index.mjs +83 -132
  68. package/{.output/server/drizzle/0000_round_marauders.sql → drizzle/0000_baseline.sql} +102 -44
  69. package/drizzle/meta/_journal.json +3 -115
  70. package/package.json +2 -11
  71. package/scripts/pievo-server.mjs +3 -1
  72. package/scripts/server-cli-lib.mjs +23 -16
  73. package/.output/public/assets/CodeField-dOzyFQNH.js +0 -34
  74. package/.output/public/assets/LoopView-DjVHUyrR.js +0 -59
  75. package/.output/public/assets/Modal-CCRvx959.js +0 -1
  76. package/.output/public/assets/SignIn-Qxw5zDFq.js +0 -1
  77. package/.output/public/assets/actionUi-CXxhzYe2.js +0 -1
  78. package/.output/public/assets/app-D1cij_NJ.css +0 -2
  79. package/.output/public/assets/artifactView-Cd5wWPil.js +0 -66
  80. package/.output/public/assets/index-BRN_CQ8U.js +0 -12
  81. package/.output/public/assets/invite._token-BIxr8DlP.js +0 -1
  82. package/.output/public/assets/invite._token-j2BTCeG1.js +0 -1
  83. package/.output/public/assets/jsx-runtime-BseJUIpC.js +0 -1
  84. package/.output/public/assets/lifecycleUi-Qy_8beQK.js +0 -1
  85. package/.output/public/assets/loopApi-CT1mMhlb.js +0 -3
  86. package/.output/public/assets/loops._loopId-BRBQzioy.js +0 -4
  87. package/.output/public/assets/loops._loopId_.runs._runId-CMnOJkem.js +0 -3
  88. package/.output/public/assets/notifyFns-DYD4EKaG.js +0 -1
  89. package/.output/public/assets/preload-helper-DFkkpP6W.js +0 -3
  90. package/.output/public/assets/routes-3nuEJGdo.js +0 -1
  91. package/.output/public/assets/routes-DORLim-C.js +0 -1
  92. package/.output/public/assets/t._teamId-F5f4K8kd.js +0 -1
  93. package/.output/public/assets/t._teamId-XfE_S1Fo.js +0 -1
  94. package/.output/public/assets/ui-Dhsx6SW0.js +0 -1
  95. package/.output/public/assets/useRouter-DsjH8G0p.js +0 -1
  96. package/.output/server/_libs/@codemirror/autocomplete+[...].mjs +0 -19713
  97. package/.output/server/_libs/@codemirror/lang-css+[...].mjs +0 -2636
  98. package/.output/server/_libs/@codemirror/lang-html+[...].mjs +0 -2247
  99. package/.output/server/_libs/@codemirror/lang-json+[...].mjs +0 -79
  100. package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +0 -1736
  101. package/.output/server/_libs/@uiw/codemirror-extensions-basic-setup+[...].mjs +0 -76
  102. package/.output/server/_libs/babel__runtime.mjs +0 -30
  103. package/.output/server/_libs/clsx.mjs +0 -16
  104. package/.output/server/_libs/codemirror__commands.mjs +0 -1725
  105. package/.output/server/_libs/codemirror__lint.mjs +0 -565
  106. package/.output/server/_libs/codemirror__search.mjs +0 -1138
  107. package/.output/server/_libs/codemirror__theme-one-dark.mjs +0 -161
  108. package/.output/server/_libs/d3-array.mjs +0 -231
  109. package/.output/server/_libs/d3-color.mjs +0 -330
  110. package/.output/server/_libs/d3-format.mjs +0 -252
  111. package/.output/server/_libs/d3-interpolate.mjs +0 -163
  112. package/.output/server/_libs/d3-path.mjs +0 -77
  113. package/.output/server/_libs/d3-scale+[...].mjs +0 -1907
  114. package/.output/server/_libs/d3-shape.mjs +0 -818
  115. package/.output/server/_libs/decimal.js-light.mjs +0 -884
  116. package/.output/server/_libs/dom-serializer+[...].mjs +0 -708
  117. package/.output/server/_libs/domhandler.mjs +0 -461
  118. package/.output/server/_libs/domutils.mjs +0 -868
  119. package/.output/server/_libs/es-toolkit.mjs +0 -1737
  120. package/.output/server/_libs/eventemitter3.mjs +0 -236
  121. package/.output/server/_libs/html-dom-parser+htmlparser2.mjs +0 -1560
  122. package/.output/server/_libs/html-react-parser+[...].mjs +0 -1360
  123. package/.output/server/_libs/react-is.mjs +0 -48
  124. package/.output/server/_libs/react-redux+[...].mjs +0 -205
  125. package/.output/server/_libs/recharts+victory-vendor.mjs +0 -17303
  126. package/.output/server/_libs/uiw__codemirror-themes.mjs +0 -32
  127. package/.output/server/_libs/uiw__react-codemirror.mjs +0 -354
  128. package/.output/server/_ssr/CodeField-B7oOmmwH.mjs +0 -143
  129. package/.output/server/_ssr/DashboardView-BF7PciP7.mjs +0 -2736
  130. package/.output/server/_ssr/LoopPlaybook-DC7QVvPY.mjs +0 -2105
  131. package/.output/server/_ssr/LoopView-DwSrm9Ja.mjs +0 -1300
  132. package/.output/server/_ssr/Modal-MaCG52Pv.mjs +0 -49
  133. package/.output/server/_ssr/artifactView-iuPsp5aa.mjs +0 -304
  134. package/.output/server/_ssr/artifacts-jQ-bfdhI.mjs +0 -2
  135. package/.output/server/_ssr/boot-CsEFT53K.mjs +0 -2
  136. package/.output/server/_ssr/db-CXownd1H.mjs +0 -2
  137. package/.output/server/_ssr/invite._token-CWl6kipD.mjs +0 -28
  138. package/.output/server/_ssr/logger-Gy-47z3k.mjs +0 -2
  139. package/.output/server/_ssr/loopApi-8_KgBapr.mjs +0 -109
  140. package/.output/server/_ssr/loopApi-ABi9SgWS.mjs +0 -564
  141. package/.output/server/_ssr/loops._loopId-SON_t43g.mjs +0 -30
  142. package/.output/server/_ssr/loops._loopId-p1KWsvMM.mjs +0 -1477
  143. package/.output/server/_ssr/notifyFns-BUCePuF3.mjs +0 -118
  144. package/.output/server/_ssr/router-Czxvra6l.mjs +0 -685
  145. package/.output/server/_ssr/runDiff--qLtU4FI.mjs +0 -2
  146. package/.output/server/_ssr/store-40eVzW1S.mjs +0 -2
  147. package/.output/server/_ssr/tokens-CbfoRC_s.mjs +0 -2
  148. package/.output/server/drizzle/0001_naive_silver_fox.sql +0 -25
  149. package/.output/server/drizzle/0002_funny_sage.sql +0 -12
  150. package/.output/server/drizzle/0003_optimal_slapstick.sql +0 -102
  151. package/.output/server/drizzle/0004_remove_grok_agent.sql +0 -5
  152. package/.output/server/drizzle/0005_heavy_gauntlet.sql +0 -8
  153. package/.output/server/drizzle/0006_tranquil_sharon_carter.sql +0 -1
  154. package/.output/server/drizzle/0007_faulty_starbolt.sql +0 -30
  155. package/.output/server/drizzle/0008_durable_lifecycle_evidence.sql +0 -15
  156. package/.output/server/drizzle/0009_ordinary_electro.sql +0 -1
  157. package/.output/server/drizzle/0010_workable_rage.sql +0 -14
  158. package/.output/server/drizzle/0011_steep_marvel_zombies.sql +0 -3
  159. package/.output/server/drizzle/0012_blocked_run_status.sql +0 -12
  160. package/.output/server/drizzle/0013_drop_run_outcome.sql +0 -2
  161. package/.output/server/drizzle/0014_luxuriant_scrambler.sql +0 -5
  162. package/.output/server/drizzle/0015_run_history_foundation.sql +0 -43
  163. package/.output/server/drizzle/0016_plural_machine_runs.sql +0 -4
  164. package/.output/server/drizzle/meta/0000_snapshot.json +0 -1333
  165. package/.output/server/drizzle/meta/0001_snapshot.json +0 -1498
  166. package/.output/server/drizzle/meta/0002_snapshot.json +0 -1576
  167. package/.output/server/drizzle/meta/0003_snapshot.json +0 -1666
  168. package/.output/server/drizzle/meta/0005_snapshot.json +0 -1666
  169. package/.output/server/drizzle/meta/0006_snapshot.json +0 -1672
  170. package/.output/server/drizzle/meta/0007_snapshot.json +0 -1787
  171. package/.output/server/drizzle/meta/0009_snapshot.json +0 -1793
  172. package/.output/server/drizzle/meta/0010_snapshot.json +0 -1891
  173. package/.output/server/drizzle/meta/0011_snapshot.json +0 -1872
  174. package/drizzle/0001_naive_silver_fox.sql +0 -25
  175. package/drizzle/0002_funny_sage.sql +0 -12
  176. package/drizzle/0003_optimal_slapstick.sql +0 -102
  177. package/drizzle/0004_remove_grok_agent.sql +0 -5
  178. package/drizzle/0005_heavy_gauntlet.sql +0 -8
  179. package/drizzle/0006_tranquil_sharon_carter.sql +0 -1
  180. package/drizzle/0007_faulty_starbolt.sql +0 -30
  181. package/drizzle/0008_durable_lifecycle_evidence.sql +0 -15
  182. package/drizzle/0009_ordinary_electro.sql +0 -1
  183. package/drizzle/0010_workable_rage.sql +0 -14
  184. package/drizzle/0011_steep_marvel_zombies.sql +0 -3
  185. package/drizzle/0012_blocked_run_status.sql +0 -12
  186. package/drizzle/0013_drop_run_outcome.sql +0 -2
  187. package/drizzle/0014_luxuriant_scrambler.sql +0 -5
  188. package/drizzle/0015_run_history_foundation.sql +0 -43
  189. package/drizzle/0016_plural_machine_runs.sql +0 -4
  190. package/drizzle/meta/0000_snapshot.json +0 -1333
  191. package/drizzle/meta/0001_snapshot.json +0 -1498
  192. package/drizzle/meta/0002_snapshot.json +0 -1576
  193. package/drizzle/meta/0003_snapshot.json +0 -1666
  194. package/drizzle/meta/0005_snapshot.json +0 -1666
  195. package/drizzle/meta/0006_snapshot.json +0 -1672
  196. package/drizzle/meta/0007_snapshot.json +0 -1787
  197. package/drizzle/meta/0009_snapshot.json +0 -1793
  198. package/drizzle/meta/0010_snapshot.json +0 -1891
  199. package/drizzle/meta/0011_snapshot.json +0 -1872
@@ -1,2105 +0,0 @@
1
- import { o as __toESM } from "../_runtime.mjs";
2
- import { g as require_jsx_runtime, h as require_react } from "../_libs/@base-ui/react+[...].mjs";
3
- import { D as createFetch, K as getBaseURL, P as defu, ht as isSafeUrlScheme, rn as toKebabCase, y as capitalizeFirstLetter } from "./boot-3BNKujyp.mjs";
4
- //#region node_modules/.nitro/vite/services/ssr/assets/LoopPlaybook-DC7QVvPY.js
5
- var import_react = /* @__PURE__ */ __toESM(require_react());
6
- var import_jsx_runtime = require_jsx_runtime();
7
- var PROTO_POLLUTION_PATTERNS = {
8
- proto: /"(?:_|\\u0{2}5[Ff]){2}(?:p|\\u0{2}70)(?:r|\\u0{2}72)(?:o|\\u0{2}6[Ff])(?:t|\\u0{2}74)(?:o|\\u0{2}6[Ff])(?:_|\\u0{2}5[Ff]){2}"\s*:/,
9
- constructor: /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/,
10
- protoShort: /"__proto__"\s*:/,
11
- constructorShort: /"constructor"\s*:/
12
- };
13
- var JSON_SIGNATURE = /^\s*["[{]|^\s*-?\d{1,16}(\.\d{1,17})?([Ee][+-]?\d+)?\s*$/;
14
- var SPECIAL_VALUES = {
15
- true: true,
16
- false: false,
17
- null: null,
18
- undefined: void 0,
19
- nan: NaN,
20
- infinity: Number.POSITIVE_INFINITY,
21
- "-infinity": Number.NEGATIVE_INFINITY
22
- };
23
- var ISO_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,7}))?(?:Z|([+-])(\d{2}):(\d{2}))$/;
24
- function isValidDate(date) {
25
- return date instanceof Date && !isNaN(date.getTime());
26
- }
27
- function parseISODate(value) {
28
- const match = ISO_DATE_REGEX.exec(value);
29
- if (!match) return null;
30
- const [, year, month, day, hour, minute, second, ms, offsetSign, offsetHour, offsetMinute] = match;
31
- const date = new Date(Date.UTC(parseInt(year, 10), parseInt(month, 10) - 1, parseInt(day, 10), parseInt(hour, 10), parseInt(minute, 10), parseInt(second, 10), ms ? parseInt(ms.padEnd(3, "0"), 10) : 0));
32
- if (offsetSign) {
33
- const offset = (parseInt(offsetHour, 10) * 60 + parseInt(offsetMinute, 10)) * (offsetSign === "+" ? -1 : 1);
34
- date.setUTCMinutes(date.getUTCMinutes() + offset);
35
- }
36
- return isValidDate(date) ? date : null;
37
- }
38
- function betterJSONParse(value, options = {}) {
39
- const { strict = false, warnings = false, reviver, parseDates = true } = options;
40
- if (typeof value !== "string") return value;
41
- const trimmed = value.trim();
42
- const lowerValue = trimmed.toLowerCase();
43
- if (lowerValue.length <= 9 && lowerValue in SPECIAL_VALUES) return SPECIAL_VALUES[lowerValue];
44
- if (!JSON_SIGNATURE.test(trimmed)) {
45
- if (strict) throw new SyntaxError("[better-json] Invalid JSON");
46
- return value;
47
- }
48
- if (Object.entries(PROTO_POLLUTION_PATTERNS).some(([key, pattern]) => {
49
- const matches = pattern.test(trimmed);
50
- if (matches && warnings) console.warn(`[better-json] Detected potential prototype pollution attempt using ${key} pattern`);
51
- return matches;
52
- }) && strict) throw new Error("[better-json] Potential prototype pollution attempt detected");
53
- try {
54
- const secureReviver = (key, value) => {
55
- if (key === "__proto__" || key === "constructor" && value && typeof value === "object" && "prototype" in value) {
56
- if (warnings) console.warn(`[better-json] Dropping "${key}" key to prevent prototype pollution`);
57
- return;
58
- }
59
- if (parseDates && typeof value === "string") {
60
- const date = parseISODate(value);
61
- if (date) return date;
62
- }
63
- return reviver ? reviver(key, value) : value;
64
- };
65
- return JSON.parse(trimmed, secureReviver);
66
- } catch (error) {
67
- if (strict) throw error;
68
- return value;
69
- }
70
- }
71
- function parseJSON(value, options = { strict: true }) {
72
- return betterJSONParse(value, options);
73
- }
74
- var redirectPlugin = {
75
- id: "redirect",
76
- name: "Redirect",
77
- hooks: { onSuccess(context) {
78
- if (context.data?.url && context.data?.redirect && isSafeUrlScheme(context.data.url)) {
79
- if (typeof window !== "undefined" && window.location) {
80
- if (window.location) try {
81
- window.location.href = context.data.url;
82
- } catch {}
83
- }
84
- }
85
- } }
86
- };
87
- var listenerQueue = [];
88
- var lqIndex = 0;
89
- var QUEUE_ITEMS_PER_LISTENER = 4;
90
- var nanostoresGlobal = globalThis.nanostoresGlobal ||= { epoch: 0 };
91
- var atom = /* @__NO_SIDE_EFFECTS__ */ (initialValue) => {
92
- let listeners = [];
93
- let $atom = {
94
- get() {
95
- if (!$atom.lc) $atom.listen(() => {})();
96
- return $atom.value;
97
- },
98
- init: initialValue,
99
- lc: 0,
100
- listen(listener) {
101
- $atom.lc = listeners.push(listener);
102
- return () => {
103
- for (let i = lqIndex + QUEUE_ITEMS_PER_LISTENER; i < listenerQueue.length;) if (listenerQueue[i] === listener) listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER);
104
- else i += QUEUE_ITEMS_PER_LISTENER;
105
- let index = listeners.indexOf(listener);
106
- if (~index) {
107
- listeners.splice(index, 1);
108
- if (!--$atom.lc) $atom.off();
109
- }
110
- };
111
- },
112
- notify(oldValue, changedKey) {
113
- nanostoresGlobal.epoch++;
114
- let runListenerQueue = !listenerQueue.length;
115
- for (let listener of listeners) listenerQueue.push(listener, $atom.value, oldValue, changedKey);
116
- if (runListenerQueue) {
117
- for (lqIndex = 0; lqIndex < listenerQueue.length; lqIndex += QUEUE_ITEMS_PER_LISTENER) listenerQueue[lqIndex](listenerQueue[lqIndex + 1], listenerQueue[lqIndex + 2], listenerQueue[lqIndex + 3]);
118
- listenerQueue.length = 0;
119
- }
120
- },
121
- off() {},
122
- set(newValue) {
123
- let oldValue = $atom.value;
124
- if (oldValue !== newValue) {
125
- $atom.value = newValue;
126
- $atom.notify(oldValue);
127
- }
128
- },
129
- subscribe(listener) {
130
- let unbind = $atom.listen(listener);
131
- listener($atom.value);
132
- return unbind;
133
- },
134
- value: initialValue
135
- };
136
- return $atom;
137
- };
138
- var SET = 2;
139
- var MOUNT = 5;
140
- var UNMOUNT = 6;
141
- var REVERT_MUTATION = 10;
142
- var on = (object, listener, eventKey, mutateStore) => {
143
- object.events = object.events || {};
144
- if (!object.events[eventKey + REVERT_MUTATION]) object.events[eventKey + REVERT_MUTATION] = mutateStore((eventProps) => {
145
- object.events[eventKey].reduceRight((event, l) => (l(event), event), {
146
- shared: {},
147
- ...eventProps
148
- });
149
- });
150
- object.events[eventKey] = object.events[eventKey] || [];
151
- object.events[eventKey].push(listener);
152
- return () => {
153
- let currentListeners = object.events[eventKey];
154
- let index = currentListeners.indexOf(listener);
155
- currentListeners.splice(index, 1);
156
- if (!currentListeners.length) {
157
- delete object.events[eventKey];
158
- object.events[eventKey + REVERT_MUTATION]();
159
- delete object.events[eventKey + REVERT_MUTATION];
160
- }
161
- };
162
- };
163
- var onSet = ($store, listener) => on($store, listener, SET, (runListeners) => {
164
- let originSet = $store.set;
165
- let originSetKey = $store.setKey;
166
- if ($store.setKey) $store.setKey = (changed, changedValue) => {
167
- let isAborted;
168
- let abort = () => {
169
- isAborted = true;
170
- };
171
- runListeners({
172
- abort,
173
- changed,
174
- newValue: {
175
- ...$store.value,
176
- [changed]: changedValue
177
- }
178
- });
179
- if (!isAborted) return originSetKey(changed, changedValue);
180
- };
181
- $store.set = (newValue) => {
182
- let isAborted;
183
- let abort = () => {
184
- isAborted = true;
185
- };
186
- runListeners({
187
- abort,
188
- newValue
189
- });
190
- if (!isAborted) return originSet(newValue);
191
- };
192
- return () => {
193
- $store.set = originSet;
194
- $store.setKey = originSetKey;
195
- };
196
- });
197
- var STORE_UNMOUNT_DELAY = 1e3;
198
- var onMount = ($store, initialize) => {
199
- let listener = (payload) => {
200
- let destroy = initialize(payload);
201
- if (destroy) $store.events[UNMOUNT].push(destroy);
202
- };
203
- return on($store, listener, MOUNT, (runListeners) => {
204
- let originListen = $store.listen;
205
- $store.listen = (...args) => {
206
- if (!$store.lc && !$store.active) {
207
- $store.active = true;
208
- runListeners();
209
- }
210
- return originListen(...args);
211
- };
212
- let originOff = $store.off;
213
- $store.events[UNMOUNT] = [];
214
- $store.off = () => {
215
- originOff();
216
- setTimeout(() => {
217
- if ($store.active && !$store.lc) {
218
- $store.active = false;
219
- for (let destroy of $store.events[UNMOUNT]) destroy();
220
- $store.events[UNMOUNT] = [];
221
- }
222
- }, STORE_UNMOUNT_DELAY);
223
- };
224
- return () => {
225
- $store.listen = originListen;
226
- $store.off = originOff;
227
- };
228
- });
229
- };
230
- function listenKeys($store, keys, listener) {
231
- let keysSet = new Set(keys).add(void 0);
232
- return $store.listen((value, oldValue, changed) => {
233
- if (keysSet.has(changed)) listener(value, oldValue, changed);
234
- });
235
- }
236
- function isPlainObject(value) {
237
- if (typeof value !== "object" || value === null) return false;
238
- const prototype = Object.getPrototypeOf(value);
239
- return prototype === Object.prototype || prototype === null;
240
- }
241
- /**
242
- * Deep structural equality for JSON-serializable values.
243
- * Handles: primitives, null, arrays, and plain objects.
244
- * Short-circuits on referential equality at every recursion level.
245
- */
246
- function isJsonEqual(a, b) {
247
- if (a === b) return true;
248
- if (Array.isArray(a) && Array.isArray(b)) {
249
- if (a.length !== b.length) return false;
250
- for (let i = 0; i < a.length; i++) if (!isJsonEqual(a[i], b[i])) return false;
251
- return true;
252
- }
253
- if (isPlainObject(a) && isPlainObject(b)) {
254
- const keysA = Object.keys(a);
255
- const keysB = Object.keys(b);
256
- if (keysA.length !== keysB.length) return false;
257
- for (const key of keysA) if (!(key in b) || !isJsonEqual(a[key], b[key])) return false;
258
- return true;
259
- }
260
- return false;
261
- }
262
- /**
263
- * Attach an equality gate to a nanostores atom via `onSet`.
264
- * When `isEqual(currentValue, newValue)` returns true, the `set()` call
265
- * is aborted: no listeners fire, no framework re-renders occur.
266
- *
267
- * Returns the unsubscribe function from `onSet`.
268
- */
269
- function withEquality(store, isEqual) {
270
- return onSet(store, ({ newValue, abort }) => {
271
- if (isEqual(store.value, newValue)) abort();
272
- });
273
- }
274
- var kBroadcastChannel = Symbol.for("better-auth:broadcast-channel");
275
- var now$1 = () => Math.floor(Date.now() / 1e3);
276
- var WindowBroadcastChannel = class {
277
- listeners = /* @__PURE__ */ new Set();
278
- name;
279
- constructor(name = "better-auth.message") {
280
- this.name = name;
281
- }
282
- subscribe(listener) {
283
- this.listeners.add(listener);
284
- return () => {
285
- this.listeners.delete(listener);
286
- };
287
- }
288
- post(message) {
289
- if (typeof window === "undefined") return;
290
- try {
291
- localStorage.setItem(this.name, JSON.stringify({
292
- ...message,
293
- timestamp: now$1()
294
- }));
295
- } catch {}
296
- }
297
- setup() {
298
- if (typeof window === "undefined" || typeof window.addEventListener === "undefined") return () => {};
299
- const handler = (event) => {
300
- if (event.key !== this.name) return;
301
- const message = JSON.parse(event.newValue ?? "{}");
302
- if (message?.event !== "session" || !message?.data) return;
303
- this.listeners.forEach((listener) => listener(message));
304
- };
305
- window.addEventListener("storage", handler);
306
- return () => {
307
- window.removeEventListener("storage", handler);
308
- };
309
- }
310
- };
311
- function getGlobalBroadcastChannel(name = "better-auth.message") {
312
- if (!globalThis[kBroadcastChannel]) globalThis[kBroadcastChannel] = new WindowBroadcastChannel(name);
313
- return globalThis[kBroadcastChannel];
314
- }
315
- var kFocusManager = Symbol.for("better-auth:focus-manager");
316
- var WindowFocusManager = class {
317
- listeners = /* @__PURE__ */ new Set();
318
- subscribe(listener) {
319
- this.listeners.add(listener);
320
- return () => {
321
- this.listeners.delete(listener);
322
- };
323
- }
324
- setFocused(focused) {
325
- this.listeners.forEach((listener) => listener(focused));
326
- }
327
- setup() {
328
- if (typeof window === "undefined" || typeof document === "undefined" || typeof window.addEventListener === "undefined") return () => {};
329
- const visibilityHandler = () => {
330
- if (document.visibilityState === "visible") this.setFocused(true);
331
- };
332
- document.addEventListener("visibilitychange", visibilityHandler, false);
333
- return () => {
334
- document.removeEventListener("visibilitychange", visibilityHandler, false);
335
- };
336
- }
337
- };
338
- function getGlobalFocusManager() {
339
- if (!globalThis[kFocusManager]) globalThis[kFocusManager] = new WindowFocusManager();
340
- return globalThis[kFocusManager];
341
- }
342
- var kOnlineManager = Symbol.for("better-auth:online-manager");
343
- var WindowOnlineManager = class {
344
- listeners = /* @__PURE__ */ new Set();
345
- isOnline = typeof navigator !== "undefined" ? navigator.onLine : true;
346
- subscribe(listener) {
347
- this.listeners.add(listener);
348
- return () => {
349
- this.listeners.delete(listener);
350
- };
351
- }
352
- setOnline(online) {
353
- this.isOnline = online;
354
- this.listeners.forEach((listener) => listener(online));
355
- }
356
- setup() {
357
- if (typeof window === "undefined" || typeof window.addEventListener === "undefined") return () => {};
358
- const onOnline = () => this.setOnline(true);
359
- const onOffline = () => this.setOnline(false);
360
- window.addEventListener("online", onOnline, false);
361
- window.addEventListener("offline", onOffline, false);
362
- return () => {
363
- window.removeEventListener("online", onOnline, false);
364
- window.removeEventListener("offline", onOffline, false);
365
- };
366
- }
367
- };
368
- function getGlobalOnlineManager() {
369
- if (!globalThis[kOnlineManager]) globalThis[kOnlineManager] = new WindowOnlineManager();
370
- return globalThis[kOnlineManager];
371
- }
372
- var now = () => Math.floor(Date.now() / 1e3);
373
- /**
374
- * Rate limit: don't refetch on focus if a session request was made within this many seconds
375
- */
376
- var FOCUS_REFETCH_RATE_LIMIT_SECONDS = 5;
377
- function createSessionRefreshManager(opts) {
378
- const { fetchSession, shouldPollSession = () => true, sessionSignal, options = {} } = opts;
379
- const refetchInterval = options.sessionOptions?.refetchInterval ?? 0;
380
- const refetchOnWindowFocus = options.sessionOptions?.refetchOnWindowFocus ?? true;
381
- const refetchWhenOffline = options.sessionOptions?.refetchWhenOffline ?? false;
382
- const state = {
383
- isInitialized: false,
384
- lastSessionRequest: 0
385
- };
386
- const shouldRefetch = () => {
387
- return refetchWhenOffline || getGlobalOnlineManager().isOnline;
388
- };
389
- const triggerRefetch = (event) => {
390
- if (!shouldRefetch()) return;
391
- if (event?.event === "storage") {
392
- fetchSession();
393
- return;
394
- }
395
- if (event?.event === "poll") {
396
- state.lastSessionRequest = now();
397
- fetchSession();
398
- return;
399
- }
400
- if (event?.event === "visibilitychange") {
401
- if (now() - state.lastSessionRequest < FOCUS_REFETCH_RATE_LIMIT_SECONDS) return;
402
- state.lastSessionRequest = now();
403
- fetchSession();
404
- return;
405
- }
406
- fetchSession();
407
- };
408
- const broadcastSessionUpdate = (trigger) => {
409
- getGlobalBroadcastChannel().post({
410
- event: "session",
411
- data: { trigger },
412
- clientId: Math.random().toString(36).substring(7)
413
- });
414
- };
415
- const setupPolling = () => {
416
- if (refetchInterval && refetchInterval > 0) state.pollInterval = setInterval(() => {
417
- if (shouldPollSession()) triggerRefetch({ event: "poll" });
418
- }, refetchInterval * 1e3);
419
- };
420
- const setupBroadcast = () => {
421
- state.unsubscribeBroadcast = getGlobalBroadcastChannel().subscribe(() => {
422
- triggerRefetch({ event: "storage" });
423
- });
424
- };
425
- const setupFocusRefetch = () => {
426
- if (!refetchOnWindowFocus) return;
427
- state.unsubscribeFocus = getGlobalFocusManager().subscribe(() => {
428
- triggerRefetch({ event: "visibilitychange" });
429
- });
430
- };
431
- const setupOnlineRefetch = () => {
432
- state.unsubscribeOnline = getGlobalOnlineManager().subscribe((online) => {
433
- if (online) triggerRefetch({ event: "visibilitychange" });
434
- });
435
- };
436
- const setupSignalSubscription = () => {
437
- state.unsubscribeSignal = sessionSignal.listen(() => {
438
- fetchSession();
439
- });
440
- };
441
- const init = () => {
442
- if (state.isInitialized) return;
443
- state.isInitialized = true;
444
- setupPolling();
445
- setupBroadcast();
446
- setupFocusRefetch();
447
- setupOnlineRefetch();
448
- setupSignalSubscription();
449
- state.cleanupBroadcastSetup = getGlobalBroadcastChannel().setup();
450
- state.cleanupFocusSetup = getGlobalFocusManager().setup();
451
- state.cleanupOnlineSetup = getGlobalOnlineManager().setup();
452
- };
453
- const cleanup = () => {
454
- if (!state.isInitialized) return;
455
- if (state.pollInterval) {
456
- clearInterval(state.pollInterval);
457
- state.pollInterval = void 0;
458
- }
459
- if (state.unsubscribeBroadcast) {
460
- state.unsubscribeBroadcast();
461
- state.unsubscribeBroadcast = void 0;
462
- }
463
- if (state.unsubscribeFocus) {
464
- state.unsubscribeFocus();
465
- state.unsubscribeFocus = void 0;
466
- }
467
- if (state.unsubscribeOnline) {
468
- state.unsubscribeOnline();
469
- state.unsubscribeOnline = void 0;
470
- }
471
- if (state.unsubscribeSignal) {
472
- state.unsubscribeSignal();
473
- state.unsubscribeSignal = void 0;
474
- }
475
- if (state.cleanupBroadcastSetup) {
476
- state.cleanupBroadcastSetup();
477
- state.cleanupBroadcastSetup = void 0;
478
- }
479
- if (state.cleanupFocusSetup) {
480
- state.cleanupFocusSetup();
481
- state.cleanupFocusSetup = void 0;
482
- }
483
- if (state.cleanupOnlineSetup) {
484
- state.cleanupOnlineSetup();
485
- state.cleanupOnlineSetup = void 0;
486
- }
487
- state.isInitialized = false;
488
- state.lastSessionRequest = 0;
489
- };
490
- return {
491
- init,
492
- cleanup,
493
- triggerRefetch,
494
- broadcastSessionUpdate
495
- };
496
- }
497
- var isServer = () => typeof window === "undefined";
498
- /**
499
- * Normalize $fetch response: `throw: true` returns data directly,
500
- * otherwise `{ data, error }`.
501
- */
502
- function normalizeSessionResponse(res) {
503
- if (typeof res === "object" && res !== null && "data" in res && "error" in res) return res;
504
- return {
505
- data: res,
506
- error: null
507
- };
508
- }
509
- function normalizeSessionData(data) {
510
- if (!data) return null;
511
- if (data.session === null && data.user === null) return null;
512
- return data;
513
- }
514
- function isSessionAtomEqual(a, b) {
515
- return isJsonEqual(a.data, b.data) && a.error === b.error && a.isPending === b.isPending && a.isRefetching === b.isRefetching && a.refetch === b.refetch;
516
- }
517
- function getSessionAtom($fetch, options) {
518
- const $signal = /* @__PURE__ */ atom(false);
519
- let abortController;
520
- const refetch = (queryParams) => fetchSession(queryParams);
521
- const session = /* @__PURE__ */ atom({
522
- data: null,
523
- error: null,
524
- isPending: true,
525
- isRefetching: false,
526
- refetch
527
- });
528
- withEquality(session, isSessionAtomEqual);
529
- const settleAbortedFetch = (controller) => {
530
- if (abortController !== controller) return;
531
- const current = session.get();
532
- abortController = void 0;
533
- if (!current.isPending && !current.isRefetching) return;
534
- session.set({
535
- ...current,
536
- isPending: false,
537
- isRefetching: false,
538
- refetch
539
- });
540
- };
541
- const fetchSession = async (queryParams) => {
542
- abortController?.abort();
543
- const controller = new AbortController();
544
- abortController = controller;
545
- const current = session.get();
546
- session.set({
547
- ...current,
548
- isPending: current.data === null,
549
- isRefetching: true,
550
- error: null,
551
- refetch
552
- });
553
- try {
554
- const res = await $fetch("/get-session", {
555
- method: "GET",
556
- query: queryParams?.query,
557
- signal: controller.signal
558
- });
559
- if (controller.signal.aborted) {
560
- settleAbortedFetch(controller);
561
- return;
562
- }
563
- let { data, error } = normalizeSessionResponse(res);
564
- if (data?.needsRefresh) try {
565
- const refreshRes = await $fetch("/get-session", {
566
- method: "POST",
567
- signal: controller.signal
568
- });
569
- if (controller.signal.aborted) {
570
- settleAbortedFetch(controller);
571
- return;
572
- }
573
- ({data, error} = normalizeSessionResponse(refreshRes));
574
- } catch {
575
- if (controller.signal.aborted) {
576
- settleAbortedFetch(controller);
577
- return;
578
- }
579
- }
580
- if (error) {
581
- const latest = session.get();
582
- const isUnauthorized = error?.status === 401;
583
- session.set({
584
- data: isUnauthorized ? null : latest.data,
585
- error,
586
- isPending: false,
587
- isRefetching: false,
588
- refetch
589
- });
590
- return;
591
- }
592
- const sessionData = normalizeSessionData(data);
593
- const current = session.get();
594
- const stableData = current.data != null && sessionData != null && isJsonEqual(current.data, sessionData) ? current.data : sessionData;
595
- session.set({
596
- data: stableData,
597
- error: null,
598
- isPending: false,
599
- isRefetching: false,
600
- refetch
601
- });
602
- } catch (fetchError) {
603
- if (controller.signal.aborted) {
604
- settleAbortedFetch(controller);
605
- return;
606
- }
607
- const latest = session.get();
608
- session.set({
609
- data: latest.data,
610
- error: fetchError,
611
- isPending: false,
612
- isRefetching: false,
613
- refetch
614
- });
615
- }
616
- };
617
- let broadcastSessionUpdate = () => {};
618
- onMount(session, () => {
619
- let timeoutId;
620
- if (!isServer()) timeoutId = setTimeout(() => {
621
- fetchSession();
622
- }, 0);
623
- const refreshManager = createSessionRefreshManager({
624
- fetchSession,
625
- shouldPollSession: () => session.get().data != null,
626
- sessionSignal: $signal,
627
- options
628
- });
629
- refreshManager.init();
630
- broadcastSessionUpdate = refreshManager.broadcastSessionUpdate;
631
- return () => {
632
- if (timeoutId) clearTimeout(timeoutId);
633
- const controller = abortController;
634
- controller?.abort();
635
- if (controller) settleAbortedFetch(controller);
636
- refreshManager.cleanup();
637
- };
638
- });
639
- return {
640
- session,
641
- $sessionSignal: $signal,
642
- broadcastSessionUpdate: (trigger) => broadcastSessionUpdate(trigger)
643
- };
644
- }
645
- var resolvePublicAuthUrl = (basePath) => {
646
- if (typeof process === "undefined") return void 0;
647
- const path = basePath ?? "/api/auth";
648
- if (process.env.NEXT_PUBLIC_AUTH_URL) return process.env.NEXT_PUBLIC_AUTH_URL;
649
- if (typeof window === "undefined") {
650
- if (process.env.NEXTAUTH_URL) try {
651
- return process.env.NEXTAUTH_URL;
652
- } catch {}
653
- if (process.env.VERCEL_URL) try {
654
- const protocol = process.env.VERCEL_URL.startsWith("http") ? "" : "https://";
655
- return `${new URL(`${protocol}${process.env.VERCEL_URL}`).origin}${path}`;
656
- } catch {}
657
- }
658
- };
659
- var getClientConfig = (options, loadEnv) => {
660
- const isCredentialsSupported = "credentials" in Request.prototype;
661
- const baseURL = getBaseURL(options?.baseURL, options?.basePath, void 0, loadEnv) ?? resolvePublicAuthUrl(options?.basePath) ?? "/api/auth";
662
- const pluginsFetchPlugins = options?.plugins?.flatMap((plugin) => plugin.fetchPlugins).filter((pl) => pl !== void 0) || [];
663
- const lifeCyclePlugin = {
664
- id: "lifecycle-hooks",
665
- name: "lifecycle-hooks",
666
- hooks: {
667
- onSuccess: options?.fetchOptions?.onSuccess,
668
- onError: options?.fetchOptions?.onError,
669
- onRequest: options?.fetchOptions?.onRequest,
670
- onResponse: options?.fetchOptions?.onResponse
671
- }
672
- };
673
- const { onSuccess: _onSuccess, onError: _onError, onRequest: _onRequest, onResponse: _onResponse, ...restOfFetchOptions } = options?.fetchOptions || {};
674
- const $fetch = createFetch({
675
- baseURL,
676
- ...isCredentialsSupported ? { credentials: "include" } : {},
677
- method: "GET",
678
- jsonParser(text) {
679
- if (!text) return null;
680
- return parseJSON(text, { strict: false });
681
- },
682
- customFetchImpl: fetch,
683
- ...restOfFetchOptions,
684
- plugins: [
685
- lifeCyclePlugin,
686
- ...restOfFetchOptions.plugins || [],
687
- ...options?.disableDefaultFetchPlugins ? [] : [redirectPlugin],
688
- ...pluginsFetchPlugins
689
- ]
690
- });
691
- const { $sessionSignal, session, broadcastSessionUpdate } = getSessionAtom($fetch, options);
692
- const plugins = options?.plugins || [];
693
- let pluginsActions = {};
694
- const pluginsAtoms = {
695
- $sessionSignal,
696
- session
697
- };
698
- const pluginPathMethods = {
699
- "/sign-out": "POST",
700
- "/revoke-sessions": "POST",
701
- "/revoke-other-sessions": "POST",
702
- "/delete-user": "POST"
703
- };
704
- const atomListeners = [{
705
- signal: "$sessionSignal",
706
- matcher(path) {
707
- return path === "/sign-out" || path === "/update-user" || path === "/update-session" || path === "/sign-up/email" || path === "/sign-in/email" || path === "/delete-user" || path === "/verify-email" || path === "/revoke-sessions" || path === "/revoke-session" || path === "/revoke-other-sessions" || path === "/change-email" || path === "/change-password";
708
- },
709
- callback(path) {
710
- if (path === "/sign-out") broadcastSessionUpdate("signout");
711
- else if (path === "/update-user" || path === "/update-session") broadcastSessionUpdate("updateUser");
712
- }
713
- }];
714
- for (const plugin of plugins) {
715
- if (plugin.getAtoms) Object.assign(pluginsAtoms, plugin.getAtoms?.($fetch));
716
- if (plugin.pathMethods) Object.assign(pluginPathMethods, plugin.pathMethods);
717
- if (plugin.atomListeners) atomListeners.push(...plugin.atomListeners);
718
- }
719
- const $store = {
720
- notify: (signal) => {
721
- pluginsAtoms[signal].set(!pluginsAtoms[signal].get());
722
- },
723
- listen: (signal, listener) => {
724
- pluginsAtoms[signal].subscribe(listener);
725
- },
726
- atoms: pluginsAtoms
727
- };
728
- for (const plugin of plugins) if (plugin.getActions) pluginsActions = defu(plugin.getActions?.($fetch, $store, options) ?? {}, pluginsActions);
729
- return {
730
- get baseURL() {
731
- return baseURL;
732
- },
733
- pluginsActions,
734
- pluginsAtoms,
735
- pluginPathMethods,
736
- atomListeners,
737
- $fetch,
738
- $store
739
- };
740
- };
741
- function isAtom(value) {
742
- return typeof value === "object" && value !== null && "get" in value && typeof value.get === "function" && "lc" in value && typeof value.lc === "number";
743
- }
744
- function getMethod(path, knownPathMethods, args) {
745
- const method = knownPathMethods[path];
746
- const { fetchOptions, query: _query, ...body } = args || {};
747
- if (method) return method;
748
- if (fetchOptions?.method) return fetchOptions.method;
749
- if (body && Object.keys(body).length > 0) return "POST";
750
- return "GET";
751
- }
752
- function createDynamicPathProxy(routes, client, knownPathMethods, atoms, atomListeners) {
753
- function createProxy(path = []) {
754
- return new Proxy(function() {}, {
755
- get(_, prop) {
756
- if (typeof prop !== "string") return;
757
- if (prop === "then" || prop === "catch" || prop === "finally") return;
758
- const fullPath = [...path, prop];
759
- let current = routes;
760
- for (const segment of fullPath) if (current && typeof current === "object" && segment in current) current = current[segment];
761
- else {
762
- current = void 0;
763
- break;
764
- }
765
- if (typeof current === "function") return current;
766
- if (isAtom(current)) return current;
767
- return createProxy(fullPath);
768
- },
769
- apply: async (_, __, args) => {
770
- const routePath = "/" + path.map(toKebabCase).join("/");
771
- const arg = args[0] || {};
772
- const fetchOptions = args[1] || {};
773
- const { query, fetchOptions: argFetchOptions, ...body } = arg;
774
- const options = {
775
- ...fetchOptions,
776
- ...argFetchOptions
777
- };
778
- const method = getMethod(routePath, knownPathMethods, arg);
779
- return await client(routePath, {
780
- ...options,
781
- body: method === "GET" ? void 0 : {
782
- ...body,
783
- ...options?.body || {}
784
- },
785
- query: query || options?.query,
786
- method,
787
- async onSuccess(context) {
788
- await options?.onSuccess?.(context);
789
- if (!atomListeners || options.disableSignal) return;
790
- /**
791
- * We trigger listeners
792
- */
793
- const matches = atomListeners.filter((s) => s.matcher(routePath));
794
- if (!matches.length) return;
795
- const visited = /* @__PURE__ */ new Set();
796
- for (const match of matches) {
797
- const signal = atoms[match.signal];
798
- if (!signal) return;
799
- if (visited.has(match.signal)) continue;
800
- visited.add(match.signal);
801
- /**
802
- * To avoid race conditions we set the signal in a setTimeout
803
- */
804
- const val = signal.get();
805
- setTimeout(() => {
806
- signal.set(!val);
807
- }, 10);
808
- match.callback?.(routePath);
809
- }
810
- }
811
- });
812
- }
813
- });
814
- }
815
- return createProxy();
816
- }
817
- /**
818
- * Subscribe to store changes and get store's value.
819
- *
820
- * Can be used with store builder too.
821
- *
822
- * ```js
823
- * import { useStore } from 'nanostores/react'
824
- *
825
- * import { router } from '../store/router'
826
- *
827
- * export const Layout = () => {
828
- * let page = useStore(router)
829
- * if (page.route === 'home') {
830
- * return <HomePage />
831
- * } else {
832
- * return <Error404 />
833
- * }
834
- * }
835
- * ```
836
- *
837
- * @param store Store instance.
838
- * @returns Store value.
839
- */
840
- function useStore(store, options = {}) {
841
- const snapshotRef = (0, import_react.useRef)(store.get());
842
- const { keys, deps = [store, keys] } = options;
843
- const subscribe = (0, import_react.useCallback)((onChange) => {
844
- const emitChange = (value) => {
845
- if (snapshotRef.current === value) return;
846
- snapshotRef.current = value;
847
- onChange();
848
- };
849
- emitChange(store.value);
850
- if (keys?.length) return listenKeys(store, keys, emitChange);
851
- return store.listen(emitChange);
852
- }, deps);
853
- const get = () => snapshotRef.current;
854
- return (0, import_react.useSyncExternalStore)(subscribe, get, get);
855
- }
856
- function getAtomKey(str) {
857
- return `use${capitalizeFirstLetter(str)}`;
858
- }
859
- function createAuthClient(options) {
860
- const { pluginPathMethods, pluginsActions, pluginsAtoms, $fetch, $store, atomListeners } = getClientConfig(options);
861
- const resolvedHooks = {};
862
- for (const [key, value] of Object.entries(pluginsAtoms)) resolvedHooks[getAtomKey(key)] = () => useStore(value);
863
- return createDynamicPathProxy({
864
- ...pluginsActions,
865
- ...resolvedHooks,
866
- $fetch,
867
- $store
868
- }, $fetch, pluginPathMethods, pluginsAtoms, atomListeners);
869
- }
870
- /** Browser auth client (same-origin /api/auth). */
871
- var authClient = createAuthClient();
872
- var { signIn, useSession } = authClient;
873
- /**
874
- * Shared Pievo mark geometry: eight durable steps form a cycle and the
875
- * interactive-blue runner marks the next scheduled pass.
876
- *
877
- * Variants are props on one geometry (styles in app.css):
878
- * - `plate` - dark tile behind the steps (favicon / app-icon contexts);
879
- * without it the steps inherit currentColor (inline contexts).
880
- * - `trail` - two fading steps behind the runner, so a static rendering
881
- * still reads as motion (print / social cards).
882
- * - `animated` - the runner advances around the cycle; reduced-motion users
883
- * see the canonical static first frame.
884
- */
885
- var RING = [
886
- [9, 9],
887
- [37, 9],
888
- [65, 9],
889
- [65, 37],
890
- [65, 65],
891
- [37, 65],
892
- [9, 65],
893
- [9, 37]
894
- ];
895
- function RingLogo({ size = 24, plate = false, trail = false, animated = false }) {
896
- const cellClass = (i) => {
897
- const parts = ["ring-cell", `rc${i}`];
898
- if (i === 0) parts.push("ring-runner");
899
- else if (trail && i === 7) parts.push("ring-trail-1");
900
- else if (trail && i === 6) parts.push("ring-trail-2");
901
- return parts.join(" ");
902
- };
903
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
904
- width: size,
905
- height: size,
906
- viewBox: "0 0 96 96",
907
- role: "img",
908
- "aria-label": "Pievo",
909
- className: [
910
- "ring-logo",
911
- plate && "ring-logo-plate",
912
- animated && "ring-logo-animated"
913
- ].filter(Boolean).join(" "),
914
- children: [plate && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
915
- width: "96",
916
- height: "96",
917
- rx: "15",
918
- fill: "#0b0b0b"
919
- }), RING.map(([x, y], i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
920
- x,
921
- y,
922
- width: 22,
923
- height: 22,
924
- rx: 6,
925
- className: cellClass(i)
926
- }, i))]
927
- });
928
- }
929
- /**
930
- * Pievo's primary product mark: one scheduled pass moving around a durable ring.
931
- * It reuses the same geometry as the favicon and README asset; animation is a
932
- * progressive enhancement and parks on the canonical first frame when reduced
933
- * motion is requested.
934
- */
935
- function PievoLogo({ size = 56 }) {
936
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RingLogo, {
937
- size,
938
- plate: true,
939
- animated: true
940
- });
941
- }
942
- /** The project's source repository, shared by public UI surfaces. */
943
- var GITHUB_URL = "https://github.com/kky42/pievo";
944
- function GitHubIcon({ className }) {
945
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
946
- viewBox: "0 0 24 24",
947
- fill: "currentColor",
948
- "aria-hidden": true,
949
- className,
950
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 .5C5.65.5.5 5.65.5 12c0 5.08 3.29 9.39 7.86 10.91.58.11.79-.25.79-.55 0-.27-.01-1.17-.02-2.12-3.2.7-3.88-1.36-3.88-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.04-.71.08-.7.08-.7 1.15.08 1.76 1.19 1.76 1.19 1.03 1.75 2.69 1.25 3.34.95.1-.74.4-1.25.72-1.54-2.55-.29-5.24-1.28-5.24-5.68 0-1.26.45-2.28 1.19-3.09-.12-.29-.52-1.46.11-3.05 0 0 .97-.31 3.18 1.18a11.1 11.1 0 0 1 5.8 0c2.2-1.49 3.17-1.18 3.17-1.18.63 1.59.23 2.76.11 3.05.74.81 1.19 1.83 1.19 3.09 0 4.41-2.69 5.38-5.25 5.67.41.35.77 1.05.77 2.12 0 1.53-.01 2.76-.01 3.14 0 .3.2.66.8.55A11.51 11.51 0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5z" })
951
- });
952
- }
953
- /**
954
- * LoopPlaybook - the static education band at the bottom of the dashboard.
955
- *
956
- * Sells the method behind the product in four beats: the anatomy of a good
957
- * loop, the three roles serious loops grow into, the evolve cycle that makes
958
- * a loop antifragile, and what Pievo scaffolds by default. Pure content -
959
- * no data wiring, so the dashboard poll never touches it. The pixel face
960
- * (font-pixel) is reserved for kickers and the big titles; everything else
961
- * stays on the app tokens so light/dark adapt for free.
962
- */
963
- function LoopPlaybook({ onStart }) {
964
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
965
- className: "mt-24 border-t border-hairline pt-16",
966
- children: [
967
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
968
- className: "text-center",
969
- children: [
970
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
971
- className: "font-pixel text-label uppercase tracking-[0.18em] text-secondary",
972
- children: "The loop playbook"
973
- }),
974
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", {
975
- className: "mx-auto mt-3 max-w-[620px] font-pixel text-[clamp(24px,4vw,34px)] leading-[1.15] text-display",
976
- children: "Anatomy of good loops"
977
- }),
978
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
979
- className: "mx-auto mt-4 max-w-[520px] text-body leading-relaxed text-secondary",
980
- children: "That is the easy 5%. The real work is the structure that lets you walk away while it runs. Every good loop we have seen follows the same playbook."
981
- })
982
- ]
983
- }),
984
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaybookHead, {
985
- num: "01",
986
- title: "Four parts of a good loop"
987
- }),
988
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
989
- className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
990
- children: [
991
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IdeaCard, {
992
- title: "Contract",
993
- caption: "One file the agent re-reads every run: the goal, the boundary fence, the steps. The fence decides whether you can walk away.",
994
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DocMock, {
995
- name: "contract.md",
996
- lines: [
997
- { h: "## Goal" },
998
- { skel: "w-4/5" },
999
- { h: "## Boundaries" },
1000
- { hot: "ship it yourself vs ask a human" },
1001
- { skel: "w-3/5" },
1002
- { h: "## SOP" },
1003
- { skel: "w-4/6" }
1004
- ]
1005
- })
1006
- }),
1007
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IdeaCard, {
1008
- title: "Memory + logs",
1009
- caption: "Durable memory across runs, so it never re-does work and every lesson sticks. Month three is smarter than week one.",
1010
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DocMock, {
1011
- name: "memory.md",
1012
- lines: [
1013
- { h: "## Memory" },
1014
- { t: "hypothesis: credit-wall users reply 3x" },
1015
- { t: "skip: known-noise fingerprints" },
1016
- { h: "## Logs" },
1017
- { t: "07-08 fixed null-team, PR #1027" },
1018
- { t: "07-07 nothing new, clean stop" }
1019
- ]
1020
- })
1021
- }),
1022
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IdeaCard, {
1023
- title: "Verifier",
1024
- caption: "Work loops with verify until there is evidence a human can glance at. No proof, not done.",
1025
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VerifierDiagram, {})
1026
- }),
1027
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(IdeaCard, {
1028
- title: "Trigger",
1029
- caption: "Pick the cheapest trigger that fits: a push toward a goal, a schedule, or an event gate so empty runs cost nothing.",
1030
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1031
- className: "flex h-full flex-col justify-center gap-2",
1032
- children: [
1033
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriggerRow, {
1034
- code: "while (goal not met)",
1035
- label: "continuous push"
1036
- }),
1037
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriggerRow, {
1038
- code: "0 6 * * *",
1039
- label: "cron schedule"
1040
- }),
1041
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TriggerRow, {
1042
- code: "on: new ticket",
1043
- label: "event, gated"
1044
- })
1045
- ]
1046
- })
1047
- })
1048
- ]
1049
- }),
1050
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaybookHead, {
1051
- num: "02",
1052
- title: "Serious loops split into three roles"
1053
- }),
1054
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1055
- className: "mx-auto -mt-3 mb-8 max-w-[590px] text-center text-body text-secondary",
1056
- children: "Simple loops are one agent doing the whole job. Once a loop ships real work to real people, it splits: one agent finds the work, one does it in an isolated lane, one proves it. You approve evidence, not diffs."
1057
- }),
1058
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RolesFlow, {}),
1059
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PlaybookHead, {
1060
- num: "03",
1061
- title: "Evolve, or the loop stays as dumb as day one"
1062
- }),
1063
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1064
- className: "rounded-card border border-hairline bg-surface p-6 sm:p-8",
1065
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1066
- className: "grid grid-cols-1 gap-x-10 gap-y-3 sm:grid-cols-2",
1067
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1068
- className: "text-body leading-relaxed text-primary",
1069
- children: "Fragile systems break on a bad run. Robust ones survive it. An antifragile loop gets stronger from it: a periodic evolve pass starts with bounded history aggregates, then drills into only the decisive runs to ask where money was wasted, which boundary is too loose, and which mistake keeps repeating."
1070
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1071
- className: "text-body leading-relaxed text-secondary",
1072
- children: "Its output is not product work. It is changes to the loop itself: a tighter contract, a cheaper trigger, mechanical steps folded into scripts and skills. A loop that improves the loop."
1073
- })]
1074
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1075
- className: "mt-6 border-t border-hairline pt-6",
1076
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EvolveTimeline, {})
1077
- })]
1078
- }),
1079
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1080
- className: "mt-4 rounded-card border border-hairline bg-surface p-6 sm:p-8",
1081
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1082
- className: "mx-auto max-w-[580px] text-center",
1083
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1084
- className: "font-pixel text-[clamp(15px,2vw,19px)] leading-snug text-display",
1085
- children: "Every run compiles a cheaper, smarter next run"
1086
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1087
- className: "mt-2.5 text-body leading-relaxed text-secondary",
1088
- children: "The payoff shows up on the bill and in the work. Each pass folds what the loop learned into scripts, skills and a tighter contract, so the next run reasons less, misses less, and costs less. Born agentic, it graduates to a cheap script, and the agent only wakes back up when something surprising happens."
1089
- })]
1090
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1091
- className: "mt-6",
1092
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CostCurve, {})
1093
- })]
1094
- }),
1095
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1096
- className: "mt-16 rounded-card bg-display px-6 py-10 text-center sm:px-10",
1097
- children: [
1098
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1099
- className: "font-pixel text-label uppercase tracking-[0.18em] text-paper/60",
1100
- children: "Built in"
1101
- }),
1102
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
1103
- className: "mx-auto mt-3 max-w-[560px] font-pixel text-[clamp(21px,3vw,28px)] leading-[1.2] text-paper",
1104
- children: "Pievo ships the guardrails by default"
1105
- }),
1106
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("ul", {
1107
- className: "mx-auto mt-7 grid max-w-[760px] grid-cols-1 gap-x-8 gap-y-2.5 text-left sm:grid-cols-2",
1108
- children: [
1109
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BuiltIn, { children: "Contract, state and logs born with every loop" }),
1110
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BuiltIn, { children: "Boundaries re-read at the top of every run" }),
1111
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BuiltIn, { children: "Missed fires caught up, failed runs recovered" }),
1112
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BuiltIn, { children: "Time, event and gated triggers: empty runs cost nothing" }),
1113
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BuiltIn, { children: "An evolve pass that reviews its own run history" }),
1114
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BuiltIn, { children: "A purpose-built dashboard per loop, not a log to scroll" })
1115
- ]
1116
- }),
1117
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
1118
- onClick: onStart,
1119
- className: "mt-9 inline-flex cursor-pointer items-center gap-1.5 rounded-full bg-paper px-6 py-2.5 text-body font-medium text-display transition-opacity hover:opacity-85",
1120
- children: ["Start a loop", /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1121
- "aria-hidden": true,
1122
- children: "→"
1123
- })]
1124
- }),
1125
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1126
- className: "mt-3 text-caption text-paper/55",
1127
- children: "Describe the job. The playbook is the default, not homework."
1128
- }),
1129
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1130
- className: "mt-7 flex items-center justify-center",
1131
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", {
1132
- href: GITHUB_URL,
1133
- target: "_blank",
1134
- rel: "noreferrer",
1135
- className: "inline-flex items-center gap-1.5 text-caption text-paper/60 transition-colors hover:text-paper",
1136
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitHubIcon, { className: "size-4" }), " Open source on GitHub"]
1137
- })
1138
- })
1139
- ]
1140
- })
1141
- ]
1142
- });
1143
- }
1144
- function PlaybookHead({ num, title }) {
1145
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1146
- className: "mb-6 mt-16 flex items-baseline justify-center gap-3",
1147
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1148
- className: "font-pixel text-meta text-secondary",
1149
- children: num
1150
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", {
1151
- className: "font-pixel text-[clamp(17px,2.4vw,21px)] text-display",
1152
- children: title
1153
- })]
1154
- });
1155
- }
1156
- function IdeaCard({ title, caption, children }) {
1157
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1158
- className: "flex min-w-0 flex-col rounded-card border border-hairline bg-surface p-4 shadow-card",
1159
- children: [
1160
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1161
- className: "text-body font-semibold text-display",
1162
- children: title
1163
- }),
1164
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1165
- className: "mt-3 flex min-h-[150px] flex-1 flex-col justify-center",
1166
- children
1167
- }),
1168
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1169
- className: "mt-3 text-caption leading-snug text-secondary",
1170
- children: caption
1171
- })
1172
- ]
1173
- });
1174
- }
1175
- /** A miniature markdown-file mock: header bar + mono headings, skeleton or
1176
- * real one-liners, and at most one highlighted "hot" boundary line. */
1177
- function DocMock({ name, lines }) {
1178
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1179
- className: "overflow-hidden rounded-control border border-hairline bg-raised",
1180
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1181
- className: "border-b border-hairline px-2.5 py-1 font-mono text-micro text-secondary",
1182
- children: name
1183
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1184
- className: "space-y-1.5 px-2.5 py-2.5",
1185
- children: lines.map((l, i) => l.h ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1186
- className: "font-mono text-micro font-semibold text-primary",
1187
- children: l.h
1188
- }, i) : l.hot ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1189
- className: "rounded-[4px] bg-interactive-soft px-1.5 py-0.5 font-mono text-micro text-interactive",
1190
- children: l.hot
1191
- }, i) : l.t ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1192
- className: "truncate font-mono text-micro text-secondary",
1193
- children: l.t
1194
- }, i) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: `h-1.5 rounded-full bg-wire/60 ${l.skel ?? "w-full"}` }, i))
1195
- })]
1196
- });
1197
- }
1198
- /** work -> verify, a fail/fix loop back, and the proof chip a human trusts. */
1199
- function VerifierDiagram() {
1200
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1201
- viewBox: "0 0 220 168",
1202
- role: "img",
1203
- "aria-label": "Work and verify loop until proof",
1204
- className: "mx-auto w-full max-w-[210px]",
1205
- children: [
1206
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("defs", { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("marker", {
1207
- id: "lp-a",
1208
- markerWidth: "8",
1209
- markerHeight: "8",
1210
- refX: "6",
1211
- refY: "4",
1212
- orient: "auto",
1213
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1214
- d: "M0,0 L8,4 L0,8 z",
1215
- fill: "var(--color-secondary)"
1216
- })
1217
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("marker", {
1218
- id: "lp-g",
1219
- markerWidth: "8",
1220
- markerHeight: "8",
1221
- refX: "6",
1222
- refY: "4",
1223
- orient: "auto",
1224
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1225
- d: "M0,0 L8,4 L0,8 z",
1226
- fill: "var(--color-success)"
1227
- })
1228
- })] }),
1229
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1230
- d: "M62,96 Q22,70 62,44",
1231
- fill: "none",
1232
- stroke: "var(--color-accent)",
1233
- strokeWidth: "1.6",
1234
- markerEnd: "url(#lp-a)"
1235
- }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1237
- x: "16",
1238
- y: "66",
1239
- fontSize: "9",
1240
- fill: "var(--color-accent)",
1241
- fontFamily: "var(--font-mono)",
1242
- children: "fail"
1243
- }),
1244
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1245
- x: "16",
1246
- y: "77",
1247
- fontSize: "9",
1248
- fill: "var(--color-accent)",
1249
- fontFamily: "var(--font-mono)",
1250
- children: "fix"
1251
- }),
1252
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1253
- d: "M110,52 L110,84",
1254
- fill: "none",
1255
- stroke: "var(--color-secondary)",
1256
- strokeWidth: "1.6",
1257
- markerEnd: "url(#lp-a)"
1258
- }),
1259
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1260
- d: "M110,120 L110,138",
1261
- fill: "none",
1262
- stroke: "var(--color-success)",
1263
- strokeWidth: "1.6",
1264
- markerEnd: "url(#lp-g)"
1265
- }),
1266
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
1267
- x: "60",
1268
- y: "18",
1269
- width: "100",
1270
- height: "34",
1271
- rx: "8",
1272
- fill: "var(--color-surface)",
1273
- stroke: "var(--color-wire)",
1274
- strokeWidth: "1.3"
1275
- }),
1276
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1277
- x: "110",
1278
- y: "39",
1279
- textAnchor: "middle",
1280
- fontSize: "11",
1281
- fill: "var(--color-primary)",
1282
- fontFamily: "var(--font-mono)",
1283
- children: "work"
1284
- }),
1285
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
1286
- x: "60",
1287
- y: "86",
1288
- width: "100",
1289
- height: "34",
1290
- rx: "8",
1291
- fill: "var(--color-surface)",
1292
- stroke: "var(--color-wire)",
1293
- strokeWidth: "1.3"
1294
- }),
1295
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1296
- x: "110",
1297
- y: "107",
1298
- textAnchor: "middle",
1299
- fontSize: "11",
1300
- fill: "var(--color-primary)",
1301
- fontFamily: "var(--font-mono)",
1302
- children: "verify"
1303
- }),
1304
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", {
1305
- x: "48",
1306
- y: "140",
1307
- width: "124",
1308
- height: "24",
1309
- rx: "12",
1310
- fill: "var(--color-success-soft)",
1311
- stroke: "var(--color-success)",
1312
- strokeWidth: "1.2"
1313
- }),
1314
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1315
- x: "110",
1316
- y: "156",
1317
- textAnchor: "middle",
1318
- fontSize: "9.5",
1319
- fill: "var(--color-success)",
1320
- fontFamily: "var(--font-mono)",
1321
- children: "✓ proof → PR"
1322
- })
1323
- ]
1324
- });
1325
- }
1326
- function TriggerRow({ code, label }) {
1327
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1328
- className: "flex min-w-0 items-center gap-2",
1329
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", {
1330
- className: "shrink-0 rounded-[5px] bg-raised px-1.5 py-0.5 font-mono text-micro text-primary",
1331
- children: code
1332
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1333
- className: "truncate text-caption text-secondary",
1334
- children: label
1335
- })]
1336
- });
1337
- }
1338
- /**
1339
- * The three roles laid out as a dispatch map (the article's infographic, on
1340
- * app tokens): a trigger wakes the orchestrator, which fans tasks out to
1341
- * parallel executor→verifier lanes; every lane ends in proof, and every run
1342
- * reports back into memory + logs. Warm ink = work being dispatched, green =
1343
- * proof flowing home. Real HTML cards carry all the text; SVG only draws the
1344
- * connectors. Wide by nature, so the diagram scrolls inside its own pane on
1345
- * narrow screens (never the page). Lane rows are fixed-height so the fan-out
1346
- * SVG's coordinates line up with the row centers by construction.
1347
- */
1348
- var LANE_ROWS = [
1349
- "row-start-2",
1350
- "row-start-3",
1351
- "row-start-4"
1352
- ];
1353
- /** Slot index + highlight ink for the diagram's 9s narrative cycle (the
1354
- * `.lpb-stage` / `.lpb-flow` rules in app.css). */
1355
- function stageStyle(i, tone) {
1356
- return {
1357
- "--lpb-i": i,
1358
- "--lpb-c": `var(--color-${tone})`
1359
- };
1360
- }
1361
- var ROLE_BADGE = {
1362
- warn: "bg-warn-soft text-warn",
1363
- interactive: "bg-interactive-soft text-interactive",
1364
- success: "bg-success-soft text-success"
1365
- };
1366
- /** A role's icon in a soft-tinted square, sized for card headers. */
1367
- function RoleBadge({ tone, children }) {
1368
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1369
- "aria-hidden": true,
1370
- className: `flex size-6 shrink-0 items-center justify-center rounded-[7px] ${ROLE_BADGE[tone]}`,
1371
- children
1372
- });
1373
- }
1374
- /** Orchestrator: a dispatch node - one point, three rays. */
1375
- function OrchestratorIcon() {
1376
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1377
- viewBox: "0 0 16 16",
1378
- className: "size-3.5",
1379
- fill: "none",
1380
- stroke: "currentColor",
1381
- strokeWidth: "1.5",
1382
- strokeLinecap: "round",
1383
- children: [
1384
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
1385
- cx: "8",
1386
- cy: "8.6",
1387
- r: "1.7",
1388
- fill: "currentColor",
1389
- stroke: "none"
1390
- }),
1391
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 6.4 V2.6 M9.7 9.8 L12.9 12 M6.3 9.8 L3.1 12" }),
1392
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1393
- d: "M4.9 3.4 A5.4 5.4 0 0 1 11.1 3.4",
1394
- opacity: "0.45"
1395
- })
1396
- ]
1397
- });
1398
- }
1399
- /** Executor: the isolated box. */
1400
- function ExecutorIcon() {
1401
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1402
- viewBox: "0 0 16 16",
1403
- className: "size-3.5",
1404
- fill: "none",
1405
- stroke: "currentColor",
1406
- strokeWidth: "1.4",
1407
- strokeLinejoin: "round",
1408
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 1.8 L14 4.8 V11.2 L8 14.2 L2 11.2 V4.8 Z" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M2 4.8 L8 7.8 L14 4.8 M8 7.8 V14.2" })]
1409
- });
1410
- }
1411
- /** Verifier: shield + check. */
1412
- function VerifierIcon() {
1413
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1414
- viewBox: "0 0 16 16",
1415
- className: "size-3.5",
1416
- fill: "none",
1417
- stroke: "currentColor",
1418
- strokeWidth: "1.5",
1419
- strokeLinecap: "round",
1420
- strokeLinejoin: "round",
1421
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M8 1.5 L13.5 3.5 V8 C13.5 11.2 11.2 13.6 8 14.5 C4.8 13.6 2.5 11.2 2.5 8 V3.5 Z" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5.6 8.2 L7.3 9.9 L10.6 6.3" })]
1422
- });
1423
- }
1424
- function RolesFlow() {
1425
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1426
- className: "rounded-card border border-hairline bg-surface p-5 shadow-card sm:p-7",
1427
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1428
- className: "mb-5 grid grid-cols-1 gap-4 border-b border-hairline pb-5 sm:grid-cols-3",
1429
- children: [
1430
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleCaption, {
1431
- name: "Orchestrator",
1432
- tone: "warn",
1433
- stage: 0,
1434
- icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OrchestratorIcon, {}),
1435
- line: "Wakes on the trigger and finds the task: reads what changed, picks the single most worthwhile thing this run. It never does the work itself."
1436
- }),
1437
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleCaption, {
1438
- name: "Executor",
1439
- tone: "interactive",
1440
- stage: 1,
1441
- icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExecutorIcon, {}),
1442
- line: "Does the work in an isolated box, a fresh git worktree per task, so lanes never touch your checkout or each other."
1443
- }),
1444
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleCaption, {
1445
- name: "Verifier",
1446
- tone: "success",
1447
- stage: 2,
1448
- icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VerifierIcon, {}),
1449
- line: "Independently proves each result and attaches the evidence: a screenshot, a video, a fact-check. That proof is what you review."
1450
- })
1451
- ]
1452
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1453
- className: "-m-2 overflow-x-auto p-2",
1454
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1455
- role: "img",
1456
- "aria-label": "A trigger fires the orchestrator, which dispatches tasks to parallel executor and verifier lanes; each lane ends in a PR with proof, and every run reports back into state and logs",
1457
- className: "grid min-w-[900px] grid-cols-[216px_72px_minmax(150px,1fr)_56px_minmax(170px,1fr)_56px_180px] grid-rows-[auto_repeat(3,84px)_auto] gap-y-3",
1458
- children: [
1459
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1460
- className: "col-start-1 row-start-1 flex flex-col items-center",
1461
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1462
- className: "lpb-stage inline-flex items-center gap-1.5 rounded-full border border-wire bg-surface px-4 py-1.5 font-mono text-label text-primary",
1463
- style: stageStyle(0, "warn"),
1464
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1465
- "aria-hidden": true,
1466
- children: "⏰"
1467
- }), " trigger fires"]
1468
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1469
- "aria-hidden": true,
1470
- className: "-mb-4 h-8 w-3",
1471
- viewBox: "0 0 12 32",
1472
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", {
1473
- x1: "6",
1474
- y1: "0",
1475
- x2: "6",
1476
- y2: "24",
1477
- stroke: "var(--color-warn)",
1478
- strokeWidth: "1.5"
1479
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1480
- d: "M1.5,23 L6,31 L10.5,23 z",
1481
- fill: "var(--color-warn)"
1482
- })]
1483
- })]
1484
- }),
1485
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1486
- className: "lpb-stage relative col-start-1 row-span-3 row-start-2 flex flex-col overflow-hidden rounded-control border border-wire bg-surface p-4 pl-5 shadow-card",
1487
- style: stageStyle(0, "warn"),
1488
- children: [
1489
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1490
- "aria-hidden": true,
1491
- className: "absolute inset-y-2 left-0 w-1 rounded-r-full bg-rubik-orange"
1492
- }),
1493
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1494
- className: "flex items-center gap-2",
1495
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleBadge, {
1496
- tone: "warn",
1497
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OrchestratorIcon, {})
1498
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1499
- className: "font-pixel text-[15px] text-display",
1500
- children: "Orchestrator"
1501
- })]
1502
- }),
1503
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1504
- className: "mt-1.5 font-mono text-micro text-secondary",
1505
- children: "find the work, don't do it"
1506
- }),
1507
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1508
- className: "mt-3 grid grid-cols-2 gap-1.5",
1509
- children: [
1510
- "🐛 errors",
1511
- "📥 inbox",
1512
- "📈 metrics",
1513
- "🔀 PRs"
1514
- ].map((s) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1515
- className: "rounded-[6px] bg-raised px-1.5 py-1 text-center font-mono text-micro text-secondary",
1516
- children: s
1517
- }, s))
1518
- }),
1519
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1520
- className: "mt-3 rounded-control border border-warn/50 bg-warn-soft px-2 py-1.5 text-center font-mono text-label font-medium text-warn",
1521
- children: "prioritise → dispatch"
1522
- }),
1523
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1524
- className: "mt-2 text-center font-mono text-micro leading-snug text-secondary",
1525
- children: [
1526
- "one task per lane,",
1527
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
1528
- "lanes never touch"
1529
- ]
1530
- }),
1531
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1532
- className: "lpb-stage mt-auto rounded-control border border-success/40 bg-success-soft px-2 py-1.5 text-center font-mono text-micro text-success",
1533
- style: stageStyle(4, "success"),
1534
- children: "✍ writes memory + logs"
1535
- })
1536
- ]
1537
- }),
1538
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1539
- "aria-hidden": true,
1540
- className: "lpb-flow col-start-2 row-span-3 row-start-2 h-full w-full",
1541
- style: stageStyle(1, "warn"),
1542
- viewBox: "0 0 72 276",
1543
- preserveAspectRatio: "none",
1544
- children: [
1545
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("marker", {
1546
- id: "rf-warn",
1547
- markerWidth: "8",
1548
- markerHeight: "8",
1549
- refX: "6.5",
1550
- refY: "4",
1551
- orient: "auto",
1552
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1553
- d: "M0,0 L8,4 L0,8 z",
1554
- fill: "var(--color-warn)"
1555
- })
1556
- }) }),
1557
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1558
- d: "M2,138 C42,138 28,42 62,42",
1559
- fill: "none",
1560
- stroke: "var(--color-warn)",
1561
- strokeWidth: "1.5",
1562
- markerEnd: "url(#rf-warn)"
1563
- }),
1564
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1565
- d: "M2,138 L62,138",
1566
- fill: "none",
1567
- stroke: "var(--color-warn)",
1568
- strokeWidth: "1.5",
1569
- markerEnd: "url(#rf-warn)"
1570
- }),
1571
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1572
- d: "M2,138 C42,138 28,234 62,234",
1573
- fill: "none",
1574
- stroke: "var(--color-warn)",
1575
- strokeWidth: "1.5",
1576
- markerEnd: "url(#rf-warn)"
1577
- })
1578
- ]
1579
- }),
1580
- [
1581
- "A",
1582
- "B",
1583
- "C"
1584
- ].map((t, i) => {
1585
- const rs = LANE_ROWS[i];
1586
- const failFix = t === "B";
1587
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
1588
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1589
- className: `col-start-3 ${rs}`,
1590
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1591
- className: "lpb-stage relative flex h-full flex-col items-center justify-center rounded-control border border-wire bg-surface shadow-card",
1592
- style: stageStyle(1, "interactive"),
1593
- children: [
1594
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1595
- "aria-hidden": true,
1596
- className: "pointer-events-none absolute inset-1.5 rounded-[7px] border border-dashed border-interactive/40"
1597
- }),
1598
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
1599
- className: "absolute -top-2 left-3 rounded bg-surface px-1.5 font-mono text-micro text-warn",
1600
- children: ["task ", t]
1601
- }),
1602
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1603
- className: "flex items-center gap-2",
1604
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleBadge, {
1605
- tone: "interactive",
1606
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExecutorIcon, {})
1607
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1608
- className: "text-meta font-semibold text-display",
1609
- children: "Executor"
1610
- })]
1611
- }),
1612
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1613
- className: "mt-1.5 font-mono text-micro text-interactive",
1614
- children: "isolated worktree"
1615
- })
1616
- ]
1617
- })
1618
- }),
1619
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1620
- className: `lpb-flow relative col-start-4 ${rs} flex items-center px-1`,
1621
- style: stageStyle(2, "warn"),
1622
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FlowArrow, { tone: "warn" }), failFix && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1623
- className: "absolute inset-x-1 top-[calc(50%+12px)] flex flex-col items-center",
1624
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(FlowArrow, {
1625
- tone: "warn",
1626
- dashed: true,
1627
- flip: true
1628
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1629
- className: "mt-0.5 font-mono text-micro text-warn",
1630
- children: "fail→fix"
1631
- })]
1632
- })]
1633
- }),
1634
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1635
- className: `col-start-5 ${rs}`,
1636
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1637
- className: "lpb-stage relative flex h-full flex-col items-center justify-center overflow-hidden rounded-control border border-wire bg-surface shadow-card",
1638
- style: stageStyle(2, "success"),
1639
- children: [
1640
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1641
- "aria-hidden": true,
1642
- className: "absolute inset-y-2 right-0 w-1 rounded-l-full bg-rubik-green"
1643
- }),
1644
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1645
- className: "flex items-center gap-2",
1646
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleBadge, {
1647
- tone: "success",
1648
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(VerifierIcon, {})
1649
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1650
- className: "text-meta font-semibold text-display",
1651
- children: "Verifier"
1652
- })]
1653
- }),
1654
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1655
- className: "mt-1.5 font-mono text-micro text-secondary",
1656
- children: "drive the app · 📸 evidence"
1657
- })
1658
- ]
1659
- })
1660
- }),
1661
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1662
- className: `lpb-flow col-start-6 ${rs} flex items-center px-1`,
1663
- style: stageStyle(3, "success"),
1664
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FlowArrow, { tone: "success" })
1665
- }),
1666
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1667
- className: `col-start-7 ${rs} flex items-center`,
1668
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1669
- className: "lpb-stage flex h-[64px] w-full flex-col items-center justify-center rounded-control border border-success/40 bg-success-soft",
1670
- style: stageStyle(3, "success"),
1671
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1672
- className: "font-mono text-label font-semibold text-success",
1673
- children: "✓ PR + proof"
1674
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
1675
- className: "mt-1 font-mono text-micro text-success/80",
1676
- children: "approve in seconds"
1677
- })]
1678
- })
1679
- })
1680
- ] }, t);
1681
- }),
1682
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1683
- className: "lpb-flow relative col-span-full row-start-5 h-10",
1684
- style: stageStyle(4, "success"),
1685
- children: [
1686
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1687
- "aria-hidden": true,
1688
- className: "absolute right-[90px] top-[-22px] bottom-1/2 border-r border-dashed border-success/70"
1689
- }),
1690
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1691
- "aria-hidden": true,
1692
- className: "absolute left-[107px] top-[-9px] bottom-1/2 border-l border-dashed border-success/70"
1693
- }),
1694
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", {
1695
- "aria-hidden": true,
1696
- className: "absolute left-[102px] top-[-15px] h-2 w-[11px]",
1697
- viewBox: "0 0 11 8",
1698
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1699
- d: "M0,8 L5.5,0 L11,8 z",
1700
- fill: "var(--color-success)"
1701
- })
1702
- }),
1703
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1704
- "aria-hidden": true,
1705
- className: "absolute left-[107px] right-[90px] top-1/2 border-t border-dashed border-success/70"
1706
- }),
1707
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1708
- className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 whitespace-nowrap bg-surface px-2.5 font-mono text-micro text-success",
1709
- children: "every run reports back → orchestrator writes memory + logs"
1710
- })
1711
- ]
1712
- })
1713
- ]
1714
- })
1715
- })]
1716
- });
1717
- }
1718
- /** A short connector arrow that fills its cell; `flip` reverses direction. */
1719
- function FlowArrow({ tone, dashed, flip }) {
1720
- const c = tone === "warn" ? "var(--color-warn)" : "var(--color-success)";
1721
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1722
- "aria-hidden": true,
1723
- className: `h-3 w-full ${flip ? "rotate-180" : ""}`,
1724
- viewBox: "0 0 56 12",
1725
- preserveAspectRatio: "none",
1726
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", {
1727
- x1: "2",
1728
- y1: "6",
1729
- x2: "45",
1730
- y2: "6",
1731
- stroke: c,
1732
- strokeWidth: "1.5",
1733
- strokeDasharray: dashed ? "4 4" : void 0
1734
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1735
- d: "M44,1.5 L54,6 L44,10.5 z",
1736
- fill: c
1737
- })]
1738
- });
1739
- }
1740
- function RoleCaption({ name, line, tone, stage, icon }) {
1741
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1742
- className: "lpb-stage -m-2 min-w-0 rounded-control p-2",
1743
- style: stageStyle(stage, tone),
1744
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
1745
- className: "flex items-center gap-2",
1746
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleBadge, {
1747
- tone,
1748
- children: icon
1749
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
1750
- className: "text-meta font-semibold text-display",
1751
- children: name
1752
- })]
1753
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", {
1754
- className: "mt-1.5 text-caption leading-snug text-secondary",
1755
- children: line
1756
- })]
1757
- });
1758
- }
1759
- /** Compute-per-run over a loop's lifetime (the concept doc's curve, on app
1760
- * tokens): born agentic and expensive while it learns the pattern, graduates
1761
- * to a cheap deterministic script, and the agent only spikes back awake when
1762
- * a tripwire trips or a scheduled re-audit comes due. */
1763
- function CostCurve() {
1764
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", {
1765
- viewBox: "0 0 980 372",
1766
- width: "100%",
1767
- className: "mx-auto block max-w-[880px]",
1768
- role: "img",
1769
- "aria-label": "Compute per run over a loop's lifetime: high while born agentic, flat after graduating to a cheap script, spiking briefly when a tripwire trips and at a scheduled re-audit",
1770
- children: [
1771
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("linearGradient", {
1772
- id: "lp-cc-fill",
1773
- x1: "0",
1774
- y1: "0",
1775
- x2: "0",
1776
- y2: "1",
1777
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", {
1778
- offset: "0%",
1779
- stopColor: "var(--color-rubik-orange)",
1780
- stopOpacity: "0.2"
1781
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("stop", {
1782
- offset: "100%",
1783
- stopColor: "var(--color-rubik-orange)",
1784
- stopOpacity: "0"
1785
- })]
1786
- }) }),
1787
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", {
1788
- x1: "70",
1789
- y1: "40",
1790
- x2: "70",
1791
- y2: "312",
1792
- stroke: "var(--color-wire)",
1793
- strokeWidth: "1.2"
1794
- }),
1795
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", {
1796
- x1: "70",
1797
- y1: "312",
1798
- x2: "912",
1799
- y2: "312",
1800
- stroke: "var(--color-wire)",
1801
- strokeWidth: "1.2"
1802
- }),
1803
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1804
- x: "70",
1805
- y: "26",
1806
- fontFamily: "var(--font-mono)",
1807
- fontSize: "12",
1808
- fill: "var(--color-secondary)",
1809
- children: "compute / run"
1810
- }),
1811
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1812
- x: "912",
1813
- y: "340",
1814
- textAnchor: "end",
1815
- fontFamily: "var(--font-mono)",
1816
- fontSize: "12",
1817
- fill: "var(--color-secondary)",
1818
- children: "loop lifetime →"
1819
- }),
1820
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1821
- d: "M70,72 C150,66 210,96 260,160 C300,210 330,256 372,262 L520,262 C544,262 560,108 580,104 C600,100 620,254 648,262 L772,262 C786,262 796,176 810,173 C824,170 836,256 854,262 L912,262 L912,312 L70,312 Z",
1822
- fill: "url(#lp-cc-fill)"
1823
- }),
1824
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", {
1825
- d: "M70,72 C150,66 210,96 260,160 C300,210 330,256 372,262 L520,262 C544,262 560,108 580,104 C600,100 620,254 648,262 L772,262 C786,262 796,176 810,173 C824,170 836,256 854,262 L912,262",
1826
- fill: "none",
1827
- stroke: "var(--color-warn)",
1828
- strokeWidth: "2.4"
1829
- }),
1830
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", {
1831
- fontFamily: "var(--font-mono)",
1832
- children: [
1833
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1834
- x: "150",
1835
- y: "58",
1836
- fontSize: "13",
1837
- fontWeight: "600",
1838
- fill: "var(--color-display)",
1839
- children: "Born agentic"
1840
- }),
1841
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1842
- x: "150",
1843
- y: "76",
1844
- fontSize: "11.5",
1845
- fill: "var(--color-secondary)",
1846
- children: "learns the pattern"
1847
- }),
1848
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", {
1849
- x1: "372",
1850
- y1: "262",
1851
- x2: "372",
1852
- y2: "300",
1853
- stroke: "var(--color-success)",
1854
- strokeWidth: "1.2",
1855
- strokeDasharray: "4 4"
1856
- }),
1857
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1858
- x: "430",
1859
- y: "292",
1860
- textAnchor: "middle",
1861
- fontSize: "12.5",
1862
- fontWeight: "600",
1863
- fill: "var(--color-success)",
1864
- children: "Graduates → cheap script"
1865
- }),
1866
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
1867
- cx: "580",
1868
- cy: "104",
1869
- r: "4",
1870
- fill: "var(--color-warn)"
1871
- }),
1872
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1873
- x: "580",
1874
- y: "92",
1875
- textAnchor: "middle",
1876
- fontSize: "12",
1877
- fontWeight: "600",
1878
- fill: "var(--color-warn)",
1879
- children: "tripwire trips"
1880
- }),
1881
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1882
- x: "580",
1883
- y: "76",
1884
- textAnchor: "middle",
1885
- fontSize: "11",
1886
- fill: "var(--color-secondary)",
1887
- children: "agent re-wakes"
1888
- }),
1889
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", {
1890
- cx: "810",
1891
- cy: "173",
1892
- r: "4",
1893
- fill: "var(--color-rubik-yellow)"
1894
- }),
1895
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("text", {
1896
- x: "812",
1897
- y: "158",
1898
- textAnchor: "middle",
1899
- fontSize: "11",
1900
- fontWeight: "600",
1901
- fill: "var(--color-running)",
1902
- children: "scheduled re-audit"
1903
- })
1904
- ]
1905
- })
1906
- ]
1907
- });
1908
- }
1909
- var EVOLVE_RUNS = [
1910
- {
1911
- c: "var(--color-success)",
1912
- status: "resolved",
1913
- note: "fixed the null-team crash, PR #1027 + video proof"
1914
- },
1915
- {
1916
- c: "var(--color-secondary)",
1917
- status: "no update",
1918
- note: "docs still match the code, clean stop ($0.03)"
1919
- },
1920
- {
1921
- c: "var(--color-success)",
1922
- status: "resolved",
1923
- note: "4 tickets answered, export-friction signal filed"
1924
- },
1925
- {
1926
- c: "var(--color-accent)",
1927
- status: "error",
1928
- note: "verify failed on a flaky selector, lesson saved to state"
1929
- },
1930
- {
1931
- c: "var(--color-success)",
1932
- status: "resolved",
1933
- note: "2 dependency patches tested in a worktree, merged"
1934
- },
1935
- {
1936
- c: "var(--color-success)",
1937
- status: "resolved",
1938
- note: "worst prod error root-caused, fingerprint now watched"
1939
- }
1940
- ];
1941
- var EVOLVE_OUTPUTS = [
1942
- "📜 contract sharpened",
1943
- "🚧 boundaries redrawn",
1944
- "⚙️ repeated steps → script",
1945
- "⏰ trigger re-tuned",
1946
- "📊 dashboard updated"
1947
- ];
1948
- /**
1949
- * The evolve story as a live timeline in the product's own run-block UI,
1950
- * sized up: exec runs land block by block, each with a one-line note of what
1951
- * happened; the evolve run (the product's blue) reads the whole history with
1952
- * a reverse ripple, ships its changes as chips, and the next hollow dot is
1953
- * already scheduled. An ~18s tick cycle drives it; prefers-reduced-motion
1954
- * renders the finished state statically.
1955
- */
1956
- function EvolveTimeline() {
1957
- const FINAL = 14;
1958
- const [tick, setTick] = (0, import_react.useState)(0);
1959
- const [reduce, setReduce] = (0, import_react.useState)(false);
1960
- const ref = (0, import_react.useRef)(null);
1961
- const timer = (0, import_react.useRef)(null);
1962
- const play = () => {
1963
- if (timer.current) clearInterval(timer.current);
1964
- setTick(0);
1965
- timer.current = setInterval(() => {
1966
- setTick((v) => Math.min(v + 1, FINAL));
1967
- }, 500);
1968
- };
1969
- (0, import_react.useEffect)(() => {
1970
- if (tick >= FINAL && timer.current) {
1971
- clearInterval(timer.current);
1972
- timer.current = null;
1973
- }
1974
- }, [tick]);
1975
- (0, import_react.useEffect)(() => {
1976
- if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
1977
- setReduce(true);
1978
- return;
1979
- }
1980
- const el = ref.current;
1981
- if (!el) return;
1982
- const io = new IntersectionObserver((entries) => {
1983
- if (entries.some((e) => e.isIntersecting)) {
1984
- io.disconnect();
1985
- play();
1986
- }
1987
- }, { threshold: .35 });
1988
- io.observe(el);
1989
- return () => {
1990
- io.disconnect();
1991
- if (timer.current) clearInterval(timer.current);
1992
- };
1993
- }, []);
1994
- const at = (n) => reduce || tick >= n;
1995
- const scanning = !reduce && tick === 8;
1996
- const activeRun = !reduce && tick >= 1 && tick <= 6 ? tick - 1 : -1;
1997
- const done = reduce || tick >= FINAL;
1998
- const line = reduce ? {
1999
- c: "var(--color-success)",
2000
- head: "",
2001
- text: "the next run starts one step smarter, and cheaper"
2002
- } : tick === 0 ? {
2003
- c: "var(--color-wire)",
2004
- head: "",
2005
- text: "a loop, run by run…"
2006
- } : tick <= 6 ? {
2007
- c: EVOLVE_RUNS[tick - 1].c,
2008
- head: EVOLVE_RUNS[tick - 1].status,
2009
- text: EVOLVE_RUNS[tick - 1].note
2010
- } : tick <= 8 ? {
2011
- c: "var(--color-interactive)",
2012
- head: "evolve",
2013
- text: "reading all six runs: where was money wasted? which boundary is too loose?"
2014
- } : tick <= 13 ? {
2015
- c: "var(--color-interactive)",
2016
- head: "evolve",
2017
- text: "rewriting the loop itself:"
2018
- } : {
2019
- c: "var(--color-success)",
2020
- head: "",
2021
- text: "the next run starts one step smarter, and cheaper"
2022
- };
2023
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2024
- ref,
2025
- className: "relative py-2",
2026
- children: [
2027
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", {
2028
- type: "button",
2029
- onClick: play,
2030
- tabIndex: done && !reduce ? 0 : -1,
2031
- "aria-hidden": !(done && !reduce),
2032
- className: `absolute -top-1 right-0 inline-flex cursor-pointer items-center gap-1.5 rounded-full border border-hairline px-3 py-1 font-mono text-caption text-secondary transition-opacity duration-300 hover:bg-raised hover:text-display ${done && !reduce ? "opacity-100" : "pointer-events-none opacity-0"}`,
2033
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2034
- "aria-hidden": true,
2035
- children: "↺"
2036
- }), " replay"]
2037
- }),
2038
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2039
- className: "-mx-2 flex min-w-0 items-center justify-center gap-2 overflow-x-auto px-2 py-2",
2040
- children: [
2041
- EVOLVE_RUNS.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2042
- title: `${r.status} · ${r.note}`,
2043
- className: `h-10 w-9 shrink-0 rounded-[7px] transition-all duration-300 ${at(i + 1) ? "scale-100 opacity-100" : "scale-50 opacity-0"}`,
2044
- style: {
2045
- background: r.c,
2046
- boxShadow: activeRun === i ? `0 0 0 2px var(--color-surface), 0 0 0 4px ${r.c}` : scanning ? "0 0 0 2px var(--color-surface), 0 0 0 4px var(--color-interactive)" : void 0,
2047
- transitionDelay: scanning ? `${(EVOLVE_RUNS.length - 1 - i) * 70}ms` : "0ms"
2048
- }
2049
- }, i)),
2050
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2051
- "aria-hidden": true,
2052
- className: `w-8 shrink-0 border-t-2 border-dashed border-wire transition-opacity duration-300 ${at(7) ? "opacity-100" : "opacity-0"}`
2053
- }),
2054
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2055
- className: `flex h-10 shrink-0 items-center rounded-[7px] bg-interactive px-3.5 font-mono text-label font-medium text-white transition-all duration-300 ${at(7) ? "scale-100 opacity-100" : "scale-50 opacity-0"} ${scanning ? "animate-pulse" : ""}`,
2056
- children: "evolve"
2057
- }),
2058
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
2059
- "aria-hidden": true,
2060
- className: `flex shrink-0 items-center gap-2.5 transition-opacity duration-500 ${at(14) ? "opacity-100" : "opacity-0"}`,
2061
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "w-10 border-t-2 border-dashed border-wire" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "size-[15px] rounded-full border-2 border-wire" })]
2062
- })
2063
- ]
2064
- }),
2065
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
2066
- className: "mt-4 flex h-6 min-w-0 items-center justify-center gap-2",
2067
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2068
- "aria-hidden": true,
2069
- className: "size-2.5 shrink-0 rounded-[3px] transition-colors duration-300",
2070
- style: { background: line.c }
2071
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
2072
- className: "truncate font-mono text-label text-primary",
2073
- children: [line.head && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
2074
- className: "font-medium",
2075
- style: { color: line.c },
2076
- children: [line.head, " · "]
2077
- }), line.text]
2078
- })]
2079
- }),
2080
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2081
- className: "mt-4 flex flex-wrap items-center justify-center gap-2",
2082
- children: EVOLVE_OUTPUTS.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2083
- className: `rounded-full border border-interactive/40 bg-interactive-soft px-3 py-1.5 font-mono text-caption text-interactive transition-all duration-300 ${at(9 + i) ? "translate-y-0 opacity-100" : "-translate-y-1.5 opacity-0"}`,
2084
- children: o
2085
- }, o))
2086
- }),
2087
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
2088
- className: `mt-4 text-center font-mono text-caption text-disabled transition-opacity duration-500 ${at(14) ? "opacity-100" : "opacity-0"}`,
2089
- children: "next run, one step smarter"
2090
- })
2091
- ]
2092
- });
2093
- }
2094
- function BuiltIn({ children }) {
2095
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", {
2096
- className: "flex min-w-0 items-start gap-2 text-body text-paper/85",
2097
- children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
2098
- "aria-hidden": true,
2099
- className: "mt-px shrink-0 text-rubik-green",
2100
- children: "✓"
2101
- }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children })]
2102
- });
2103
- }
2104
- //#endregion
2105
- export { authClient as a, PievoLogo as i, GitHubIcon as n, signIn as o, LoopPlaybook as r, useSession as s, GITHUB_URL as t };