@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.
- package/.output/nitro.json +1 -1
- package/.output/public/assets/MachinesModal-CSbnrUER.js +1 -0
- package/.output/public/assets/SignIn-0Tjqs-Ma.js +1 -0
- package/.output/public/assets/actionUi-DpwGIGpw.js +1 -0
- package/.output/public/assets/app-CaZpuwOS.css +2 -0
- package/.output/public/assets/index-CaS_SmDq.js +10 -0
- package/.output/public/assets/invite._token-Btg_0aLp.js +1 -0
- package/.output/public/assets/invite._token-KMD2JAgE.js +1 -0
- package/.output/public/assets/lifecycleUi-C7dwHtbw.js +1 -0
- package/.output/public/assets/loops._loopId-D5usF3DO.js +67 -0
- package/.output/public/assets/loops._loopId_.runs._runId-DRCgXaCq.js +3 -0
- package/.output/public/assets/preload-helper-DsxECZIS.js +5 -0
- package/.output/public/assets/routes-CtFgwdgW.js +1 -0
- package/.output/public/assets/routes-LDbnnQ3f.js +1 -0
- package/.output/public/assets/t._teamId-D41xcbsF.js +1 -0
- package/.output/public/assets/t._teamId-DUena1pV.js +1 -0
- package/.output/public/assets/ui-Do4gqMyP.js +1 -0
- package/.output/server/_libs/@base-ui/react+[...].mjs +4130 -4130
- package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
- package/.output/server/_libs/drizzle-orm+postgres.mjs +28 -1
- package/.output/server/_ssr/DashboardView-C2LdV6J0.mjs +914 -0
- package/.output/server/_ssr/{notifyFns-DuPR1zd7.mjs → MachinesModal-BjkcVjjx.mjs} +55 -35
- package/.output/server/_ssr/{SignIn-RmpWm9uy.mjs → SignIn-DEGrvJvb.mjs} +10 -24
- package/.output/server/_ssr/SocialLinks-Cm4H8pUJ.mjs +1044 -0
- package/.output/server/_ssr/{actionUi-BN55TNYE.mjs → actionUi-DJBWuNwr.mjs} +3 -3
- package/.output/server/_ssr/{artifactFiles-BCaIIrrT.mjs → artifactFiles-DtpRidFZ.mjs} +7 -8
- package/.output/server/_ssr/{artifactKind-BW0isV8L.mjs → artifactKind-FBYbgSuf.mjs} +27 -2
- package/.output/server/_ssr/artifacts-BR3jj0NC.mjs +2 -0
- package/.output/server/_ssr/{auth-30Z4lV1w.mjs → auth-C0zoZCGe.mjs} +16 -19
- package/.output/server/_ssr/boot-CdOO4xOo.mjs +2 -0
- package/.output/server/_ssr/{boot-3BNKujyp.mjs → boot-sNlIkoLe.mjs} +1331 -3927
- package/.output/server/_ssr/{bun-sqlite-dialect-BW9W1_Ps-_7tfuNRi.mjs → bun-sqlite-dialect-BW9W1_Ps-DmlZWqO7.mjs} +2 -2
- package/.output/server/_ssr/{d1-sqlite-dialect-BLC8LXE6-ucDUbeBk.mjs → d1-sqlite-dialect-BLC8LXE6-CCNzqZwZ.mjs} +2 -2
- package/.output/server/_ssr/db-CwLD-5w1.mjs +2 -0
- package/.output/server/_ssr/{dist-Cd6nlLlO.mjs → dist-B3SxDOpW.mjs} +2 -2
- package/.output/server/_ssr/{factory-CWWwV7XZ.mjs → factory-Dv3Zopis.mjs} +2 -2
- package/.output/server/_ssr/invite._token-CJ6-H-s3.mjs +20 -0
- package/.output/server/_ssr/{invite._token-SdWXemIc.mjs → invite._token-dLKDJKVs.mjs} +9 -17
- package/.output/server/_ssr/{invite._token-BKlz0R2f.mjs → invite._token-l1SjouDz.mjs} +6 -15
- package/.output/server/_ssr/{kysely-adapter-C8iS51DB.mjs → kysely-adapter-nL7WKSgw.mjs} +1 -1
- package/.output/server/_ssr/{lifecycleUi-DgBQAYzp.mjs → lifecycleUi-Dad3hvhm.mjs} +11 -11
- package/.output/server/_ssr/logger-B8m8F1Qu.mjs +2 -0
- package/.output/server/_ssr/loopApi-BKyFB4KM.mjs +342 -0
- package/.output/server/_ssr/{adapters-BoLkOf1T.mjs → loopProjection-B8a829ij.mjs} +25 -55
- package/.output/server/_ssr/loops._loopId-DS16Phmq.mjs +1271 -0
- package/.output/server/_ssr/{loops._loopId_.runs._runId-PUGBrD5q.mjs → loops._loopId_.runs._runId-BEJI6iK5.mjs} +23 -74
- package/.output/server/_ssr/{loops._loopId_.runs._runId-Ymy4lwee.mjs → loops._loopId_.runs._runId-CduETLqH.mjs} +4 -5
- package/.output/server/_ssr/{machineFns-BZ9puxDt.mjs → machineFns-ByMsgG12.mjs} +3 -5
- package/.output/server/_ssr/{node-sqlite-dialect-D_3JmkMo.mjs → node-sqlite-dialect-CjNineno.mjs} +2 -2
- package/.output/server/_ssr/router-CXyrnvx-.mjs +565 -0
- package/.output/server/_ssr/{routes-ClZEdsnB.mjs → routes-BulNEUEE.mjs} +6 -10
- package/.output/server/_ssr/{routes-ComqHvCL.mjs → routes-DD94baie.mjs} +3 -3
- package/.output/server/_ssr/{routes-D5jJJ-30.mjs → routes-Wjexi35W.mjs} +6 -6
- package/.output/server/_ssr/runDiff-Ba8Lg1vg.mjs +2 -0
- package/.output/server/_ssr/ssr.mjs +60 -100
- package/.output/server/_ssr/store-Cujtg2QE.mjs +2 -0
- package/.output/server/_ssr/{t._teamId-BgHV_KFP.mjs → t._teamId-1CreIlPV.mjs} +7 -11
- package/.output/server/_ssr/{t._teamId-DDERNgfn.mjs → t._teamId-Bd6-zZsy.mjs} +4 -4
- package/.output/server/_ssr/{t._teamId-DRJvKHZn.mjs → t._teamId-COuMKQ4r.mjs} +7 -7
- package/.output/server/_ssr/{teamFns-Bp81UO-x.mjs → teamFns-H438WnZC.mjs} +12 -30
- package/.output/server/_ssr/{teamFns-bm82twd5.mjs → teamFns-j2JKjorZ.mjs} +2 -2
- package/.output/server/_ssr/tokens-DgG_Syq3.mjs +2 -0
- package/.output/server/_ssr/{ui-Ww2tTM2u.mjs → ui-D5KWstlb.mjs} +26 -48
- package/.output/server/{_tanstack-start-manifest_v-DwKENYCN.mjs → _tanstack-start-manifest_v-3H7yBKLz.mjs} +25 -35
- package/{drizzle/0000_round_marauders.sql → .output/server/drizzle/0000_baseline.sql} +102 -44
- package/.output/server/drizzle/meta/_journal.json +3 -115
- package/.output/server/index.mjs +83 -132
- package/{.output/server/drizzle/0000_round_marauders.sql → drizzle/0000_baseline.sql} +102 -44
- package/drizzle/meta/_journal.json +3 -115
- package/package.json +2 -11
- package/scripts/pievo-server.mjs +3 -1
- package/scripts/server-cli-lib.mjs +23 -16
- package/.output/public/assets/CodeField-dOzyFQNH.js +0 -34
- package/.output/public/assets/LoopView-DjVHUyrR.js +0 -59
- package/.output/public/assets/Modal-CCRvx959.js +0 -1
- package/.output/public/assets/SignIn-Qxw5zDFq.js +0 -1
- package/.output/public/assets/actionUi-CXxhzYe2.js +0 -1
- package/.output/public/assets/app-D1cij_NJ.css +0 -2
- package/.output/public/assets/artifactView-Cd5wWPil.js +0 -66
- package/.output/public/assets/index-BRN_CQ8U.js +0 -12
- package/.output/public/assets/invite._token-BIxr8DlP.js +0 -1
- package/.output/public/assets/invite._token-j2BTCeG1.js +0 -1
- package/.output/public/assets/jsx-runtime-BseJUIpC.js +0 -1
- package/.output/public/assets/lifecycleUi-Qy_8beQK.js +0 -1
- package/.output/public/assets/loopApi-CT1mMhlb.js +0 -3
- package/.output/public/assets/loops._loopId-BRBQzioy.js +0 -4
- package/.output/public/assets/loops._loopId_.runs._runId-CMnOJkem.js +0 -3
- package/.output/public/assets/notifyFns-DYD4EKaG.js +0 -1
- package/.output/public/assets/preload-helper-DFkkpP6W.js +0 -3
- package/.output/public/assets/routes-3nuEJGdo.js +0 -1
- package/.output/public/assets/routes-DORLim-C.js +0 -1
- package/.output/public/assets/t._teamId-F5f4K8kd.js +0 -1
- package/.output/public/assets/t._teamId-XfE_S1Fo.js +0 -1
- package/.output/public/assets/ui-Dhsx6SW0.js +0 -1
- package/.output/public/assets/useRouter-DsjH8G0p.js +0 -1
- package/.output/server/_libs/@codemirror/autocomplete+[...].mjs +0 -19713
- package/.output/server/_libs/@codemirror/lang-css+[...].mjs +0 -2636
- package/.output/server/_libs/@codemirror/lang-html+[...].mjs +0 -2247
- package/.output/server/_libs/@codemirror/lang-json+[...].mjs +0 -79
- package/.output/server/_libs/@reduxjs/toolkit+[...].mjs +0 -1736
- package/.output/server/_libs/@uiw/codemirror-extensions-basic-setup+[...].mjs +0 -76
- package/.output/server/_libs/babel__runtime.mjs +0 -30
- package/.output/server/_libs/clsx.mjs +0 -16
- package/.output/server/_libs/codemirror__commands.mjs +0 -1725
- package/.output/server/_libs/codemirror__lint.mjs +0 -565
- package/.output/server/_libs/codemirror__search.mjs +0 -1138
- package/.output/server/_libs/codemirror__theme-one-dark.mjs +0 -161
- package/.output/server/_libs/d3-array.mjs +0 -231
- package/.output/server/_libs/d3-color.mjs +0 -330
- package/.output/server/_libs/d3-format.mjs +0 -252
- package/.output/server/_libs/d3-interpolate.mjs +0 -163
- package/.output/server/_libs/d3-path.mjs +0 -77
- package/.output/server/_libs/d3-scale+[...].mjs +0 -1907
- package/.output/server/_libs/d3-shape.mjs +0 -818
- package/.output/server/_libs/decimal.js-light.mjs +0 -884
- package/.output/server/_libs/dom-serializer+[...].mjs +0 -708
- package/.output/server/_libs/domhandler.mjs +0 -461
- package/.output/server/_libs/domutils.mjs +0 -868
- package/.output/server/_libs/es-toolkit.mjs +0 -1737
- package/.output/server/_libs/eventemitter3.mjs +0 -236
- package/.output/server/_libs/html-dom-parser+htmlparser2.mjs +0 -1560
- package/.output/server/_libs/html-react-parser+[...].mjs +0 -1360
- package/.output/server/_libs/react-is.mjs +0 -48
- package/.output/server/_libs/react-redux+[...].mjs +0 -205
- package/.output/server/_libs/recharts+victory-vendor.mjs +0 -17303
- package/.output/server/_libs/uiw__codemirror-themes.mjs +0 -32
- package/.output/server/_libs/uiw__react-codemirror.mjs +0 -354
- package/.output/server/_ssr/CodeField-B7oOmmwH.mjs +0 -143
- package/.output/server/_ssr/DashboardView-BF7PciP7.mjs +0 -2736
- package/.output/server/_ssr/LoopPlaybook-DC7QVvPY.mjs +0 -2105
- package/.output/server/_ssr/LoopView-DwSrm9Ja.mjs +0 -1300
- package/.output/server/_ssr/Modal-MaCG52Pv.mjs +0 -49
- package/.output/server/_ssr/artifactView-iuPsp5aa.mjs +0 -304
- package/.output/server/_ssr/artifacts-jQ-bfdhI.mjs +0 -2
- package/.output/server/_ssr/boot-CsEFT53K.mjs +0 -2
- package/.output/server/_ssr/db-CXownd1H.mjs +0 -2
- package/.output/server/_ssr/invite._token-CWl6kipD.mjs +0 -28
- package/.output/server/_ssr/logger-Gy-47z3k.mjs +0 -2
- package/.output/server/_ssr/loopApi-8_KgBapr.mjs +0 -109
- package/.output/server/_ssr/loopApi-ABi9SgWS.mjs +0 -564
- package/.output/server/_ssr/loops._loopId-SON_t43g.mjs +0 -30
- package/.output/server/_ssr/loops._loopId-p1KWsvMM.mjs +0 -1477
- package/.output/server/_ssr/notifyFns-BUCePuF3.mjs +0 -118
- package/.output/server/_ssr/router-Czxvra6l.mjs +0 -685
- package/.output/server/_ssr/runDiff--qLtU4FI.mjs +0 -2
- package/.output/server/_ssr/store-40eVzW1S.mjs +0 -2
- package/.output/server/_ssr/tokens-CbfoRC_s.mjs +0 -2
- package/.output/server/drizzle/0001_naive_silver_fox.sql +0 -25
- package/.output/server/drizzle/0002_funny_sage.sql +0 -12
- package/.output/server/drizzle/0003_optimal_slapstick.sql +0 -102
- package/.output/server/drizzle/0004_remove_grok_agent.sql +0 -5
- package/.output/server/drizzle/0005_heavy_gauntlet.sql +0 -8
- package/.output/server/drizzle/0006_tranquil_sharon_carter.sql +0 -1
- package/.output/server/drizzle/0007_faulty_starbolt.sql +0 -30
- package/.output/server/drizzle/0008_durable_lifecycle_evidence.sql +0 -15
- package/.output/server/drizzle/0009_ordinary_electro.sql +0 -1
- package/.output/server/drizzle/0010_workable_rage.sql +0 -14
- package/.output/server/drizzle/0011_steep_marvel_zombies.sql +0 -3
- package/.output/server/drizzle/0012_blocked_run_status.sql +0 -12
- package/.output/server/drizzle/0013_drop_run_outcome.sql +0 -2
- package/.output/server/drizzle/0014_luxuriant_scrambler.sql +0 -5
- package/.output/server/drizzle/0015_run_history_foundation.sql +0 -43
- package/.output/server/drizzle/0016_plural_machine_runs.sql +0 -4
- package/.output/server/drizzle/meta/0000_snapshot.json +0 -1333
- package/.output/server/drizzle/meta/0001_snapshot.json +0 -1498
- package/.output/server/drizzle/meta/0002_snapshot.json +0 -1576
- package/.output/server/drizzle/meta/0003_snapshot.json +0 -1666
- package/.output/server/drizzle/meta/0005_snapshot.json +0 -1666
- package/.output/server/drizzle/meta/0006_snapshot.json +0 -1672
- package/.output/server/drizzle/meta/0007_snapshot.json +0 -1787
- package/.output/server/drizzle/meta/0009_snapshot.json +0 -1793
- package/.output/server/drizzle/meta/0010_snapshot.json +0 -1891
- package/.output/server/drizzle/meta/0011_snapshot.json +0 -1872
- package/drizzle/0001_naive_silver_fox.sql +0 -25
- package/drizzle/0002_funny_sage.sql +0 -12
- package/drizzle/0003_optimal_slapstick.sql +0 -102
- package/drizzle/0004_remove_grok_agent.sql +0 -5
- package/drizzle/0005_heavy_gauntlet.sql +0 -8
- package/drizzle/0006_tranquil_sharon_carter.sql +0 -1
- package/drizzle/0007_faulty_starbolt.sql +0 -30
- package/drizzle/0008_durable_lifecycle_evidence.sql +0 -15
- package/drizzle/0009_ordinary_electro.sql +0 -1
- package/drizzle/0010_workable_rage.sql +0 -14
- package/drizzle/0011_steep_marvel_zombies.sql +0 -3
- package/drizzle/0012_blocked_run_status.sql +0 -12
- package/drizzle/0013_drop_run_outcome.sql +0 -2
- package/drizzle/0014_luxuriant_scrambler.sql +0 -5
- package/drizzle/0015_run_history_foundation.sql +0 -43
- package/drizzle/0016_plural_machine_runs.sql +0 -4
- package/drizzle/meta/0000_snapshot.json +0 -1333
- package/drizzle/meta/0001_snapshot.json +0 -1498
- package/drizzle/meta/0002_snapshot.json +0 -1576
- package/drizzle/meta/0003_snapshot.json +0 -1666
- package/drizzle/meta/0005_snapshot.json +0 -1666
- package/drizzle/meta/0006_snapshot.json +0 -1672
- package/drizzle/meta/0007_snapshot.json +0 -1787
- package/drizzle/meta/0009_snapshot.json +0 -1793
- package/drizzle/meta/0010_snapshot.json +0 -1891
- 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 };
|