diff --git a/AGENTS.md b/AGENTS.md index 71dbbc9..779137b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -119,7 +119,7 @@ The repo is wired up with `@effect/language-service` as a `tsconfig.json` `plugi ## Effect Observability Guidance - Inspect the target repo’s existing Effect runtime and observability wiring before adding anything new. - Prefer the repo’s existing Effect-native observability APIs if available. -- If `effect/unstable/observability` is already the best fit, prefer it over adding `@effect/opentelemetry`. +- If `effect/observability` is already the best fit, prefer it over adding `@effect/opentelemetry`. - Only add new OpenTelemetry SDK packages when the repo already uses them or they are clearly required. - Merge telemetry into the main runtime once, not per-feature. - Prefer structured log annotations so fields like `sessionID`, `modelID`, `providerID`, and `tool` are queryable. diff --git a/bun.lock b/bun.lock index 3fc9eca..fafb5d4 100644 --- a/bun.lock +++ b/bun.lock @@ -5,9 +5,9 @@ "": { "name": "motel", "dependencies": { - "@effect/atom-react": "4.0.0-beta.90", - "@effect/opentelemetry": "4.0.0-beta.90", - "@effect/platform-bun": "4.0.0-beta.90", + "@effect/atom-react": "4.0.1", + "@effect/opentelemetry": "4.0.1", + "@effect/platform-bun": "4.0.1", "@opentelemetry/api": "^1.9.0", "@opentelemetry/exporter-logs-otlp-http": "^0.219.0", "@opentelemetry/exporter-trace-otlp-http": "^0.219.0", @@ -18,7 +18,7 @@ "@opentelemetry/sdk-trace-node": "^2.8.0", "@opentui/core": "0.4.2", "@opentui/react": "0.4.2", - "effect": "4.0.0-beta.90", + "effect": "4.0.1", "protobufjs": "7.6.4", "react": "^19.2.7", "scheduler": "^0.27.0", @@ -33,10 +33,10 @@ "web": { "name": "motel-web", "dependencies": { - "@effect/atom-react": "4.0.0-beta.90", + "@effect/atom-react": "4.0.1", "@tailwindcss/vite": "^4.3.1", "@tanstack/react-virtual": "^3.14.3", - "effect": "4.0.0-beta.90", + "effect": "4.0.1", "react": "^19.2.7", "react-dom": "^19.2.7", "react-router-dom": "^7.18.0", @@ -59,15 +59,15 @@ "ws": "8.21.0", }, "packages": { - "@effect/atom-react": ["@effect/atom-react@4.0.0-beta.90", "", { "peerDependencies": { "effect": "^4.0.0-beta.90", "react": "^19.2.4", "scheduler": "*" } }, "sha512-E1GFtNT+ZeIA3//g+IcbaAfjVAn5VZ08q4/MTEEV/862AlCfia8nRETJqpvVcTEK4X6EnebjTXdWu7tTV9wggg=="], + "@effect/atom-react": ["@effect/atom-react@4.0.1", "", { "peerDependencies": { "effect": "^4.0.1", "react": ">=19.0.0 <20.0.0", "scheduler": ">=0.25.0 <0.28.0" } }, "sha512-V/vcbFCVY2AV7PvjhmOP37Cr4NofrtxBBGW6M1ckBIBxmpi3sMwdPTxj2obPNE4Ho3gkeEQzRC9zEIQ4BDNdQg=="], "@effect/language-service": ["@effect/language-service@0.86.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-SaPln+8srOqDJDUwNTDmP5e+IYpEDr9+1epGznnsLqu8xvo6VnxyWARdeLpqvZJlb0Pgy9ca7ppqvvdWbHPXAg=="], - "@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.90", "", { "peerDependencies": { "@opentelemetry/api": "^1.9", "@opentelemetry/api-logs": ">=0.203.0 <0.300.0", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": "^2.0.0", "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/sdk-trace-node": "^2.0.0", "@opentelemetry/sdk-trace-web": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.33.0", "effect": "^4.0.0-beta.90" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/api-logs", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-PGThhkj60NKX6HkKXDEmmmVTc8dxedP8XurE+eM1n+eGOQ2wMxLLnFLBEoGCrnyLFo6gG1tHPsSRcJMfUyP2QA=="], + "@effect/opentelemetry": ["@effect/opentelemetry@4.0.1", "", { "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <2.0.0", "@opentelemetry/api-logs": ">=0.203.0 <0.300.0", "@opentelemetry/resources": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-base": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-node": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-web": ">=2.0.0 <3.0.0", "@opentelemetry/semantic-conventions": ">=1.33.0 <2.0.0", "effect": "^4.0.1" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/api-logs", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-MZ7M1a1dxMqTqeNwIGSECjO7RrReEgeEwHo8BnbOqP+8IfVpdiJi/iPCmkFVWlAxanMl4qhsq69e0Hkul9t+bA=="], - "@effect/platform-bun": ["@effect/platform-bun@4.0.0-beta.90", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.90" }, "peerDependencies": { "effect": "^4.0.0-beta.90" } }, "sha512-EL6IVL8+HcrldPcJvQLXtj6kwsM5RZ57PqY54mPE5B+KSbNmT5T04Kuso6PAnl8tQtiOqLI8X+RG6fyKXggwjQ=="], + "@effect/platform-bun": ["@effect/platform-bun@4.0.1", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.1" }, "peerDependencies": { "effect": "^4.0.1" } }, "sha512-m+QR4bp39ZWujCuEsUhZADIYIOFZcUHHlmrixENZqZRbEYgaPLMUWiPrRJ69CM4BuuHW8oCOxfMGUU7oSw/o5g=="], - "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.90", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.20.0" }, "peerDependencies": { "effect": "^4.0.0-beta.90" } }, "sha512-0UlZgqJdAjcEr6RtLSqeOtTBeuLO03cTX4FKpzW1nTCScz3wGpELgcaU/T+fURf4LBiD0QQS3tcOYTN/T+qFsw=="], + "@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.1", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.22.0" }, "peerDependencies": { "effect": "^4.0.1" } }, "sha512-VanaejudEhKJ4mpmqnEzdncVUhN6sGSO9ZDND54mRxAlZxj+4dYAWjDTYAy9o4tJo9aALeP2U8cVcOFzEdSeLg=="], "@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], @@ -91,18 +91,6 @@ "@js-sdsl/ordered-map": ["@js-sdsl/ordered-map@4.4.2", "", {}, "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw=="], - "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ=="], - - "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w=="], - - "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw=="], - - "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw=="], - - "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ=="], - - "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="], "@opentelemetry/api": ["@opentelemetry/api@1.9.1", "", {}, "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q=="], @@ -235,8 +223,6 @@ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="], - "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@tailwindcss/node": ["@tailwindcss/node@4.3.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "5.21.6", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.1" } }, "sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A=="], "@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.1", "@tailwindcss/oxide-darwin-arm64": "4.3.1", "@tailwindcss/oxide-darwin-x64": "4.3.1", "@tailwindcss/oxide-freebsd-x64": "4.3.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.1", "@tailwindcss/oxide-linux-arm64-musl": "4.3.1", "@tailwindcss/oxide-linux-x64-gnu": "4.3.1", "@tailwindcss/oxide-linux-x64-musl": "4.3.1", "@tailwindcss/oxide-wasm32-wasi": "4.3.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.1", "@tailwindcss/oxide-win32-x64-msvc": "4.3.1" } }, "sha512-yVPyo8RNkabVr3O2EhHEE0Rewu7YKzc1DhIqfL46LKveFrmu9XbDazNOJY7/GRuvw1h6u3utWnR29H/p5JPlgA=="], @@ -315,7 +301,7 @@ "diff": ["diff@9.0.0", "", {}, "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw=="], - "effect": ["effect@4.0.0-beta.90", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-A0U3OE+2oyK/iFG6VYbFj9gwjJ7rFXjgP7qV+m7n/4lOREp9Lfk1///SlGCpX7HRueOCZO1l7aW0KByXuJeiPA=="], + "effect": ["effect@4.0.1", "", {}, "sha512-b1VlQG9g8fwxE5QnIZuPoOP/0MsqHJSRKxUijjoM80E5q95FXrX5yWtY5XI8G+GJsBQAVSDbLS458z9a++uVvw=="], "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], @@ -323,12 +309,8 @@ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], - "fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="], - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], - "find-my-way-ts": ["find-my-way-ts@0.1.6", "", {}, "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA=="], - "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], @@ -339,13 +321,9 @@ "import-in-the-middle": ["import-in-the-middle@3.0.1", "", { "dependencies": { "acorn": "^8.15.0", "acorn-import-attributes": "^1.9.5", "cjs-module-lexer": "^2.2.0", "module-details-from-path": "^1.0.4" } }, "sha512-pYkiyXVL2Mf3pozdlDGV6NAObxQx13Ae8knZk1UJRJ6uRW/ZRmTGHlQYtrsSl7ubuE5F8CD1z+s1n4RHNuTtuA=="], - "ini": ["ini@7.0.0", "", {}, "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w=="], - "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], - "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - - "kubernetes-types": ["kubernetes-types@1.30.0", "", {}, "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q=="], + "jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], @@ -385,16 +363,8 @@ "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], - - "msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="], - - "multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="], - "nanoid": ["nanoid@3.3.15", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA=="], - "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], - "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], @@ -403,8 +373,6 @@ "protobufjs": ["protobufjs@7.6.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw=="], - "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], - "react": ["react@19.2.7", "", {}, "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ=="], "react-devtools-core": ["react-devtools-core@7.0.1", "", { "dependencies": { "shell-quote": "^1.6.1", "ws": "^7" } }, "sha512-C3yNvRHaizlpiASzy7b9vbnBGLrhvdhl1CbdU6EnZgxPNbai60szdLtl+VL76UNOt5bOoVTOz5rNWZxgGt+Gsw=="], @@ -441,16 +409,12 @@ "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], - "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="], "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], - "uuid": ["uuid@14.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew=="], - "vite": ["vite@8.1.0", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.4", "postcss": "^8.5.15", "rolldown": "~1.1.2", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q=="], "web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="], @@ -461,14 +425,12 @@ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], - "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], + "yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], - "@opentelemetry/configuration/yaml": ["yaml@2.8.3", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg=="], - "@opentelemetry/exporter-logs-otlp-grpc/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.219.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.219.0", "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0", "@opentelemetry/sdk-logs": "0.219.0", "@opentelemetry/sdk-metrics": "2.8.0", "@opentelemetry/sdk-trace-base": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-aaYKAyXhw9VchKZVGOopD3Gw/kPsyrX2c6IQ0AW32mTjqmZOh5Y6Gf5OYqTNqVktAeBjmFinhyFaCwW6GYK9YQ=="], "@opentelemetry/exporter-logs-otlp-http/@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.219.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.219.0", "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0", "@opentelemetry/sdk-logs": "0.219.0", "@opentelemetry/sdk-metrics": "2.8.0", "@opentelemetry/sdk-trace-base": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-aaYKAyXhw9VchKZVGOopD3Gw/kPsyrX2c6IQ0AW32mTjqmZOh5Y6Gf5OYqTNqVktAeBjmFinhyFaCwW6GYK9YQ=="], @@ -515,8 +477,6 @@ "@opentelemetry/sdk-node/@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.8.0", "", { "dependencies": { "@opentelemetry/core": "2.8.0", "@opentelemetry/resources": "2.8.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "sha512-UDBGaj6W0Rgy5rTTaoxs8gVGF/aGkAKyjurJv7se6wjRxJu7FoquTLT/vt54DZfo4crbprYfhX/SOK9+BPw1qg=="], - "@tailwindcss/node/jiti": ["jiti@2.7.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="], diff --git a/package.json b/package.json index 718a599..8a9c21c 100644 --- a/package.json +++ b/package.json @@ -92,9 +92,9 @@ "typescript": "^6.0.3" }, "dependencies": { - "@effect/atom-react": "4.0.0-beta.90", - "@effect/opentelemetry": "4.0.0-beta.90", - "@effect/platform-bun": "4.0.0-beta.90", + "@effect/atom-react": "4.0.1", + "@effect/opentelemetry": "4.0.1", + "@effect/platform-bun": "4.0.1", "@opentelemetry/api": "^1.9.0", "@opentelemetry/exporter-logs-otlp-http": "^0.219.0", "@opentelemetry/exporter-trace-otlp-http": "^0.219.0", @@ -105,7 +105,7 @@ "@opentelemetry/sdk-trace-node": "^2.8.0", "@opentui/core": "0.4.2", "@opentui/react": "0.4.2", - "effect": "4.0.0-beta.90", + "effect": "4.0.1", "protobufjs": "7.6.4", "react": "^19.2.7", "scheduler": "^0.27.0" diff --git a/skills/motel-debug/references/effect.md b/skills/motel-debug/references/effect.md index 6dcff09..38906c4 100644 --- a/skills/motel-debug/references/effect.md +++ b/skills/motel-debug/references/effect.md @@ -6,7 +6,7 @@ Apply these only when the target repo already uses Effect or `@effect/*`. - Inspect the existing runtime and observability wiring before adding anything new. - Prefer the repo's existing Effect-native observability APIs if they already exist. -- If `effect/unstable/observability` is already the best fit, prefer it over adding new OTEL packages. +- If `effect/observability` is already the best fit, prefer it over adding new OTEL packages. - Merge telemetry into the main runtime once, not per feature or per request path. ## Instrumentation diff --git a/src/httpApi.ts b/src/httpApi.ts index 69f24f6..1cb141a 100644 --- a/src/httpApi.ts +++ b/src/httpApi.ts @@ -1,5 +1,5 @@ import { Schema } from "effect" -import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/unstable/httpapi" +import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/http-api" import { AiCallSummary, AiCallDetail, FacetItem, StatsItem, TraceSpanStatus, diff --git a/src/localServer.ts b/src/localServer.ts index eb0f1f7..7a5eb66 100644 --- a/src/localServer.ts +++ b/src/localServer.ts @@ -1,11 +1,11 @@ import path from "node:path" import { Effect, FileSystem, Layer } from "effect" import { config } from "./config.js" -import { HttpApiBuilder, HttpApiScalar } from "effect/unstable/httpapi" -import * as HttpMiddleware from "effect/unstable/http/HttpMiddleware" -import * as HttpRouter from "effect/unstable/http/HttpRouter" -import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse" -import * as HttpStaticServer from "effect/unstable/http/HttpStaticServer" +import { HttpApiBuilder, HttpApiScalar } from "effect/http-api" +import * as HttpMiddleware from "effect/http/HttpMiddleware" +import * as HttpRouter from "effect/http/HttpRouter" +import * as HttpServerResponse from "effect/http/HttpServerResponse" +import * as HttpStaticServer from "effect/http/HttpStaticServer" import * as BunHttpServer from "@effect/platform-bun/BunHttpServer" import { MotelHttpApi } from "./httpApi.js" import { AI_LIST, LOG_LIST, LOG_STATS, SPAN_LIST, TRACE_LIST, TRACE_STATS, listMeta, logCursorArgs, paginateLogs, paginateSummaries, parseLimit, parseListParams as decodeListParams, parseLookbackMinutes, requestUrl as decodeRequestUrl, traceCursorArgs, type ListBounds, type ListParams } from "./httpListPolicy.js" diff --git a/src/mcp.ts b/src/mcp.ts index 9edee14..6ec178f 100755 --- a/src/mcp.ts +++ b/src/mcp.ts @@ -2,7 +2,7 @@ import { BunRuntime, BunStdio } from "@effect/platform-bun" import { Effect, Layer, Logger, Schema } from "effect" import { MOTEL_VERSION } from "./registry.js" -import { McpServer, Tool, Toolkit } from "effect/unstable/ai" +import { McpProtocol, McpServer, Tool, Toolkit } from "effect/ai" import { TraceSpanStatus } from "./domain.js" import { MotelClient, MotelClientLive } from "./motelClient.js" import { Locator, LocatorLive } from "./locator.js" @@ -424,10 +424,12 @@ const ServerLayer = McpServer.toolkit(MotelToolkit).pipe( McpServer.layerStdio({ name: "motel", version: MOTEL_VERSION, + protocols: [McpProtocol.v2025_11_25, McpProtocol.v2025_06_18, McpProtocol.v2025_03_26, McpProtocol.v2024_11_05], }), ), Layer.provide(BunStdio.layer), - Layer.provide(Logger.layer([Logger.consolePretty({ stderr: true })])), + Layer.provide(Logger.layer([Logger.consolePretty()])), + Layer.provide(Layer.succeed(Logger.LogToStderr, true)), ) Layer.launch(ServerLayer).pipe(BunRuntime.runMain) diff --git a/src/services/AsyncIngest.ts b/src/services/AsyncIngest.ts index 03f46c7..5611bf2 100644 --- a/src/services/AsyncIngest.ts +++ b/src/services/AsyncIngest.ts @@ -21,10 +21,9 @@ import * as BunWorker from "@effect/platform-bun/BunWorker" import { Context, Duration, Effect, Exit, Layer, Scope } from "effect" -import * as RpcClient from "effect/unstable/rpc/RpcClient" -import type { RpcClientError } from "effect/unstable/rpc/RpcClientError" -import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization" -import type { WorkerError } from "effect/unstable/workers/WorkerError" +import * as RpcClient from "effect/rpc/RpcClient" +import type { RpcClientError } from "effect/rpc/RpcClientError" +import type { WorkerError } from "effect/workers/WorkerError" import { IngestRpcs } from "./ingestRpc.ts" // RpcClient.make always surfaces RpcClientError in addition to the @@ -38,10 +37,9 @@ export class AsyncIngest extends Context.Service< >()("@motel/AsyncIngest") {} // Protocol: RpcClient.layerProtocolWorker manages a worker pool and -// speaks msgpack over structured-clone messages. `size: 1` matches +// speaks over structured-clone messages. `size: 1` matches // SQLite's single-writer constraint. const WorkerProtocol = RpcClient.layerProtocolWorker({ size: 1 }).pipe( - Layer.provide(RpcSerialization.layerMsgPack), Layer.provide( BunWorker.layer(() => new Worker(new URL("./telemetryWorker.ts", import.meta.url))), ), diff --git a/src/services/TelemetryQuery.ts b/src/services/TelemetryQuery.ts index 41d8ba0..3d2ba1c 100644 --- a/src/services/TelemetryQuery.ts +++ b/src/services/TelemetryQuery.ts @@ -1,18 +1,16 @@ import * as BunWorker from "@effect/platform-bun/BunWorker" import { Duration, Effect, Exit, Layer, Scope } from "effect" -import * as RpcClient from "effect/unstable/rpc/RpcClient" -import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization" -import type { WorkerError } from "effect/unstable/workers/WorkerError" -import type { RpcClientError } from "effect/unstable/rpc/RpcClientError" +import * as RpcClient from "effect/rpc/RpcClient" +import type { WorkerError } from "effect/workers/WorkerError" +import type { RpcClientError } from "effect/rpc/RpcClientError" import { TelemetryStoreReadonly, type TelemetryStoreReader } from "./TelemetryStore.js" import { QueryRpcs } from "./queryRpc.js" type QueryMethod = keyof TelemetryStoreReader type QueryClient = RpcClient.FromGroup -type QueryClientEntry = { readonly client: QueryClient; readonly clientScope: Scope.Scope } +type QueryClientEntry = { readonly client: QueryClient; readonly clientScope: Scope.Closeable } const WorkerProtocol = RpcClient.layerProtocolWorker({ size: 1 }).pipe( - Layer.provide(RpcSerialization.layerMsgPack), Layer.provide(BunWorker.layer(() => new Worker(new URL("./telemetryQueryWorker.ts", import.meta.url)))), ) diff --git a/src/services/ingestRpc.ts b/src/services/ingestRpc.ts index 588d0b4..ef0bdf1 100644 --- a/src/services/ingestRpc.ts +++ b/src/services/ingestRpc.ts @@ -8,7 +8,7 @@ * seconds at a time. Read-only TelemetryStore methods use the separate * query RPC worker so no synchronous SQLite call runs on the HTTP thread. * - * Payloads are typed as Schema.Unknown because OTLP's protobuf-JSON + * Payloads are typed as StructuredClone (a pass-through) because OTLP's protobuf-JSON * shape is enormous and nested — the store validates structurally * during the actual insert loop, and serialising a schema through * the worker boundary would add overhead that beats the purpose of @@ -18,21 +18,22 @@ */ import { Schema } from "effect" -import * as Rpc from "effect/unstable/rpc/Rpc" -import * as RpcGroup from "effect/unstable/rpc/RpcGroup" +import * as Rpc from "effect/rpc/Rpc" +import * as RpcGroup from "effect/rpc/RpcGroup" +import { StructuredClone } from "./rpcSchema.js" -export class IngestError extends Schema.TaggedErrorClass()("IngestError", { +export class IngestError extends Schema.TaggedError()("IngestError", { message: Schema.String, }) {} export const IngestRpcs = RpcGroup.make( Rpc.make("ingestTraces", { - payload: { payload: Schema.Unknown }, + payload: { payload: StructuredClone }, success: Schema.Struct({ insertedSpans: Schema.Number }), error: IngestError, }), Rpc.make("ingestLogs", { - payload: { payload: Schema.Unknown }, + payload: { payload: StructuredClone }, success: Schema.Struct({ insertedLogs: Schema.Number }), error: IngestError, }), diff --git a/src/services/queryRpc.ts b/src/services/queryRpc.ts index 794df56..38a00fa 100644 --- a/src/services/queryRpc.ts +++ b/src/services/queryRpc.ts @@ -1,15 +1,16 @@ import { Schema } from "effect" -import * as Rpc from "effect/unstable/rpc/Rpc" -import * as RpcGroup from "effect/unstable/rpc/RpcGroup" +import * as Rpc from "effect/rpc/Rpc" +import * as RpcGroup from "effect/rpc/RpcGroup" +import { StructuredClone } from "./rpcSchema.js" -export class QueryError extends Schema.TaggedErrorClass()("QueryError", { +export class QueryError extends Schema.TaggedError()("QueryError", { message: Schema.String, }) {} export const QueryRpcs = RpcGroup.make( Rpc.make("query", { - payload: { method: Schema.String, args: Schema.Array(Schema.Unknown) }, - success: Schema.Unknown, + payload: { method: Schema.String, args: Schema.Array(StructuredClone) }, + success: StructuredClone, error: QueryError, }), ) diff --git a/src/services/rpcSchema.ts b/src/services/rpcSchema.ts new file mode 100644 index 0000000..d6fe800 --- /dev/null +++ b/src/services/rpcSchema.ts @@ -0,0 +1,6 @@ +import { Schema } from "effect" + +// Worker RPC encodes with the JSON codec, which walks the whole value and +// rejects `Date`, `undefined`, non-finite numbers, etc. Worker messages travel +// via structured clone, so pass values through untouched. +export const StructuredClone = Schema.declare((_: unknown): _ is unknown => true, { toCodecJson: () => undefined }) diff --git a/src/services/telemetryQueryWorker.ts b/src/services/telemetryQueryWorker.ts index a179101..4ce96d2 100644 --- a/src/services/telemetryQueryWorker.ts +++ b/src/services/telemetryQueryWorker.ts @@ -1,8 +1,7 @@ import { BunRuntime } from "@effect/platform-bun" import * as BunWorkerRunner from "@effect/platform-bun/BunWorkerRunner" import { Effect, Layer } from "effect" -import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization" -import * as RpcServer from "effect/unstable/rpc/RpcServer" +import * as RpcServer from "effect/rpc/RpcServer" import { TelemetryStoreQueryWorkerLive, TelemetryStoreReadonly, type TelemetryStoreReader } from "./TelemetryStore.js" import { QueryError, QueryRpcs } from "./queryRpc.js" @@ -25,7 +24,6 @@ const WorkerLive = RpcServer.layer(QueryRpcs).pipe( Layer.provide(QueryHandlers), Layer.provide(TelemetryStoreQueryWorkerLive), Layer.provide(RpcServer.layerProtocolWorkerRunner), - Layer.provide(RpcSerialization.layerMsgPack), Layer.provide(BunWorkerRunner.layer), ) diff --git a/src/services/telemetryWorker.ts b/src/services/telemetryWorker.ts index 81af541..8f83967 100644 --- a/src/services/telemetryWorker.ts +++ b/src/services/telemetryWorker.ts @@ -17,8 +17,7 @@ import { BunRuntime } from "@effect/platform-bun" import * as BunWorkerRunner from "@effect/platform-bun/BunWorkerRunner" import { Effect, Layer } from "effect" -import * as RpcSerialization from "effect/unstable/rpc/RpcSerialization" -import * as RpcServer from "effect/unstable/rpc/RpcServer" +import * as RpcServer from "effect/rpc/RpcServer" import type { OtlpLogExportRequest, OtlpTraceExportRequest } from "../otlp.ts" import { IngestError, IngestRpcs } from "./ingestRpc.ts" import { TelemetryStore, TelemetryStoreWorkerLive } from "./TelemetryStore.ts" @@ -49,7 +48,6 @@ const WorkerLive = RpcServer.layer(IngestRpcs).pipe( Layer.provide(IngestHandlers), Layer.provide(TelemetryStoreWorkerLive), Layer.provide(RpcServer.layerProtocolWorkerRunner), - Layer.provide(RpcSerialization.layerMsgPack), Layer.provide(BunWorkerRunner.layer), ) diff --git a/src/ui/aiState.ts b/src/ui/aiState.ts index f568d31..73a7ff3 100644 --- a/src/ui/aiState.ts +++ b/src/ui/aiState.ts @@ -1,5 +1,5 @@ import { Effect } from "effect" -import * as Atom from "effect/unstable/reactivity/Atom" +import * as Atom from "effect/reactivity/Atom" import type { AiCallDetail } from "../domain.ts" import { queryRuntime } from "../runtime.ts" import { TelemetryStoreReadonly } from "../services/TelemetryStore.ts" diff --git a/src/ui/atoms.ts b/src/ui/atoms.ts index 900218d..d10845b 100644 --- a/src/ui/atoms.ts +++ b/src/ui/atoms.ts @@ -1,4 +1,4 @@ -import * as Atom from "effect/unstable/reactivity/Atom" +import * as Atom from "effect/reactivity/Atom" import { config, explicitServiceName } from "../config.ts" import type { LogItem, TraceItem, TraceSummaryItem } from "../domain.ts" import type { ThemeName } from "./theme.ts" diff --git a/src/ui/serviceSelection.test.ts b/src/ui/serviceSelection.test.ts index c1ba5bf..8ca1231 100644 --- a/src/ui/serviceSelection.test.ts +++ b/src/ui/serviceSelection.test.ts @@ -20,7 +20,7 @@ describe("initial TUI service selection", () => { // Fresh processes exercise import-time config and persistence without module-cache leakage. const result = Bun.spawnSync([process.execPath, "--no-env-file", "--eval", ` - import * as AtomRegistry from "effect/unstable/reactivity/AtomRegistry" + import * as AtomRegistry from "effect/reactivity/AtomRegistry" import { config } from "./src/config.ts" import { selectedTraceServiceAtom } from "./src/ui/atoms.ts" const registry = AtomRegistry.make() diff --git a/web/package.json b/web/package.json index aa8a4cb..3f293b8 100644 --- a/web/package.json +++ b/web/package.json @@ -8,10 +8,10 @@ "preview": "vite preview" }, "dependencies": { - "@effect/atom-react": "4.0.0-beta.90", + "@effect/atom-react": "4.0.1", "@tailwindcss/vite": "^4.3.1", "@tanstack/react-virtual": "^3.14.3", - "effect": "4.0.0-beta.90", + "effect": "4.0.1", "react": "^19.2.7", "react-dom": "^19.2.7", "react-router-dom": "^7.18.0", diff --git a/web/src/api.ts b/web/src/api.ts index ee84bf8..2bcc5f4 100644 --- a/web/src/api.ts +++ b/web/src/api.ts @@ -1,6 +1,6 @@ import { Layer } from "effect" -import { FetchHttpClient } from "effect/unstable/http" -import { AtomHttpApi } from "effect/unstable/reactivity" +import { FetchHttpClient } from "effect/http" +import { AtomHttpApi } from "effect/reactivity" import { MotelHttpApi } from "@motel/httpApi" export const MotelClient = AtomHttpApi.Service()("MotelClient", { diff --git a/web/src/pages/AiCallsPage.tsx b/web/src/pages/AiCallsPage.tsx index cccb79c..765d760 100644 --- a/web/src/pages/AiCallsPage.tsx +++ b/web/src/pages/AiCallsPage.tsx @@ -1,7 +1,7 @@ import { Fragment, useMemo, Suspense, useState } from "react" import { useSearchParams, Link } from "react-router-dom" import { useAtomValue } from "@effect/atom-react" -import type { AsyncResult } from "effect/unstable/reactivity" +import type { AsyncResult } from "effect/reactivity" import { MotelClient } from "../api" import { PageHeader, RefreshButton, LoadingState, ErrorState, EmptyState } from "../components/shared" import { formatDuration, formatRelativeTime } from "../format" diff --git a/web/src/pages/LogsPage.tsx b/web/src/pages/LogsPage.tsx index baab474..eb2a9c0 100644 --- a/web/src/pages/LogsPage.tsx +++ b/web/src/pages/LogsPage.tsx @@ -1,7 +1,7 @@ import { useMemo, useState, Suspense } from "react" import { useSearchParams, Link } from "react-router-dom" import { useAtomValue } from "@effect/atom-react" -import type { AsyncResult } from "effect/unstable/reactivity" +import type { AsyncResult } from "effect/reactivity" import { MotelClient } from "../api" import { PageContainer, diff --git a/web/src/pages/TracesPage.tsx b/web/src/pages/TracesPage.tsx index 4d16224..ef7a824 100644 --- a/web/src/pages/TracesPage.tsx +++ b/web/src/pages/TracesPage.tsx @@ -2,7 +2,7 @@ import { useMemo, useRef, Suspense } from "react" import { useSearchParams, useNavigate } from "react-router-dom" import { useAtomValue } from "@effect/atom-react" import { useVirtualizer } from "@tanstack/react-virtual" -import type { AsyncResult } from "effect/unstable/reactivity" +import type { AsyncResult } from "effect/reactivity" import { MotelClient } from "../api" import { PageHeader, RefreshButton, LiveBadge, LoadingState, ErrorState, EmptyState } from "../components/shared" import { formatDuration, formatRelativeTime, serviceColor } from "../format"