@graphrefly/graphrefly 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -2
- package/dist/_internal-B23BagFd.d.cts +33 -0
- package/dist/_internal-B23BagFd.d.ts +33 -0
- package/dist/adaptive-rate-limiter-Dch_xYIi.d.cts +111 -0
- package/dist/adaptive-rate-limiter-Dch_xYIi.d.ts +111 -0
- package/dist/agents-C0Ji9ldU.d.cts +629 -0
- package/dist/agents-C9zexT7I.d.ts +629 -0
- package/dist/audit-BAXb3VOg.d.ts +246 -0
- package/dist/audit-C_bPfkqS.d.cts +246 -0
- package/dist/backoff-7KIK3WQW.js +24 -0
- package/dist/backoff-7KIK3WQW.js.map +1 -0
- package/dist/backoff-Bnb9OoPh.d.cts +6 -0
- package/dist/backoff-Bnb9OoPh.d.ts +6 -0
- package/dist/base/composition/index.cjs +811 -0
- package/dist/base/composition/index.cjs.map +1 -0
- package/dist/base/composition/index.d.cts +469 -0
- package/dist/base/composition/index.d.ts +469 -0
- package/dist/base/composition/index.js +40 -0
- package/dist/base/composition/index.js.map +1 -0
- package/dist/base/index.cjs +6336 -0
- package/dist/base/index.cjs.map +1 -0
- package/dist/base/index.d.cts +22 -0
- package/dist/base/index.d.ts +22 -0
- package/dist/base/index.js +259 -0
- package/dist/base/index.js.map +1 -0
- package/dist/base/io/index.cjs +3270 -0
- package/dist/base/io/index.cjs.map +1 -0
- package/dist/base/io/index.d.cts +2245 -0
- package/dist/base/io/index.d.ts +2245 -0
- package/dist/base/io/index.js +117 -0
- package/dist/base/io/index.js.map +1 -0
- package/dist/base/meta/index.cjs +43 -0
- package/dist/base/meta/index.cjs.map +1 -0
- package/dist/base/meta/index.d.cts +45 -0
- package/dist/base/meta/index.d.ts +45 -0
- package/dist/base/meta/index.js +13 -0
- package/dist/base/meta/index.js.map +1 -0
- package/dist/base/mutation/index.cjs +200 -0
- package/dist/base/mutation/index.cjs.map +1 -0
- package/dist/base/mutation/index.d.cts +177 -0
- package/dist/base/mutation/index.d.ts +177 -0
- package/dist/base/mutation/index.js +22 -0
- package/dist/base/mutation/index.js.map +1 -0
- package/dist/base/render/index.cjs +1120 -0
- package/dist/base/render/index.cjs.map +1 -0
- package/dist/base/render/index.d.cts +227 -0
- package/dist/base/render/index.d.ts +227 -0
- package/dist/base/render/index.js +24 -0
- package/dist/base/render/index.js.map +1 -0
- package/dist/base/sources/browser/index.cjs +172 -0
- package/dist/base/sources/browser/index.cjs.map +1 -0
- package/dist/base/sources/browser/index.d.cts +84 -0
- package/dist/base/sources/browser/index.d.ts +84 -0
- package/dist/base/sources/browser/index.js +151 -0
- package/dist/base/sources/browser/index.js.map +1 -0
- package/dist/base/sources/event/index.cjs +98 -0
- package/dist/base/sources/event/index.cjs.map +1 -0
- package/dist/base/sources/event/index.d.cts +91 -0
- package/dist/base/sources/event/index.d.ts +91 -0
- package/dist/base/sources/event/index.js +13 -0
- package/dist/base/sources/event/index.js.map +1 -0
- package/dist/base/sources/index.cjs +755 -0
- package/dist/base/sources/index.cjs.map +1 -0
- package/dist/base/sources/index.d.cts +357 -0
- package/dist/base/sources/index.d.ts +357 -0
- package/dist/base/sources/index.js +42 -0
- package/dist/base/sources/index.js.map +1 -0
- package/dist/base/sources/node/index.cjs +320 -0
- package/dist/base/sources/node/index.cjs.map +1 -0
- package/dist/base/sources/node/index.d.cts +185 -0
- package/dist/base/sources/node/index.d.ts +185 -0
- package/dist/base/sources/node/index.js +306 -0
- package/dist/base/sources/node/index.js.map +1 -0
- package/dist/base/utils/index.cjs +37 -0
- package/dist/base/utils/index.cjs.map +1 -0
- package/dist/base/utils/index.d.cts +37 -0
- package/dist/base/utils/index.d.ts +37 -0
- package/dist/base/utils/index.js +11 -0
- package/dist/base/utils/index.js.map +1 -0
- package/dist/base/worker/index.cjs +548 -0
- package/dist/base/worker/index.cjs.map +1 -0
- package/dist/base/worker/index.d.cts +207 -0
- package/dist/base/worker/index.d.ts +207 -0
- package/dist/base/worker/index.js +20 -0
- package/dist/base/worker/index.js.map +1 -0
- package/dist/breaker-C9skL3d8.d.ts +175 -0
- package/dist/breaker-ugSdq54q.d.cts +175 -0
- package/dist/cascading-CSSbKGrJ.d.ts +199 -0
- package/dist/cascading-baGkiihI.d.cts +199 -0
- package/dist/chunk-255UCBG4.js +58 -0
- package/dist/chunk-255UCBG4.js.map +1 -0
- package/dist/chunk-2LO3EL4W.js +1 -0
- package/dist/chunk-2LO3EL4W.js.map +1 -0
- package/dist/chunk-2OB3CEJS.js +1065 -0
- package/dist/chunk-2OB3CEJS.js.map +1 -0
- package/dist/chunk-36NMM65U.js +144 -0
- package/dist/chunk-36NMM65U.js.map +1 -0
- package/dist/chunk-3CEXCBN6.js +1 -0
- package/dist/chunk-3CEXCBN6.js.map +1 -0
- package/dist/chunk-3MUSLI6E.js +105 -0
- package/dist/chunk-3MUSLI6E.js.map +1 -0
- package/dist/chunk-3PSLNJDU.js +884 -0
- package/dist/chunk-3PSLNJDU.js.map +1 -0
- package/dist/chunk-3QZY5BI7.js +92 -0
- package/dist/chunk-3QZY5BI7.js.map +1 -0
- package/dist/chunk-42FQ27MQ.js +594 -0
- package/dist/chunk-42FQ27MQ.js.map +1 -0
- package/dist/chunk-4GYMCUDZ.js +1085 -0
- package/dist/chunk-4GYMCUDZ.js.map +1 -0
- package/dist/chunk-4S53H2KR.js +382 -0
- package/dist/chunk-4S53H2KR.js.map +1 -0
- package/dist/chunk-4XCHZRUJ.js +128 -0
- package/dist/chunk-4XCHZRUJ.js.map +1 -0
- package/dist/chunk-5THCXDWY.js +725 -0
- package/dist/chunk-5THCXDWY.js.map +1 -0
- package/dist/chunk-6XZYT4SW.js +256 -0
- package/dist/chunk-6XZYT4SW.js.map +1 -0
- package/dist/chunk-7EGRP2VX.js +76 -0
- package/dist/chunk-7EGRP2VX.js.map +1 -0
- package/dist/chunk-A7KV5UK4.js +150 -0
- package/dist/chunk-A7KV5UK4.js.map +1 -0
- package/dist/chunk-APY2SS5X.js +156 -0
- package/dist/chunk-APY2SS5X.js.map +1 -0
- package/dist/chunk-AZDQPQ3V.js +66 -0
- package/dist/chunk-AZDQPQ3V.js.map +1 -0
- package/dist/chunk-BU3SEFA5.js +90 -0
- package/dist/chunk-BU3SEFA5.js.map +1 -0
- package/dist/chunk-BXGZFGZ4.js +189 -0
- package/dist/chunk-BXGZFGZ4.js.map +1 -0
- package/dist/chunk-CGHORL6G.js +579 -0
- package/dist/chunk-CGHORL6G.js.map +1 -0
- package/dist/chunk-CXANAIZU.js +530 -0
- package/dist/chunk-CXANAIZU.js.map +1 -0
- package/dist/chunk-CZQHCKKG.js +1 -0
- package/dist/chunk-CZQHCKKG.js.map +1 -0
- package/dist/chunk-DKNHAICT.js +133 -0
- package/dist/chunk-DKNHAICT.js.map +1 -0
- package/dist/chunk-DM4OMPWK.js +584 -0
- package/dist/chunk-DM4OMPWK.js.map +1 -0
- package/dist/chunk-DMSNO6ZB.js +452 -0
- package/dist/chunk-DMSNO6ZB.js.map +1 -0
- package/dist/chunk-E5OZPDIW.js +229 -0
- package/dist/chunk-E5OZPDIW.js.map +1 -0
- package/dist/chunk-EVYY4X5A.js +509 -0
- package/dist/chunk-EVYY4X5A.js.map +1 -0
- package/dist/chunk-FDFD67UO.js +1 -0
- package/dist/chunk-FDFD67UO.js.map +1 -0
- package/dist/chunk-FMPF42Q4.js +13 -0
- package/dist/chunk-FMPF42Q4.js.map +1 -0
- package/dist/chunk-FR6RGA3B.js +1277 -0
- package/dist/chunk-FR6RGA3B.js.map +1 -0
- package/dist/chunk-FW23JYNQ.js +454 -0
- package/dist/chunk-FW23JYNQ.js.map +1 -0
- package/dist/chunk-GBCENOLN.js +1575 -0
- package/dist/chunk-GBCENOLN.js.map +1 -0
- package/dist/chunk-HL7HUJIX.js +1 -0
- package/dist/chunk-HL7HUJIX.js.map +1 -0
- package/dist/chunk-HULCUY35.js +2508 -0
- package/dist/chunk-HULCUY35.js.map +1 -0
- package/dist/chunk-IHTWQEDR.js +169 -0
- package/dist/chunk-IHTWQEDR.js.map +1 -0
- package/dist/chunk-IJRR6YAI.js +128 -0
- package/dist/chunk-IJRR6YAI.js.map +1 -0
- package/dist/chunk-JGFRAFDL.js +221 -0
- package/dist/chunk-JGFRAFDL.js.map +1 -0
- package/dist/chunk-KIIXR252.js +211 -0
- package/dist/chunk-KIIXR252.js.map +1 -0
- package/dist/chunk-KN3H5CNT.js +11 -0
- package/dist/chunk-KN3H5CNT.js.map +1 -0
- package/dist/chunk-KPG3DGLA.js +1 -0
- package/dist/chunk-KPG3DGLA.js.map +1 -0
- package/dist/chunk-KRNQ6RGQ.js +1 -0
- package/dist/chunk-KRNQ6RGQ.js.map +1 -0
- package/dist/chunk-LBAJK24K.js +1071 -0
- package/dist/chunk-LBAJK24K.js.map +1 -0
- package/dist/chunk-MLTPJMH6.js +417 -0
- package/dist/chunk-MLTPJMH6.js.map +1 -0
- package/dist/chunk-N3SZ7BMH.js +95 -0
- package/dist/chunk-N3SZ7BMH.js.map +1 -0
- package/dist/chunk-NDUD3IMO.js +540 -0
- package/dist/chunk-NDUD3IMO.js.map +1 -0
- package/dist/chunk-NY2PYHNC.js +873 -0
- package/dist/chunk-NY2PYHNC.js.map +1 -0
- package/dist/chunk-O3MT7DYI.js +225 -0
- package/dist/chunk-O3MT7DYI.js.map +1 -0
- package/dist/chunk-OCUDSN63.js +2386 -0
- package/dist/chunk-OCUDSN63.js.map +1 -0
- package/dist/chunk-OIWU3NYV.js +199 -0
- package/dist/chunk-OIWU3NYV.js.map +1 -0
- package/dist/chunk-OO5BM6CJ.js +1153 -0
- package/dist/chunk-OO5BM6CJ.js.map +1 -0
- package/dist/chunk-OQUIJT7A.js +1 -0
- package/dist/chunk-OQUIJT7A.js.map +1 -0
- package/dist/chunk-P5LBT622.js +105 -0
- package/dist/chunk-P5LBT622.js.map +1 -0
- package/dist/chunk-PKGQG5QQ.js +519 -0
- package/dist/chunk-PKGQG5QQ.js.map +1 -0
- package/dist/chunk-PKPO3JTZ.js +561 -0
- package/dist/chunk-PKPO3JTZ.js.map +1 -0
- package/dist/chunk-PL5UDIQ5.js +118 -0
- package/dist/chunk-PL5UDIQ5.js.map +1 -0
- package/dist/chunk-PZWISPIQ.js +432 -0
- package/dist/chunk-PZWISPIQ.js.map +1 -0
- package/dist/chunk-Q3EYOCZB.js +510 -0
- package/dist/chunk-Q3EYOCZB.js.map +1 -0
- package/dist/chunk-QMBYUVRL.js +15 -0
- package/dist/chunk-QMBYUVRL.js.map +1 -0
- package/dist/chunk-RAGGHLCV.js +200 -0
- package/dist/chunk-RAGGHLCV.js.map +1 -0
- package/dist/chunk-RGL53X5G.js +574 -0
- package/dist/chunk-RGL53X5G.js.map +1 -0
- package/dist/chunk-RJOG4IJU.js +1039 -0
- package/dist/chunk-RJOG4IJU.js.map +1 -0
- package/dist/chunk-SOOKUYVM.js +403 -0
- package/dist/chunk-SOOKUYVM.js.map +1 -0
- package/dist/chunk-T5BN5KG7.js +1 -0
- package/dist/chunk-T5BN5KG7.js.map +1 -0
- package/dist/chunk-TP7244Y6.js +207 -0
- package/dist/chunk-TP7244Y6.js.map +1 -0
- package/dist/chunk-TSBFTJKM.js +57 -0
- package/dist/chunk-TSBFTJKM.js.map +1 -0
- package/dist/chunk-URQ2CBBF.js +143 -0
- package/dist/chunk-URQ2CBBF.js.map +1 -0
- package/dist/chunk-W2BOPXTI.js +1 -0
- package/dist/chunk-W2BOPXTI.js.map +1 -0
- package/dist/chunk-WKSWLSCX.js +207 -0
- package/dist/chunk-WKSWLSCX.js.map +1 -0
- package/dist/chunk-Y52CS6YA.js +88 -0
- package/dist/chunk-Y52CS6YA.js.map +1 -0
- package/dist/chunk-YCBUWK77.js +92 -0
- package/dist/chunk-YCBUWK77.js.map +1 -0
- package/dist/chunk-YJ4U2D2C.js +314 -0
- package/dist/chunk-YJ4U2D2C.js.map +1 -0
- package/dist/chunk-Z4YXAUDN.js +239 -0
- package/dist/chunk-Z4YXAUDN.js.map +1 -0
- package/dist/chunk-Z6EGP5D7.js +92 -0
- package/dist/chunk-Z6EGP5D7.js.map +1 -0
- package/dist/compat/index.cjs +3083 -2
- package/dist/compat/index.cjs.map +1 -1
- package/dist/compat/index.d.cts +116 -1
- package/dist/compat/index.d.ts +116 -1
- package/dist/compat/index.js +175 -2
- package/dist/compat/index.js.map +1 -1
- package/dist/compat/jotai/index.cjs +130 -2
- package/dist/compat/jotai/index.cjs.map +1 -1
- package/dist/compat/jotai/index.d.cts +2 -1
- package/dist/compat/jotai/index.d.ts +2 -1
- package/dist/compat/jotai/index.js +7 -2
- package/dist/compat/jotai/index.js.map +1 -1
- package/dist/compat/nanostores/index.cjs +186 -2
- package/dist/compat/nanostores/index.cjs.map +1 -1
- package/dist/compat/nanostores/index.d.cts +2 -1
- package/dist/compat/nanostores/index.d.ts +2 -1
- package/dist/compat/nanostores/index.js +21 -2
- package/dist/compat/nanostores/index.js.map +1 -1
- package/dist/compat/nestjs/index.cjs +2224 -2
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +10 -1
- package/dist/compat/nestjs/index.d.ts +10 -1
- package/dist/compat/nestjs/index.js +77 -2
- package/dist/compat/nestjs/index.js.map +1 -1
- package/dist/compat/react/index.cjs +95 -2
- package/dist/compat/react/index.cjs.map +1 -1
- package/dist/compat/react/index.d.cts +2 -1
- package/dist/compat/react/index.d.ts +2 -1
- package/dist/compat/react/index.js +11 -2
- package/dist/compat/react/index.js.map +1 -1
- package/dist/compat/solid/index.cjs +82 -2
- package/dist/compat/solid/index.cjs.map +1 -1
- package/dist/compat/solid/index.d.cts +2 -1
- package/dist/compat/solid/index.d.ts +2 -1
- package/dist/compat/solid/index.js +11 -2
- package/dist/compat/solid/index.js.map +1 -1
- package/dist/compat/svelte/index.cjs +85 -2
- package/dist/compat/svelte/index.cjs.map +1 -1
- package/dist/compat/svelte/index.d.cts +2 -1
- package/dist/compat/svelte/index.d.ts +2 -1
- package/dist/compat/svelte/index.js +11 -2
- package/dist/compat/svelte/index.js.map +1 -1
- package/dist/compat/vue/index.cjs +100 -2
- package/dist/compat/vue/index.cjs.map +1 -1
- package/dist/compat/vue/index.d.cts +3 -1
- package/dist/compat/vue/index.d.ts +3 -1
- package/dist/compat/vue/index.js +11 -2
- package/dist/compat/vue/index.js.map +1 -1
- package/dist/compat/zustand/index.cjs +50 -2
- package/dist/compat/zustand/index.cjs.map +1 -1
- package/dist/compat/zustand/index.d.cts +2 -1
- package/dist/compat/zustand/index.d.ts +2 -1
- package/dist/compat/zustand/index.js +7 -2
- package/dist/compat/zustand/index.js.map +1 -1
- package/dist/distill-De6Rnn15.d.cts +48 -0
- package/dist/distill-De6Rnn15.d.ts +48 -0
- package/dist/external-register-CWyroXb_.d.cts +138 -0
- package/dist/external-register-CWyroXb_.d.ts +138 -0
- package/dist/fallback-Bx46zqky.d.cts +243 -0
- package/dist/fallback-pIWW8A2d.d.ts +243 -0
- package/dist/guarded-execution-BcdtxeBk.d.ts +207 -0
- package/dist/guarded-execution-C-3hnP6A.d.cts +207 -0
- package/dist/index-5SU_O78r.d.cts +754 -0
- package/dist/index-B6pxYJzO.d.cts +36 -0
- package/dist/index-B6pxYJzO.d.ts +36 -0
- package/dist/index-BFsng6v1.d.cts +44 -0
- package/dist/index-BFsng6v1.d.ts +44 -0
- package/dist/index-Bg-LwEt-.d.cts +45 -0
- package/dist/index-Bg-LwEt-.d.ts +45 -0
- package/dist/index-Brp888t0.d.cts +127 -0
- package/dist/index-Brp888t0.d.ts +127 -0
- package/dist/index-CDfk6jHN.d.cts +37 -0
- package/dist/index-CDfk6jHN.d.ts +37 -0
- package/dist/index-CEXCtYYJ.d.ts +754 -0
- package/dist/index-DLAxYaN5.d.cts +169 -0
- package/dist/index-DLAxYaN5.d.ts +169 -0
- package/dist/index-DeWbQzMe.d.cts +34 -0
- package/dist/index-DeWbQzMe.d.ts +34 -0
- package/dist/index-dX9IzPqj.d.cts +86 -0
- package/dist/index-dX9IzPqj.d.ts +86 -0
- package/dist/index.cjs +25950 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -42
- package/dist/index.d.ts +56 -42
- package/dist/index.js +849 -0
- package/dist/index.js.map +1 -1
- package/dist/layout-types-B5aiHYgk.d.cts +72 -0
- package/dist/layout-types-B5aiHYgk.d.ts +72 -0
- package/dist/memory-composers-BryDrRBX.d.cts +529 -0
- package/dist/memory-composers-CVQqPYEV.d.ts +529 -0
- package/dist/observable-BXQoW1P-.d.cts +36 -0
- package/dist/observable-BXQoW1P-.d.ts +36 -0
- package/dist/pipeline-graph-Ce47CB6Y.d.cts +145 -0
- package/dist/pipeline-graph-DXCwY9vG.d.ts +145 -0
- package/dist/presets/ai/index.cjs +4377 -0
- package/dist/presets/ai/index.cjs.map +1 -0
- package/dist/presets/ai/index.d.cts +98 -0
- package/dist/presets/ai/index.d.ts +98 -0
- package/dist/presets/ai/index.js +54 -0
- package/dist/presets/ai/index.js.map +1 -0
- package/dist/presets/harness/index.cjs +5929 -0
- package/dist/presets/harness/index.cjs.map +1 -0
- package/dist/presets/harness/index.d.cts +566 -0
- package/dist/presets/harness/index.d.ts +566 -0
- package/dist/presets/harness/index.js +71 -0
- package/dist/presets/harness/index.js.map +1 -0
- package/dist/presets/index.cjs +9782 -0
- package/dist/presets/index.cjs.map +1 -0
- package/dist/presets/index.d.cts +28 -0
- package/dist/presets/index.d.ts +28 -0
- package/dist/presets/index.js +129 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/inspect/index.cjs +1087 -0
- package/dist/presets/inspect/index.cjs.map +1 -0
- package/dist/presets/inspect/index.d.cts +172 -0
- package/dist/presets/inspect/index.d.ts +172 -0
- package/dist/presets/inspect/index.js +21 -0
- package/dist/presets/inspect/index.js.map +1 -0
- package/dist/presets/resilience/index.cjs +1593 -0
- package/dist/presets/resilience/index.cjs.map +1 -0
- package/dist/presets/resilience/index.d.cts +205 -0
- package/dist/presets/resilience/index.d.ts +205 -0
- package/dist/presets/resilience/index.js +18 -0
- package/dist/presets/resilience/index.js.map +1 -0
- package/dist/rate-limiter-CEALq4N1.d.ts +559 -0
- package/dist/rate-limiter-DpVbSYdH.d.cts +559 -0
- package/dist/reactive-layout-fswlBUvX.d.cts +195 -0
- package/dist/reactive-layout-fswlBUvX.d.ts +195 -0
- package/dist/retry-BDbRZ_gx.d.ts +125 -0
- package/dist/retry-DWuhjvsA.d.cts +125 -0
- package/dist/solutions/index.cjs +8200 -0
- package/dist/solutions/index.cjs.map +1 -0
- package/dist/solutions/index.d.cts +23 -0
- package/dist/solutions/index.d.ts +23 -0
- package/dist/solutions/index.js +55 -0
- package/dist/solutions/index.js.map +1 -0
- package/dist/spawnable-5mDY501F.d.cts +746 -0
- package/dist/spawnable-D3lR0oQu.d.ts +746 -0
- package/dist/status-U-rUI79b.d.cts +84 -0
- package/dist/status-U-rUI79b.d.ts +84 -0
- package/dist/timeout-U5O4ESK3.js +12 -0
- package/dist/timeout-U5O4ESK3.js.map +1 -0
- package/dist/types-BB5Lw-pB.d.cts +442 -0
- package/dist/types-BB5Lw-pB.d.ts +442 -0
- package/dist/types-CJWIMJiZ.d.ts +548 -0
- package/dist/types-vCq7ShIm.d.cts +548 -0
- package/dist/utils/ai/browser.cjs +2169 -0
- package/dist/utils/ai/browser.cjs.map +1 -0
- package/dist/utils/ai/browser.d.cts +129 -0
- package/dist/utils/ai/browser.d.ts +129 -0
- package/dist/utils/ai/browser.js +255 -0
- package/dist/utils/ai/browser.js.map +1 -0
- package/dist/utils/ai/index.cjs +8468 -0
- package/dist/utils/ai/index.cjs.map +1 -0
- package/dist/utils/ai/index.d.cts +1777 -0
- package/dist/utils/ai/index.d.ts +1777 -0
- package/dist/utils/ai/index.js +173 -0
- package/dist/utils/ai/index.js.map +1 -0
- package/dist/utils/ai/node.cjs +648 -0
- package/dist/utils/ai/node.cjs.map +1 -0
- package/dist/utils/ai/node.d.cts +57 -0
- package/dist/utils/ai/node.d.ts +57 -0
- package/dist/utils/ai/node.js +84 -0
- package/dist/utils/ai/node.js.map +1 -0
- package/dist/utils/cqrs/index.cjs +1036 -0
- package/dist/utils/cqrs/index.cjs.map +1 -0
- package/dist/utils/cqrs/index.d.cts +438 -0
- package/dist/utils/cqrs/index.d.ts +438 -0
- package/dist/utils/cqrs/index.js +18 -0
- package/dist/utils/cqrs/index.js.map +1 -0
- package/dist/utils/demo-shell/index.cjs +865 -0
- package/dist/utils/demo-shell/index.cjs.map +1 -0
- package/dist/utils/demo-shell/index.d.cts +90 -0
- package/dist/utils/demo-shell/index.d.ts +90 -0
- package/dist/utils/demo-shell/index.js +13 -0
- package/dist/utils/demo-shell/index.js.map +1 -0
- package/dist/utils/domain-templates/index.cjs +732 -0
- package/dist/utils/domain-templates/index.cjs.map +1 -0
- package/dist/utils/domain-templates/index.d.cts +214 -0
- package/dist/utils/domain-templates/index.d.ts +214 -0
- package/dist/utils/domain-templates/index.js +17 -0
- package/dist/utils/domain-templates/index.js.map +1 -0
- package/dist/utils/graphspec/index.cjs +1174 -0
- package/dist/utils/graphspec/index.cjs.map +1 -0
- package/dist/utils/graphspec/index.d.cts +449 -0
- package/dist/utils/graphspec/index.d.ts +449 -0
- package/dist/utils/graphspec/index.js +35 -0
- package/dist/utils/graphspec/index.js.map +1 -0
- package/dist/utils/harness/index.cjs +656 -0
- package/dist/utils/harness/index.cjs.map +1 -0
- package/dist/utils/harness/index.d.cts +542 -0
- package/dist/utils/harness/index.d.ts +542 -0
- package/dist/utils/harness/index.js +56 -0
- package/dist/utils/harness/index.js.map +1 -0
- package/dist/utils/index.cjs +17609 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.d.cts +96 -0
- package/dist/utils/index.d.ts +96 -0
- package/dist/utils/index.js +514 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/inspect/index.cjs +807 -0
- package/dist/utils/inspect/index.cjs.map +1 -0
- package/dist/utils/inspect/index.d.cts +123 -0
- package/dist/utils/inspect/index.d.ts +123 -0
- package/dist/utils/inspect/index.js +30 -0
- package/dist/utils/inspect/index.js.map +1 -0
- package/dist/utils/job-queue/index.cjs +717 -0
- package/dist/utils/job-queue/index.cjs.map +1 -0
- package/dist/utils/job-queue/index.d.cts +200 -0
- package/dist/utils/job-queue/index.d.ts +200 -0
- package/dist/utils/job-queue/index.js +18 -0
- package/dist/utils/job-queue/index.js.map +1 -0
- package/dist/utils/memory/index.cjs +1451 -0
- package/dist/utils/memory/index.cjs.map +1 -0
- package/dist/utils/memory/index.d.cts +582 -0
- package/dist/utils/memory/index.d.ts +582 -0
- package/dist/utils/memory/index.js +19 -0
- package/dist/utils/memory/index.js.map +1 -0
- package/dist/utils/messaging/index.cjs +666 -0
- package/dist/utils/messaging/index.cjs.map +1 -0
- package/dist/utils/messaging/index.d.cts +562 -0
- package/dist/utils/messaging/index.d.ts +562 -0
- package/dist/utils/messaging/index.js +50 -0
- package/dist/utils/messaging/index.js.map +1 -0
- package/dist/utils/orchestration/index.cjs +876 -0
- package/dist/utils/orchestration/index.cjs.map +1 -0
- package/dist/utils/orchestration/index.d.cts +233 -0
- package/dist/utils/orchestration/index.d.ts +233 -0
- package/dist/utils/orchestration/index.js +19 -0
- package/dist/utils/orchestration/index.js.map +1 -0
- package/dist/utils/process/index.cjs +743 -0
- package/dist/utils/process/index.cjs.map +1 -0
- package/dist/utils/process/index.d.cts +411 -0
- package/dist/utils/process/index.d.ts +411 -0
- package/dist/utils/process/index.js +14 -0
- package/dist/utils/process/index.js.map +1 -0
- package/dist/utils/reactive-layout/index.cjs +1607 -0
- package/dist/utils/reactive-layout/index.cjs.map +1 -0
- package/dist/utils/reactive-layout/index.d.cts +492 -0
- package/dist/utils/reactive-layout/index.d.ts +492 -0
- package/dist/utils/reactive-layout/index.js +52 -0
- package/dist/utils/reactive-layout/index.js.map +1 -0
- package/dist/utils/reduction/index.cjs +203 -0
- package/dist/utils/reduction/index.cjs.map +1 -0
- package/dist/utils/reduction/index.d.cts +102 -0
- package/dist/utils/reduction/index.d.ts +102 -0
- package/dist/utils/reduction/index.js +14 -0
- package/dist/utils/reduction/index.js.map +1 -0
- package/dist/utils/resilience/index.cjs +1617 -0
- package/dist/utils/resilience/index.cjs.map +1 -0
- package/dist/utils/resilience/index.d.cts +9 -0
- package/dist/utils/resilience/index.d.ts +9 -0
- package/dist/utils/resilience/index.js +44 -0
- package/dist/utils/resilience/index.js.map +1 -0
- package/dist/utils/surface/index.cjs +1070 -0
- package/dist/utils/surface/index.cjs.map +1 -0
- package/dist/utils/surface/index.d.cts +240 -0
- package/dist/utils/surface/index.d.ts +240 -0
- package/dist/utils/surface/index.js +30 -0
- package/dist/utils/surface/index.js.map +1 -0
- package/dist/utils/topology-view/index.cjs +620 -0
- package/dist/utils/topology-view/index.cjs.map +1 -0
- package/dist/utils/topology-view/index.d.cts +68 -0
- package/dist/utils/topology-view/index.d.ts +68 -0
- package/dist/utils/topology-view/index.js +11 -0
- package/dist/utils/topology-view/index.js.map +1 -0
- package/package.json +293 -237
- package/dist/core/index.cjs +0 -21
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.js +0 -3
- package/dist/core/index.js.map +0 -1
- package/dist/extra/browser.cjs +0 -21
- package/dist/extra/browser.cjs.map +0 -1
- package/dist/extra/browser.d.cts +0 -1
- package/dist/extra/browser.d.ts +0 -1
- package/dist/extra/browser.js +0 -3
- package/dist/extra/browser.js.map +0 -1
- package/dist/extra/index.cjs +0 -21
- package/dist/extra/index.cjs.map +0 -1
- package/dist/extra/index.d.cts +0 -1
- package/dist/extra/index.d.ts +0 -1
- package/dist/extra/index.js +0 -3
- package/dist/extra/index.js.map +0 -1
- package/dist/extra/node.cjs +0 -21
- package/dist/extra/node.cjs.map +0 -1
- package/dist/extra/node.d.cts +0 -1
- package/dist/extra/node.d.ts +0 -1
- package/dist/extra/node.js +0 -3
- package/dist/extra/node.js.map +0 -1
- package/dist/extra/operators.cjs +0 -21
- package/dist/extra/operators.cjs.map +0 -1
- package/dist/extra/operators.d.cts +0 -1
- package/dist/extra/operators.d.ts +0 -1
- package/dist/extra/operators.js +0 -3
- package/dist/extra/operators.js.map +0 -1
- package/dist/extra/reactive.cjs +0 -21
- package/dist/extra/reactive.cjs.map +0 -1
- package/dist/extra/reactive.d.cts +0 -1
- package/dist/extra/reactive.d.ts +0 -1
- package/dist/extra/reactive.js +0 -3
- package/dist/extra/reactive.js.map +0 -1
- package/dist/extra/render/index.cjs +0 -21
- package/dist/extra/render/index.cjs.map +0 -1
- package/dist/extra/render/index.d.cts +0 -1
- package/dist/extra/render/index.d.ts +0 -1
- package/dist/extra/render/index.js +0 -3
- package/dist/extra/render/index.js.map +0 -1
- package/dist/extra/sources.cjs +0 -21
- package/dist/extra/sources.cjs.map +0 -1
- package/dist/extra/sources.d.cts +0 -1
- package/dist/extra/sources.d.ts +0 -1
- package/dist/extra/sources.js +0 -3
- package/dist/extra/sources.js.map +0 -1
- package/dist/extra/storage-browser.cjs +0 -21
- package/dist/extra/storage-browser.cjs.map +0 -1
- package/dist/extra/storage-browser.d.cts +0 -1
- package/dist/extra/storage-browser.d.ts +0 -1
- package/dist/extra/storage-browser.js +0 -3
- package/dist/extra/storage-browser.js.map +0 -1
- package/dist/extra/storage-core.cjs +0 -21
- package/dist/extra/storage-core.cjs.map +0 -1
- package/dist/extra/storage-core.d.cts +0 -1
- package/dist/extra/storage-core.d.ts +0 -1
- package/dist/extra/storage-core.js +0 -3
- package/dist/extra/storage-core.js.map +0 -1
- package/dist/extra/storage-node.cjs +0 -21
- package/dist/extra/storage-node.cjs.map +0 -1
- package/dist/extra/storage-node.d.cts +0 -1
- package/dist/extra/storage-node.d.ts +0 -1
- package/dist/extra/storage-node.js +0 -3
- package/dist/extra/storage-node.js.map +0 -1
- package/dist/extra/storage-tiers-browser.cjs +0 -21
- package/dist/extra/storage-tiers-browser.cjs.map +0 -1
- package/dist/extra/storage-tiers-browser.d.cts +0 -1
- package/dist/extra/storage-tiers-browser.d.ts +0 -1
- package/dist/extra/storage-tiers-browser.js +0 -3
- package/dist/extra/storage-tiers-browser.js.map +0 -1
- package/dist/extra/storage-tiers-node.cjs +0 -21
- package/dist/extra/storage-tiers-node.cjs.map +0 -1
- package/dist/extra/storage-tiers-node.d.cts +0 -1
- package/dist/extra/storage-tiers-node.d.ts +0 -1
- package/dist/extra/storage-tiers-node.js +0 -3
- package/dist/extra/storage-tiers-node.js.map +0 -1
- package/dist/extra/storage-tiers.cjs +0 -21
- package/dist/extra/storage-tiers.cjs.map +0 -1
- package/dist/extra/storage-tiers.d.cts +0 -1
- package/dist/extra/storage-tiers.d.ts +0 -1
- package/dist/extra/storage-tiers.js +0 -3
- package/dist/extra/storage-tiers.js.map +0 -1
- package/dist/extra/storage-wal.cjs +0 -21
- package/dist/extra/storage-wal.cjs.map +0 -1
- package/dist/extra/storage-wal.d.cts +0 -1
- package/dist/extra/storage-wal.d.ts +0 -1
- package/dist/extra/storage-wal.js +0 -3
- package/dist/extra/storage-wal.js.map +0 -1
- package/dist/graph/index.cjs +0 -21
- package/dist/graph/index.cjs.map +0 -1
- package/dist/graph/index.d.cts +0 -1
- package/dist/graph/index.d.ts +0 -1
- package/dist/graph/index.js +0 -3
- package/dist/graph/index.js.map +0 -1
- package/dist/patterns/ai/browser.cjs +0 -21
- package/dist/patterns/ai/browser.cjs.map +0 -1
- package/dist/patterns/ai/browser.d.cts +0 -1
- package/dist/patterns/ai/browser.d.ts +0 -1
- package/dist/patterns/ai/browser.js +0 -3
- package/dist/patterns/ai/browser.js.map +0 -1
- package/dist/patterns/ai/index.cjs +0 -21
- package/dist/patterns/ai/index.cjs.map +0 -1
- package/dist/patterns/ai/index.d.cts +0 -1
- package/dist/patterns/ai/index.d.ts +0 -1
- package/dist/patterns/ai/index.js +0 -3
- package/dist/patterns/ai/index.js.map +0 -1
- package/dist/patterns/ai/node.cjs +0 -21
- package/dist/patterns/ai/node.cjs.map +0 -1
- package/dist/patterns/ai/node.d.cts +0 -1
- package/dist/patterns/ai/node.d.ts +0 -1
- package/dist/patterns/ai/node.js +0 -3
- package/dist/patterns/ai/node.js.map +0 -1
- package/dist/patterns/cqrs/index.cjs +0 -21
- package/dist/patterns/cqrs/index.cjs.map +0 -1
- package/dist/patterns/cqrs/index.d.cts +0 -1
- package/dist/patterns/cqrs/index.d.ts +0 -1
- package/dist/patterns/cqrs/index.js +0 -3
- package/dist/patterns/cqrs/index.js.map +0 -1
- package/dist/patterns/demo-shell/index.cjs +0 -21
- package/dist/patterns/demo-shell/index.cjs.map +0 -1
- package/dist/patterns/demo-shell/index.d.cts +0 -1
- package/dist/patterns/demo-shell/index.d.ts +0 -1
- package/dist/patterns/demo-shell/index.js +0 -3
- package/dist/patterns/demo-shell/index.js.map +0 -1
- package/dist/patterns/domain-templates/index.cjs +0 -21
- package/dist/patterns/domain-templates/index.cjs.map +0 -1
- package/dist/patterns/domain-templates/index.d.cts +0 -1
- package/dist/patterns/domain-templates/index.d.ts +0 -1
- package/dist/patterns/domain-templates/index.js +0 -3
- package/dist/patterns/domain-templates/index.js.map +0 -1
- package/dist/patterns/graphspec/index.cjs +0 -21
- package/dist/patterns/graphspec/index.cjs.map +0 -1
- package/dist/patterns/graphspec/index.d.cts +0 -1
- package/dist/patterns/graphspec/index.d.ts +0 -1
- package/dist/patterns/graphspec/index.js +0 -3
- package/dist/patterns/graphspec/index.js.map +0 -1
- package/dist/patterns/harness/index.cjs +0 -21
- package/dist/patterns/harness/index.cjs.map +0 -1
- package/dist/patterns/harness/index.d.cts +0 -1
- package/dist/patterns/harness/index.d.ts +0 -1
- package/dist/patterns/harness/index.js +0 -3
- package/dist/patterns/harness/index.js.map +0 -1
- package/dist/patterns/inspect/index.cjs +0 -21
- package/dist/patterns/inspect/index.cjs.map +0 -1
- package/dist/patterns/inspect/index.d.cts +0 -1
- package/dist/patterns/inspect/index.d.ts +0 -1
- package/dist/patterns/inspect/index.js +0 -3
- package/dist/patterns/inspect/index.js.map +0 -1
- package/dist/patterns/job-queue/index.cjs +0 -21
- package/dist/patterns/job-queue/index.cjs.map +0 -1
- package/dist/patterns/job-queue/index.d.cts +0 -1
- package/dist/patterns/job-queue/index.d.ts +0 -1
- package/dist/patterns/job-queue/index.js +0 -3
- package/dist/patterns/job-queue/index.js.map +0 -1
- package/dist/patterns/memory/index.cjs +0 -21
- package/dist/patterns/memory/index.cjs.map +0 -1
- package/dist/patterns/memory/index.d.cts +0 -1
- package/dist/patterns/memory/index.d.ts +0 -1
- package/dist/patterns/memory/index.js +0 -3
- package/dist/patterns/memory/index.js.map +0 -1
- package/dist/patterns/messaging/index.cjs +0 -21
- package/dist/patterns/messaging/index.cjs.map +0 -1
- package/dist/patterns/messaging/index.d.cts +0 -1
- package/dist/patterns/messaging/index.d.ts +0 -1
- package/dist/patterns/messaging/index.js +0 -3
- package/dist/patterns/messaging/index.js.map +0 -1
- package/dist/patterns/orchestration/index.cjs +0 -21
- package/dist/patterns/orchestration/index.cjs.map +0 -1
- package/dist/patterns/orchestration/index.d.cts +0 -1
- package/dist/patterns/orchestration/index.d.ts +0 -1
- package/dist/patterns/orchestration/index.js +0 -3
- package/dist/patterns/orchestration/index.js.map +0 -1
- package/dist/patterns/process/index.cjs +0 -21
- package/dist/patterns/process/index.cjs.map +0 -1
- package/dist/patterns/process/index.d.cts +0 -1
- package/dist/patterns/process/index.d.ts +0 -1
- package/dist/patterns/process/index.js +0 -3
- package/dist/patterns/process/index.js.map +0 -1
- package/dist/patterns/reactive-layout/index.cjs +0 -21
- package/dist/patterns/reactive-layout/index.cjs.map +0 -1
- package/dist/patterns/reactive-layout/index.d.cts +0 -1
- package/dist/patterns/reactive-layout/index.d.ts +0 -1
- package/dist/patterns/reactive-layout/index.js +0 -3
- package/dist/patterns/reactive-layout/index.js.map +0 -1
- package/dist/patterns/reduction/index.cjs +0 -21
- package/dist/patterns/reduction/index.cjs.map +0 -1
- package/dist/patterns/reduction/index.d.cts +0 -1
- package/dist/patterns/reduction/index.d.ts +0 -1
- package/dist/patterns/reduction/index.js +0 -3
- package/dist/patterns/reduction/index.js.map +0 -1
- package/dist/patterns/surface/index.cjs +0 -21
- package/dist/patterns/surface/index.cjs.map +0 -1
- package/dist/patterns/surface/index.d.cts +0 -1
- package/dist/patterns/surface/index.d.ts +0 -1
- package/dist/patterns/surface/index.js +0 -3
- package/dist/patterns/surface/index.js.map +0 -1
- package/dist/patterns/topology-view/index.cjs +0 -21
- package/dist/patterns/topology-view/index.cjs.map +0 -1
- package/dist/patterns/topology-view/index.d.cts +0 -1
- package/dist/patterns/topology-view/index.d.ts +0 -1
- package/dist/patterns/topology-view/index.js +0 -3
- package/dist/patterns/topology-view/index.js.map +0 -1
- package/dist/testing/index.cjs +0 -21
- package/dist/testing/index.cjs.map +0 -1
- package/dist/testing/index.d.cts +0 -1
- package/dist/testing/index.d.ts +0 -1
- package/dist/testing/index.js +0 -3
- package/dist/testing/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/graphspec/index.ts"],"sourcesContent":["/**\n * LLM graph composition (roadmap §8.3).\n *\n * Declarative GraphSpec schema + compiler/decompiler for graph topology.\n * The LLM designs graphs as JSON; `compileSpec` instantiates them;\n * `decompileSpec` extracts them back. Templates support reusable subgraph\n * patterns. Feedback edges express bounded cycles via §8.1 feedback().\n *\n * **Tier 1.5.3 Phase 3 (2026-04-27):** `GraphSpec` is a structural alias of\n * {@link GraphDescribeOutput} with two LLM-author-friendly extras\n * (`templates?` / `feedback?`). Per-node factory references are encoded in\n * `meta.factory` + `meta.factoryArgs` (no more `fn` / `source` / `config` /\n * `initial` fields). State node initial values live in\n * `meta.factoryArgs.initial` (state self-tags with\n * `factoryTag(\"state\", { initial })`).\n *\n * @module\n */\n\nimport type { DescribeNodeOutput } from \"@graphrefly/pure-ts/core\";\nimport { type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { GRAPH_META_SEGMENT, Graph, type GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport type { ChatMessage, LLMAdapter, LLMResponse } from \"../ai/index.js\";\nimport { feedback as feedbackPrimitive } from \"../reduction/index.js\";\n\n// ---------------------------------------------------------------------------\n// GraphSpec types — structural alias of GraphDescribeOutput\n// ---------------------------------------------------------------------------\n\n/**\n * A single node declaration in a GraphSpec — structural alias of\n * {@link DescribeNodeOutput}.\n *\n * Per-node factory provenance lives in `meta.factory` + `meta.factoryArgs`\n * (use {@link factoryTag} to stamp them at construction time). State node\n * initial values come through `meta.factoryArgs.initial` for tagged states,\n * with fallback to `value` (since spec projection retains state values).\n */\nexport type GraphSpecNode = DescribeNodeOutput;\n\n/** Template instantiation node — expanded at compile time. */\nexport type GraphSpecTemplateRef = {\n\ttype: \"template\";\n\t/** Name of the template to instantiate. */\n\ttemplate: string;\n\t/** Parameter bindings: template param name → node name. */\n\tbind: Record<string, string>;\n};\n\n/** A reusable subgraph pattern with parameter substitution. */\nexport type GraphSpecTemplate = {\n\t/** Parameter names (prefixed with $ in node refs). */\n\tparams: string[];\n\t/** Node declarations within the template. */\n\tnodes: Record<string, GraphSpecNode>;\n\t/** Which node's output is the template's output. */\n\toutput: string;\n};\n\n/** A feedback edge: bounded cycle from condition to reentry. */\nexport type GraphSpecFeedbackEdge = {\n\t/** Node whose DATA triggers the feedback. */\n\tfrom: string;\n\t/** State node that receives the feedback value. */\n\tto: string;\n\t/** Max iterations before stopping (default: 10). */\n\tmaxIterations?: number;\n};\n\n/**\n * Declarative graph topology for LLM composition (§8.3).\n *\n * Tier 1.5.3 Phase 3 (2026-04-27): structural alias of\n * {@link GraphDescribeOutput} extended with optional `templates` /\n * `feedback` fields for LLM-author convenience. Top-level `factory` /\n * `factoryArgs` (Phase 2.5 carry) ride along on every describe output.\n *\n * Round-trip property: `decompileSpec(g) === g.describe({ detail: \"spec\" })`\n * (modulo the small feedback-edge extraction sugar).\n */\nexport type GraphSpec = Omit<GraphDescribeOutput, \"nodes\" | \"expand\"> & {\n\t/** Node declarations (keyed by node name). Either a structural describe entry or a template ref. */\n\tnodes: Record<string, GraphSpecNode | GraphSpecTemplateRef>;\n\t/** Reusable subgraph templates (LLM-author extra; not present in `describe()` output). */\n\ttemplates?: Record<string, GraphSpecTemplate>;\n\t/** Feedback edges (bounded cycles, LLM-author extra). */\n\tfeedback?: GraphSpecFeedbackEdge[];\n};\n\n/**\n * Extract `meta.factory` from a node, if any. Pure read — no normalization.\n */\nfunction readFactory(node: GraphSpecNode): string | undefined {\n\tconst f = (node.meta as Record<string, unknown> | undefined)?.factory;\n\treturn typeof f === \"string\" ? f : undefined;\n}\n\n/**\n * Extract `meta.factoryArgs` from a node as a plain Record. Pure read.\n */\nfunction readFactoryArgs(node: GraphSpecNode): Record<string, unknown> {\n\tconst a = (node.meta as Record<string, unknown> | undefined)?.factoryArgs;\n\treturn a != null && typeof a === \"object\" ? (a as Record<string, unknown>) : {};\n}\n\n/**\n * Resolve the initial value for a state node. Prefers\n * `meta.factoryArgs.initial` (the path the `state()` factory itself stamps)\n * and falls back to `value` (in case the spec carries the resolved value\n * without a factory tag, e.g. from a hand-written spec).\n */\nfunction readStateInitial(node: GraphSpecNode): unknown {\n\tconst args = readFactoryArgs(node);\n\tif (\"initial\" in args) return args.initial;\n\treturn node.value;\n}\n\n// ---------------------------------------------------------------------------\n// Catalog types\n// ---------------------------------------------------------------------------\n\n/**\n * Factory for creating a derived/effect/operator node from catalog.\n * Receives resolved dep nodes and the config from the spec.\n */\nexport type FnFactory = (deps: Node<unknown>[], config: Record<string, unknown>) => Node<unknown>;\n\n/**\n * Factory for creating a producer node from catalog.\n * Receives the config from the spec.\n */\nexport type SourceFactory = (config: Record<string, unknown>) => Node<unknown>;\n\n// ---------------------------------------------------------------------------\n// Rich catalog entries (§9.1b — auto-prompt, catalog-aware validation)\n// ---------------------------------------------------------------------------\n\n/** Simple config field descriptor for LLM prompt generation and validation. */\nexport type ConfigFieldSchema = {\n\t/** Human-readable type: \"string\", \"number\", \"boolean\", \"string[]\", etc. */\n\ttype: string;\n\t/** Whether this field is required (default: true). */\n\trequired?: boolean;\n\t/** Allowed values (enum constraint). */\n\tenum?: readonly (string | number | boolean)[];\n\t/** Human-readable description for LLM context. */\n\tdescription?: string;\n\t/** Default value if omitted. */\n\tdefault?: unknown;\n};\n\n/**\n * Rich catalog entry: bundles a runtime factory with LLM-facing metadata.\n *\n * The metadata is used to:\n * 1. Auto-generate prompt text for {@link llmCompose} (replaces manual `catalogDescription`)\n * 2. Validate LLM output in {@link validateSpec} (catch wrong fn names, invalid config)\n * 3. Provide actionable error messages for {@link llmRefine} feedback loops\n *\n * Developers register ONE object; the library handles prompt generation and validation.\n */\nexport type CatalogFnEntry = {\n\t/** Runtime factory. */\n\tfactory: FnFactory;\n\t/** One-line description for LLM prompt (what it does, not how). */\n\tdescription: string;\n\t/** Config field schemas. Keys are config field names. */\n\tconfigSchema?: Record<string, ConfigFieldSchema>;\n\t/** Example config objects (shown in prompt for complex fns). */\n\texamples?: Record<string, unknown>[];\n\t/** Category tags for grouping in prompt (e.g., \"resilience\", \"reduction\", \"ai\"). */\n\ttags?: string[];\n};\n\n/** Rich catalog entry for producer sources. */\nexport type CatalogSourceEntry = {\n\t/** Runtime factory. */\n\tfactory: SourceFactory;\n\t/** One-line description for LLM prompt. */\n\tdescription: string;\n\t/** Config field schemas. */\n\tconfigSchema?: Record<string, ConfigFieldSchema>;\n\t/** Example config objects. */\n\texamples?: Record<string, unknown>[];\n\t/** Category tags. */\n\ttags?: string[];\n};\n\n/**\n * Top-level Graph factory — used when a spec was produced from a graph that\n * called `Graph.prototype.tagFactory(name, args)`. The catalog supplies a\n * function that takes the recorded `factoryArgs` (JSON-serializable subset)\n * and returns a fully-wired Graph. Runtime context (LLMAdapter instances,\n * callbacks, embedders) is captured by the closure — the args themselves are\n * a documentation fragment, not a complete construction recipe.\n *\n * Tier 1.5.3 Phase 2.5 (DG1=B, 2026-04-27).\n */\nexport type GraphSpecFactory = (factoryArgs: unknown) => Graph;\n\n/**\n * Fn/source lookup table passed to compileSpec and llmCompose.\n *\n * Accepts both bare factories (backward-compatible) and rich {@link CatalogFnEntry}\n * / {@link CatalogSourceEntry} objects. When rich entries are provided, the library\n * auto-generates LLM prompts and validates LLM output against the catalog.\n *\n * `graphFactories` (Tier 1.5.3 Phase 2.5) handles top-level Graph-returning\n * factories — when `spec.factory` matches a key, `compileSpec` delegates the\n * entire reconstruction to that factory.\n */\nexport type GraphSpecCatalog = {\n\tfns?: Record<string, FnFactory | CatalogFnEntry>;\n\tsources?: Record<string, SourceFactory | CatalogSourceEntry>;\n\tgraphFactories?: Record<string, GraphSpecFactory>;\n};\n\n// ---------------------------------------------------------------------------\n// Catalog helpers\n// ---------------------------------------------------------------------------\n\n/** Type guard: is this a rich catalog fn entry (vs bare factory)? */\nexport function isRichFnEntry(entry: FnFactory | CatalogFnEntry): entry is CatalogFnEntry {\n\treturn typeof entry === \"object\" && entry !== null && \"factory\" in entry;\n}\n\n/** Type guard: is this a rich catalog source entry (vs bare factory)? */\nexport function isRichSourceEntry(\n\tentry: SourceFactory | CatalogSourceEntry,\n): entry is CatalogSourceEntry {\n\treturn typeof entry === \"object\" && entry !== null && \"factory\" in entry;\n}\n\n/** Extract the runtime factory from a catalog entry (rich or bare). */\nexport function extractFnFactory(entry: FnFactory | CatalogFnEntry): FnFactory {\n\treturn isRichFnEntry(entry) ? entry.factory : entry;\n}\n\n/** Extract the runtime factory from a catalog source entry (rich or bare). */\nexport function extractSourceFactory(entry: SourceFactory | CatalogSourceEntry): SourceFactory {\n\treturn isRichSourceEntry(entry) ? entry.factory : entry;\n}\n\n/**\n * Auto-generate catalog prompt text from rich catalog entries.\n *\n * Groups fns by tag, formats each as `- name: description. Config: { ... }`.\n * Falls back to listing names only for bare factories.\n */\nexport function generateCatalogPrompt(catalog: GraphSpecCatalog): string {\n\tconst sections: string[] = [];\n\n\tif (catalog.fns) {\n\t\t// Group by first tag (or \"Other\")\n\t\tconst groups = new Map<string, string[]>();\n\t\tfor (const [name, entry] of Object.entries(catalog.fns)) {\n\t\t\tconst tag = isRichFnEntry(entry) ? (entry.tags?.[0] ?? \"Other\") : \"Other\";\n\t\t\tif (!groups.has(tag)) groups.set(tag, []);\n\t\t\tgroups.get(tag)!.push(formatFnEntry(name, entry));\n\t\t}\n\t\tfor (const [tag, lines] of groups) {\n\t\t\tsections.push(`${tag}:\\n${lines.join(\"\\n\")}`);\n\t\t}\n\t}\n\n\tif (catalog.sources) {\n\t\tconst lines: string[] = [];\n\t\tfor (const [name, entry] of Object.entries(catalog.sources)) {\n\t\t\tlines.push(formatSourceEntry(name, entry));\n\t\t}\n\t\tif (lines.length > 0) {\n\t\t\tsections.push(`Sources:\\n${lines.join(\"\\n\")}`);\n\t\t}\n\t}\n\n\treturn sections.join(\"\\n\\n\");\n}\n\nfunction formatFnEntry(name: string, entry: FnFactory | CatalogFnEntry): string {\n\tif (!isRichFnEntry(entry)) return `- ${name}`;\n\tlet line = `- ${name}: ${entry.description}`;\n\tif (entry.configSchema) {\n\t\tconst fields = Object.entries(entry.configSchema).map(([k, v]) => {\n\t\t\tlet desc = `${k}: ${v.type}`;\n\t\t\tif (v.enum) desc += ` (${v.enum.join(\"|\")})`;\n\t\t\tif (v.required === false) desc += \"?\";\n\t\t\treturn desc;\n\t\t});\n\t\tline += `. Config: { ${fields.join(\", \")} }`;\n\t}\n\treturn line;\n}\n\nfunction formatSourceEntry(name: string, entry: SourceFactory | CatalogSourceEntry): string {\n\tif (!isRichSourceEntry(entry)) return `- ${name}`;\n\tlet line = `- ${name}: ${entry.description}`;\n\tif (entry.configSchema) {\n\t\tconst fields = Object.entries(entry.configSchema).map(([k, v]) => {\n\t\t\tlet desc = `${k}: ${v.type}`;\n\t\t\tif (v.required === false) desc += \"?\";\n\t\t\treturn desc;\n\t\t});\n\t\tline += `. Config: { ${fields.join(\", \")} }`;\n\t}\n\treturn line;\n}\n\n/**\n * Validate a GraphSpec against a catalog.\n *\n * Checks that fn/source names reference actual catalog entries, and validates\n * config fields against configSchema when rich entries are available.\n * Returns additional errors beyond structural {@link validateSpec} checks.\n */\nexport function validateSpecAgainstCatalog(\n\tspec: GraphSpec,\n\tcatalog: GraphSpecCatalog,\n): GraphSpecValidation {\n\tconst errors: string[] = [];\n\tconst fnNames = new Set(Object.keys(catalog.fns ?? {}));\n\tconst sourceNames = new Set(Object.keys(catalog.sources ?? {}));\n\n\tfor (const [nodeName, nodeRaw] of Object.entries(spec.nodes)) {\n\t\tif (nodeRaw.type === \"template\") continue;\n\t\tconst node = nodeRaw as GraphSpecNode;\n\t\tconst factoryName = readFactory(node);\n\t\tif (factoryName == null) continue;\n\n\t\tconst isProducer = node.type === \"producer\";\n\t\t// State nodes self-tag with `factory: \"state\"` — never expected to live\n\t\t// in the catalog. Skip.\n\t\tif (node.type === \"state\" && factoryName === \"state\") continue;\n\n\t\t// Producers may resolve via either sources (preferred) or fns; non-\n\t\t// producers only resolve via fns. Mismatched-side suggestions (e.g.\n\t\t// using a source name on a derived node) match the legacy diagnostic.\n\t\tif (isProducer) {\n\t\t\tconst inSources = sourceNames.has(factoryName);\n\t\t\tconst inFns = fnNames.has(factoryName);\n\t\t\tif (!inSources && !inFns && (sourceNames.size > 0 || fnNames.size > 0)) {\n\t\t\t\tconst suggestion =\n\t\t\t\t\tfindClosest(factoryName, sourceNames) ?? findClosest(factoryName, fnNames);\n\t\t\t\terrors.push(\n\t\t\t\t\t`Node \"${nodeName}\": source \"${factoryName}\" not found in catalog` +\n\t\t\t\t\t\t(suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"),\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\tif (fnNames.size > 0 && !fnNames.has(factoryName)) {\n\t\t\t\tif (sourceNames.has(factoryName)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Node \"${nodeName}\": fn \"${factoryName}\" is a source, not a function. ` +\n\t\t\t\t\t\t\t`Use it as a producer source instead, or use a function from: ${[...fnNames].join(\", \")}`,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst suggestion = findClosest(factoryName, fnNames);\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Node \"${nodeName}\": fn \"${factoryName}\" not found in catalog` +\n\t\t\t\t\t\t\t(suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Validate config (`meta.factoryArgs`) against schema (if rich entry).\n\t\tconst factoryArgs = readFactoryArgs(node);\n\t\tif (!isProducer && catalog.fns?.[factoryName]) {\n\t\t\tconst entry = catalog.fns[factoryName];\n\t\t\tif (isRichFnEntry(entry) && entry.configSchema) {\n\t\t\t\tfor (const [field, schema] of Object.entries(entry.configSchema)) {\n\t\t\t\t\tif (schema.required !== false && !(field in factoryArgs)) {\n\t\t\t\t\t\terrors.push(`Node \"${nodeName}\": config missing required field \"${field}\"`);\n\t\t\t\t\t}\n\t\t\t\t\tif (field in factoryArgs && schema.enum) {\n\t\t\t\t\t\tconst val = factoryArgs[field];\n\t\t\t\t\t\tif (!schema.enum.includes(val as string | number | boolean)) {\n\t\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\t\t`Node \"${nodeName}\": config.${field} = ${JSON.stringify(val)}, ` +\n\t\t\t\t\t\t\t\t\t`expected one of: ${schema.enum.join(\", \")}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isProducer && catalog.sources?.[factoryName]) {\n\t\t\tconst entry = catalog.sources[factoryName];\n\t\t\tif (isRichSourceEntry(entry) && entry.configSchema) {\n\t\t\t\tfor (const [field, schema] of Object.entries(entry.configSchema)) {\n\t\t\t\t\tif (schema.required !== false && !(field in factoryArgs)) {\n\t\t\t\t\t\terrors.push(`Node \"${nodeName}\": config missing required field \"${field}\"`);\n\t\t\t\t\t}\n\t\t\t\t\tif (field in factoryArgs && schema.enum) {\n\t\t\t\t\t\tconst val = factoryArgs[field];\n\t\t\t\t\t\tif (!schema.enum.includes(val as string | number | boolean)) {\n\t\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\t\t`Node \"${nodeName}\": config.${field} = ${JSON.stringify(val)}, ` +\n\t\t\t\t\t\t\t\t\t`expected one of: ${schema.enum.join(\", \")}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Also check template inner nodes\n\tif (spec.templates) {\n\t\tfor (const [tName, template] of Object.entries(spec.templates)) {\n\t\t\tfor (const [nodeName, node] of Object.entries(template.nodes)) {\n\t\t\t\tconst factoryName = readFactory(node);\n\t\t\t\tif (factoryName == null) continue;\n\t\t\t\tif (node.type === \"state\" && factoryName === \"state\") continue;\n\t\t\t\tif (node.type === \"producer\") continue; // template producer/source skipped (parity with legacy)\n\t\t\t\tif (fnNames.size > 0 && !fnNames.has(factoryName)) {\n\t\t\t\t\tconst suggestion = findClosest(factoryName, fnNames);\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Template \"${tName}\" node \"${nodeName}\": fn \"${factoryName}\" not found in catalog` +\n\t\t\t\t\t\t\t(suggestion ? `. Did you mean \"${suggestion}\"?` : \"\"),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { valid: errors.length === 0, errors, warnings: [] };\n}\n\n/** Simple Levenshtein-based closest match for \"did you mean?\" suggestions. */\nfunction findClosest(input: string, candidates: Set<string>): string | null {\n\tlet best: string | null = null;\n\tlet bestDist = Infinity;\n\tconst lower = input.toLowerCase();\n\tfor (const c of candidates) {\n\t\tconst dist = levenshtein(lower, c.toLowerCase());\n\t\tif (dist < bestDist && dist <= Math.max(3, Math.floor(input.length / 2))) {\n\t\t\tbestDist = dist;\n\t\t\tbest = c;\n\t\t}\n\t}\n\treturn best;\n}\n\nfunction levenshtein(a: string, b: string): number {\n\tconst m = a.length;\n\tconst n = b.length;\n\tconst dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>\n\t\tArray.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n\t);\n\tfor (let i = 1; i <= m; i++) {\n\t\tfor (let j = 1; j <= n; j++) {\n\t\t\tdp[i][j] =\n\t\t\t\ta[i - 1] === b[j - 1]\n\t\t\t\t\t? dp[i - 1][j - 1]\n\t\t\t\t\t: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);\n\t\t}\n\t}\n\treturn dp[m][n];\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\n/** Validation result from {@link validateSpec}. */\nexport type GraphSpecValidation = {\n\tvalid: boolean;\n\terrors: string[];\n\t/**\n\t * Non-fatal advisories. Currently includes feedback edges whose `from`\n\t * refers to an `effect` node (effects produce no DATA — the feedback\n\t * counter will never advance). Always present (empty array when nothing\n\t * is flagged) — symmetry with `errors` so callers can read\n\t * `result.warnings.length` without a null check.\n\t */\n\twarnings: string[];\n};\n\nconst VALID_NODE_TYPES = new Set([\n\t\"state\",\n\t\"producer\",\n\t\"derived\",\n\t\"effect\",\n\t\"operator\",\n\t\"template\",\n]);\n\nconst INNER_NODE_TYPES = new Set([\"state\", \"producer\", \"derived\", \"effect\", \"operator\"]);\n\n/**\n * Validate a GraphSpec JSON object.\n *\n * Checks structural validity: required fields, node types, dep references,\n * template references, feedback edge targets, self-cycles, and bind completeness.\n *\n * **Effect-node feedback advisory (C24-3).** When a feedback edge's `from`\n * refers to an `effect` node, the validator flags it via `warnings` (not\n * `errors`) — effect nodes produce no DATA emission, so a feedback counter\n * targeting one will never advance. The spec compiles either way; the\n * advisory exists because the misconfiguration is silent at runtime\n * (counter at 0 forever) without it.\n */\nexport function validateSpec(spec: unknown): GraphSpecValidation {\n\tconst errors: string[] = [];\n\tconst warnings: string[] = [];\n\n\tif (spec == null || typeof spec !== \"object\") {\n\t\treturn { valid: false, errors: [\"GraphSpec must be a non-null object\"], warnings };\n\t}\n\n\tconst s = spec as Record<string, unknown>;\n\n\tif (typeof s.name !== \"string\" || s.name.length === 0) {\n\t\terrors.push(\"Missing or empty 'name' field\");\n\t}\n\n\tif (s.nodes == null || typeof s.nodes !== \"object\" || Array.isArray(s.nodes)) {\n\t\terrors.push(\"Missing or invalid 'nodes' field (must be an object)\");\n\t\treturn { valid: false, errors, warnings };\n\t}\n\n\tconst nodeNames = new Set(Object.keys(s.nodes as object));\n\tconst nodeTypes = new Map<string, string>();\n\tconst templateDefs = new Map<string, { params: string[] }>();\n\n\t// Pre-scan template definitions for param validation\n\tif (s.templates != null && typeof s.templates === \"object\" && !Array.isArray(s.templates)) {\n\t\tfor (const [tName, tRaw] of Object.entries(s.templates as Record<string, unknown>)) {\n\t\t\tif (tRaw != null && typeof tRaw === \"object\") {\n\t\t\t\tconst t = tRaw as Record<string, unknown>;\n\t\t\t\ttemplateDefs.set(tName, {\n\t\t\t\t\tparams: Array.isArray(t.params) ? (t.params as string[]) : [],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate templates\n\tif (s.templates != null) {\n\t\tif (typeof s.templates !== \"object\" || Array.isArray(s.templates)) {\n\t\t\terrors.push(\"'templates' must be an object\");\n\t\t} else {\n\t\t\tfor (const [tName, tRaw] of Object.entries(s.templates as Record<string, unknown>)) {\n\t\t\t\tif (tRaw == null || typeof tRaw !== \"object\") {\n\t\t\t\t\terrors.push(`Template \"${tName}\": must be an object`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst t = tRaw as Record<string, unknown>;\n\t\t\t\tif (!Array.isArray(t.params)) {\n\t\t\t\t\terrors.push(`Template \"${tName}\": missing 'params' array`);\n\t\t\t\t}\n\t\t\t\tif (t.nodes == null || typeof t.nodes !== \"object\" || Array.isArray(t.nodes)) {\n\t\t\t\t\terrors.push(`Template \"${tName}\": missing or invalid 'nodes' object`);\n\t\t\t\t} else {\n\t\t\t\t\tconst paramSet = new Set(Array.isArray(t.params) ? (t.params as string[]) : []);\n\t\t\t\t\tconst innerNames = new Set(Object.keys(t.nodes as object));\n\t\t\t\t\tfor (const [nName, nRaw] of Object.entries(t.nodes as Record<string, unknown>)) {\n\t\t\t\t\t\tif (nRaw == null || typeof nRaw !== \"object\") {\n\t\t\t\t\t\t\terrors.push(`Template \"${tName}\" node \"${nName}\": must be an object`);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst n = nRaw as Record<string, unknown>;\n\t\t\t\t\t\tif (typeof n.type !== \"string\" || !INNER_NODE_TYPES.has(n.type)) {\n\t\t\t\t\t\t\terrors.push(`Template \"${tName}\" node \"${nName}\": invalid type`);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (Array.isArray(n.deps)) {\n\t\t\t\t\t\t\tfor (const dep of n.deps as string[]) {\n\t\t\t\t\t\t\t\tif (!innerNames.has(dep) && !paramSet.has(dep)) {\n\t\t\t\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\t\t\t\t`Template \"${tName}\" node \"${nName}\": dep \"${dep}\" is not an inner node or param`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof t.output !== \"string\") {\n\t\t\t\t\t\terrors.push(`Template \"${tName}\": missing 'output' string`);\n\t\t\t\t\t} else if (!(t.nodes as Record<string, unknown>)[t.output as string]) {\n\t\t\t\t\t\terrors.push(`Template \"${tName}\": output \"${t.output}\" is not a declared node`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate nodes\n\tfor (const [name, raw] of Object.entries(s.nodes as Record<string, unknown>)) {\n\t\tif (raw == null || typeof raw !== \"object\") {\n\t\t\terrors.push(`Node \"${name}\": must be an object`);\n\t\t\tcontinue;\n\t\t}\n\t\tconst n = raw as Record<string, unknown>;\n\t\tif (typeof n.type !== \"string\" || !VALID_NODE_TYPES.has(n.type)) {\n\t\t\terrors.push(\n\t\t\t\t`Node \"${name}\": invalid type \"${String(n.type)}\" (expected: ${[...VALID_NODE_TYPES].join(\", \")})`,\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\t\tnodeTypes.set(name, n.type);\n\n\t\tif (n.type === \"template\") {\n\t\t\tif (typeof n.template !== \"string\" || !templateDefs.has(n.template)) {\n\t\t\t\terrors.push(`Node \"${name}\": template \"${String(n.template)}\" not found in templates`);\n\t\t\t} else {\n\t\t\t\t// Check bind completeness: all template params must be bound\n\t\t\t\tif (n.bind == null || typeof n.bind !== \"object\" || Array.isArray(n.bind)) {\n\t\t\t\t\terrors.push(`Node \"${name}\": template ref requires 'bind' object`);\n\t\t\t\t} else {\n\t\t\t\t\tconst tmpl = templateDefs.get(n.template as string)!;\n\t\t\t\t\tconst bind = n.bind as Record<string, string>;\n\t\t\t\t\tfor (const param of tmpl.params) {\n\t\t\t\t\t\tif (!(param in bind)) {\n\t\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\t\t`Node \"${name}\": template param \"${param}\" is not bound (template \"${n.template}\")`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (const [, target] of Object.entries(bind)) {\n\t\t\t\t\t\tif (typeof target === \"string\" && !nodeNames.has(target)) {\n\t\t\t\t\t\t\terrors.push(\n\t\t\t\t\t\t\t\t`Node \"${name}\": bind target \"${target}\" does not reference an existing node`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (Array.isArray(n.deps)) {\n\t\t\t\tfor (const dep of n.deps as string[]) {\n\t\t\t\t\t// Self-referencing dep\n\t\t\t\t\tif (dep === name) {\n\t\t\t\t\t\terrors.push(`Node \"${name}\": self-referencing dep`);\n\t\t\t\t\t} else if (!nodeNames.has(dep)) {\n\t\t\t\t\t\terrors.push(`Node \"${name}\": dep \"${dep}\" does not reference an existing node`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Warn: derived/effect/operator without deps\n\t\t\tif (\n\t\t\t\t(n.type === \"derived\" || n.type === \"effect\" || n.type === \"operator\") &&\n\t\t\t\t!Array.isArray(n.deps)\n\t\t\t) {\n\t\t\t\terrors.push(`Node \"${name}\": ${n.type} node should have a 'deps' array`);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate feedback edges\n\tif (s.feedback != null) {\n\t\tif (!Array.isArray(s.feedback)) {\n\t\t\terrors.push(\"'feedback' must be an array\");\n\t\t} else {\n\t\t\tfor (let i = 0; i < (s.feedback as unknown[]).length; i++) {\n\t\t\t\tconst edge = (s.feedback as unknown[])[i];\n\t\t\t\tif (edge == null || typeof edge !== \"object\") {\n\t\t\t\t\terrors.push(`Feedback [${i}]: must be an object`);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst e = edge as Record<string, unknown>;\n\t\t\t\tif (typeof e.from !== \"string\" || !nodeNames.has(e.from)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Feedback [${i}]: 'from' \"${String(e.from)}\" does not reference an existing node`,\n\t\t\t\t\t);\n\t\t\t\t} else if (nodeTypes.get(e.from) === \"effect\") {\n\t\t\t\t\t// Effect nodes produce no DATA — a feedback edge from one will\n\t\t\t\t\t// never trigger the counter / re-entry. Almost certainly a\n\t\t\t\t\t// modelling mistake (caller probably meant the upstream\n\t\t\t\t\t// derived/state node). Warn but don't reject — the spec is\n\t\t\t\t\t// structurally valid; some advanced uses might still be ok.\n\t\t\t\t\twarnings.push(\n\t\t\t\t\t\t`Feedback [${i}]: 'from' \"${e.from}\" is an effect node — effects emit no DATA, so the feedback edge will never fire. Did you mean a derived/state node upstream?`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (typeof e.from === \"string\" && e.from === e.to) {\n\t\t\t\t\terrors.push(`Feedback [${i}]: 'from' and 'to' must be different nodes`);\n\t\t\t\t}\n\t\t\t\tif (typeof e.to !== \"string\" || !nodeNames.has(e.to)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Feedback [${i}]: 'to' \"${String(e.to)}\" does not reference an existing node`,\n\t\t\t\t\t);\n\t\t\t\t} else if (typeof e.to === \"string\" && nodeTypes.get(e.to) !== \"state\") {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\t`Feedback [${i}]: 'to' node \"${e.to}\" must be a state node (got \"${nodeTypes.get(e.to) ?? \"unknown\"}\")`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tvalid: errors.length === 0,\n\t\terrors,\n\t\twarnings,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// validateOwnership — multi-agent subgraph ownership PR lint (DS-14.5.A #5)\n// ---------------------------------------------------------------------------\n\n/**\n * Read `meta.owner` from a spec node. Pure read — no normalization.\n * Empty / non-string is treated as \"no annotation\" (silent, INV-OWNER-2).\n */\nfunction readOwner(node: GraphSpecNode): string | undefined {\n\tconst o = (node.meta as Record<string, unknown> | undefined)?.owner;\n\treturn typeof o === \"string\" && o.length > 0 ? o : undefined;\n}\n\n/**\n * The change-set fed to {@link validateOwnership}. Mirrors the minimal slice\n * of a PR diff the lint needs: the set of factory identifiers whose\n * implementation the diff touches, plus the PR author and (optionally) the\n * raw commit-message text so the `Override-Owner:` trailer can be detected.\n *\n * **Why factory-keyed (not path-keyed) — locked decision (DS-14.5.A Q5\n * sub-flag).** PR-diff → spec-node mapping resolves through `meta.factory`\n * provenance, NOT a `meta.ownerPath` glob. A diff that edits the\n * implementation of factory `\"rateLimiter\"` maps to *every* spec node whose\n * `meta.factory === \"rateLimiter\"`. This reuses the existing\n * `factoryTag` / `decompileSpec` round-trip (the same `meta.factory` field\n * `compileSpec` consumes) — no parallel ownership-path indexing scheme.\n */\nexport type OwnershipPrDiff = {\n\t/**\n\t * Factory identifiers (the `meta.factory` value) whose source the PR\n\t * modifies. A spec node is \"edited by this PR\" iff its `meta.factory` is\n\t * in this set. Nodes without `meta.factory` cannot be mapped from a code\n\t * diff and are therefore never flagged (silent — consistent with the\n\t * un-annotated rule).\n\t */\n\treadonly editedFactories: readonly string[];\n\t/** PR author's `Actor.id`. Compared against each edited node's `meta.owner`. */\n\treadonly author: string;\n\t/**\n\t * Raw commit message(s) text. If any line is an `Override-Owner: <reason>`\n\t * trailer (case-insensitive key, non-empty reason) the lint hard-fail is\n\t * bypassed and recorded as an audit-trail override (Q5 sub-lock i — any\n\t * committer may use it; it is recorded, never silently granted).\n\t */\n\treadonly commitMessage?: string;\n};\n\n/** One cross-owner violation surfaced by {@link validateOwnership}. */\nexport type OwnershipViolation = {\n\t/** Spec node path that carries `meta.owner` and was edited by a non-owner. */\n\treadonly node: string;\n\t/** The `meta.owner` value on that node. */\n\treadonly owner: string;\n\t/** The PR author who edited it. */\n\treadonly author: string;\n\t/** The `meta.factory` that mapped the diff onto this node. */\n\treadonly factory: string;\n};\n\n/** Result of {@link validateOwnership}. */\nexport type OwnershipValidation = {\n\t/**\n\t * `true` when no hard-fail applies — either no cross-owner edit, or every\n\t * cross-owner edit is bypassed by a valid `Override-Owner:` trailer.\n\t */\n\treadonly ok: boolean;\n\t/** Cross-owner edits that hard-fail (empty when `ok`). */\n\treadonly violations: readonly OwnershipViolation[];\n\t/**\n\t * Cross-owner edits that WOULD have failed but were bypassed by an\n\t * `Override-Owner:` commit trailer. Pure audit trail — CI / reviewers\n\t * grep this to surface override abuse. Present (possibly empty) so callers\n\t * can read `.overridden.length` without a null check.\n\t */\n\treadonly overridden: readonly OwnershipViolation[];\n\t/**\n\t * The override reason parsed from the `Override-Owner:` trailer, when one\n\t * was present and applied. `undefined` when no trailer was used.\n\t */\n\treadonly overrideReason?: string;\n};\n\nconst OVERRIDE_OWNER_TRAILER = /^\\s*override-owner\\s*:\\s*(.+?)\\s*$/im;\n\n/**\n * Detect an `Override-Owner: <reason>` commit trailer (case-insensitive key;\n * reason must be non-empty after trim). Returns the trimmed reason, or\n * `undefined` when absent.\n */\nfunction parseOverrideOwner(commitMessage: string | undefined): string | undefined {\n\tif (commitMessage == null) return undefined;\n\tconst m = OVERRIDE_OWNER_TRAILER.exec(commitMessage);\n\tconst reason = m?.[1]?.trim();\n\treturn reason != null && reason.length > 0 ? reason : undefined;\n}\n\n/**\n * Multi-agent subgraph ownership PR lint (DS-14.5.A delta #5, L0 rung;\n * spec §2.3a INV-OWNER-2).\n *\n * Hard-fails a pull request whose code diff edits a spec node carrying\n * `meta.owner` when the PR author is not that owner. Nodes **without**\n * `meta.owner` are silent (no advisory, no failure) — \"shared infrastructure\"\n * is exactly the un-annotated case; no separate allow-list is maintained.\n *\n * **Rules (Q5 lock):**\n * - Edited node has no `meta.owner` → silent.\n * - Edited node has `meta.owner` AND `author === meta.owner` → OK.\n * - Edited node has `meta.owner` AND `author !== meta.owner` → **violation**\n * (hard-fail) unless an `Override-Owner: <reason>` commit trailer is present,\n * in which case the violation is moved to `overridden` (audit trail) and\n * `ok` stays `true`.\n *\n * **PR-diff → spec-node mapping (Q5 sub-flag lock):** `meta.factory`\n * resolution. A node is \"edited\" iff its `meta.factory` appears in\n * `prDiff.editedFactories`. This reuses the `factoryTag` / `decompileSpec`\n * round-trip rather than introducing a `meta.ownerPath` glob. Nodes without\n * `meta.factory` can't be mapped from a code diff and are never flagged.\n *\n * Pure function — no `Node` / `Graph` returned, no side effects. Designed to\n * be called from a `graphrefly check-spec`-adjacent CI step (delta #6, Phase\n * 16) or any host PR gate.\n *\n * @param spec - The committed GraphSpec (or any `describe({ detail: \"spec\" })`\n * projection / structural superset).\n * @param prDiff - The factory-keyed diff slice + author + commit text.\n */\nexport function validateOwnership(spec: unknown, prDiff: OwnershipPrDiff): OwnershipValidation {\n\tconst violations: OwnershipViolation[] = [];\n\tconst overridden: OwnershipViolation[] = [];\n\n\tif (spec == null || typeof spec !== \"object\") {\n\t\treturn { ok: true, violations, overridden };\n\t}\n\tconst s = spec as Record<string, unknown>;\n\tconst nodes = s.nodes;\n\tif (nodes == null || typeof nodes !== \"object\" || Array.isArray(nodes)) {\n\t\treturn { ok: true, violations, overridden };\n\t}\n\n\tconst edited = new Set(prDiff.editedFactories);\n\tif (edited.size > 0) {\n\t\tfor (const [path, nRaw] of Object.entries(nodes as Record<string, unknown>)) {\n\t\t\tif (nRaw == null || typeof nRaw !== \"object\") continue;\n\t\t\tconst n = nRaw as GraphSpecNode;\n\t\t\tconst factory = readFactory(n);\n\t\t\t// Unmappable from a code diff (no factory provenance) → silent.\n\t\t\tif (factory == null || !edited.has(factory)) continue;\n\t\t\tconst owner = readOwner(n);\n\t\t\t// No annotation → silent (INV-OWNER-2: un-annotated == shared).\n\t\t\tif (owner == null) continue;\n\t\t\t// Author IS the owner → OK.\n\t\t\tif (owner === prDiff.author) continue;\n\t\t\tviolations.push({ node: path, owner, author: prDiff.author, factory });\n\t\t}\n\t}\n\n\tconst overrideReason = parseOverrideOwner(prDiff.commitMessage);\n\tif (violations.length > 0 && overrideReason != null) {\n\t\t// Trailer bypasses ALL cross-owner violations in this PR (the trailer\n\t\t// is PR-scoped and a pure audit-trail record per Q5 sub-lock i).\n\t\toverridden.push(...violations);\n\t\treturn { ok: true, violations: [], overridden, overrideReason };\n\t}\n\n\treturn {\n\t\tok: violations.length === 0,\n\t\tviolations,\n\t\toverridden,\n\t\t...(overrideReason != null ? { overrideReason } : {}),\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// compileSpec\n// ---------------------------------------------------------------------------\n\n/** Options for {@link compileSpec}. */\nexport type CompileSpecOptions = {\n\t/** Fn/source catalog for resolving named factories. */\n\tcatalog?: GraphSpecCatalog;\n\t/**\n\t * How to handle nodes whose `fn` / `source` is missing from the catalog.\n\t * - `\"placeholder\"` (default): silently substitute identity passthroughs\n\t * (`node([], () => {})` / `node(deps, (bd, a, ctx) => a.emit(bd[0]?.at(-1)))`). Backward-\n\t * compatible — preserves the historical \"soft compile\" behavior.\n\t * - `\"warn\"`: substitute placeholders AND log each missing entry via\n\t * `console.warn`, or via the `onWarn` callback if supplied.\n\t * - `\"error\"`: collect every missing entry across the whole spec, then\n\t * throw an `Error` listing them all (no partial graph returned).\n\t */\n\tonMissing?: \"error\" | \"warn\" | \"placeholder\";\n\t/** Custom warning sink. Used only when `onMissing === \"warn\"`. Defaults to `console.warn`. */\n\tonWarn?: (message: string) => void;\n};\n\ninterface MissingCatalogEntry {\n\t/** Node path (template-prefixed where applicable, e.g. `myMount.inner`). */\n\tpath: string;\n\t/** The catalog kind (`\"fn\"` or `\"source\"`) that was looked up. */\n\tkind: \"fn\" | \"source\";\n\t/** The catalog name string supplied in the spec. */\n\tname: string;\n}\n\n/**\n * Instantiate a Graph from a GraphSpec.\n *\n * Handles template expansion (mounted subgraphs), feedback wiring via §8.1\n * feedback(), node factory lookup from the catalog, and topology validation.\n *\n * @param spec - Declarative graph topology.\n * @param opts - Catalog and compile options.\n * @returns A running Graph.\n * @throws On validation failure, missing catalog entries, or unresolvable deps.\n *\n * @category patterns\n */\nexport function compileSpec(spec: GraphSpec, opts?: CompileSpecOptions): Graph {\n\t// QA F4: validate FIRST, even when the early-dispatch path will delegate to\n\t// a Graph-level factory. The early-dispatch is a *constructor* short-circuit,\n\t// not a *validation* short-circuit — we still want malformed specs to throw\n\t// so a catalog-tagged spec with bogus nodes/templates surfaces the error.\n\tconst validation = validateSpec(spec);\n\tif (!validation.valid) {\n\t\tthrow new Error(`compileSpec: invalid GraphSpec:\\n${validation.errors.join(\"\\n\")}`);\n\t}\n\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): if the spec carries a top-level `factory`\n\t// tag and the catalog has a matching `graphFactories` entry, delegate the\n\t// full reconstruction. This lets Graph-returning factories\n\t// (`agentMemory`, `harnessLoop`, etc.) own their own rebuild path with\n\t// access to user-supplied runtime ctx (LLMAdapter, callbacks).\n\tconst specFactory = spec.factory;\n\tconst specFactoryArgs = spec.factoryArgs;\n\tif (typeof specFactory === \"string\") {\n\t\tconst graphFactory = opts?.catalog?.graphFactories?.[specFactory];\n\t\tif (graphFactory) return graphFactory(specFactoryArgs);\n\t\t// No catalog entry for the named factory — fall through to per-node\n\t\t// compile so the per-node-tagged paths still work.\n\t}\n\n\tconst catalog = opts?.catalog ?? {};\n\tconst onMissing = opts?.onMissing ?? \"placeholder\";\n\tconst g = new Graph(spec.name);\n\tconst templates = spec.templates ?? {};\n\n\t// Catalog-aware validation (when rich entries are available)\n\tconst catalogValidation = validateSpecAgainstCatalog(spec, catalog);\n\tif (!catalogValidation.valid) {\n\t\tthrow new Error(\n\t\t\t`compileSpec: catalog validation errors:\\n${catalogValidation.errors.join(\"\\n\")}`,\n\t\t);\n\t}\n\n\t// Track missing catalog entries across both top-level and template passes;\n\t// the chosen `onMissing` policy is applied once after compile so callers see\n\t// every miss in a single error / warn batch instead of one-at-a-time.\n\tconst missingEntries: MissingCatalogEntry[] = [];\n\n\tconst recordMissing = (nodePath: string, kind: \"fn\" | \"source\", name: string): void => {\n\t\tmissingEntries.push({ path: nodePath, kind, name });\n\t};\n\n\t// Helper: resolve fn/source factories from catalog (handles rich + bare entries)\n\tconst resolveFn = (fnName: string): FnFactory | undefined => {\n\t\tconst entry = catalog.fns?.[fnName];\n\t\treturn entry ? extractFnFactory(entry) : undefined;\n\t};\n\tconst resolveSource = (sourceName: string): SourceFactory | undefined => {\n\t\tconst entry = catalog.sources?.[sourceName];\n\t\treturn entry ? extractSourceFactory(entry) : undefined;\n\t};\n\n\t/**\n\t * Strip the `factory` / `factoryArgs` keys from a spec node's `meta`\n\t * before forwarding to the construction factory. The factory itself\n\t * re-stamps its own `factoryTag(...)` (so the rebuilt node carries the\n\t * canonical factoryArgs); leaving the spec's pre-stamped meta in place\n\t * would shadow that with stale args (esp. after `placeholderArgs`\n\t * scrubbed non-JSON fields).\n\t */\n\tconst stripFactoryMeta = (\n\t\tmeta: Record<string, unknown> | undefined,\n\t): Record<string, unknown> | undefined => {\n\t\tif (!meta) return undefined;\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [k, v] of Object.entries(meta)) {\n\t\t\tif (k === \"factory\" || k === \"factoryArgs\") continue;\n\t\t\tout[k] = v;\n\t\t}\n\t\treturn Object.keys(out).length > 0 ? out : undefined;\n\t};\n\n\t// Phase 1: Create non-template nodes (state/producer first, then derived/effect/operator)\n\tconst created = new Map<string, Node<unknown>>();\n\tconst deferred: [string, GraphSpecNode][] = [];\n\n\tfor (const [name, raw] of Object.entries(spec.nodes)) {\n\t\tif (raw.type === \"template\") continue; // handled in Phase 2\n\n\t\tconst n = raw as GraphSpecNode;\n\t\tconst factoryName = readFactory(n);\n\t\tconst factoryArgs = readFactoryArgs(n);\n\n\t\tif (n.type === \"state\") {\n\t\t\tconst initial = readStateInitial(n);\n\t\t\tconst nd = node([], {\n\t\t\t\tname,\n\t\t\t\tinitial,\n\t\t\t\tmeta: stripFactoryMeta(n.meta),\n\t\t\t});\n\t\t\tg.add(nd, { name: name });\n\t\t\tcreated.set(name, nd);\n\t\t} else if (n.type === \"producer\") {\n\t\t\t// Producer: try sources first (matching the legacy precedence) then fns.\n\t\t\tconst sourceFactory = factoryName ? resolveSource(factoryName) : undefined;\n\t\t\tconst fnFactory = factoryName ? resolveFn(factoryName) : undefined;\n\t\t\tif (sourceFactory) {\n\t\t\t\tconst nd = sourceFactory(factoryArgs);\n\t\t\t\tg.add(nd, { name: name });\n\t\t\t\tcreated.set(name, nd);\n\t\t\t} else if (fnFactory) {\n\t\t\t\tconst nd = fnFactory([], factoryArgs);\n\t\t\t\tg.add(nd, { name: name });\n\t\t\t\tcreated.set(name, nd);\n\t\t\t} else {\n\t\t\t\t// No catalog entry — create a bare producer placeholder.\n\t\t\t\tif (factoryName) recordMissing(name, \"source\", factoryName);\n\t\t\t\tconst nd = node([], () => {}, {\n\t\t\t\t\tname,\n\t\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\t\tmeta: { ...stripFactoryMeta(n.meta), _specSource: factoryName },\n\t\t\t\t});\n\t\t\t\tg.add(nd, { name: name });\n\t\t\t\tcreated.set(name, nd);\n\t\t\t}\n\t\t} else {\n\t\t\tdeferred.push([name, n]);\n\t\t}\n\t}\n\n\t// Resolve deferred nodes (derived/effect/operator) in dependency order\n\tlet progressed = true;\n\tconst pending = new Map(deferred);\n\twhile (pending.size > 0 && progressed) {\n\t\tprogressed = false;\n\t\tfor (const [name, n] of [...pending.entries()]) {\n\t\t\tconst deps = n.deps ?? [];\n\t\t\tif (!deps.every((dep) => created.has(dep))) continue;\n\n\t\t\tconst resolvedDeps = deps.map((dep) => created.get(dep)!);\n\t\t\tconst factoryName = readFactory(n);\n\t\t\tconst factoryArgs = readFactoryArgs(n);\n\t\t\tconst fnFactory = factoryName ? resolveFn(factoryName) : undefined;\n\n\t\t\tlet nd: Node<unknown>;\n\t\t\tif (fnFactory) {\n\t\t\t\tnd = fnFactory(resolvedDeps, factoryArgs);\n\t\t\t} else if (n.type === \"effect\") {\n\t\t\t\tif (factoryName) recordMissing(name, \"fn\", factoryName);\n\t\t\t\tnd = node(resolvedDeps, () => {}, { describeKind: \"effect\" });\n\t\t\t} else {\n\t\t\t\t// derived without catalog fn — identity passthrough\n\t\t\t\tif (factoryName) recordMissing(name, \"fn\", factoryName);\n\t\t\t\tnd = node(\n\t\t\t\t\tresolvedDeps,\n\t\t\t\t\t(batchData, actions, ctx) => {\n\t\t\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tactions.emit(data[0]);\n\t\t\t\t\t},\n\t\t\t\t\t{ describeKind: \"derived\" },\n\t\t\t\t);\n\t\t\t}\n\t\t\tg.add(nd, { name: name });\n\t\t\tcreated.set(name, nd);\n\t\t\tpending.delete(name);\n\t\t\tprogressed = true;\n\t\t}\n\t}\n\tif (pending.size > 0) {\n\t\tconst unresolved = [...pending.keys()].sort().join(\", \");\n\t\tthrow new Error(`compileSpec: unresolvable deps for nodes: ${unresolved}`);\n\t}\n\n\t// Phase 2: Expand template instantiations as mounted subgraphs\n\tfor (const [name, raw] of Object.entries(spec.nodes)) {\n\t\tif (raw.type !== \"template\") continue;\n\t\tconst ref = raw as GraphSpecTemplateRef;\n\t\tconst tmpl = templates[ref.template]!;\n\n\t\tconst sub = new Graph(name);\n\t\tconst subCreated = new Map<string, Node<unknown>>();\n\t\tconst subDeferred: [string, GraphSpecNode][] = [];\n\n\t\t// Create inner nodes, resolving $params to bound nodes\n\t\tfor (const [nName, nSpec] of Object.entries(tmpl.nodes)) {\n\t\t\tconst resolvedDeps = (nSpec.deps ?? []).map((dep) => {\n\t\t\t\tif (dep.startsWith(\"$\") && ref.bind[dep]) {\n\t\t\t\t\treturn ref.bind[dep];\n\t\t\t\t}\n\t\t\t\treturn dep;\n\t\t\t});\n\t\t\tconst specWithResolvedDeps: GraphSpecNode = { ...nSpec, deps: resolvedDeps };\n\t\t\tconst factoryName = readFactory(nSpec);\n\t\t\tconst factoryArgs = readFactoryArgs(nSpec);\n\n\t\t\tif (nSpec.type === \"state\") {\n\t\t\t\tconst initial = readStateInitial(nSpec);\n\t\t\t\tconst nd = node([], {\n\t\t\t\t\tname: nName,\n\t\t\t\t\tinitial,\n\t\t\t\t\tmeta: stripFactoryMeta(nSpec.meta),\n\t\t\t\t});\n\t\t\t\tsub.add(nd, { name: nName });\n\t\t\t\tsubCreated.set(nName, nd);\n\t\t\t} else if (nSpec.type === \"producer\") {\n\t\t\t\tconst sourceFactory = factoryName ? resolveSource(factoryName) : undefined;\n\t\t\t\tconst fnFactory = factoryName ? resolveFn(factoryName) : undefined;\n\t\t\t\tif (sourceFactory) {\n\t\t\t\t\tconst nd = sourceFactory(factoryArgs);\n\t\t\t\t\tsub.add(nd, { name: nName });\n\t\t\t\t\tsubCreated.set(nName, nd);\n\t\t\t\t} else if (fnFactory) {\n\t\t\t\t\tconst nd = fnFactory([], factoryArgs);\n\t\t\t\t\tsub.add(nd, { name: nName });\n\t\t\t\t\tsubCreated.set(nName, nd);\n\t\t\t\t} else {\n\t\t\t\t\tif (factoryName) recordMissing(`${name}.${nName}`, \"source\", factoryName);\n\t\t\t\t\tconst nd = node([], () => {}, {\n\t\t\t\t\t\tname: nName,\n\t\t\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\t\t\tmeta: { ...stripFactoryMeta(nSpec.meta), _specSource: factoryName },\n\t\t\t\t\t});\n\t\t\t\t\tsub.add(nd, { name: nName });\n\t\t\t\t\tsubCreated.set(nName, nd);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsubDeferred.push([nName, specWithResolvedDeps]);\n\t\t\t}\n\t\t}\n\n\t\t// Resolve deferred inner nodes\n\t\tlet subProgressed = true;\n\t\tconst subPending = new Map(subDeferred);\n\t\twhile (subPending.size > 0 && subProgressed) {\n\t\t\tsubProgressed = false;\n\t\t\tfor (const [nName, nSpec] of [...subPending.entries()]) {\n\t\t\t\tconst deps = nSpec.deps ?? [];\n\t\t\t\tconst allReady = deps.every((dep) => subCreated.has(dep) || created.has(dep));\n\t\t\t\tif (!allReady) continue;\n\n\t\t\t\tconst resolvedDeps = deps.map((dep) => subCreated.get(dep) ?? created.get(dep)!);\n\t\t\t\tconst factoryName = readFactory(nSpec);\n\t\t\t\tconst factoryArgs = readFactoryArgs(nSpec);\n\t\t\t\tconst fnFactory = factoryName ? resolveFn(factoryName) : undefined;\n\n\t\t\t\tlet nd: Node<unknown>;\n\t\t\t\tif (fnFactory) {\n\t\t\t\t\tnd = fnFactory(resolvedDeps, factoryArgs);\n\t\t\t\t} else if (nSpec.type === \"effect\") {\n\t\t\t\t\tif (factoryName) recordMissing(`${name}.${nName}`, \"fn\", factoryName);\n\t\t\t\t\tnd = node(resolvedDeps, () => {}, { describeKind: \"effect\" });\n\t\t\t\t} else {\n\t\t\t\t\tif (factoryName) recordMissing(`${name}.${nName}`, \"fn\", factoryName);\n\t\t\t\t\tnd = node(\n\t\t\t\t\t\tresolvedDeps,\n\t\t\t\t\t\t(batchData, actions, ctx) => {\n\t\t\t\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tactions.emit(data[0]);\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ describeKind: \"derived\" },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tsub.add(nd, { name: nName });\n\t\t\t\tsubCreated.set(nName, nd);\n\t\t\t\tsubPending.delete(nName);\n\t\t\t\tsubProgressed = true;\n\t\t\t}\n\t\t}\n\t\tif (subPending.size > 0) {\n\t\t\tconst unresolved = [...subPending.keys()].sort().join(\", \");\n\t\t\tthrow new Error(\n\t\t\t\t`compileSpec: template \"${ref.template}\" has unresolvable deps: ${unresolved}`,\n\t\t\t);\n\t\t}\n\n\t\tg.mount(name, sub);\n\t\t// Register template output as a reachable node path\n\t\tconst outputPath = `${name}::${tmpl.output}`;\n\t\tcreated.set(name, g.resolve(outputPath));\n\n\t\t// Store template origin meta on the mounted subgraph's output node\n\t\t// so decompile-style introspection can recover the template name.\n\t\ttry {\n\t\t\tconst outputNode = g.resolve(outputPath);\n\t\t\toutputNode.meta._templateName?.emit(ref.template);\n\t\t\toutputNode.meta._templateBind?.emit(ref.bind);\n\t\t} catch {\n\t\t\t/* meta nodes may not exist; template origin is best-effort */\n\t\t}\n\t}\n\n\t// Edges are derived from node `_deps` (Unit 7) — no explicit edge wiring step.\n\n\t// Phase 4: Wire feedback edges via §8.1 feedback()\n\tfor (const fb of spec.feedback ?? []) {\n\t\tfeedbackPrimitive(g, fb.from, fb.to, {\n\t\t\tmaxIterations: fb.maxIterations,\n\t\t});\n\t}\n\n\t// Apply onMissing policy. We always finish compilation first (for \"warn\"\n\t// + \"placeholder\") so the caller still gets a usable graph in non-strict\n\t// modes. In \"error\" mode we throw before returning.\n\tif (missingEntries.length > 0) {\n\t\tif (onMissing === \"error\") {\n\t\t\tconst lines = missingEntries.map((e) => ` - ${e.path}: missing ${e.kind} \"${e.name}\"`);\n\t\t\tthrow new Error(\n\t\t\t\t`compileSpec: ${missingEntries.length} catalog entr${\n\t\t\t\t\tmissingEntries.length === 1 ? \"y\" : \"ies\"\n\t\t\t\t} missing — pass them via opts.catalog or set opts.onMissing to \"warn\"/\"placeholder\":\\n${lines.join(\"\\n\")}`,\n\t\t\t);\n\t\t}\n\t\tif (onMissing === \"warn\") {\n\t\t\tconst warn = opts?.onWarn ?? ((m: string): void => console.warn(m));\n\t\t\tfor (const e of missingEntries) {\n\t\t\t\twarn(\n\t\t\t\t\t`compileSpec: ${e.path} references missing ${e.kind} \"${e.name}\" — substituted placeholder`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn g;\n}\n\n// ---------------------------------------------------------------------------\n// decompileGraph\n// ---------------------------------------------------------------------------\n\n/** Internal meta keys used by compileSpec/feedback — stripped from output. */\nconst INTERNAL_META_KEYS = new Set([\n\t\"reduction\",\n\t\"reduction_type\",\n\t\"_specFn\",\n\t\"_specSource\",\n\t\"_templateName\",\n\t\"_templateBind\",\n\t\"feedbackFrom\",\n\t\"feedbackTo\",\n\t\"_internal\",\n]);\n\n/**\n * Extract a {@link GraphSpec} from a running graph.\n *\n * Tier 1.5.3 Phase 3 (2026-04-27): thin projection over\n * `graph.describe({ detail: \"spec\" })`. The describe-output already carries\n * structural fields (`type`, `deps`, optional `value`) plus per-node\n * `meta.factory` / `meta.factoryArgs` for tagged factories and top-level\n * `factory` / `factoryArgs` for graph-level tags. The only sugar this helper\n * adds is a feedback-edge recovery scan over `meta.feedbackFrom` /\n * `meta.feedbackTo` companion fields stamped by the §8.1 `feedback()`\n * primitive.\n *\n * **Removed in Phase 3:** template fingerprinting / `_templateName` /\n * `_templateBind` recovery. Mounted subgraphs surface as nested `subname::*`\n * paths in `desc.nodes`; if you need the template-instantiation form, build\n * the spec by hand or read the meta companions directly.\n *\n * @param graph - Running graph to decompile.\n * @returns A GraphSpec representation.\n *\n * @category patterns\n */\nexport function decompileSpec(graph: Graph): GraphSpec {\n\tconst desc = graph.describe({ detail: \"spec\" }) as GraphDescribeOutput;\n\tconst metaSegment = `::${GRAPH_META_SEGMENT}::`;\n\tconst feedbackCounterPattern = /^__feedback_(?!effect_)(.+)$/;\n\tconst feedbackEdges: GraphSpecFeedbackEdge[] = [];\n\n\t// qa D1 — Pre-pass: collect paths whose own node carries `meta.factory`.\n\t// These are \"factory parents\" (e.g. `prompt_node` for the `promptNode`\n\t// compound factory). Their `::`-prefixed sibling paths (`prompt_node::messages`,\n\t// `prompt_node::output`, etc.) are factory-internal and SHOULD NOT round-trip\n\t// as separate spec nodes — `compileSpec` will recreate them when the factory\n\t// runs against the parent's `meta.factory` / `meta.factoryArgs` tag. Without\n\t// this filter, every compound-factory internal would be emitted as a top-level\n\t// spec node, then `compileSpec` would try to re-add them via `g.add(nd, {name})`\n\t// alongside the factory's own outputs — duplicate-name failures or split topology.\n\tconst compoundFactoryPrefixes = new Set<string>();\n\tfor (const [path, nodeDesc] of Object.entries(desc.nodes)) {\n\t\tconst meta = nodeDesc.meta as Record<string, unknown> | undefined;\n\t\tif (meta?.factory != null && !path.includes(\"::\")) {\n\t\t\t// A12 (QA fix 2026-05-01): skip the `proxy` factoryTag — proxies\n\t\t\t// are local wrappers around foreign-source Nodes (used by\n\t\t\t// `pipelineGraph.approvalGate`, `gatedStream`, `stratify` after\n\t\t\t// the C3 ownership migration). They're regenerated by their\n\t\t\t// parent factory and don't have their own catalog entry; treating\n\t\t\t// them as compound-factory roots would cause `compileSpec` to\n\t\t\t// look up \"proxy\" as a registered factory name and fail.\n\t\t\tif (meta.factory === \"proxy\") continue;\n\t\t\tcompoundFactoryPrefixes.add(path);\n\t\t}\n\t}\n\n\t// 5.6 (b) — DF1 hard-require (Tier 5, 2026-04-29). Locked: any `::`-path\n\t// whose parent prefix exists in the graph but does NOT carry\n\t// `meta.factory` is an untagged compound factory. `compileSpec` cannot\n\t// reconstruct it, so the spec round-trip would silently break. Fail\n\t// loud at decompile time so the offending factory author tags the\n\t// parent. Skip well-known internal prefixes that are not factory output\n\t// (meta companions, feedback / bridge infrastructure).\n\tconst allPaths = new Set(Object.keys(desc.nodes));\n\tfor (const path of allPaths) {\n\t\tconst sepIdx = path.indexOf(\"::\");\n\t\tif (sepIdx <= 0) continue;\n\t\tconst parent = path.slice(0, sepIdx);\n\t\t// Skip internal infrastructure prefixes (handled below in the main loop).\n\t\tif (path.includes(metaSegment)) continue;\n\t\tif (path.startsWith(\"__feedback_effect_\") || path.startsWith(\"__bridge_\")) continue;\n\t\t// Parent is a tagged compound factory → covered by the existing pre-pass.\n\t\tif (compoundFactoryPrefixes.has(parent)) continue;\n\t\t// Parent doesn't appear in the graph (untagged child path with no\n\t\t// matching parent) — treat as a regular `::`-named node, not a\n\t\t// compound factory. Allowed.\n\t\tif (!allPaths.has(parent)) continue;\n\t\t// Parent IS in the graph but lacks `meta.factory` — untagged compound\n\t\t// factory. Refuse to round-trip.\n\t\tthrow new Error(\n\t\t\t`decompileSpec: untagged compound factory at \"${parent}\" (child: \"${path}\"). ` +\n\t\t\t\t\"Compound factories that ship `parent::child` topology MUST set `meta.factory` \" +\n\t\t\t\t\"on the parent so `compileSpec` can reconstruct the internals via the catalog. \" +\n\t\t\t\t\"Either tag the parent (`{ meta: factoryTag('myFactory', args) }`) OR rename the \" +\n\t\t\t\t\"child to use `/` instead of `::` if it's not a compound-factory internal \" +\n\t\t\t\t\"(see COMPOSITION-GUIDE §38).\",\n\t\t);\n\t}\n\n\t// Build the spec-shaped node map by walking describe's output. Strip\n\t// meta-companion paths, bridge / feedback-effect internals, AND compound-\n\t// factory `::` internals (per pre-pass above); preserve everything else verbatim.\n\tconst nodes: Record<string, GraphSpecNode | GraphSpecTemplateRef> = {};\n\tfor (const [path, nodeDesc] of Object.entries(desc.nodes)) {\n\t\tif (path.includes(metaSegment)) continue;\n\n\t\t// qa D1 — skip compound-factory `::` internals (e.g. `prompt_node::messages`)\n\t\t// when their parent is a tagged factory. The factory recreates them.\n\t\tconst sepIdx = path.indexOf(\"::\");\n\t\tif (sepIdx > 0 && compoundFactoryPrefixes.has(path.slice(0, sepIdx))) continue;\n\n\t\tconst match = feedbackCounterPattern.exec(path);\n\t\tif (match) {\n\t\t\tconst meta = nodeDesc.meta as Record<string, unknown> | undefined;\n\t\t\tif (meta?.feedbackFrom && meta?.feedbackTo) {\n\t\t\t\tfeedbackEdges.push({\n\t\t\t\t\tfrom: meta.feedbackFrom as string,\n\t\t\t\t\tto: meta.feedbackTo as string,\n\t\t\t\t\t...(meta.maxIterations ? { maxIterations: meta.maxIterations as number } : {}),\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\t// Skip internal infrastructure nodes (feedback-effect, bridge).\n\t\tif (nodeDesc.meta?._internal) continue;\n\t\tif (path.startsWith(\"__feedback_effect_\")) continue;\n\t\tif (path.startsWith(\"__bridge_\")) continue;\n\n\t\t// QA F5 carry: strip runtime-state sibling keys for known stateful factory\n\t\t// tags so the spec doesn't carry transient runtime state into round-trips.\n\t\tconst meta = nodeDesc.meta as Record<string, unknown> | undefined;\n\t\tlet cleanedMeta: Record<string, unknown> | undefined = meta;\n\t\tif (meta && Object.keys(meta).length > 0) {\n\t\t\tconst out: Record<string, unknown> = {};\n\t\t\tfor (const [k, v] of Object.entries(meta)) {\n\t\t\t\tif (INTERNAL_META_KEYS.has(k)) continue;\n\t\t\t\tout[k] = v;\n\t\t\t}\n\t\t\tif (out.factory === \"withStatus\") {\n\t\t\t\tdelete out.status;\n\t\t\t\tdelete out.error;\n\t\t\t} else if (out.factory === \"withBreaker\") {\n\t\t\t\tdelete out.breakerState;\n\t\t\t} else if (out.factory === \"verifiable\") {\n\t\t\t\tdelete out.sourceVersion;\n\t\t\t}\n\t\t\tcleanedMeta = Object.keys(out).length > 0 ? out : undefined;\n\t\t}\n\n\t\tconst cleaned: GraphSpecNode = { ...nodeDesc };\n\t\tif (cleanedMeta === undefined) delete cleaned.meta;\n\t\telse cleaned.meta = cleanedMeta;\n\t\tnodes[path] = cleaned;\n\t}\n\n\tconst result: GraphSpec = { ...desc, nodes };\n\t// `expand` (a closure injected onto live describe outputs) is not part of\n\t// the GraphSpec wire shape — it leaks function refs into JSON-stringified\n\t// specs. Drop it.\n\tdelete (result as { expand?: unknown }).expand;\n\tif (feedbackEdges.length > 0) result.feedback = feedbackEdges;\n\treturn result;\n}\n\n// ---------------------------------------------------------------------------\n// specDiff\n// ---------------------------------------------------------------------------\n\n/** A single change in a spec diff. */\nexport type SpecDiffEntry = {\n\ttype: \"added\" | \"removed\" | \"changed\";\n\tpath: string;\n\tdetail?: string;\n};\n\n/** Structural diff between two GraphSpecs. */\nexport type SpecDiffResult = {\n\tentries: SpecDiffEntry[];\n\tsummary: string;\n};\n\n/**\n * Compute a structural diff between two GraphSpecs.\n *\n * Template-aware: reports \"changed template definition\" vs \"changed\n * instantiation bindings.\" No runtime needed — pure JSON comparison.\n *\n * @param specA - The \"before\" spec.\n * @param specB - The \"after\" spec.\n * @returns Diff entries and a human-readable summary.\n *\n * @category patterns\n */\nexport function specDiff(specA: GraphSpec, specB: GraphSpec): SpecDiffResult {\n\tconst entries: SpecDiffEntry[] = [];\n\n\t// Diff name\n\tif (specA.name !== specB.name) {\n\t\tentries.push({\n\t\t\ttype: \"changed\",\n\t\t\tpath: \"name\",\n\t\t\tdetail: `\"${specA.name}\" → \"${specB.name}\"`,\n\t\t});\n\t}\n\n\t// Diff nodes\n\tconst nodesA = new Set(Object.keys(specA.nodes));\n\tconst nodesB = new Set(Object.keys(specB.nodes));\n\n\tfor (const name of nodesB) {\n\t\tif (!nodesA.has(name)) {\n\t\t\tconst n = specB.nodes[name]!;\n\t\t\tentries.push({\n\t\t\t\ttype: \"added\",\n\t\t\t\tpath: `nodes.${name}`,\n\t\t\t\tdetail: `type: ${n.type}`,\n\t\t\t});\n\t\t}\n\t}\n\tfor (const name of nodesA) {\n\t\tif (!nodesB.has(name)) {\n\t\t\tentries.push({ type: \"removed\", path: `nodes.${name}` });\n\t\t}\n\t}\n\tfor (const name of nodesA) {\n\t\tif (!nodesB.has(name)) continue;\n\t\tconst a = specA.nodes[name]!;\n\t\tconst b = specB.nodes[name]!;\n\t\tif (JSON.stringify(a) !== JSON.stringify(b)) {\n\t\t\tconst details: string[] = [];\n\t\t\tif (a.type !== b.type) details.push(`type: ${a.type} → ${b.type}`);\n\t\t\tif (JSON.stringify((a as GraphSpecNode).deps) !== JSON.stringify((b as GraphSpecNode).deps)) {\n\t\t\t\tdetails.push(\"deps changed\");\n\t\t\t}\n\t\t\tconst aFactory = a.type === \"template\" ? undefined : readFactory(a as GraphSpecNode);\n\t\t\tconst bFactory = b.type === \"template\" ? undefined : readFactory(b as GraphSpecNode);\n\t\t\tif (aFactory !== bFactory) {\n\t\t\t\tdetails.push(`fn: ${aFactory} → ${bFactory}`);\n\t\t\t}\n\t\t\tconst aArgs = a.type === \"template\" ? undefined : readFactoryArgs(a as GraphSpecNode);\n\t\t\tconst bArgs = b.type === \"template\" ? undefined : readFactoryArgs(b as GraphSpecNode);\n\t\t\tif (JSON.stringify(aArgs) !== JSON.stringify(bArgs)) {\n\t\t\t\tdetails.push(\"config changed\");\n\t\t\t}\n\t\t\tentries.push({\n\t\t\t\ttype: \"changed\",\n\t\t\t\tpath: `nodes.${name}`,\n\t\t\t\tdetail: details.join(\"; \") || \"modified\",\n\t\t\t});\n\t\t}\n\t}\n\n\t// Diff templates\n\tconst tmplA = specA.templates ?? {};\n\tconst tmplB = specB.templates ?? {};\n\tconst tmplNamesA = new Set(Object.keys(tmplA));\n\tconst tmplNamesB = new Set(Object.keys(tmplB));\n\n\tfor (const name of tmplNamesB) {\n\t\tif (!tmplNamesA.has(name)) {\n\t\t\tentries.push({ type: \"added\", path: `templates.${name}` });\n\t\t}\n\t}\n\tfor (const name of tmplNamesA) {\n\t\tif (!tmplNamesB.has(name)) {\n\t\t\tentries.push({ type: \"removed\", path: `templates.${name}` });\n\t\t}\n\t}\n\tfor (const name of tmplNamesA) {\n\t\tif (!tmplNamesB.has(name)) continue;\n\t\tif (JSON.stringify(tmplA[name]) !== JSON.stringify(tmplB[name])) {\n\t\t\tentries.push({\n\t\t\t\ttype: \"changed\",\n\t\t\t\tpath: `templates.${name}`,\n\t\t\t\tdetail: \"template definition changed\",\n\t\t\t});\n\t\t}\n\t}\n\n\t// Diff feedback\n\tconst fbA = specA.feedback ?? [];\n\tconst fbB = specB.feedback ?? [];\n\tconst fbKeyA = new Set(fbA.map((e) => `${e.from}->${e.to}`));\n\tconst fbKeyB = new Set(fbB.map((e) => `${e.from}->${e.to}`));\n\n\tfor (const fb of fbB) {\n\t\tconst key = `${fb.from}->${fb.to}`;\n\t\tif (!fbKeyA.has(key)) {\n\t\t\tentries.push({\n\t\t\t\ttype: \"added\",\n\t\t\t\tpath: `feedback.${key}`,\n\t\t\t\tdetail: `maxIterations: ${fb.maxIterations ?? 10}`,\n\t\t\t});\n\t\t}\n\t}\n\tfor (const fb of fbA) {\n\t\tconst key = `${fb.from}->${fb.to}`;\n\t\tif (!fbKeyB.has(key)) {\n\t\t\tentries.push({ type: \"removed\", path: `feedback.${key}` });\n\t\t}\n\t}\n\tfor (const fb of fbA) {\n\t\tconst key = `${fb.from}->${fb.to}`;\n\t\tconst counterpart = fbB.find((b) => b.from === fb.from && b.to === fb.to);\n\t\tif (counterpart && JSON.stringify(fb) !== JSON.stringify(counterpart)) {\n\t\t\tentries.push({\n\t\t\t\ttype: \"changed\",\n\t\t\t\tpath: `feedback.${key}`,\n\t\t\t\tdetail: `maxIterations: ${fb.maxIterations ?? 10} → ${counterpart.maxIterations ?? 10}`,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Build summary\n\tconst added = entries.filter((e) => e.type === \"added\").length;\n\tconst removed = entries.filter((e) => e.type === \"removed\").length;\n\tconst changed = entries.filter((e) => e.type === \"changed\").length;\n\tconst parts: string[] = [];\n\tif (added) parts.push(`${added} added`);\n\tif (removed) parts.push(`${removed} removed`);\n\tif (changed) parts.push(`${changed} changed`);\n\tconst summary = parts.length > 0 ? parts.join(\", \") : \"no changes\";\n\n\treturn { entries, summary };\n}\n\n// ---------------------------------------------------------------------------\n// llmCompose\n// ---------------------------------------------------------------------------\n\n/** Options for {@link llmCompose}. */\nexport type LLMComposeOptions = {\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/** Extra instructions appended to the system prompt. */\n\tsystemPromptExtra?: string;\n\t/**\n\t * Available fn/source catalog names for the LLM to reference.\n\t * When omitted and `catalog` contains rich {@link CatalogFnEntry} entries,\n\t * the prompt is auto-generated via {@link generateCatalogPrompt}.\n\t */\n\tcatalogDescription?: string;\n\t/**\n\t * Catalog for auto-prompt generation and catalog-aware validation.\n\t * When rich entries are provided, the catalog prompt is auto-generated\n\t * and LLM output is validated against fn/source names and config schemas.\n\t */\n\tcatalog?: GraphSpecCatalog;\n\t/**\n\t * Max auto-refine attempts when the LLM output fails catalog validation.\n\t * Each attempt feeds the validation errors back to the LLM via llmRefine.\n\t * Default: 0 (no auto-refine). Set to 2-3 for production use.\n\t */\n\tmaxAutoRefine?: number;\n};\n\nconst LLM_COMPOSE_SYSTEM_PROMPT = `You are a graph architect for GraphReFly, a reactive graph protocol.\n\nGiven a natural-language description, produce a JSON GraphSpec with this structure:\n\n{\n \"name\": \"<graph_name>\",\n \"nodes\": {\n \"<node_name>\": {\n \"type\": \"state\" | \"derived\" | \"producer\" | \"effect\",\n \"deps\": [\"<dep_node_name>\", ...],\n \"value\": <initial_value>,\n \"meta\": {\n \"factory\": \"<catalog_factory_name>\",\n \"factoryArgs\": { ... },\n \"description\": \"<purpose>\"\n }\n },\n \"<template_instance>\": {\n \"type\": \"template\",\n \"template\": \"<template_name>\",\n \"bind\": { \"$param\": \"node_name\" }\n }\n },\n \"templates\": {\n \"<template_name>\": {\n \"params\": [\"$param1\", \"$param2\"],\n \"nodes\": { ... },\n \"output\": \"<output_node>\"\n }\n },\n \"feedback\": [\n { \"from\": \"<condition_node>\", \"to\": \"<state_node>\", \"maxIterations\": 10 }\n ]\n}\n\nRules:\n- \"state\" nodes hold user/LLM-writable values (knobs). Stamp the initial value\n in \"meta.factoryArgs.initial\" (or as the top-level \"value\" field — both work).\n- \"derived\" nodes compute from deps using a catalog function named in\n \"meta.factory\"; pass any config via \"meta.factoryArgs\".\n- \"effect\" nodes produce side effects from deps; same meta.factory shape as derived.\n- \"producer\" nodes generate values from a catalog source named in \"meta.factory\";\n pass any config via \"meta.factoryArgs\".\n- Use \"templates\" when the same subgraph pattern repeats (e.g., per-source resilience).\n- Use \"feedback\" for bounded cycles where a derived value writes back to a state node.\n- meta.description is required for every node.\n- Return ONLY valid JSON, no markdown fences or commentary.`;\n\n/** Strip markdown code fences. */\nfunction stripFences(text: string): string {\n\tconst match = text.match(/^```(?:json)?\\s*([\\s\\S]*?)\\s*```[\\s\\S]*$/);\n\treturn match ? match[1]! : text;\n}\n\n/**\n * Ask an LLM to compose a GraphSpec from a natural-language problem description.\n *\n * The LLM generates a GraphSpec (with templates + feedback), validated before\n * returning. The spec is for human review before compilation via compileSpec().\n *\n * @param problem - Natural language problem description.\n * @param adapter - LLM adapter for the generation call.\n * @param opts - Model options and catalog description.\n * @returns A validated GraphSpec.\n * @throws On invalid LLM output or validation failure.\n *\n * @category patterns\n */\nexport async function llmCompose(\n\tproblem: string,\n\tadapter: LLMAdapter,\n\topts?: LLMComposeOptions,\n): Promise<GraphSpec> {\n\tlet systemPrompt = LLM_COMPOSE_SYSTEM_PROMPT;\n\n\t// Auto-generate catalog prompt from rich entries, or use manual description\n\tconst catalogPrompt =\n\t\topts?.catalogDescription ?? (opts?.catalog ? generateCatalogPrompt(opts.catalog) : undefined);\n\tif (catalogPrompt) {\n\t\tsystemPrompt += `\\n\\nAvailable catalog (use ONLY these names):\\n${catalogPrompt}`;\n\t}\n\tif (opts?.systemPromptExtra) {\n\t\tsystemPrompt += `\\n\\n${opts.systemPromptExtra}`;\n\t}\n\n\tconst messages: ChatMessage[] = [\n\t\t{ role: \"system\", content: systemPrompt },\n\t\t{ role: \"user\", content: problem },\n\t];\n\n\tconst rawResult = adapter.invoke(messages, {\n\t\tmodel: opts?.model,\n\t\ttemperature: opts?.temperature ?? 0,\n\t\tmaxTokens: opts?.maxTokens,\n\t});\n\n\t// System boundary: await the adapter's response (Promise, plain value).\n\tconst response = (await rawResult) as LLMResponse;\n\tlet content = response.content.trim();\n\n\tif (content.startsWith(\"```\")) {\n\t\tcontent = stripFences(content);\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(content);\n\t} catch {\n\t\tthrow new Error(`llmCompose: LLM response is not valid JSON: ${content.slice(0, 200)}`);\n\t}\n\n\tconst validation = validateSpec(parsed);\n\tif (!validation.valid) {\n\t\tthrow new Error(`llmCompose: invalid GraphSpec:\\n${validation.errors.join(\"\\n\")}`);\n\t}\n\n\tlet spec = parsed as GraphSpec;\n\n\t// Catalog-aware validation + auto-refine loop\n\tif (opts?.catalog) {\n\t\tconst maxRefine = opts.maxAutoRefine ?? 0;\n\t\tfor (let attempt = 0; attempt <= maxRefine; attempt++) {\n\t\t\tconst catalogValidation = validateSpecAgainstCatalog(spec, opts.catalog);\n\t\t\tif (catalogValidation.valid) break;\n\n\t\t\tif (attempt === maxRefine) {\n\t\t\t\t// Last attempt failed — return with errors attached as meta\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`llmCompose: catalog validation failed after ${maxRefine} refine attempts:\\n${catalogValidation.errors.join(\"\\n\")}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Auto-refine: feed catalog errors back to LLM\n\t\t\tspec = await llmRefine(\n\t\t\t\tspec,\n\t\t\t\t`Fix these catalog errors:\\n${catalogValidation.errors.join(\"\\n\")}\\n\\nUse ONLY functions and sources from the catalog.`,\n\t\t\t\tadapter,\n\t\t\t\t{ ...opts, catalogDescription: catalogPrompt },\n\t\t\t);\n\t\t}\n\t}\n\n\treturn spec;\n}\n\n// ---------------------------------------------------------------------------\n// llmRefine\n// ---------------------------------------------------------------------------\n\n/** Options for {@link llmRefine}. */\nexport type LLMRefineOptions = LLMComposeOptions;\n\n/**\n * Ask an LLM to modify an existing GraphSpec based on feedback or changed requirements.\n *\n * @param currentSpec - The current GraphSpec to modify.\n * @param feedback - Natural language feedback or changed requirements.\n * @param adapter - LLM adapter for the generation call.\n * @param opts - Model options.\n * @returns A new GraphSpec incorporating the feedback.\n * @throws On invalid LLM output or validation failure.\n *\n * @category patterns\n */\nexport async function llmRefine(\n\tcurrentSpec: GraphSpec,\n\tfeedback: string,\n\tadapter: LLMAdapter,\n\topts?: LLMRefineOptions,\n): Promise<GraphSpec> {\n\tlet systemPrompt = LLM_COMPOSE_SYSTEM_PROMPT;\n\tif (opts?.catalogDescription) {\n\t\tsystemPrompt += `\\n\\nAvailable catalog:\\n${opts.catalogDescription}`;\n\t}\n\tif (opts?.systemPromptExtra) {\n\t\tsystemPrompt += `\\n\\n${opts.systemPromptExtra}`;\n\t}\n\n\tconst messages: ChatMessage[] = [\n\t\t{ role: \"system\", content: systemPrompt },\n\t\t{\n\t\t\trole: \"user\",\n\t\t\tcontent: `Current GraphSpec:\\n${JSON.stringify(currentSpec, null, 2)}\\n\\nModification request: ${feedback}\\n\\nReturn the complete modified GraphSpec as JSON.`,\n\t\t},\n\t];\n\n\tconst rawResult = adapter.invoke(messages, {\n\t\tmodel: opts?.model,\n\t\ttemperature: opts?.temperature ?? 0,\n\t\tmaxTokens: opts?.maxTokens,\n\t});\n\n\t// System boundary: await the adapter's response.\n\tconst response = (await rawResult) as LLMResponse;\n\tlet content = response.content.trim();\n\n\tif (content.startsWith(\"```\")) {\n\t\tcontent = stripFences(content);\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(content);\n\t} catch {\n\t\tthrow new Error(`llmRefine: LLM response is not valid JSON: ${content.slice(0, 200)}`);\n\t}\n\n\tconst validation = validateSpec(parsed);\n\tif (!validation.valid) {\n\t\tthrow new Error(`llmRefine: invalid GraphSpec:\\n${validation.errors.join(\"\\n\")}`);\n\t}\n\n\treturn parsed as GraphSpec;\n}\n"],"mappings":"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","names":["node","_","meta","feedback"]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// src/base/render/_ascii-width.ts
|
|
2
|
+
function cellWidth(code) {
|
|
3
|
+
if (code >= 768 && code <= 879 || // Combining Diacritical Marks
|
|
4
|
+
code >= 1155 && code <= 1161 || // Cyrillic combining marks
|
|
5
|
+
code >= 1425 && code <= 1469 || // Hebrew combining marks
|
|
6
|
+
code >= 1552 && code <= 1562 || // Arabic combining marks
|
|
7
|
+
code >= 1611 && code <= 1631 || // Arabic combining marks
|
|
8
|
+
code >= 1648 && code === 1648 || // Arabic superscript alef
|
|
9
|
+
code >= 1750 && code <= 1756 || // Arabic combining marks
|
|
10
|
+
code >= 1759 && code <= 1764 || // Arabic combining marks
|
|
11
|
+
code >= 1767 && code <= 1768 || // Arabic combining marks
|
|
12
|
+
code >= 1770 && code <= 1773 || // Arabic combining marks
|
|
13
|
+
code >= 1840 && code <= 1866 || // Syriac combining marks
|
|
14
|
+
code >= 1958 && code <= 1968 || // Thaana combining marks
|
|
15
|
+
code >= 2304 && code <= 2307 || // Devanagari combining marks
|
|
16
|
+
code >= 2362 && code <= 2383 || // Devanagari combining marks
|
|
17
|
+
code >= 2385 && code <= 2391 || // Devanagari combining marks
|
|
18
|
+
code >= 2402 && code <= 2403 || // Devanagari combining marks
|
|
19
|
+
code >= 2433 && code <= 2435 || // Bengali combining marks
|
|
20
|
+
code >= 2492 && code <= 2509 || // Bengali combining marks
|
|
21
|
+
code >= 2561 && code <= 2563 || // Gurmukhi combining marks
|
|
22
|
+
code >= 2620 && code <= 2641 || // Gurmukhi combining marks
|
|
23
|
+
code >= 2672 && code <= 2673 || // Gurmukhi combining marks
|
|
24
|
+
code >= 2677 && code === 2677 || // Gurmukhi combining mark
|
|
25
|
+
code >= 3633 && code === 3633 || // Thai combining mark
|
|
26
|
+
code >= 3636 && code <= 3642 || // Thai combining marks
|
|
27
|
+
code >= 3655 && code <= 3662 || // Thai combining marks
|
|
28
|
+
code >= 3761 && code === 3761 || // Lao combining mark
|
|
29
|
+
code >= 3764 && code <= 3772 || // Lao combining marks
|
|
30
|
+
code >= 3784 && code <= 3790 || // Lao combining marks
|
|
31
|
+
code >= 7616 && code <= 7679 || // Combining Diacritical Marks Supplement
|
|
32
|
+
code >= 8400 && code <= 8447 || // Combining Diacritical Marks for Symbols
|
|
33
|
+
code >= 65024 && code <= 65039 || // Variation Selectors
|
|
34
|
+
code >= 65056 && code <= 65071 || // Combining Half Marks
|
|
35
|
+
code === 8205) {
|
|
36
|
+
return 0;
|
|
37
|
+
}
|
|
38
|
+
if (code >= 4352 && code <= 4447 || // Hangul Jamo
|
|
39
|
+
code >= 8986 && code <= 8987 || // Watch, Hourglass
|
|
40
|
+
code >= 9001 && code <= 9002 || // Angle brackets
|
|
41
|
+
code >= 9193 && code <= 9203 || // Media control symbols
|
|
42
|
+
code >= 9208 && code <= 9210 || // Media control symbols
|
|
43
|
+
code >= 9725 && code <= 9726 || // Medium squares
|
|
44
|
+
code >= 9748 && code <= 9749 || // Umbrella, Hot Beverage
|
|
45
|
+
code >= 9800 && code <= 9811 || // Zodiac symbols
|
|
46
|
+
code === 9855 || // Wheelchair
|
|
47
|
+
code === 9875 || // Anchor
|
|
48
|
+
code === 9889 || // High Voltage
|
|
49
|
+
code >= 9898 && code <= 9899 || // Medium circles
|
|
50
|
+
code >= 9917 && code <= 9918 || // Soccer, Baseball
|
|
51
|
+
code >= 9924 && code <= 9925 || // Snowman, Sun behind cloud
|
|
52
|
+
code === 9934 || // Ophiuchus
|
|
53
|
+
code === 9940 || // No Entry
|
|
54
|
+
code === 9962 || // Church
|
|
55
|
+
code >= 9970 && code <= 9971 || // Fountain, Golf
|
|
56
|
+
code === 9973 || // Sailboat
|
|
57
|
+
code === 9978 || // Tent
|
|
58
|
+
code === 9981 || // Fuel Pump
|
|
59
|
+
code === 9986 || // Scissors
|
|
60
|
+
code === 9989 || // Check Mark
|
|
61
|
+
code >= 9992 && code <= 9997 || // Airplane...Writing Hand
|
|
62
|
+
code === 9999 || // Pencil
|
|
63
|
+
code >= 10067 && code <= 10069 || // Question marks
|
|
64
|
+
code === 10071 || // Exclamation
|
|
65
|
+
code >= 10133 && code <= 10135 || // Plus, Minus, Divide
|
|
66
|
+
code === 10160 || // Curly Loop
|
|
67
|
+
code === 10175 || // Double Curly Loop
|
|
68
|
+
code >= 10548 && code <= 10549 || // Arrows
|
|
69
|
+
code >= 11013 && code <= 11015 || // Arrows
|
|
70
|
+
code >= 11035 && code <= 11036 || // Squares
|
|
71
|
+
code === 11088 || // Star
|
|
72
|
+
code === 11093 || // Circle
|
|
73
|
+
code >= 11904 && code <= 12350 || // CJK Radicals, Symbols, Punctuation
|
|
74
|
+
code >= 12352 && code <= 12447 || // Hiragana
|
|
75
|
+
code >= 12448 && code <= 12543 || // Katakana
|
|
76
|
+
code >= 12549 && code <= 12591 || // Bopomofo
|
|
77
|
+
code >= 12593 && code <= 12686 || // Hangul Compatibility Jamo
|
|
78
|
+
code >= 12688 && code <= 12771 || // Kanbun, CJK Strokes
|
|
79
|
+
code >= 12784 && code <= 12830 || // Katakana Phonetic Extensions
|
|
80
|
+
code >= 12832 && code <= 12871 || // Enclosed CJK
|
|
81
|
+
code >= 12880 && code <= 19903 || // CJK Extensions + Unified block
|
|
82
|
+
code >= 19968 && code <= 40959 || // CJK Unified Ideographs
|
|
83
|
+
code >= 43360 && code <= 43388 || // Hangul Jamo Extended-A
|
|
84
|
+
code >= 44032 && code <= 55203 || // Hangul Syllables
|
|
85
|
+
code >= 63744 && code <= 64255 || // CJK Compatibility Ideographs
|
|
86
|
+
code >= 65040 && code <= 65049 || // Vertical forms
|
|
87
|
+
code >= 65072 && code <= 65131 || // CJK Compatibility Forms
|
|
88
|
+
code >= 65281 && code <= 65376 || // Fullwidth Forms (excl. halfwidth)
|
|
89
|
+
code >= 65504 && code <= 65510 || // Fullwidth Signs
|
|
90
|
+
code >= 126980 && code === 126980 || // Mahjong Red Dragon
|
|
91
|
+
code === 127183 || // Joker
|
|
92
|
+
code >= 127344 && code <= 127345 || // A/B buttons
|
|
93
|
+
code === 127358 || // O button
|
|
94
|
+
code === 127359 || // P button
|
|
95
|
+
code === 127374 || // AB button
|
|
96
|
+
code >= 127377 && code <= 127386 || // Squared symbols
|
|
97
|
+
code >= 127456 && code <= 127487 || // Regional Indicator Symbols
|
|
98
|
+
code >= 127488 && code <= 127490 || // Enclosed ideographic
|
|
99
|
+
code === 127514 || // Squared CJK
|
|
100
|
+
code === 127535 || // Squared CJK
|
|
101
|
+
code >= 127538 && code <= 127546 || // Squared CJK
|
|
102
|
+
code >= 127568 && code <= 127569 || // Circled ideographic
|
|
103
|
+
code >= 127744 && code <= 129535 || // Misc Symbols / Emoticons / Emoji
|
|
104
|
+
code >= 129536 && code <= 129791 || // Chess, Symbols Extended-A
|
|
105
|
+
code >= 129792 && code <= 130047 || // Symbols for Legacy Computing
|
|
106
|
+
code >= 131072 && code <= 196605 || // CJK Extension B-F (excl. nonchars)
|
|
107
|
+
code >= 196608 && code <= 262141) {
|
|
108
|
+
return 2;
|
|
109
|
+
}
|
|
110
|
+
return 1;
|
|
111
|
+
}
|
|
112
|
+
function countCells(text) {
|
|
113
|
+
let cells = 0;
|
|
114
|
+
for (const ch of text) {
|
|
115
|
+
cells += cellWidth(ch.codePointAt(0));
|
|
116
|
+
}
|
|
117
|
+
return cells;
|
|
118
|
+
}
|
|
119
|
+
function truncateToCells(text, maxCells) {
|
|
120
|
+
if (maxCells <= 0) return "";
|
|
121
|
+
let cells = 0;
|
|
122
|
+
let out = "";
|
|
123
|
+
for (const ch of text) {
|
|
124
|
+
const w = cellWidth(ch.codePointAt(0));
|
|
125
|
+
if (cells + w > maxCells) {
|
|
126
|
+
if (maxCells <= 1) return "\u2026";
|
|
127
|
+
while (cells + 1 > maxCells && out.length > 0) {
|
|
128
|
+
const last = [...out].pop();
|
|
129
|
+
out = out.slice(0, -last.length);
|
|
130
|
+
cells -= cellWidth(last.codePointAt(0));
|
|
131
|
+
}
|
|
132
|
+
return `${out}\u2026`;
|
|
133
|
+
}
|
|
134
|
+
out += ch;
|
|
135
|
+
cells += w;
|
|
136
|
+
}
|
|
137
|
+
return out;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export {
|
|
141
|
+
countCells,
|
|
142
|
+
truncateToCells
|
|
143
|
+
};
|
|
144
|
+
//# sourceMappingURL=chunk-36NMM65U.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/base/render/_ascii-width.ts"],"sourcesContent":["/**\n * Monospace-terminal cell-width utilities shared by the CLI measurement\n * adapter ([src/patterns/reactive-layout/measurement-adapters.ts](../patterns/reactive-layout/measurement-adapters.ts))\n * and the ASCII describe renderer ([graph-spec-to-ascii.ts](./graph-spec-to-ascii.ts)).\n *\n * Approximates UAX #11 East_Asian_Width (W/F → 2) plus known combining-mark\n * ranges (→ 0). Not a full EAW table — covers CJK, Hangul, fullwidth forms,\n * common emoji, and Extensions B-G. Does not handle ZWJ emoji sequences\n * (multi-codepoint clusters rendered as a single glyph) — terminal support\n * for those varies widely.\n */\n\nexport function cellWidth(code: number): 0 | 1 | 2 {\n\t// Combining marks (Mn, Mc, Me) → 0 cells\n\tif (\n\t\t(code >= 0x0300 && code <= 0x036f) || // Combining Diacritical Marks\n\t\t(code >= 0x0483 && code <= 0x0489) || // Cyrillic combining marks\n\t\t(code >= 0x0591 && code <= 0x05bd) || // Hebrew combining marks\n\t\t(code >= 0x0610 && code <= 0x061a) || // Arabic combining marks\n\t\t(code >= 0x064b && code <= 0x065f) || // Arabic combining marks\n\t\t(code >= 0x0670 && code === 0x0670) || // Arabic superscript alef\n\t\t(code >= 0x06d6 && code <= 0x06dc) || // Arabic combining marks\n\t\t(code >= 0x06df && code <= 0x06e4) || // Arabic combining marks\n\t\t(code >= 0x06e7 && code <= 0x06e8) || // Arabic combining marks\n\t\t(code >= 0x06ea && code <= 0x06ed) || // Arabic combining marks\n\t\t(code >= 0x0730 && code <= 0x074a) || // Syriac combining marks\n\t\t(code >= 0x07a6 && code <= 0x07b0) || // Thaana combining marks\n\t\t(code >= 0x0900 && code <= 0x0903) || // Devanagari combining marks\n\t\t(code >= 0x093a && code <= 0x094f) || // Devanagari combining marks\n\t\t(code >= 0x0951 && code <= 0x0957) || // Devanagari combining marks\n\t\t(code >= 0x0962 && code <= 0x0963) || // Devanagari combining marks\n\t\t(code >= 0x0981 && code <= 0x0983) || // Bengali combining marks\n\t\t(code >= 0x09bc && code <= 0x09cd) || // Bengali combining marks\n\t\t(code >= 0x0a01 && code <= 0x0a03) || // Gurmukhi combining marks\n\t\t(code >= 0x0a3c && code <= 0x0a51) || // Gurmukhi combining marks\n\t\t(code >= 0x0a70 && code <= 0x0a71) || // Gurmukhi combining marks\n\t\t(code >= 0x0a75 && code === 0x0a75) || // Gurmukhi combining mark\n\t\t(code >= 0x0e31 && code === 0x0e31) || // Thai combining mark\n\t\t(code >= 0x0e34 && code <= 0x0e3a) || // Thai combining marks\n\t\t(code >= 0x0e47 && code <= 0x0e4e) || // Thai combining marks\n\t\t(code >= 0x0eb1 && code === 0x0eb1) || // Lao combining mark\n\t\t(code >= 0x0eb4 && code <= 0x0ebc) || // Lao combining marks\n\t\t(code >= 0x0ec8 && code <= 0x0ece) || // Lao combining marks\n\t\t(code >= 0x1dc0 && code <= 0x1dff) || // Combining Diacritical Marks Supplement\n\t\t(code >= 0x20d0 && code <= 0x20ff) || // Combining Diacritical Marks for Symbols\n\t\t(code >= 0xfe00 && code <= 0xfe0f) || // Variation Selectors\n\t\t(code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks\n\t\tcode === 0x200d // Zero Width Joiner\n\t) {\n\t\treturn 0;\n\t}\n\t// Wide / fullwidth → 2 cells\n\tif (\n\t\t(code >= 0x1100 && code <= 0x115f) || // Hangul Jamo\n\t\t(code >= 0x231a && code <= 0x231b) || // Watch, Hourglass\n\t\t(code >= 0x2329 && code <= 0x232a) || // Angle brackets\n\t\t(code >= 0x23e9 && code <= 0x23f3) || // Media control symbols\n\t\t(code >= 0x23f8 && code <= 0x23fa) || // Media control symbols\n\t\t(code >= 0x25fd && code <= 0x25fe) || // Medium squares\n\t\t(code >= 0x2614 && code <= 0x2615) || // Umbrella, Hot Beverage\n\t\t(code >= 0x2648 && code <= 0x2653) || // Zodiac symbols\n\t\tcode === 0x267f || // Wheelchair\n\t\tcode === 0x2693 || // Anchor\n\t\tcode === 0x26a1 || // High Voltage\n\t\t(code >= 0x26aa && code <= 0x26ab) || // Medium circles\n\t\t(code >= 0x26bd && code <= 0x26be) || // Soccer, Baseball\n\t\t(code >= 0x26c4 && code <= 0x26c5) || // Snowman, Sun behind cloud\n\t\tcode === 0x26ce || // Ophiuchus\n\t\tcode === 0x26d4 || // No Entry\n\t\tcode === 0x26ea || // Church\n\t\t(code >= 0x26f2 && code <= 0x26f3) || // Fountain, Golf\n\t\tcode === 0x26f5 || // Sailboat\n\t\tcode === 0x26fa || // Tent\n\t\tcode === 0x26fd || // Fuel Pump\n\t\tcode === 0x2702 || // Scissors\n\t\tcode === 0x2705 || // Check Mark\n\t\t(code >= 0x2708 && code <= 0x270d) || // Airplane...Writing Hand\n\t\tcode === 0x270f || // Pencil\n\t\t(code >= 0x2753 && code <= 0x2755) || // Question marks\n\t\tcode === 0x2757 || // Exclamation\n\t\t(code >= 0x2795 && code <= 0x2797) || // Plus, Minus, Divide\n\t\tcode === 0x27b0 || // Curly Loop\n\t\tcode === 0x27bf || // Double Curly Loop\n\t\t(code >= 0x2934 && code <= 0x2935) || // Arrows\n\t\t(code >= 0x2b05 && code <= 0x2b07) || // Arrows\n\t\t(code >= 0x2b1b && code <= 0x2b1c) || // Squares\n\t\tcode === 0x2b50 || // Star\n\t\tcode === 0x2b55 || // Circle\n\t\t(code >= 0x2e80 && code <= 0x303e) || // CJK Radicals, Symbols, Punctuation\n\t\t(code >= 0x3040 && code <= 0x309f) || // Hiragana\n\t\t(code >= 0x30a0 && code <= 0x30ff) || // Katakana\n\t\t(code >= 0x3105 && code <= 0x312f) || // Bopomofo\n\t\t(code >= 0x3131 && code <= 0x318e) || // Hangul Compatibility Jamo\n\t\t(code >= 0x3190 && code <= 0x31e3) || // Kanbun, CJK Strokes\n\t\t(code >= 0x31f0 && code <= 0x321e) || // Katakana Phonetic Extensions\n\t\t(code >= 0x3220 && code <= 0x3247) || // Enclosed CJK\n\t\t(code >= 0x3250 && code <= 0x4dbf) || // CJK Extensions + Unified block\n\t\t(code >= 0x4e00 && code <= 0x9fff) || // CJK Unified Ideographs\n\t\t(code >= 0xa960 && code <= 0xa97c) || // Hangul Jamo Extended-A\n\t\t(code >= 0xac00 && code <= 0xd7a3) || // Hangul Syllables\n\t\t(code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility Ideographs\n\t\t(code >= 0xfe10 && code <= 0xfe19) || // Vertical forms\n\t\t(code >= 0xfe30 && code <= 0xfe6b) || // CJK Compatibility Forms\n\t\t(code >= 0xff01 && code <= 0xff60) || // Fullwidth Forms (excl. halfwidth)\n\t\t(code >= 0xffe0 && code <= 0xffe6) || // Fullwidth Signs\n\t\t(code >= 0x1f004 && code === 0x1f004) || // Mahjong Red Dragon\n\t\tcode === 0x1f0cf || // Joker\n\t\t(code >= 0x1f170 && code <= 0x1f171) || // A/B buttons\n\t\tcode === 0x1f17e || // O button\n\t\tcode === 0x1f17f || // P button\n\t\tcode === 0x1f18e || // AB button\n\t\t(code >= 0x1f191 && code <= 0x1f19a) || // Squared symbols\n\t\t(code >= 0x1f1e0 && code <= 0x1f1ff) || // Regional Indicator Symbols\n\t\t(code >= 0x1f200 && code <= 0x1f202) || // Enclosed ideographic\n\t\tcode === 0x1f21a || // Squared CJK\n\t\tcode === 0x1f22f || // Squared CJK\n\t\t(code >= 0x1f232 && code <= 0x1f23a) || // Squared CJK\n\t\t(code >= 0x1f250 && code <= 0x1f251) || // Circled ideographic\n\t\t(code >= 0x1f300 && code <= 0x1f9ff) || // Misc Symbols / Emoticons / Emoji\n\t\t(code >= 0x1fa00 && code <= 0x1faff) || // Chess, Symbols Extended-A\n\t\t(code >= 0x1fb00 && code <= 0x1fbff) || // Symbols for Legacy Computing\n\t\t(code >= 0x20000 && code <= 0x2fffd) || // CJK Extension B-F (excl. nonchars)\n\t\t(code >= 0x30000 && code <= 0x3fffd) // CJK Extension G+ (excl. nonchars)\n\t) {\n\t\treturn 2;\n\t}\n\treturn 1;\n}\n\n/**\n * Count total display cells for a string in a monospace terminal.\n *\n * Combining marks contribute 0 cells; CJK / fullwidth contribute 2.\n * Does not handle ZWJ emoji sequences.\n */\nexport function countCells(text: string): number {\n\tlet cells = 0;\n\tfor (const ch of text) {\n\t\tcells += cellWidth(ch.codePointAt(0)!);\n\t}\n\treturn cells;\n}\n\n/**\n * Truncate `text` to at most `maxCells` terminal cells, appending an ellipsis\n * (\"…\" → 1 cell) when truncation occurs. Grapheme-unaware — splits at\n * codepoints; ZWJ sequences may be cut mid-cluster.\n */\nexport function truncateToCells(text: string, maxCells: number): string {\n\tif (maxCells <= 0) return \"\";\n\tlet cells = 0;\n\tlet out = \"\";\n\tfor (const ch of text) {\n\t\tconst w = cellWidth(ch.codePointAt(0)!);\n\t\tif (cells + w > maxCells) {\n\t\t\tif (maxCells <= 1) return \"…\";\n\t\t\t// Drop last wide char if we'd exceed budget with the ellipsis\n\t\t\twhile (cells + 1 > maxCells && out.length > 0) {\n\t\t\t\tconst last = [...out].pop()!;\n\t\t\t\tout = out.slice(0, -last.length);\n\t\t\t\tcells -= cellWidth(last.codePointAt(0)!);\n\t\t\t}\n\t\t\treturn `${out}…`;\n\t\t}\n\t\tout += ch;\n\t\tcells += w;\n\t}\n\treturn out;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-3CEXCBN6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__export
|
|
3
|
+
} from "./chunk-AZDQPQ3V.js";
|
|
4
|
+
|
|
5
|
+
// src/compat/react/index.ts
|
|
6
|
+
var react_exports = {};
|
|
7
|
+
__export(react_exports, {
|
|
8
|
+
useStore: () => useStore,
|
|
9
|
+
useSubscribe: () => useSubscribe,
|
|
10
|
+
useSubscribeRecord: () => useSubscribeRecord
|
|
11
|
+
});
|
|
12
|
+
import { DATA, DIRTY, RESOLVED } from "@graphrefly/pure-ts/core";
|
|
13
|
+
import { useCallback, useMemo, useRef, useSyncExternalStore } from "react";
|
|
14
|
+
function useSubscribe(node) {
|
|
15
|
+
return useSyncExternalStore(
|
|
16
|
+
(onStoreChange) => {
|
|
17
|
+
let disposed = false;
|
|
18
|
+
const unsub = node.subscribe(() => {
|
|
19
|
+
if (!disposed) onStoreChange();
|
|
20
|
+
});
|
|
21
|
+
return () => {
|
|
22
|
+
disposed = true;
|
|
23
|
+
unsub();
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
() => node.cache,
|
|
27
|
+
() => node.cache
|
|
28
|
+
// Server snapshot
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
function useStore(node) {
|
|
32
|
+
const value = useSubscribe(node);
|
|
33
|
+
const setter = useCallback(
|
|
34
|
+
(v) => {
|
|
35
|
+
node.down([[DIRTY], [DATA, v]]);
|
|
36
|
+
},
|
|
37
|
+
[node]
|
|
38
|
+
);
|
|
39
|
+
return [value, setter];
|
|
40
|
+
}
|
|
41
|
+
function useSubscribeRecord(keysNode, factory) {
|
|
42
|
+
const factoryRef = useRef(factory);
|
|
43
|
+
factoryRef.current = factory;
|
|
44
|
+
const store = useMemo(() => {
|
|
45
|
+
const computeSnap = () => {
|
|
46
|
+
const snap = {};
|
|
47
|
+
const keys = keysNode.cache ?? [];
|
|
48
|
+
for (const key of keys) {
|
|
49
|
+
const nodes = factoryRef.current(key);
|
|
50
|
+
const values = {};
|
|
51
|
+
for (const field of Object.keys(nodes)) {
|
|
52
|
+
values[field] = nodes[field].cache;
|
|
53
|
+
}
|
|
54
|
+
snap[key] = values;
|
|
55
|
+
}
|
|
56
|
+
return snap;
|
|
57
|
+
};
|
|
58
|
+
let currentSnapshot = computeSnap();
|
|
59
|
+
return {
|
|
60
|
+
subscribe: (onStoreChange) => {
|
|
61
|
+
let disposed = false;
|
|
62
|
+
let entrySubs = [];
|
|
63
|
+
const cleanupEntries = () => {
|
|
64
|
+
for (const unsub of entrySubs) unsub();
|
|
65
|
+
entrySubs = [];
|
|
66
|
+
};
|
|
67
|
+
const sync = (nextKeys) => {
|
|
68
|
+
cleanupEntries();
|
|
69
|
+
for (const key of nextKeys) {
|
|
70
|
+
const nodes = factoryRef.current(key);
|
|
71
|
+
for (const field of Object.keys(nodes)) {
|
|
72
|
+
const unsub = nodes[field].subscribe(() => {
|
|
73
|
+
currentSnapshot = computeSnap();
|
|
74
|
+
if (!disposed) onStoreChange();
|
|
75
|
+
});
|
|
76
|
+
entrySubs.push(unsub);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
currentSnapshot = computeSnap();
|
|
80
|
+
if (!disposed) onStoreChange();
|
|
81
|
+
};
|
|
82
|
+
const keysUnsub = keysNode.subscribe((msgs) => {
|
|
83
|
+
const hasSettled = msgs.some((m) => m[0] === DATA || m[0] === RESOLVED);
|
|
84
|
+
if (!disposed && hasSettled) sync(keysNode.cache ?? []);
|
|
85
|
+
});
|
|
86
|
+
sync(keysNode.cache ?? []);
|
|
87
|
+
return () => {
|
|
88
|
+
disposed = true;
|
|
89
|
+
keysUnsub();
|
|
90
|
+
cleanupEntries();
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
getSnapshot: () => currentSnapshot
|
|
94
|
+
};
|
|
95
|
+
}, [keysNode]);
|
|
96
|
+
return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export {
|
|
100
|
+
useSubscribe,
|
|
101
|
+
useStore,
|
|
102
|
+
useSubscribeRecord,
|
|
103
|
+
react_exports
|
|
104
|
+
};
|
|
105
|
+
//# sourceMappingURL=chunk-3MUSLI6E.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/compat/react/index.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// React bindings — useStore / useSubscribe\n// ---------------------------------------------------------------------------\n// Bridges GraphReFly nodes into React via useSyncExternalStore.\n// Works with any Node<T>, including companion nodes (node.meta.status).\n//\n// Usage:\n// import { useStore, useSubscribe } from '@graphrefly/graphrefly-ts/compat/react';\n// // Optional peer install (only for this adapter): pnpm add react react-dom\n// const value = useSubscribe(myNode); // T | undefined (read-only)\n// const [count, setCount] = useStore(counter); // [T | undefined, setter]\n// ---------------------------------------------------------------------------\n\nimport { DATA, DIRTY, type Messages, type Node, RESOLVED } from \"@graphrefly/pure-ts/core\";\nimport { useCallback, useMemo, useRef, useSyncExternalStore } from \"react\";\n\n/**\n * Subscribe to a read-only `Node<T>` as a React value. Re-renders on node value settlement.\n * Subscription lifecycle is tied to React mount/unmount (not node terminal messages).\n *\n * @param node - Any `Node<T>`.\n * @returns `T | undefined` — the current node value, kept in sync via `useSyncExternalStore`.\n */\nexport function useSubscribe<T>(node: Node<T>): T | undefined | null {\n\treturn useSyncExternalStore(\n\t\t(onStoreChange) => {\n\t\t\tlet disposed = false;\n\t\t\tconst unsub = node.subscribe(() => {\n\t\t\t\tif (!disposed) onStoreChange();\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tdisposed = true;\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\t() => node.cache,\n\t\t() => node.cache, // Server snapshot\n\t);\n}\n\n/**\n * Bind a writable `Node<T>` as a React `[value, setter]` tuple.\n * Setting the value always pushes `[[DIRTY], [DATA, value]]`, including `value === undefined`.\n * Subscription lifecycle is tied to React mount/unmount (not node terminal messages).\n *\n * @param node - A `Node<T>` (e.g. state node).\n * @returns `[T | undefined, (value: T) => void]` — current value and setter function.\n */\nexport function useStore<T>(node: Node<T>): [T | undefined | null, (value: T) => void] {\n\tconst value = useSubscribe(node);\n\tconst setter = useCallback(\n\t\t(v: T) => {\n\t\t\tnode.down([[DIRTY], [DATA, v]]);\n\t\t},\n\t\t[node],\n\t);\n\treturn [value, setter];\n}\n\n/** Maps a key to an object of nodes. Used by `useSubscribeRecord`. */\nexport type NodeFactory<K, R extends Record<string, any>> = (key: K) => {\n\t[P in keyof R]: Node<R[P]>;\n};\n\n/**\n * Subscribe to a dynamic set of keyed node records.\n * Re-subscribes all per-key fields whenever `keysNode` changes.\n * Key re-sync is gated to settled batches (`messageTier >= 3`) to avoid DIRTY-phase churn.\n * Guaranteed to clean up strictly with React hook lifecycle, utilizing no global mappings.\n *\n * @param keysNode - Node of current keys (e.g. node IDs)\n * @param factory - Function returning `{ [field]: Node<V> }` for each key.\n * @returns `Record<K, R>` — snapshot of resolved values for all keys.\n */\nexport function useSubscribeRecord<K extends string, R extends Record<string, any>>(\n\tkeysNode: Node<K[]>,\n\tfactory: NodeFactory<K, R>,\n): Record<K, R> {\n\tconst factoryRef = useRef(factory);\n\tfactoryRef.current = factory;\n\n\tconst store = useMemo(() => {\n\t\tconst computeSnap = () => {\n\t\t\tconst snap = {} as Record<K, R>;\n\t\t\tconst keys = keysNode.cache ?? [];\n\t\t\tfor (const key of keys) {\n\t\t\t\tconst nodes = factoryRef.current(key);\n\t\t\t\tconst values = {} as R;\n\t\t\t\tfor (const field of Object.keys(nodes) as (keyof R)[]) {\n\t\t\t\t\tvalues[field] = nodes[field].cache as R[keyof R];\n\t\t\t\t}\n\t\t\t\tsnap[key] = values;\n\t\t\t}\n\t\t\treturn snap;\n\t\t};\n\n\t\tlet currentSnapshot = computeSnap();\n\n\t\treturn {\n\t\t\tsubscribe: (onStoreChange: () => void) => {\n\t\t\t\tlet disposed = false;\n\t\t\t\tlet entrySubs: Array<() => void> = [];\n\n\t\t\t\tconst cleanupEntries = () => {\n\t\t\t\t\tfor (const unsub of entrySubs) unsub();\n\t\t\t\t\tentrySubs = [];\n\t\t\t\t};\n\n\t\t\t\tconst sync = (nextKeys: K[]) => {\n\t\t\t\t\tcleanupEntries();\n\t\t\t\t\tfor (const key of nextKeys) {\n\t\t\t\t\t\tconst nodes = factoryRef.current(key);\n\t\t\t\t\t\tfor (const field of Object.keys(nodes) as (keyof R)[]) {\n\t\t\t\t\t\t\tconst unsub = nodes[field].subscribe(() => {\n\t\t\t\t\t\t\t\tcurrentSnapshot = computeSnap();\n\t\t\t\t\t\t\t\tif (!disposed) onStoreChange();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tentrySubs.push(unsub);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcurrentSnapshot = computeSnap();\n\t\t\t\t\tif (!disposed) onStoreChange();\n\t\t\t\t};\n\n\t\t\t\tconst keysUnsub = keysNode.subscribe((msgs: Messages) => {\n\t\t\t\t\tconst hasSettled = msgs.some((m) => m[0] === DATA || m[0] === RESOLVED);\n\t\t\t\t\tif (!disposed && hasSettled) sync(keysNode.cache ?? []);\n\t\t\t\t});\n\t\t\t\tsync(keysNode.cache ?? []);\n\n\t\t\t\treturn () => {\n\t\t\t\t\tdisposed = true;\n\t\t\t\t\tkeysUnsub();\n\t\t\t\t\tcleanupEntries();\n\t\t\t\t};\n\t\t\t},\n\t\t\tgetSnapshot: () => currentSnapshot,\n\t\t};\n\t}, [keysNode]);\n\n\treturn useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);\n}\n"],"mappings":";;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,SAAS,MAAM,OAAiC,gBAAgB;AAChE,SAAS,aAAa,SAAS,QAAQ,4BAA4B;AAS5D,SAAS,aAAgB,MAAqC;AACpE,SAAO;AAAA,IACN,CAAC,kBAAkB;AAClB,UAAI,WAAW;AACf,YAAM,QAAQ,KAAK,UAAU,MAAM;AAClC,YAAI,CAAC,SAAU,eAAc;AAAA,MAC9B,CAAC;AACD,aAAO,MAAM;AACZ,mBAAW;AACX,cAAM;AAAA,MACP;AAAA,IACD;AAAA,IACA,MAAM,KAAK;AAAA,IACX,MAAM,KAAK;AAAA;AAAA,EACZ;AACD;AAUO,SAAS,SAAY,MAA2D;AACtF,QAAM,QAAQ,aAAa,IAAI;AAC/B,QAAM,SAAS;AAAA,IACd,CAAC,MAAS;AACT,WAAK,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,IAC/B;AAAA,IACA,CAAC,IAAI;AAAA,EACN;AACA,SAAO,CAAC,OAAO,MAAM;AACtB;AAiBO,SAAS,mBACf,UACA,SACe;AACf,QAAM,aAAa,OAAO,OAAO;AACjC,aAAW,UAAU;AAErB,QAAM,QAAQ,QAAQ,MAAM;AAC3B,UAAM,cAAc,MAAM;AACzB,YAAM,OAAO,CAAC;AACd,YAAM,OAAO,SAAS,SAAS,CAAC;AAChC,iBAAW,OAAO,MAAM;AACvB,cAAM,QAAQ,WAAW,QAAQ,GAAG;AACpC,cAAM,SAAS,CAAC;AAChB,mBAAW,SAAS,OAAO,KAAK,KAAK,GAAkB;AACtD,iBAAO,KAAK,IAAI,MAAM,KAAK,EAAE;AAAA,QAC9B;AACA,aAAK,GAAG,IAAI;AAAA,MACb;AACA,aAAO;AAAA,IACR;AAEA,QAAI,kBAAkB,YAAY;AAElC,WAAO;AAAA,MACN,WAAW,CAAC,kBAA8B;AACzC,YAAI,WAAW;AACf,YAAI,YAA+B,CAAC;AAEpC,cAAM,iBAAiB,MAAM;AAC5B,qBAAW,SAAS,UAAW,OAAM;AACrC,sBAAY,CAAC;AAAA,QACd;AAEA,cAAM,OAAO,CAAC,aAAkB;AAC/B,yBAAe;AACf,qBAAW,OAAO,UAAU;AAC3B,kBAAM,QAAQ,WAAW,QAAQ,GAAG;AACpC,uBAAW,SAAS,OAAO,KAAK,KAAK,GAAkB;AACtD,oBAAM,QAAQ,MAAM,KAAK,EAAE,UAAU,MAAM;AAC1C,kCAAkB,YAAY;AAC9B,oBAAI,CAAC,SAAU,eAAc;AAAA,cAC9B,CAAC;AACD,wBAAU,KAAK,KAAK;AAAA,YACrB;AAAA,UACD;AACA,4BAAkB,YAAY;AAC9B,cAAI,CAAC,SAAU,eAAc;AAAA,QAC9B;AAEA,cAAM,YAAY,SAAS,UAAU,CAAC,SAAmB;AACxD,gBAAM,aAAa,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,QAAQ,EAAE,CAAC,MAAM,QAAQ;AACtE,cAAI,CAAC,YAAY,WAAY,MAAK,SAAS,SAAS,CAAC,CAAC;AAAA,QACvD,CAAC;AACD,aAAK,SAAS,SAAS,CAAC,CAAC;AAEzB,eAAO,MAAM;AACZ,qBAAW;AACX,oBAAU;AACV,yBAAe;AAAA,QAChB;AAAA,MACD;AAAA,MACA,aAAa,MAAM;AAAA,IACpB;AAAA,EACD,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO,qBAAqB,MAAM,WAAW,MAAM,aAAa,MAAM,WAAW;AAClF;","names":[]}
|