chore(effect): update to beta.107 (#43109)

This commit is contained in:
Kit Langton
2026-08-17 17:54:08 -04:00
committed by GitHub
parent 8fc65b3038
commit d9b81d2233
91 changed files with 1332 additions and 1117 deletions
+18 -24
View File
@@ -191,7 +191,7 @@
"solid-js": "catalog:",
},
"peerDependencies": {
"effect": "4.0.0-beta.101",
"effect": "4.0.0-beta.107",
"solid-js": ">=1.9.0",
},
"optionalPeers": [
@@ -520,7 +520,7 @@
"name": "@opencode-ai/http-recorder",
"version": "1.18.15",
"dependencies": {
"@effect/platform-node-shared": "4.0.0-beta.101",
"@effect/platform-node-shared": "4.0.0-beta.107",
},
"devDependencies": {
"@effect/platform-node": "catalog:",
@@ -1053,9 +1053,9 @@
],
"patchedDependencies": {
"@pierre/trees@1.0.0-beta.4": "patches/@pierre%2Ftrees@1.0.0-beta.4.patch",
"effect@4.0.0-beta.101": "patches/effect@4.0.0-beta.101.patch",
"@modelcontextprotocol/sdk@1.29.0": "patches/@modelcontextprotocol%2Fsdk@1.29.0.patch",
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch",
"drizzle-orm@1.0.0-rc.2": "patches/drizzle-orm@1.0.0-rc.2.patch",
"@modelcontextprotocol/sdk@1.29.0": "patches/@modelcontextprotocol%2Fsdk@1.29.0.patch",
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
"@ai-sdk/mistral@3.0.51": "patches/@ai-sdk%2Fmistral@3.0.51.patch",
"@ff-labs/fff-bun@0.10.1": "patches/@ff-labs%2Ffff-bun@0.10.1.patch",
@@ -1067,6 +1067,7 @@
"@ai-sdk/openai-compatible@2.0.41": "patches/@ai-sdk%2Fopenai-compatible@2.0.41.patch",
},
"overrides": {
"@effect/platform-node-shared": "catalog:",
"@opentui/core": "catalog:",
"@opentui/keymap": "catalog:",
"@opentui/solid": "catalog:",
@@ -1077,9 +1078,10 @@
"catalog": {
"@cloudflare/workers-types": "4.20251008.0",
"@corvu/drawer": "0.2.4",
"@effect/opentelemetry": "4.0.0-beta.101",
"@effect/platform-node": "4.0.0-beta.101",
"@effect/sql-sqlite-bun": "4.0.0-beta.101",
"@effect/opentelemetry": "4.0.0-beta.107",
"@effect/platform-node": "4.0.0-beta.107",
"@effect/platform-node-shared": "4.0.0-beta.107",
"@effect/sql-sqlite-bun": "4.0.0-beta.107",
"@hono/standard-validator": "0.2.0",
"@hono/zod-validator": "0.4.2",
"@kobalte/core": "0.13.11",
@@ -1116,7 +1118,7 @@
"dompurify": "3.3.1",
"drizzle-kit": "1.0.0-rc.2",
"drizzle-orm": "1.0.0-rc.2",
"effect": "4.0.0-beta.101",
"effect": "4.0.0-beta.107",
"fuzzysort": "3.1.0",
"get-east-asian-width": "1.6.0",
"hono": "4.10.7",
@@ -1563,13 +1565,13 @@
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.11.0", "", {}, "sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg=="],
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.101", "", { "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.101" }, "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-IdejlqRLbjRHJgVnea4s8CxTWfvkSjM0HlnpNfP07IGTbhmAvPs7PMaWt1xzYWbOnI7CriQwxv+54eW1PwIkZg=="],
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.107", "", { "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.0-beta.107" }, "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-WxR3OEcwVtckNYGxvERA4kiS8cb2B46lSWxQw8P6dCCzW0j0VC7hkWyzryJ16MVXfI/5xQHS3r5j9mud+JVvsg=="],
"@effect/platform-node": ["@effect/platform-node@4.0.0-beta.101", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.101", "mime": "^4.1.0", "undici": "^8.7.0" }, "peerDependencies": { "effect": "^4.0.0-beta.101", "ioredis": "^5.7.0" } }, "sha512-pClk7dmMtHgM6Byu7CzGfrPvZ1/4BwmrRlCg2Op+iJozMkwVUxq8v4beK8b9SvxsliJjHZFznjvkVLX7LQjBqw=="],
"@effect/platform-node": ["@effect/platform-node@4.0.0-beta.107", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.107", "mime": "^4.1.0", "undici": "^8.7.0" }, "peerDependencies": { "effect": "^4.0.0-beta.107", "ioredis": ">=5.7.0 <6.0.0" } }, "sha512-k+6YNbV4Ck0L6YXtlgkvEnuP5tlxWD8EeWOrpn46PDqbGEwt4ONpRltTwm3tn2cyBXD0i+2P11cUH/6sdFagTA=="],
"@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.101", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.21.0" }, "peerDependencies": { "effect": "^4.0.0-beta.101" } }, "sha512-g4L7XiyJSNJLJVhlslyg2zBCQsoKQf1y1gd+Yfd+3wD9ymC+m7ymbd/5FGqnT1aXV6E2AwRr4D/R1eyRUikvWQ=="],
"@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.107", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.21.0" }, "peerDependencies": { "effect": "^4.0.0-beta.107" } }, "sha512-y6BqcRi86BfTJv+tvDrob4ozYVHxxlHYcn/zIQqZjXI9CvKnkgD6ng+38G1o45c4f2ucU+6HRI9POCmFdMoVGA=="],
"@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.101", "", { "peerDependencies": { "effect": "^4.0.0-beta.101" } }, "sha512-s6AC7LXCEjCN+nKegKFY4MOi6bmT1+SLR9YHEYwhY3P5qyQQB4R5yYLgt+3J4EPp5fa3t4FIDdPEUwz9LdKm6g=="],
"@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.107", "", { "peerDependencies": { "effect": "^4.0.0-beta.107" } }, "sha512-BuSSCUoXz6JSR30wT4Y0ukmJKvIFhm/gROwEeA0nLO5QYf33CdTunwX+q35+/MNOOLT8jL3xaDsz5R5aAF1vYQ=="],
"@electron/asar": ["@electron/asar@3.4.1", "", { "dependencies": { "commander": "^5.0.0", "glob": "^7.1.6", "minimatch": "^3.0.4" }, "bin": { "asar": "bin/asar.js" } }, "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA=="],
@@ -3871,7 +3873,7 @@
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
"effect": ["effect@4.0.0-beta.101", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.9.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.4", "multipasta": "^0.2.8", "toml": "^4.1.2", "uuid": "^14.0.1", "yaml": "^2.9.0" } }, "sha512-HjowumlIo+orthn4jMlEJPuzIYPBV+uq/XiciHWhiedLsXQpWHdNJHO5d59BVDP5s1LPuvERcktwFqRXnJqnhA=="],
"effect": ["effect@4.0.0-beta.107", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.9.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.4", "uuid": "^14.0.1" } }, "sha512-OoBAv8eF+yanc+C6xhgEUnWeXUSHA6ynnscYqpkAY9GSnzZWystsIjBowVqCkLpHGlnRtdIqYT3wHwpOY6JDnQ=="],
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
@@ -4073,8 +4075,6 @@
"find-babel-config": ["find-babel-config@2.1.2", "", { "dependencies": { "json5": "^2.2.3" } }, "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg=="],
"find-my-way-ts": ["find-my-way-ts@0.1.6", "", {}, "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA=="],
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
"finity": ["finity@0.5.4", "", {}, "sha512-3l+5/1tuw616Lgb0QBimxfdd2TqaDGpfCBpfX6EqtFmqUV3FtQnVEX4Aa62DagYEqnsTIjZcTfbq9msDbXYgyA=="],
@@ -4325,7 +4325,7 @@
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"ini": ["ini@7.0.0", "", {}, "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w=="],
"ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="],
"inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
@@ -4833,8 +4833,6 @@
"muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="],
"multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="],
"mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
"mysql2": ["mysql2@3.14.4", "", { "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", "seq-queue": "^0.0.5", "sqlstring": "^2.3.2" } }, "sha512-Cs/jx3WZPNrYHVz+Iunp9ziahaG5uFMvD2R8Zlmc194AqXNxt9HBNu7ZsPYrUtmJsF0egETCWIdMIYAwOGjL1w=="],
@@ -5641,8 +5639,6 @@
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"toml": ["toml@4.3.0", "", {}, "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A=="],
"toolbeam-docs-theme": ["toolbeam-docs-theme@0.4.8", "", { "peerDependencies": { "@astrojs/starlight": "^0.34.3", "astro": "^5.7.13" } }, "sha512-b+5ynEFp4Woe5a22hzNQm42lD23t13ZMihVxHbzjA50zdcM9aOSJTIjdJ0PDSd4/50HbBXcpHiQsz6rM4N88ww=="],
"topojson-client": ["topojson-client@3.1.0", "", { "dependencies": { "commander": "2" }, "bin": { "topo2geo": "bin/topo2geo", "topomerge": "bin/topomerge", "topoquantize": "bin/topoquantize" } }, "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw=="],
@@ -6247,6 +6243,8 @@
"@dot/log/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"@effect/platform-node-shared/ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="],
"@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="],
"@electron/asar/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
@@ -6301,10 +6299,6 @@
"@modelcontextprotocol/sdk/jose": ["jose@6.2.8", "", {}, "sha512-Bsdjwm3Qsd/P0jR+BHDe3LytDfY7WBq2HmCCLIwuVRHMuEC9ae7/R474GIUdF1NgCyZjzVo/A9DOiOBtXq8ZoQ=="],
"@npmcli/config/ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="],
"@npmcli/git/ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="],
"@npmcli/query/postcss-selector-parser": ["postcss-selector-parser@7.1.5", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw=="],
"@octokit/auth-app/@octokit/request": ["@octokit/request@10.0.13", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.1.1", "@octokit/types": "^17.0.0", "content-type": "^2.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-v2269YxL9Yf+x3d+gRI63FP0vFQEiWgLyBzxe/Y+0yFDg2B/Tzf5dhh9VNfccVAQnfcfwQWyk/y6Bn7rUXXs7A=="],
+7 -5
View File
@@ -37,9 +37,10 @@
"packages/slack"
],
"catalog": {
"@effect/opentelemetry": "4.0.0-beta.101",
"@effect/platform-node": "4.0.0-beta.101",
"@effect/sql-sqlite-bun": "4.0.0-beta.101",
"@effect/opentelemetry": "4.0.0-beta.107",
"@effect/platform-node": "4.0.0-beta.107",
"@effect/platform-node-shared": "4.0.0-beta.107",
"@effect/sql-sqlite-bun": "4.0.0-beta.107",
"@npmcli/arborist": "9.4.0",
"@types/bun": "1.3.13",
"@types/cross-spawn": "6.0.6",
@@ -70,7 +71,7 @@
"dompurify": "3.3.1",
"drizzle-kit": "1.0.0-rc.2",
"drizzle-orm": "1.0.0-rc.2",
"effect": "4.0.0-beta.101",
"effect": "4.0.0-beta.107",
"ai": "6.0.168",
"cross-spawn": "7.0.6",
"hono": "4.10.7",
@@ -154,6 +155,7 @@
"@opentui/core": "catalog:",
"@opentui/keymap": "catalog:",
"@opentui/solid": "catalog:",
"@effect/platform-node-shared": "catalog:",
"@types/bun": "catalog:",
"@types/node": "catalog:",
"effect": "catalog:"
@@ -164,6 +166,7 @@
"@npmcli/agent@4.0.2": "patches/@npmcli%2Fagent@4.0.2.patch",
"@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch",
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
"drizzle-orm@1.0.0-rc.2": "patches/drizzle-orm@1.0.0-rc.2.patch",
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch",
"@ai-sdk/mistral@3.0.51": "patches/@ai-sdk%2Fmistral@3.0.51.patch",
"gcp-metadata@8.1.2": "patches/gcp-metadata@8.1.2.patch",
@@ -171,7 +174,6 @@
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
"@pierre/trees@1.0.0-beta.4": "patches/@pierre%2Ftrees@1.0.0-beta.4.patch",
"@modelcontextprotocol/sdk@1.29.0": "patches/@modelcontextprotocol%2Fsdk@1.29.0.patch",
"effect@4.0.0-beta.101": "patches/effect@4.0.0-beta.101.patch",
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch",
"@ff-labs/fff-bun@0.10.1": "patches/@ff-labs%2Ffff-bun@0.10.1.patch"
}
+3 -2
View File
@@ -202,14 +202,15 @@ export const errorText = (error: unknown) => {
* decoder, and drops empty / `[DONE]` keep-alive events so the downstream
* `decodeChunk` sees one JSON string per element. The SSE channel emits a
* `Retry` control event on its error channel; we drop it here (we don't
* implement client-driven retries) so the public error channel stays
* `AIError`.
* implement client-driven retries). Decoder failures become provider output
* errors so the public error channel stays `AIError`.
*/
export const sseFraming = (bytes: Stream.Stream<Uint8Array, AIError>): Stream.Stream<string, AIError> =>
bytes.pipe(
Stream.decodeText(),
Stream.pipeThroughChannel(Sse.decode()),
Stream.catchTag("Retry", () => Stream.empty),
Stream.catchTag("SseError", (error) => Stream.fail(eventError("sse", error.message))),
Stream.filter((event) => event.data.length > 0 && event.data !== "[DONE]"),
Stream.map((event) => event.data),
)
+1 -1
View File
@@ -57,7 +57,7 @@ export const isContextOverflowFailure = (failure: unknown) =>
? failure.reason._tag === "InvalidRequest" && failure.reason.classification === "context-overflow"
: Schema.is(ProviderErrorEvent)(failure) && failure.classification === "context-overflow"
const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const QUOTA_CODES = new Set(["insufficient_quota", "usage_not_included", "billing_error"])
const SERVER_CODES = new Set([
"api_error",
+1 -1
View File
@@ -148,7 +148,7 @@ export const AIErrorReason = Schema.Union([
]).pipe(Schema.toTaggedUnion("_tag"))
export type AIErrorReason = Schema.Schema.Type<typeof AIErrorReason>
export class AIError extends Schema.TaggedErrorClass<AIError>()("AI.Error", {
export class AIError extends Schema.TaggedError<AIError>()("AI.Error", {
module: Schema.String,
method: Schema.String,
reason: AIErrorReason,
@@ -75,7 +75,6 @@ describe("Amazon Bedrock Mantle provider", () => {
}),
),
),
Effect.flip,
)
expect(seen).toEqual([{ url: "https://mantle.test/v1/chat/completions", authorization: "Bearer test-key" }])
+12 -1
View File
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
import { Effect, Schema } from "effect"
import { Effect, Schema, Stream } from "effect"
import * as OpenAIChat from "../src/protocols/openai-chat.js"
import * as OpenAIResponses from "../src/protocols/openai-responses.js"
import {
@@ -90,6 +90,17 @@ describe("AI.Usage", () => {
expect(ProviderShared.sumTokens()).toBeUndefined()
})
test("sseFraming maps decoder failures to AI errors", async () => {
const error = await Effect.runPromise(
ProviderShared.sseFraming(
Stream.make(new TextEncoder().encode(`data: ${"x".repeat(10 * 1024 * 1024)}`)),
).pipe(Stream.runCollect, Effect.flip),
)
expect(error).toBeInstanceOf(AIError)
expect(error.reason._tag).toBe("InvalidProviderOutput")
})
test("visibleOutputTokens clamps reasoning > output to zero", () => {
expect(new Usage({ outputTokens: 10, reasoningTokens: 4 }).visibleOutputTokens).toBe(6)
expect(new Usage({ outputTokens: 10 }).visibleOutputTokens).toBe(10)
+1 -1
View File
@@ -10,7 +10,7 @@ import { Option, Schema } from "effect"
const emptyTokens = { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } }
const emptyModel: { id: string; providerID: string; variant?: string } = { id: "", providerID: "" }
const decodeToolInput = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeToolInput = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
export function compareMessages(a: Pick<Message, "id" | "time">, b: Pick<Message, "id" | "time">) {
const left = messageKey(a)
+8 -8
View File
@@ -1,36 +1,36 @@
import { RequestError } from "@agentclientprotocol/sdk"
import { Schema } from "effect"
export class SessionNotFoundError extends Schema.TaggedErrorClass<SessionNotFoundError>()("ACPSessionNotFoundError", {
export class SessionNotFoundError extends Schema.TaggedError<SessionNotFoundError>()("ACPSessionNotFoundError", {
sessionId: Schema.String,
}) {}
export class InvalidConfigOptionError extends Schema.TaggedErrorClass<InvalidConfigOptionError>()(
export class InvalidConfigOptionError extends Schema.TaggedError<InvalidConfigOptionError>()(
"ACPInvalidConfigOptionError",
{ configId: Schema.String },
) {}
export class InvalidModelError extends Schema.TaggedErrorClass<InvalidModelError>()("ACPInvalidModelError", {
export class InvalidModelError extends Schema.TaggedError<InvalidModelError>()("ACPInvalidModelError", {
modelId: Schema.String,
providerId: Schema.optional(Schema.String),
}) {}
export class InvalidEffortError extends Schema.TaggedErrorClass<InvalidEffortError>()("ACPInvalidEffortError", {
export class InvalidEffortError extends Schema.TaggedError<InvalidEffortError>()("ACPInvalidEffortError", {
effort: Schema.String,
}) {}
export class InvalidModeError extends Schema.TaggedErrorClass<InvalidModeError>()("ACPInvalidModeError", {
export class InvalidModeError extends Schema.TaggedError<InvalidModeError>()("ACPInvalidModeError", {
mode: Schema.String,
}) {}
export class AuthRequiredError extends Schema.TaggedErrorClass<AuthRequiredError>()("ACPAuthRequiredError", {}) {}
export class AuthRequiredError extends Schema.TaggedError<AuthRequiredError>()("ACPAuthRequiredError", {}) {}
export class UnknownAuthMethodError extends Schema.TaggedErrorClass<UnknownAuthMethodError>()(
export class UnknownAuthMethodError extends Schema.TaggedError<UnknownAuthMethodError>()(
"ACPUnknownAuthMethodError",
{ methodId: Schema.String },
) {}
export class ServiceFailureError extends Schema.TaggedErrorClass<ServiceFailureError>()("ACPServiceFailureError", {
export class ServiceFailureError extends Schema.TaggedError<ServiceFailureError>()("ACPServiceFailureError", {
safeMessage: Schema.String,
service: Schema.optional(Schema.String),
errorName: Schema.optional(Schema.String),
+1 -1
View File
@@ -37,7 +37,7 @@
"@opencode-ai/protocol": "workspace:*"
},
"peerDependencies": {
"effect": "4.0.0-beta.101",
"effect": "4.0.0-beta.107",
"solid-js": ">=1.9.0"
},
"peerDependenciesMeta": {
@@ -1,5 +1,5 @@
import { Schema } from "effect"
export class ClientError extends Schema.TaggedErrorClass<ClientError>()("ClientError", {
export class ClientError extends Schema.TaggedError<ClientError>()("ClientError", {
cause: Schema.Defect(),
}) {}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -4,7 +4,7 @@ import { ToolError, toolError } from "../tool-error.js"
import { isRecord, own } from "./spec.js"
import type { AppliedAuth, Credential, Plan, SecurityScheme } from "./types.js"
const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const maxErrorBodyChars = 1_024
const maxResponseBodyBytes = 50 * 1024 * 1024
+1 -1
View File
@@ -1,7 +1,7 @@
import { Schema } from "effect"
/** Safe operational refusal from a standard tool pack, reported as `ToolFailure`. */
export class ToolError extends Schema.TaggedErrorClass<ToolError>()("ToolError", {
export class ToolError extends Schema.TaggedError<ToolError>()("ToolError", {
message: Schema.String,
cause: Schema.optionalKey(Schema.Defect()),
}) {}
+1 -1
View File
@@ -5,7 +5,7 @@ import { CodeMode, Tool, toolError } from "../src/index.js"
const run = (tool: Tool.Tool<never>) =>
Effect.runPromise(CodeMode.make({ tools: { host: { call: tool } } }).execute("return await tools.host.call({})"))
class UnsafeHostError extends Schema.TaggedErrorClass<UnsafeHostError>()("UnsafeHostError", {
class UnsafeHostError extends Schema.TaggedError<UnsafeHostError>()("UnsafeHostError", {
reason: Schema.String,
}) {}
+4 -2
View File
@@ -275,8 +275,10 @@ describe("non-identifier property names render as quoted keys", () => {
input: Schema.Struct({ "foo-bar": Schema.String, plain: Schema.optionalKey(Schema.Number) }),
execute: () => Effect.succeed(null),
})
expect(inputTypeScript(tool)).toBe('{ "foo-bar": string; plain?: number }')
expect(inputTypeScript(tool, true)).toBe(["{", ' "foo-bar": string,', " plain?: number,", "}"].join("\n"))
expect(inputTypeScript(tool)).toBe('{ "foo-bar": string; plain?: number | "Infinity" | "-Infinity" | "NaN" }')
expect(inputTypeScript(tool, true)).toBe(
["{", ' "foo-bar": string,', ' plain?: number | "Infinity" | "-Infinity" | "NaN",', "}"].join("\n"),
)
})
})
+4 -2
View File
@@ -43,6 +43,8 @@ type UserContent = Extract<LanguageModelV3Message, { role: "user" }>["content"]
type AssistantContent = Extract<LanguageModelV3Message, { role: "assistant" }>["content"]
type ToolResultContent = Extract<AssistantContent[number], { type: "tool-result" }>
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
export interface SDKEvent {
readonly model: Info
readonly package: string
@@ -146,7 +148,7 @@ function prepareOptions(model: Info, pkg: string) {
}
if (typeof opts.body === "string" && model.body !== undefined) {
const decoded = Option.getOrUndefined(Schema.decodeUnknownOption(Schema.UnknownFromJsonString)(opts.body))
const decoded = Option.getOrUndefined(decodeJson(opts.body))
if (Schema.is(Schema.Record(Schema.String, Schema.Json))(decoded)) {
opts.body = JSON.stringify(Provider.mergeOverlay(decoded, model.body))
}
@@ -163,7 +165,7 @@ function prepareOptions(model: Info, pkg: string) {
return options
}
export class InitError extends Schema.TaggedErrorClass<InitError>()("AISDK.InitError", {
export class InitError extends Schema.TaggedError<InitError>()("AISDK.InitError", {
providerID: Provider.ID,
cause: Schema.Defect(),
}) {}
+1 -1
View File
@@ -53,7 +53,7 @@ export type SerializedEvent = {
readonly data: Record<string, unknown>
}
export class InvalidDurableEventError extends Schema.TaggedErrorClass<InvalidDurableEventError>()(
export class InvalidDurableEventError extends Schema.TaggedError<InvalidDurableEventError>()(
"Bus.InvalidDurableEvent",
{
type: Schema.String,
+2 -2
View File
@@ -25,12 +25,12 @@ export type Data = {
commands: Map<string, Types.DeepMutable<Info>>
}
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Command.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Command.NotFoundError", {
command: Schema.String,
message: Schema.String,
}) {}
export class EvaluationError extends Schema.TaggedErrorClass<EvaluationError>()("Command.EvaluationError", {
export class EvaluationError extends Schema.TaggedError<EvaluationError>()("Command.EvaluationError", {
command: Schema.String,
message: Schema.String,
}) {}
+1 -1
View File
@@ -47,7 +47,7 @@ export interface Interface {
readonly changes: () => Stream.Stream<Watcher.Update>
}
export class UpdateError extends Schema.TaggedErrorClass<UpdateError>()("Config.UpdateError", {
export class UpdateError extends Schema.TaggedError<UpdateError>()("Config.UpdateError", {
message: Schema.String,
cause: Schema.optional(Schema.Defect()),
}) {}
@@ -27,7 +27,7 @@ const LegacyWellKnown = Schema.Struct({
token: Schema.String,
})
const LegacyValue = Schema.Union([LegacyOAuth, LegacyKey, LegacyWellKnown])
const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const decodeValue = Schema.decodeUnknownOption(LegacyValue)
const wellKnownSourcesKey = "wellknown:sources"
@@ -162,7 +162,7 @@ type NextMessage = {
const lock = Semaphore.makeUnsafe(1)
const MIGRATION_STATE_KEY = "migration.v1-v2"
const EVENT_DELETE_BATCH_SIZE = 1_000
const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const decodeMessage = Schema.decodeUnknownOption(SessionV1.Info)
const decodePart = Schema.decodeUnknownOption(SessionV1.Part)
let runtimeState: RuntimeState = { status: "idle" }
+3 -3
View File
@@ -14,16 +14,16 @@ export interface DirEntry {
readonly type: FileType
}
export class NotFound extends Schema.TaggedErrorClass<NotFound>()("Environment.NotFound", {
export class NotFound extends Schema.TaggedError<NotFound>()("Environment.NotFound", {
path: Schema.String,
}) {}
export class WrongKind extends Schema.TaggedErrorClass<WrongKind>()("Environment.WrongKind", {
export class WrongKind extends Schema.TaggedError<WrongKind>()("Environment.WrongKind", {
path: Schema.String,
actual: FileType,
}) {}
export class Failed extends Schema.TaggedErrorClass<Failed>()("Environment.Failed", {
export class Failed extends Schema.TaggedError<Failed>()("Environment.Failed", {
path: Schema.String,
cause: Schema.Defect(),
}) {}
+5 -5
View File
@@ -34,7 +34,7 @@ export type Reply = typeof Reply.Type
export { Event } from "@opencode-ai/schema/form"
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Form.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Form.NotFoundError", {
id: ID,
}) {
override get message() {
@@ -42,7 +42,7 @@ export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("For
}
}
export class AlreadySettledError extends Schema.TaggedErrorClass<AlreadySettledError>()("Form.AlreadySettledError", {
export class AlreadySettledError extends Schema.TaggedError<AlreadySettledError>()("Form.AlreadySettledError", {
id: ID,
}) {
override get message() {
@@ -50,7 +50,7 @@ export class AlreadySettledError extends Schema.TaggedErrorClass<AlreadySettledE
}
}
export class AlreadyExistsError extends Schema.TaggedErrorClass<AlreadyExistsError>()("Form.AlreadyExistsError", {
export class AlreadyExistsError extends Schema.TaggedError<AlreadyExistsError>()("Form.AlreadyExistsError", {
id: ID,
}) {
override get message() {
@@ -58,12 +58,12 @@ export class AlreadyExistsError extends Schema.TaggedErrorClass<AlreadyExistsErr
}
}
export class InvalidAnswerError extends Schema.TaggedErrorClass<InvalidAnswerError>()("Form.InvalidAnswerError", {
export class InvalidAnswerError extends Schema.TaggedError<InvalidAnswerError>()("Form.InvalidAnswerError", {
id: ID,
message: Schema.String,
}) {}
export class InvalidFormError extends Schema.TaggedErrorClass<InvalidFormError>()("Form.InvalidFormError", {
export class InvalidFormError extends Schema.TaggedError<InvalidFormError>()("Form.InvalidFormError", {
message: Schema.String,
}) {}
+2 -2
View File
@@ -12,12 +12,12 @@ export interface TextInput {
readonly model?: Model.Ref
}
export class ModelSelectionError extends Schema.TaggedErrorClass<ModelSelectionError>()(
export class ModelSelectionError extends Schema.TaggedError<ModelSelectionError>()(
"Generate.ModelSelectionError",
{ message: Schema.String },
) {}
export class UnavailableError extends Schema.TaggedErrorClass<UnavailableError>()("Generate.UnavailableError", {
export class UnavailableError extends Schema.TaggedError<UnavailableError>()("Generate.UnavailableError", {
message: Schema.String,
service: Schema.optional(Schema.String),
}) {}
+2 -2
View File
@@ -38,7 +38,7 @@ const snapshotConfig = `[core]
export const TreeID = Schema.String.pipe(Schema.brand("Git.TreeID"))
export type TreeID = typeof TreeID.Type
export class OperationError extends Schema.TaggedErrorClass<OperationError>()("Git.OperationError", {
export class OperationError extends Schema.TaggedError<OperationError>()("Git.OperationError", {
operation: Schema.Literals([
"clone",
"fetch",
@@ -61,7 +61,7 @@ export class Worktree extends Schema.Class<Worktree>("Git.Worktree")({
kind: Schema.Literals(["main", "linked"]),
}) {}
export class WorktreeError extends Schema.TaggedErrorClass<WorktreeError>()("Git.WorktreeError", {
export class WorktreeError extends Schema.TaggedError<WorktreeError>()("Git.WorktreeError", {
operation: Schema.Literals(["create", "remove", "list"]),
message: Schema.String,
directory: Schema.optional(AbsolutePath),
+3 -3
View File
@@ -5,12 +5,12 @@ import { Context, Effect, Layer, Schema } from "effect"
import { Config } from "./config.js"
import { FileSystem } from "./filesystem.js"
export class ResizerUnavailableError extends Schema.TaggedErrorClass<ResizerUnavailableError>()(
export class ResizerUnavailableError extends Schema.TaggedError<ResizerUnavailableError>()(
"Image.ResizerUnavailableError",
{},
) {}
export class DecodeError extends Schema.TaggedErrorClass<DecodeError>()("Image.DecodeError", {
export class DecodeError extends Schema.TaggedError<DecodeError>()("Image.DecodeError", {
resource: Schema.String,
}) {
override get message() {
@@ -18,7 +18,7 @@ export class DecodeError extends Schema.TaggedErrorClass<DecodeError>()("Image.D
}
}
export class SizeError extends Schema.TaggedErrorClass<SizeError>()("Image.SizeError", {
export class SizeError extends Schema.TaggedError<SizeError>()("Image.SizeError", {
resource: Schema.String,
width: Schema.Number,
height: Schema.Number,
+2 -2
View File
@@ -65,7 +65,7 @@ export interface Admission {
readonly blobs: Readonly<Record<string, Schema.Json>>
}
export class InitializationBlocked extends Schema.TaggedErrorClass<InitializationBlocked>()(
export class InitializationBlocked extends Schema.TaggedError<InitializationBlocked>()(
"Instructions.InitializationBlocked",
{ keys: Schema.Array(Key) },
) {
@@ -74,7 +74,7 @@ export class InitializationBlocked extends Schema.TaggedErrorClass<Initializatio
}
}
export class DuplicateKeyError extends Schema.TaggedErrorClass<DuplicateKeyError>()("Instructions.DuplicateKeyError", {
export class DuplicateKeyError extends Schema.TaggedError<DuplicateKeyError>()("Instructions.DuplicateKeyError", {
key: Key,
}) {
override get message() {
+2 -2
View File
@@ -105,11 +105,11 @@ export type CommandAttempt = Integration.CommandAttempt
export const CommandAttemptStatus = Integration.CommandAttemptStatus
export type CommandAttemptStatus = Integration.CommandAttemptStatus
export class CodeRequiredError extends Schema.TaggedErrorClass<CodeRequiredError>()("Integration.CodeRequired", {
export class CodeRequiredError extends Schema.TaggedError<CodeRequiredError>()("Integration.CodeRequired", {
attemptID: AttemptID,
}) {}
export class AuthorizationError extends Schema.TaggedErrorClass<AuthorizationError>()("Integration.Authorization", {
export class AuthorizationError extends Schema.TaggedError<AuthorizationError>()("Integration.Authorization", {
cause: Schema.Defect(),
}) {}
+2 -2
View File
@@ -44,7 +44,7 @@ const TolerantListPromptsResult = ListPromptsResultSchema.extend({
prompts: PromptSchema.array(),
})
export class NeedsAuthError extends Schema.TaggedErrorClass<NeedsAuthError>()("MCP.NeedsAuthError", {
export class NeedsAuthError extends Schema.TaggedError<NeedsAuthError>()("MCP.NeedsAuthError", {
server: Schema.String,
}) {
override get message() {
@@ -52,7 +52,7 @@ export class NeedsAuthError extends Schema.TaggedErrorClass<NeedsAuthError>()("M
}
}
export class ConnectError extends Schema.TaggedErrorClass<ConnectError>()("MCP.ConnectError", {
export class ConnectError extends Schema.TaggedError<ConnectError>()("MCP.ConnectError", {
server: Schema.String,
message: Schema.String,
}) {}
+2 -2
View File
@@ -97,7 +97,7 @@ export type ResourceContentPart = Mcp.ResourceContentPart
export const ResourceContent = Mcp.ResourceContent
export type ResourceContent = Mcp.ResourceContent
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("MCP.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("MCP.NotFoundError", {
server: ServerName,
}) {
override get message() {
@@ -105,7 +105,7 @@ export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("MCP
}
}
export class ToolCallError extends Schema.TaggedErrorClass<ToolCallError>()("MCP.ToolCallError", {
export class ToolCallError extends Schema.TaggedError<ToolCallError>()("MCP.ToolCallError", {
server: ServerName,
tool: Schema.String,
message: Schema.String,
+3 -3
View File
@@ -20,7 +20,7 @@ import { Capabilities, ID, Info, Ref, VariantID } from "./model.js"
import { Npm } from "@opencode-ai/util/npm"
import { Provider } from "./provider.js"
export class VariantUnavailableError extends Schema.TaggedErrorClass<VariantUnavailableError>()(
export class VariantUnavailableError extends Schema.TaggedError<VariantUnavailableError>()(
"SessionRunnerModel.VariantUnavailableError",
{
providerID: Provider.ID,
@@ -33,7 +33,7 @@ export class VariantUnavailableError extends Schema.TaggedErrorClass<VariantUnav
}
}
export class UnsupportedPackageError extends Schema.TaggedErrorClass<UnsupportedPackageError>()(
export class UnsupportedPackageError extends Schema.TaggedError<UnsupportedPackageError>()(
"SessionRunnerModel.UnsupportedPackageError",
{
providerID: Provider.ID,
@@ -46,7 +46,7 @@ export class UnsupportedPackageError extends Schema.TaggedErrorClass<Unsupported
}
}
export class UnresolvedProviderVariablesError extends Schema.TaggedErrorClass<UnresolvedProviderVariablesError>()(
export class UnresolvedProviderVariablesError extends Schema.TaggedError<UnresolvedProviderVariablesError>()(
"SessionRunnerModel.UnresolvedProviderVariablesError",
{
providerID: Provider.ID,
+4 -4
View File
@@ -60,13 +60,13 @@ export type AskResult = typeof AskResult.Type
export { Event } from "@opencode-ai/schema/permission"
export class DeclinedError extends Schema.TaggedErrorClass<DeclinedError>()("Permission.DeclinedError", {}) {}
export class DeclinedError extends Schema.TaggedError<DeclinedError>()("Permission.DeclinedError", {}) {}
export class CorrectedError extends Schema.TaggedErrorClass<CorrectedError>()("Permission.CorrectedError", {
export class CorrectedError extends Schema.TaggedError<CorrectedError>()("Permission.CorrectedError", {
feedback: Schema.String,
}) {}
export class BlockedError extends Schema.TaggedErrorClass<BlockedError>()("Permission.BlockedError", {
export class BlockedError extends Schema.TaggedError<BlockedError>()("Permission.BlockedError", {
rules: Permission.Ruleset,
permission: Schema.String,
resources: Schema.Array(Schema.String),
@@ -76,7 +76,7 @@ export class BlockedError extends Schema.TaggedErrorClass<BlockedError>()("Permi
}
}
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Permission.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Permission.NotFoundError", {
requestID: ID,
}) {}
@@ -85,7 +85,7 @@ type GatewayConfig = {
apiKey: string
}
const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
function gatewayConfig(options: Record<string, unknown>): GatewayConfig | undefined {
const accountId = process.env.CLOUDFLARE_ACCOUNT_ID ?? stringOption(options, "accountId")
@@ -37,7 +37,7 @@ const User = Schema.Struct({
),
})
const decodeUser = Schema.decodeUnknownOption(User)
const JsonBody = Schema.UnknownFromJsonString
const JsonBody = Schema.fromJsonString(Schema.Unknown)
const decodeBody = Schema.decodeUnknownOption(JsonBody)
const oauth = (app: App.Info) =>
+1 -1
View File
@@ -25,7 +25,7 @@ type Json = Schema.Schema.Type<typeof Schema.Json>
const JsonRecord = Schema.Record(Schema.String, Schema.Json)
const decodeJsonRecord = Schema.decodeUnknownSync(JsonRecord)
export class LoadError extends Schema.TaggedErrorClass<LoadError>()("Provider.LoadError", {
export class LoadError extends Schema.TaggedError<LoadError>()("Provider.LoadError", {
package: Schema.String,
cause: Schema.Defect(),
}) {}
+2 -2
View File
@@ -70,11 +70,11 @@ export type Attachment = {
readonly detach: () => void
}
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Pty.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Pty.NotFoundError", {
ptyID: PtyID,
}) {}
export class ExitedError extends Schema.TaggedErrorClass<ExitedError>()("Pty.ExitedError", {
export class ExitedError extends Schema.TaggedError<ExitedError>()("Pty.ExitedError", {
ptyID: PtyID,
}) {}
+7 -7
View File
@@ -31,7 +31,7 @@ export type EnsureInput = {
readonly branch?: string
}
export class InvalidBranchError extends Schema.TaggedErrorClass<InvalidBranchError>()(
export class InvalidBranchError extends Schema.TaggedError<InvalidBranchError>()(
"RepositoryCacheInvalidBranchError",
{
branch: Schema.String,
@@ -39,17 +39,17 @@ export class InvalidBranchError extends Schema.TaggedErrorClass<InvalidBranchErr
},
) {}
export class CloneFailedError extends Schema.TaggedErrorClass<CloneFailedError>()("RepositoryCacheCloneFailedError", {
export class CloneFailedError extends Schema.TaggedError<CloneFailedError>()("RepositoryCacheCloneFailedError", {
repository: Schema.String,
message: Schema.String,
}) {}
export class FetchFailedError extends Schema.TaggedErrorClass<FetchFailedError>()("RepositoryCacheFetchFailedError", {
export class FetchFailedError extends Schema.TaggedError<FetchFailedError>()("RepositoryCacheFetchFailedError", {
repository: Schema.String,
message: Schema.String,
}) {}
export class CheckoutFailedError extends Schema.TaggedErrorClass<CheckoutFailedError>()(
export class CheckoutFailedError extends Schema.TaggedError<CheckoutFailedError>()(
"RepositoryCacheCheckoutFailedError",
{
repository: Schema.String,
@@ -58,17 +58,17 @@ export class CheckoutFailedError extends Schema.TaggedErrorClass<CheckoutFailedE
},
) {}
export class ResetFailedError extends Schema.TaggedErrorClass<ResetFailedError>()("RepositoryCacheResetFailedError", {
export class ResetFailedError extends Schema.TaggedError<ResetFailedError>()("RepositoryCacheResetFailedError", {
repository: Schema.String,
message: Schema.String,
}) {}
export class LockFailedError extends Schema.TaggedErrorClass<LockFailedError>()("RepositoryCacheLockFailedError", {
export class LockFailedError extends Schema.TaggedError<LockFailedError>()("RepositoryCacheLockFailedError", {
localPath: Schema.String,
message: Schema.String,
}) {}
export class CacheOperationError extends Schema.TaggedErrorClass<CacheOperationError>()(
export class CacheOperationError extends Schema.TaggedError<CacheOperationError>()(
"RepositoryCacheOperationError",
{
operation: Schema.String,
+3 -3
View File
@@ -23,7 +23,7 @@ export type FileReference = BaseReference & {
export type Reference = RemoteReference | FileReference
export class InvalidReferenceError extends Schema.TaggedErrorClass<InvalidReferenceError>()(
export class InvalidReferenceError extends Schema.TaggedError<InvalidReferenceError>()(
"RepositoryInvalidReferenceError",
{
repository: Schema.String,
@@ -31,7 +31,7 @@ export class InvalidReferenceError extends Schema.TaggedErrorClass<InvalidRefere
},
) {}
export class UnsupportedLocalRepositoryError extends Schema.TaggedErrorClass<UnsupportedLocalRepositoryError>()(
export class UnsupportedLocalRepositoryError extends Schema.TaggedError<UnsupportedLocalRepositoryError>()(
"RepositoryUnsupportedLocalRepositoryError",
{
repository: Schema.String,
@@ -39,7 +39,7 @@ export class UnsupportedLocalRepositoryError extends Schema.TaggedErrorClass<Uns
},
) {}
export class InvalidBranchError extends Schema.TaggedErrorClass<InvalidBranchError>()("RepositoryInvalidBranchError", {
export class InvalidBranchError extends Schema.TaggedError<InvalidBranchError>()("RepositoryInvalidBranchError", {
branch: Schema.String,
message: Schema.String,
}) {}
+3 -3
View File
@@ -35,16 +35,16 @@ const RawMatch = Schema.Struct({
),
}),
})
const decodeJsonRecord = Schema.decodeUnknownEffect(Schema.UnknownFromJsonString)
const decodeJsonRecord = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Unknown))
type RawMatchData = (typeof RawMatch.Type)["data"]
export class Error extends Schema.TaggedErrorClass<Error>()("Ripgrep.Error", {
export class Error extends Schema.TaggedError<Error>()("Ripgrep.Error", {
message: Schema.String,
cause: Schema.optional(Schema.Defect()),
}) {}
export class InvalidPatternError extends Schema.TaggedErrorClass<InvalidPatternError>()("Ripgrep.InvalidPatternError", {
export class InvalidPatternError extends Schema.TaggedError<InvalidPatternError>()("Ripgrep.InvalidPatternError", {
pattern: Schema.String,
message: Schema.String,
}) {}
+1 -1
View File
@@ -58,7 +58,7 @@ export type DeepMutable<T> = T extends string | number | boolean | bigint | symb
type NewtypeSchema<Self, Tag extends string, S extends Schema.Top> = (abstract new (_: never) => {
readonly _newtype: Tag
}) &
Schema.Bottom<
Schema.BottomWithoutNew<
Self,
S["Encoded"],
S["DecodingServices"],
+9 -9
View File
@@ -111,46 +111,46 @@ type ForkInput = {
export { MessageDecodeError, NotFoundError }
export class PromptConflictError extends Schema.TaggedErrorClass<PromptConflictError>()("Session.PromptConflictError", {
export class PromptConflictError extends Schema.TaggedError<PromptConflictError>()("Session.PromptConflictError", {
sessionID: SessionSchema.ID,
messageID: SessionMessage.ID,
}) {}
export class SyntheticConflictError extends Schema.TaggedErrorClass<SyntheticConflictError>()(
export class SyntheticConflictError extends Schema.TaggedError<SyntheticConflictError>()(
"Session.SyntheticConflictError",
{
sessionID: SessionSchema.ID,
inputID: SessionMessage.ID,
},
) {}
export class AttachmentError extends Schema.TaggedErrorClass<AttachmentError>()("Session.AttachmentError", {
export class AttachmentError extends Schema.TaggedError<AttachmentError>()("Session.AttachmentError", {
uri: Schema.String,
message: Schema.String,
}) {}
export class CompactionConflictError extends Schema.TaggedErrorClass<CompactionConflictError>()(
export class CompactionConflictError extends Schema.TaggedError<CompactionConflictError>()(
"Session.CompactionConflictError",
{
sessionID: SessionSchema.ID,
inputID: SessionMessage.ID,
},
) {}
export class BusyError extends Schema.TaggedErrorClass<BusyError>()("Session.BusyError", {
export class BusyError extends Schema.TaggedError<BusyError>()("Session.BusyError", {
sessionID: SessionSchema.ID,
}) {}
export class InboxConflictError extends Schema.TaggedErrorClass<InboxConflictError>()("Session.InboxConflictError", {
export class InboxConflictError extends Schema.TaggedError<InboxConflictError>()("Session.InboxConflictError", {
sessionID: SessionSchema.ID,
inboxID: SessionMessage.ID,
}) {}
type InboxItemRef = { readonly sessionID: SessionSchema.ID; readonly inboxID: SessionMessage.ID }
export class SkillNotFoundError extends Schema.TaggedErrorClass<SkillNotFoundError>()("Session.SkillNotFoundError", {
export class SkillNotFoundError extends Schema.TaggedError<SkillNotFoundError>()("Session.SkillNotFoundError", {
skill: Skill.ID,
}) {}
export class DestinationNotFoundError extends Schema.TaggedErrorClass<DestinationNotFoundError>()(
export class DestinationNotFoundError extends Schema.TaggedError<DestinationNotFoundError>()(
"Session.DestinationNotFoundError",
{ directory: AbsolutePath },
) {}
export class DestinationNotDirectoryError extends Schema.TaggedErrorClass<DestinationNotDirectoryError>()(
export class DestinationNotDirectoryError extends Schema.TaggedError<DestinationNotDirectoryError>()(
"Session.DestinationNotDirectoryError",
{ directory: AbsolutePath },
) {}
+6 -6
View File
@@ -6,11 +6,11 @@ import { SessionMessage } from "./message.js"
import { SessionSchema } from "./schema.js"
import { SessionError } from "@opencode-ai/schema/session-error"
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Session.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Session.NotFoundError", {
sessionID: SessionSchema.ID,
}) {}
export class ForkEmptyError extends Schema.TaggedErrorClass<ForkEmptyError>()("Session.ForkEmptyError", {
export class ForkEmptyError extends Schema.TaggedError<ForkEmptyError>()("Session.ForkEmptyError", {
sessionID: SessionSchema.ID,
}) {
override get message() {
@@ -18,7 +18,7 @@ export class ForkEmptyError extends Schema.TaggedErrorClass<ForkEmptyError>()("S
}
}
export class MessageDecodeError extends Schema.TaggedErrorClass<MessageDecodeError>()("Session.MessageDecodeError", {
export class MessageDecodeError extends Schema.TaggedError<MessageDecodeError>()("Session.MessageDecodeError", {
sessionID: SessionSchema.ID,
messageID: SessionMessage.ID,
}) {
@@ -27,7 +27,7 @@ export class MessageDecodeError extends Schema.TaggedErrorClass<MessageDecodeErr
}
}
export class AgentNotFoundError extends Schema.TaggedErrorClass<AgentNotFoundError>()("Session.AgentNotFoundError", {
export class AgentNotFoundError extends Schema.TaggedError<AgentNotFoundError>()("Session.AgentNotFoundError", {
sessionID: SessionSchema.ID,
agent: Agent.ID,
}) {
@@ -36,7 +36,7 @@ export class AgentNotFoundError extends Schema.TaggedErrorClass<AgentNotFoundErr
}
}
export class StepFailedError extends Schema.TaggedErrorClass<StepFailedError>()("Session.StepFailedError", {
export class StepFailedError extends Schema.TaggedError<StepFailedError>()("Session.StepFailedError", {
error: SessionError.Error,
}) {
override get message() {
@@ -44,7 +44,7 @@ export class StepFailedError extends Schema.TaggedErrorClass<StepFailedError>()(
}
}
export class UserInterruptedError extends Schema.TaggedErrorClass<UserInterruptedError>()(
export class UserInterruptedError extends Schema.TaggedError<UserInterruptedError>()(
"Session.UserInterruptedError",
{},
) {
+1 -1
View File
@@ -61,7 +61,7 @@ type PendingRef = { readonly id: SessionMessage.ID; readonly sessionID: SessionS
export const serialized = <A, E, R>(sessionID: SessionSchema.ID, effect: Effect.Effect<A, E, R>) =>
inboxLocks.withLock(sessionID)(effect)
export class LifecycleConflict extends Schema.TaggedErrorClass<LifecycleConflict>()("SessionInbox.LifecycleConflict", {
export class LifecycleConflict extends Schema.TaggedError<LifecycleConflict>()("SessionInbox.LifecycleConflict", {
id: SessionMessage.ID,
}) {}
+1 -1
View File
@@ -11,7 +11,7 @@ import { SessionMessage } from "./message.js"
import { SessionSchema } from "./schema.js"
import { SessionMessageTable } from "./sql.js"
export class MessageNotFoundError extends Schema.TaggedErrorClass<MessageNotFoundError>()(
export class MessageNotFoundError extends Schema.TaggedError<MessageNotFoundError>()(
"Session.MessageNotFoundError",
{
sessionID: SessionSchema.ID,
+2 -2
View File
@@ -9,7 +9,7 @@ import { Capabilities, ID, Info, Ref, VariantID } from "../../model.js"
import { Provider } from "../../provider.js"
import { SessionSchema } from "../schema.js"
export class ModelNotSelectedError extends Schema.TaggedErrorClass<ModelNotSelectedError>()(
export class ModelNotSelectedError extends Schema.TaggedError<ModelNotSelectedError>()(
"SessionRunnerModel.ModelNotSelectedError",
{ sessionID: SessionSchema.ID },
) {
@@ -18,7 +18,7 @@ export class ModelNotSelectedError extends Schema.TaggedErrorClass<ModelNotSelec
}
}
export class ModelUnavailableError extends Schema.TaggedErrorClass<ModelUnavailableError>()(
export class ModelUnavailableError extends Schema.TaggedError<ModelUnavailableError>()(
"SessionRunnerModel.ModelUnavailableError",
{ providerID: Provider.ID, modelID: ID },
) {
@@ -93,7 +93,7 @@ const userAttachmentContent = (files: readonly FileAttachment[]) => {
})
}
const decodeToolInput = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeToolInput = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const providerMetadata = (
provider: string,
+1 -1
View File
@@ -24,7 +24,7 @@ import { SessionMessageTable, SessionTable } from "./sql.js"
export const Data = SessionTransfer.Data
export type Data = SessionTransfer.Data
export class ImportConflictError extends Schema.TaggedErrorClass<ImportConflictError>()(
export class ImportConflictError extends Schema.TaggedError<ImportConflictError>()(
"SessionTransfer.ImportConflictError",
{ sessionID: Session.ID },
) {}
+1 -1
View File
@@ -18,7 +18,7 @@ import { PluginHooks } from "./plugin/hooks.js"
import { SessionEnvironment } from "./session/environment.js"
import { SessionSchema } from "./session/schema.js"
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Shell.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Shell.NotFoundError", {
id: Shell.ID,
}) {}
+1 -1
View File
@@ -15,7 +15,7 @@ import { Hash } from "@opencode-ai/util/hash"
export { ID }
export class Error extends Schema.TaggedErrorClass<Error>()("Snapshot.Error", {
export class Error extends Schema.TaggedError<Error>()("Snapshot.Error", {
operation: Schema.Literals(["capture", "files", "diff", "restore"]),
message: Schema.String,
cause: Schema.optional(Schema.Defect()),
+10 -3
View File
@@ -4,7 +4,7 @@ export type { Context, Metadata, Options, Result } from "@opencode-ai/schema/too
import { ToolDefinition, type ToolCall } from "@opencode-ai/ai"
import { Tool } from "@opencode-ai/schema/tool"
import { Context, Effect, Layer, Schema, Scope, Semaphore } from "effect"
import { Context, Effect, Layer, Schema, SchemaIssue, Scope, Semaphore } from "effect"
import { makeLocationNode } from "@opencode-ai/util/effect/app-node"
import type { Agent } from "./agent.js"
import { CodeModeCatalog } from "./codemode/catalog.js"
@@ -17,7 +17,7 @@ import { SessionSchema } from "./session/schema.js"
import { definition, execute, normalizeContent } from "./tool/runtime.js"
import { Wildcard } from "./util/wildcard.js"
export class RegistrationError extends Schema.TaggedErrorClass<RegistrationError>()("Tool.RegistrationError", {
export class RegistrationError extends Schema.TaggedError<RegistrationError>()("Tool.RegistrationError", {
name: Schema.String,
message: Schema.String,
}) {}
@@ -173,7 +173,7 @@ const layer = Layer.effect(
catch: (error) =>
new RegistrationError({
name: entry.key,
message: `Invalid tool definition ${entry.key}: ${error instanceof Error ? error.message : String(error)}`,
message: `Invalid tool definition ${entry.key}: ${schemaMakeError(error)}`,
}),
}),
{ discard: true },
@@ -262,6 +262,13 @@ const whollyDisabled = (action: string, rules: Permission.Ruleset) => {
return rule?.resource === "*" && rule.effect === "deny"
}
const formatSchemaIssue = SchemaIssue.makeFormatterDefault()
function schemaMakeError(error: unknown) {
if (error instanceof Error && SchemaIssue.isIssue(error.cause)) return formatSchemaIssue(error.cause)
return error instanceof Error ? error.message : String(error)
}
const validateName = (name: string) =>
/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(name)
? Effect.void
+1 -1
View File
@@ -29,7 +29,7 @@ export const Output = Schema.Struct({
})
export type Output = typeof Output.Type
export class CancelledError extends Schema.TaggedErrorClass<CancelledError>()("QuestionTool.CancelledError", {}) {
export class CancelledError extends Schema.TaggedError<CancelledError>()("QuestionTool.CancelledError", {}) {
override get message() {
return "The user dismissed this question"
}
+4 -4
View File
@@ -19,7 +19,7 @@ const MAX_LINE_LENGTH = 2_000
const MAX_LINE_SUFFIX = `... (line truncated to ${MAX_LINE_LENGTH} chars)`
const MEDIA_MIMES = new Set(["image/png", "image/jpeg", "image/gif", "image/webp", "application/pdf"])
export class BinaryFileError extends Schema.TaggedErrorClass<BinaryFileError>()("ReadTool.BinaryFileError", {
export class BinaryFileError extends Schema.TaggedError<BinaryFileError>()("ReadTool.BinaryFileError", {
resource: Schema.String,
}) {
override get message() {
@@ -27,7 +27,7 @@ export class BinaryFileError extends Schema.TaggedErrorClass<BinaryFileError>()(
}
}
export class MediaIngestLimitError extends Schema.TaggedErrorClass<MediaIngestLimitError>()(
export class MediaIngestLimitError extends Schema.TaggedError<MediaIngestLimitError>()(
"ReadTool.MediaIngestLimitError",
{
resource: Schema.String,
@@ -39,7 +39,7 @@ export class MediaIngestLimitError extends Schema.TaggedErrorClass<MediaIngestLi
}
}
export class OffsetOutOfRangeError extends Schema.TaggedErrorClass<OffsetOutOfRangeError>()(
export class OffsetOutOfRangeError extends Schema.TaggedError<OffsetOutOfRangeError>()(
"ReadTool.OffsetOutOfRangeError",
{ offset: Schema.Number },
) {
@@ -48,7 +48,7 @@ export class OffsetOutOfRangeError extends Schema.TaggedErrorClass<OffsetOutOfRa
}
}
export class PathKindError extends Schema.TaggedErrorClass<PathKindError>()("ReadTool.PathKindError", {
export class PathKindError extends Schema.TaggedError<PathKindError>()("ReadTool.PathKindError", {
resource: Schema.String,
expected: Schema.Literals(["a file", "a file or directory"]),
}) {
+2 -2
View File
@@ -6,7 +6,7 @@ import { Effect, Schema } from "effect"
import { Hash } from "@opencode-ai/util/hash"
export namespace ProcessLock {
export class HeldError extends Schema.TaggedErrorClass<HeldError>()("ProcessLockHeldError", {
export class HeldError extends Schema.TaggedError<HeldError>()("ProcessLockHeldError", {
file: Schema.String,
}) {
override get message() {
@@ -14,7 +14,7 @@ export namespace ProcessLock {
}
}
export class SystemError extends Schema.TaggedErrorClass<SystemError>()("ProcessLockSystemError", {
export class SystemError extends Schema.TaggedError<SystemError>()("ProcessLockSystemError", {
file: Schema.String,
operation: Schema.Literals(["open", "acquire"]),
code: Schema.String,
+4 -4
View File
@@ -4,13 +4,13 @@ import { Schema } from "effect"
export * from "@opencode-ai/schema/permission-v1"
import { ID } from "@opencode-ai/schema/permission-v1"
export class RejectedError extends Schema.TaggedErrorClass<RejectedError>()("PermissionRejectedError", {}) {
export class RejectedError extends Schema.TaggedError<RejectedError>()("PermissionRejectedError", {}) {
override get message() {
return "The user rejected permission to use this specific tool call."
}
}
export class CorrectedError extends Schema.TaggedErrorClass<CorrectedError>()("PermissionCorrectedError", {
export class CorrectedError extends Schema.TaggedError<CorrectedError>()("PermissionCorrectedError", {
feedback: Schema.String,
}) {
override get message() {
@@ -18,7 +18,7 @@ export class CorrectedError extends Schema.TaggedErrorClass<CorrectedError>()("P
}
}
export class DeniedError extends Schema.TaggedErrorClass<DeniedError>()("PermissionDeniedError", {
export class DeniedError extends Schema.TaggedError<DeniedError>()("PermissionDeniedError", {
ruleset: Schema.Any,
}) {
override get message() {
@@ -26,7 +26,7 @@ export class DeniedError extends Schema.TaggedErrorClass<DeniedError>()("Permiss
}
}
export class NotFoundError extends Schema.TaggedErrorClass<NotFoundError>()("Permission.NotFoundError", {
export class NotFoundError extends Schema.TaggedError<NotFoundError>()("Permission.NotFoundError", {
requestID: ID,
}) {}
+4 -4
View File
@@ -28,21 +28,21 @@ export interface ProviderImplementation extends Provider {
readonly execute: (input: ProviderInput) => Effect.Effect<readonly Result[], unknown>
}
export class ProviderRequiredError extends Schema.TaggedErrorClass<ProviderRequiredError>()(
export class ProviderRequiredError extends Schema.TaggedError<ProviderRequiredError>()(
"WebSearch.ProviderRequired",
{},
) {}
export class ProviderNotFoundError extends Schema.TaggedErrorClass<ProviderNotFoundError>()(
export class ProviderNotFoundError extends Schema.TaggedError<ProviderNotFoundError>()(
"WebSearch.ProviderNotFound",
{
providerID: ID,
},
) {}
export class DisabledError extends Schema.TaggedErrorClass<DisabledError>()("WebSearch.Disabled", {}) {}
export class DisabledError extends Schema.TaggedError<DisabledError>()("WebSearch.Disabled", {}) {}
export class RequestError extends Schema.TaggedErrorClass<RequestError>()("WebSearch.Request", {
export class RequestError extends Schema.TaggedError<RequestError>()("WebSearch.Request", {
providerID: ID,
cause: Schema.Defect(),
}) {}
+1 -1
View File
@@ -23,7 +23,7 @@ export class Info extends Schema.Class<Info>("Workspace.Info")({
lastUsedAt: Schema.Number,
}) {}
export class NotFound extends Schema.TaggedErrorClass<NotFound>()("Workspace.NotFound", { workspaceID: ID }) {}
export class NotFound extends Schema.TaggedError<NotFound>()("Workspace.NotFound", { workspaceID: ID }) {}
export interface Interface {
readonly create: (provider: string) => Effect.Effect<Info, WorkspaceDriver.Error | WorkspaceDriver.ProviderNotFound>
+2 -2
View File
@@ -14,12 +14,12 @@ import type { Driver as EnvironmentDriver } from "../environment/driver.js"
export const Binding = Schema.Record(Schema.String, Schema.Json)
export type Binding = typeof Binding.Type
export class Error extends Schema.TaggedErrorClass<Error>()("WorkspaceDriver.Error", {
export class Error extends Schema.TaggedError<Error>()("WorkspaceDriver.Error", {
message: Schema.optional(Schema.String),
cause: Schema.optional(Schema.Defect()),
}) {}
export class ProviderNotFound extends Schema.TaggedErrorClass<ProviderNotFound>()("WorkspaceDriver.ProviderNotFound", {
export class ProviderNotFound extends Schema.TaggedError<ProviderNotFound>()("WorkspaceDriver.ProviderNotFound", {
provider: Schema.String,
}) {}
+5 -5
View File
@@ -56,27 +56,27 @@ export const ListEntry = Schema.Struct({
}).annotate({ identifier: "Worktree.ListEntry" })
export type ListEntry = typeof ListEntry.Type
export class SourceDirectoryNotFoundError extends Schema.TaggedErrorClass<SourceDirectoryNotFoundError>()(
export class SourceDirectoryNotFoundError extends Schema.TaggedError<SourceDirectoryNotFoundError>()(
"Worktree.SourceDirectoryNotFoundError",
{ projectID: ProjectSchema.ID, directory: Schema.optional(AbsolutePath) },
) {}
export class DestinationExistsError extends Schema.TaggedErrorClass<DestinationExistsError>()(
export class DestinationExistsError extends Schema.TaggedError<DestinationExistsError>()(
"Worktree.DestinationExistsError",
{ directory: AbsolutePath },
) {}
export class InvalidDirectoryError extends Schema.TaggedErrorClass<InvalidDirectoryError>()(
export class InvalidDirectoryError extends Schema.TaggedError<InvalidDirectoryError>()(
"Worktree.InvalidDirectoryError",
{ directory: AbsolutePath },
) {}
export class StrategyUnavailableError extends Schema.TaggedErrorClass<StrategyUnavailableError>()(
export class StrategyUnavailableError extends Schema.TaggedError<StrategyUnavailableError>()(
"Worktree.StrategyUnavailableError",
{ strategy: StrategyID },
) {}
export class DuplicateStrategyError extends Schema.TaggedErrorClass<DuplicateStrategyError>()(
export class DuplicateStrategyError extends Schema.TaggedError<DuplicateStrategyError>()(
"Worktree.DuplicateStrategyError",
{ strategy: StrategyID },
) {}
+1 -1
View File
@@ -4,7 +4,7 @@ import { Effect, Schema } from "effect"
import { FSUtil } from "@opencode-ai/util/fs-util"
import { AbsolutePath } from "../schema.js"
export class DirectoryUnavailableError extends Schema.TaggedErrorClass<DirectoryUnavailableError>()(
export class DirectoryUnavailableError extends Schema.TaggedError<DirectoryUnavailableError>()(
"Worktree.DirectoryUnavailableError",
{ directory: AbsolutePath },
) {}
+3 -3
View File
@@ -541,10 +541,10 @@ describe("Config", () => {
it.effect("migrates arbitrary v1 configuration into valid v2 configuration", () =>
Effect.sync(() => {
FastCheck.assert(
FastCheck.property(Schema.toArbitrary(ConfigV1.Info), (info) => {
FastCheck.property(Schema.toArbitrary(ConfigV1.Info)(FastCheck), (info) => {
const parsed = Schema.decodeUnknownSync(ConfigV1.Info)(
Schema.decodeUnknownSync(Schema.UnknownFromJsonString)(
Schema.encodeUnknownSync(Schema.UnknownFromJsonString)(info),
Schema.decodeUnknownSync(Schema.fromJsonString(Schema.Unknown))(
Schema.encodeUnknownSync(Schema.fromJsonString(Schema.Unknown))(info),
),
)
Schema.decodeUnknownSync(Info)(ConfigMigrateV1.migrate(parsed), { errors: "all" })
@@ -81,7 +81,7 @@ describe("ConfigNormalize", () => {
test("preserves arbitrary JSON-round-tripped native configuration", () => {
FastCheck.assert(
FastCheck.property(Schema.toArbitrary(Info), (info) => {
FastCheck.property(Schema.toArbitrary(Info)(FastCheck), (info) => {
const source = JSON.parse(JSON.stringify(Schema.encodeSync(Info)(info)))
const result = normalized(source)
expect(Schema.decodeUnknownSync(Info)(result.encoded)).toEqual(
@@ -10,7 +10,7 @@ import { Tool } from "@opencode-ai/core/tool"
import type { Info } from "@opencode-ai/schema/tool"
import { LayerNode } from "@opencode-ai/util/effect/layer-node"
import { executeTool, toolDefinitions } from "./lib/tool"
import { Cause, Deferred, Effect, Exit, Fiber, Layer, Option, Schema, SchemaGetter, SchemaIssue, Scope } from "effect"
import { Cause, Deferred, Effect, Exit, Fiber, Layer, Schema, SchemaGetter, SchemaIssue, Scope } from "effect"
import { testEffect } from "./lib/effect"
const imageStore = Layer.mock(Image.Service, {
@@ -127,7 +127,7 @@ describe("Tool", () => {
expect(error).toBeInstanceOf(Tool.RegistrationError)
expect(error.name).toBe("phone_type")
expect(error.message).toContain('Expected string, got undefined\n at ["description"]')
expect(error.message).toContain('Expected string\n at ["description"]')
expect((yield* service.snapshot()).definitions.map((tool) => tool.name)).toEqual(["execute"])
}),
)
@@ -529,7 +529,7 @@ describe("Tool", () => {
encode: SchemaGetter.transformOrFail((value) =>
value === "valid"
? Effect.succeed(true)
: Effect.fail(new SchemaIssue.InvalidValue(Option.some(value), { message: "invalid output" })),
: Effect.fail(new SchemaIssue.InvalidValue({ message: "invalid output" }, value)),
),
}),
),
+3 -3
View File
@@ -9,13 +9,13 @@ Use it for provider integrations, retries, polling, multi-step flows, and any te
## Install
```sh
bun add effect@4.0.0-beta.101
bun add -d @opencode-ai/http-recorder @effect/vitest@4.0.0-beta.101 vitest@^4
bun add effect@4.0.0-beta.107
bun add -d @opencode-ai/http-recorder @effect/vitest@4.0.0-beta.107 vitest@^4
```
The package supports Node.js 22+ and Bun. It is not intended for browsers, workers, or Deno.
Effect `4.0.0-beta.101` currently contains unresolved symbols in its published declarations. Until those upstream declarations are fixed, TypeScript consumers need:
Effect `4.0.0-beta.107` currently contains unresolved symbols in its published declarations. Until those upstream declarations are fixed, TypeScript consumers need:
```json
{
+1 -1
View File
@@ -52,7 +52,7 @@
"typescript": "catalog:"
},
"dependencies": {
"@effect/platform-node-shared": "4.0.0-beta.101"
"@effect/platform-node-shared": "4.0.0-beta.107"
},
"peerDependencies": {
"effect": "catalog:"
+3 -3
View File
@@ -6,7 +6,7 @@ import { CassetteSchema, encodeCassette, type Cassette, type CassetteMetadata, t
const DEFAULT_RECORDINGS_DIR = path.resolve(process.cwd(), "test", "fixtures", "recordings")
export class CassetteNotFoundError extends Schema.TaggedErrorClass<CassetteNotFoundError>()("CassetteNotFoundError", {
export class CassetteNotFoundError extends Schema.TaggedError<CassetteNotFoundError>()("CassetteNotFoundError", {
cassetteName: Schema.String,
}) {
override get message() {
@@ -14,7 +14,7 @@ export class CassetteNotFoundError extends Schema.TaggedErrorClass<CassetteNotFo
}
}
export class InvalidCassetteError extends Schema.TaggedErrorClass<InvalidCassetteError>()("InvalidCassetteError", {
export class InvalidCassetteError extends Schema.TaggedError<InvalidCassetteError>()("InvalidCassetteError", {
cassetteName: Schema.String,
description: Schema.String,
}) {
@@ -23,7 +23,7 @@ export class InvalidCassetteError extends Schema.TaggedErrorClass<InvalidCassett
}
}
export class UnsafeCassetteError extends Schema.TaggedErrorClass<UnsafeCassetteError>()("UnsafeCassetteError", {
export class UnsafeCassetteError extends Schema.TaggedError<UnsafeCassetteError>()("UnsafeCassetteError", {
cassetteName: Schema.String,
findings: Schema.Array(SecretFindingSchema),
}) {
@@ -28,7 +28,7 @@ const DEFAULT_REDACT_QUERY = [
"x-amz-security-token",
"x-amz-signature",
]
const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const redactionSet = (values: ReadonlyArray<string> | undefined, defaults: ReadonlyArray<string>) =>
new Set([...defaults, ...(values ?? [])].map((value) => value.toLowerCase()))
@@ -2,7 +2,7 @@ import { Option, Schema } from "effect"
import { REDACTED } from "../redaction/redactor.js"
import { secretFindings } from "../redaction/secrets.js"
export const decodeJson = Schema.decodeUnknownOption(Schema.UnknownFromJsonString)
export const decodeJson = Schema.decodeUnknownOption(Schema.fromJsonString(Schema.Unknown))
const isRecord = (value: unknown): value is Record<string, unknown> =>
value !== null && typeof value === "object" && !Array.isArray(value)
+176 -62
View File
@@ -48,7 +48,7 @@ export type EffectOutputType = {
type ResolvedEffectTypeReference = Omit<EffectTypeReference, "schema"> & { readonly ast: SchemaAST.AST }
export class GenerationError extends Schema.TaggedErrorClass<GenerationError>()("GenerationError", {
export class GenerationError extends Schema.TaggedError<GenerationError>()("GenerationError", {
reason: Schema.String,
}) {
override get message() {
@@ -92,7 +92,6 @@ type PromiseInputField =
const resolveHttpApiStatus = SchemaAST.resolveAt<number>("httpApiStatus")
const resolveHttpApiEncoding = SchemaAST.resolveAt<HttpApiSchema.Encoding>("~httpApiEncoding")
const resolveContentSchema = SchemaAST.resolveAt<SchemaAST.AST>("contentSchema")
const Manifest = Schema.fromJsonString(Schema.Array(Schema.String))
const manifestName = ".httpapi-codegen.json"
@@ -430,7 +429,7 @@ function effectTypeReferences(input: ReadonlyArray<EffectTypeReference>) {
for (const reference of input) {
const value = { name: reference.name, import: reference.import, ast: reference.schema.ast }
const document = SchemaRepresentation.toCodeDocument(
SchemaRepresentation.fromASTs([Schema.toType(reference.schema).ast]),
SchemaRepresentation.toRepresentations([codegenAst(Schema.toType(reference.schema).ast)]),
)
const name = document.codes[0]?.Type
const type =
@@ -462,7 +461,7 @@ function effectType(schema: Schema.Top, references: ReturnType<typeof effectType
imports.add(direct.import)
return direct.name
}
const document = SchemaRepresentation.toCodeDocument(SchemaRepresentation.fromASTs([projected.ast]))
const document = SchemaRepresentation.toCodeDocument(SchemaRepresentation.toRepresentations([codegenAst(projected.ast)]))
const source = new Map(document.references.nonRecursives.map((reference) => [reference.$ref, reference.code.Type]))
const expand = (type: string, seen = new Set<string>()): string => {
for (const [name, value] of source) {
@@ -588,7 +587,7 @@ function renderEffectFiles(groups: ReadonlyArray<Group>): Output["files"] {
{
path: "client-error.ts",
content:
'import { Schema } from "effect"\n\nexport class ClientError extends Schema.TaggedErrorClass<ClientError>()("ClientError", {\n cause: Schema.Defect(),\n}) {}\n',
'import { Schema } from "effect"\n\nexport class ClientError extends Schema.TaggedError<ClientError>()("ClientError", {\n cause: Schema.Defect(),\n}) {}\n',
},
{ path: "client.ts", content: renderClient(groups) },
{
@@ -706,7 +705,7 @@ function renderImportedEffectFiles(
{
path: "client-error.ts",
content:
'import { Schema } from "effect"\n\nexport class ClientError extends Schema.TaggedErrorClass<ClientError>()("ClientError", {\n cause: Schema.Defect(),\n}) {}\n',
'import { Schema } from "effect"\n\nexport class ClientError extends Schema.TaggedError<ClientError>()("ClientError", {\n cause: Schema.Defect(),\n}) {}\n',
},
{ path: "client.ts", content: client },
{
@@ -983,9 +982,10 @@ function identifierPart(value: string) {
function structuralTypes(schemas: ReadonlyArray<Schema.Top>, mutable: boolean, reservedNames: ReadonlySet<string>) {
if (schemas.length === 0) return { types: [], definitions: [] }
const document = SchemaRepresentation.toCodeDocument(
SchemaRepresentation.fromASTs(schemas.map((schema) => schema.ast) as [SchemaAST.AST, ...Array<SchemaAST.AST>]),
const representations = SchemaRepresentation.toRepresentations(
promiseTypeAsts(schemas) as [SchemaAST.AST, ...Array<SchemaAST.AST>],
)
const document = SchemaRepresentation.toCodeDocument(representations)
if (
document.artifacts.some(
(artifact) =>
@@ -995,9 +995,35 @@ function structuralTypes(schemas: ReadonlyArray<Schema.Top>, mutable: boolean, r
) {
throw new GenerationError({ reason: "Referenced Promise types are not implemented" })
}
const anonymous = new Set(
Object.entries(representations.references)
.filter(([, reference]) => {
if (!("annotations" in reference) || reference.annotations === undefined) return true
return reference.annotations.identifier === undefined && reference.annotations["~identifier"] === undefined
})
.map(([name]) => name),
)
const anonymousTypes = new Map(
document.references.nonRecursives
.filter((reference) => anonymous.has(reference.$ref))
.map((reference) => [reference.$ref, reference.code.Type]),
)
const inlineAnonymous = (type: string, seen = new Set<string>()): string => {
for (const [reference, value] of anonymousTypes) {
const pattern = `(?<![A-Za-z0-9_$.'"])${reference.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?![A-Za-z0-9_$.'"])`
if (!new RegExp(pattern).test(type)) continue
if (seen.has(reference)) {
throw new GenerationError({ reason: `Recursive Promise types are not implemented: ${reference}` })
}
type = type.replaceAll(new RegExp(pattern, "g"), `(${inlineAnonymous(value, new Set([...seen, reference]))})`)
}
return type
}
const names = new Map<string, string>()
const usedNames = new Set(reservedNames)
for (const reference of document.references.nonRecursives) {
const references = document.references.nonRecursives.filter((reference) => !anonymous.has(reference.$ref))
const referenceNames = new Set(references.map((reference) => reference.$ref))
for (const reference of references) {
const seed = identifierPart(reference.$ref)
const name = uniqueTypeName(seed, usedNames)
names.set(reference.$ref, name)
@@ -1014,11 +1040,30 @@ function structuralTypes(schemas: ReadonlyArray<Schema.Top>, mutable: boolean, r
.replaceAll(/(?<!["'])\bunknown\b(?!["'])/g, "any")
return mutable ? mutableType(preserveStringSuggestions(output)) : preserveStringSuggestions(output)
}
const equivalent = new Map<string, string>()
for (const reference of references) {
const base = reference.$ref.replace(/_\d+$/, "")
const identifier = referenceNames.has(base) ? base : reference.$ref
const key = `${identifier}\0${render(inlineAnonymous(reference.code.Type))}`
const existing = equivalent.get(key)
if (existing !== undefined) {
names.set(reference.$ref, existing)
continue
}
const name = names.get(reference.$ref)
if (name === undefined) throw new GenerationError({ reason: `Missing Promise type name: ${reference.$ref}` })
equivalent.set(key, name)
}
const emitted = new Set<string>()
return {
types: document.codes.map((code) => render(code.Type)),
definitions: document.references.nonRecursives.map(
(reference) => `export type ${names.get(reference.$ref)} = ${render(reference.code.Type)}`,
),
types: document.codes.map((code) => render(inlineAnonymous(code.Type))),
definitions: references.flatMap((reference) => {
const name = names.get(reference.$ref)
if (name === undefined) throw new GenerationError({ reason: `Missing Promise type name: ${reference.$ref}` })
if (emitted.has(name)) return []
emitted.add(name)
return [`export type ${name} = ${render(inlineAnonymous(reference.code.Type))}`]
}),
}
}
@@ -1028,7 +1073,7 @@ function uniqueTypeName(seed: string, used: ReadonlySet<string>, suffix = 1): st
}
function structuralType(schema: Schema.Top) {
const document = SchemaRepresentation.toCodeDocument(SchemaRepresentation.fromASTs([schema.ast]))
const document = SchemaRepresentation.toCodeDocument(SchemaRepresentation.toRepresentations([promiseTypeAst(schema)]))
if (
document.artifacts.some(
(artifact) =>
@@ -1059,6 +1104,63 @@ function structuralType(schema: Schema.Top) {
)
}
function promiseTypeAst(schema: Schema.Top) {
return codegenAst(schema.ast)
}
function promiseTypeAsts(schemas: ReadonlyArray<Schema.Top>) {
return codegenAsts(schemas.map((schema) => schema.ast))
}
function codegenAst(root: SchemaAST.AST) {
return codegenAsts([root])[0]
}
function codegenAsts(roots: ReadonlyArray<SchemaAST.AST>) {
const cache = new WeakMap<SchemaAST.AST, SchemaAST.AST>()
const references = new Map<string, SchemaAST.AST>()
const recur = (ast: SchemaAST.AST): SchemaAST.AST => {
const cached = cache.get(ast)
if (cached !== undefined) return cached
const identifier = SchemaAST.resolveIdentifier(ast)
const output = normalize(ast)
const referenceKey =
identifier === undefined
? undefined
: `${identifier}\0${ast.context?.isOptional === true}\0${ast.context?.isMutable === true}\0${representationEncoding(output)}`
const reference = referenceKey === undefined ? undefined : references.get(referenceKey)
if (reference !== undefined) {
cache.set(ast, reference)
return reference
}
cache.set(ast, output)
if (referenceKey !== undefined) references.set(referenceKey, output)
return output
}
const normalize = (ast: SchemaAST.AST): SchemaAST.AST => {
if (SchemaAST.isDeclaration(ast) && ast.annotations?.toCode === undefined) {
const representation = ast.annotations?.representation
if (
typeof representation === "object" &&
representation !== null &&
"id" in representation &&
representation.id === "effect/schema/Json"
) {
return Schema.Json.ast
}
if (ast.annotations?.["~constructor"] !== undefined && ast.typeParameters[0] !== undefined) {
const identifier = SchemaAST.resolveIdentifier(ast)
const fields = recur(ast.typeParameters[0])
if (identifier === undefined) return fields
return Schema.make<Schema.Top>(fields).annotate({ identifier }).ast
}
}
if (!("recur" in ast) || typeof ast.recur !== "function") return ast
return ast.recur(recur)
}
return roots.map(recur)
}
function preserveStringSuggestions(type: string) {
return type.replaceAll(/((?:"(?:\\.|[^"\\])*"\s*\|\s*)+)string\b/g, "$1(string & {})")
}
@@ -1206,40 +1308,64 @@ function isPathInput(path: string): path is HttpRouter.PathInput {
return path === "*" || path.startsWith("/")
}
const encodings = new WeakMap<SchemaAST.AST, string>()
function sameEncoding(left: SchemaAST.AST, right: SchemaAST.AST): boolean {
if (!sameRuntimeEncoding(left, right)) return false
return sameRepresentation(left, right)
}
function sameRepresentation(left: SchemaAST.AST, right: SchemaAST.AST): boolean {
return representationEncoding(left) === representationEncoding(right)
}
function representationEncoding(ast: SchemaAST.AST) {
const cached = encodings.get(ast)
if (cached !== undefined) return cached
const encoded = JSON.stringify(SchemaRepresentation.toJson(SchemaRepresentation.toRepresentation(ast)))
encodings.set(ast, encoded)
return encoded
}
function sameRuntimeEncoding(left: SchemaAST.AST, right: SchemaAST.AST): boolean {
if (left._tag !== right._tag || left.encoding?.length !== right.encoding?.length) return false
if (
left.encoding?.some((link, index) => {
const other = right.encoding?.[index]
return other === undefined || link.transformation !== other.transformation || !sameEncoding(link.to, other.to)
return other === undefined || !sameRuntimeEncoding(link.to, other.to)
})
)
) {
return false
}
if (!sameChecks(left.checks, right.checks) || !sameContext(left.context, right.context)) return false
if (SchemaAST.isSuspend(left) && SchemaAST.isSuspend(right)) return sameEncoding(left.thunk(), right.thunk())
if (SchemaAST.isSuspend(left) && SchemaAST.isSuspend(right)) {
return sameRuntimeEncoding(left.thunk(), right.thunk())
}
if (SchemaAST.isUnion(left) && SchemaAST.isUnion(right)) {
return (
left.types.length === right.types.length &&
left.types.every((ast, index) => sameEncoding(ast, right.types[index]))
left.types.every((ast, index) => sameRuntimeEncoding(ast, right.types[index]))
)
}
if (SchemaAST.isArrays(left) && SchemaAST.isArrays(right)) {
return (
left.elements.length === right.elements.length &&
left.rest.length === right.rest.length &&
left.elements.every((ast, index) => sameEncoding(ast, right.elements[index])) &&
left.rest.every((ast, index) => sameEncoding(ast, right.rest[index]))
left.elements.every((ast, index) => sameRuntimeEncoding(ast, right.elements[index])) &&
left.rest.every((ast, index) => sameRuntimeEncoding(ast, right.rest[index]))
)
}
if (SchemaAST.isObjects(left) && SchemaAST.isObjects(right)) {
return (
left.propertySignatures.length === right.propertySignatures.length &&
left.indexSignatures.length === right.indexSignatures.length &&
left.propertySignatures.every((field, index) => sameEncoding(field.type, right.propertySignatures[index].type)) &&
left.propertySignatures.every((field, index) =>
sameRuntimeEncoding(field.type, right.propertySignatures[index].type),
) &&
left.indexSignatures.every(
(field, index) =>
sameEncoding(field.parameter, right.indexSignatures[index].parameter) &&
sameEncoding(field.type, right.indexSignatures[index].type),
sameRuntimeEncoding(field.parameter, right.indexSignatures[index].parameter) &&
sameRuntimeEncoding(field.type, right.indexSignatures[index].type),
)
)
}
@@ -1399,9 +1525,9 @@ function assertPortable(schema: Schema.Top, path: string, portable: Map<SchemaAS
if (!annotationsPortable(ast.annotations)) return false
if (!checksPortable(ast.checks) || ("encodingChecks" in ast && !checksPortable(ast.encodingChecks))) return false
if (SchemaAST.isDeclaration(ast)) {
return generationPortable(ast.annotations?.generation) && ast.typeParameters.every(visit)
return typeof ast.annotations?.toCode === "function" && ast.typeParameters.every(visit)
}
if (ast.encoding !== undefined && ast.annotations?.generation === undefined) return false
if (ast.encoding !== undefined && ast.annotations?.toCode === undefined) return false
if (SchemaAST.isSuspend(ast)) return visit(ast.thunk())
if (SchemaAST.isUnion(ast)) return ast.types.every(visit)
if (SchemaAST.isArrays(ast)) {
@@ -1435,7 +1561,8 @@ function checksPortable(checks: SchemaAST.Checks | undefined): boolean {
return checks.every((check) =>
check._tag === "Filter"
? !check.aborted &&
check.annotations?.meta !== undefined &&
check.annotations?.representation !== undefined &&
serializable(check.annotations.representation) &&
typeof check.annotations.arbitrary === "object" &&
check.annotations.arbitrary !== null &&
"constraint" in check.annotations.arbitrary
@@ -1469,38 +1596,23 @@ function metadataPortable(ast: SchemaAST.AST, seen: Set<SchemaAST.AST>): boolean
return true
}
function generationPortable(generation: unknown): boolean {
if (typeof generation !== "object" || generation === null) return false
const value = generation as {
readonly runtime?: unknown
readonly Type?: unknown
readonly importDeclaration?: unknown
}
if (typeof value.runtime !== "string" || typeof value.Type !== "string") return false
if (value.importDeclaration !== undefined) {
if (
typeof value.importDeclaration !== "string" ||
!/from ["']effect(?:\/[^"']+)?["']$/.test(value.importDeclaration)
) {
return false
}
}
const namespace =
typeof value.importDeclaration === "string"
? /import(?: type)? \* as ([A-Za-z_$][\w$]*)/.exec(value.importDeclaration)?.[1]
: undefined
return value.runtime.startsWith("Schema.") || (namespace !== undefined && value.runtime.startsWith(`${namespace}.`))
}
function annotationsPortable(annotations: Schema.Annotations.Annotations | undefined) {
if (annotations === undefined) return true
return Object.entries(annotations).every(([key, value]) => {
if (
["toCodec", "toCodecJson", "toArbitrary", "toFormatter", "toEquivalence", "~effect/Schema/Class"].includes(key)
[
"toCodec",
"toCodecJson",
"toCodecStringTree",
"toArbitrary",
"toFormatter",
"toEquivalence",
"toCode",
"~constructor",
].includes(key)
) {
return true
}
if (key === "generation") return generationPortable(value)
return serializable(value)
})
}
@@ -1518,7 +1630,7 @@ function taggedErrorFields(schema: Schema.Top) {
}
function declaredErrorFields(schema: Schema.Top) {
if (!SchemaAST.isDeclaration(schema.ast) || schema.ast.annotations?.["~effect/Schema/Class"] === undefined) {
if (!SchemaAST.isDeclaration(schema.ast) || schema.ast.annotations?.["~constructor"] === undefined) {
return undefined
}
const fields = schema.ast.typeParameters[0]
@@ -1559,12 +1671,11 @@ function streamDataSchema(schema: Extract<HttpApiSchema.StreamSchema, { readonly
}
function streamEncodedDataSchema(schema: Extract<HttpApiSchema.StreamSchema, { readonly _tag: "StreamSse" }>) {
const data = streamDataAst(schema.events.ast)
const encodedAst = data.encoding?.at(-1)?.to
if (encodedAst === undefined) throw new GenerationError({ reason: "Invalid SSE data schema" })
const encoded = resolveContentSchema(encodedAst)
if (!SchemaAST.isAST(encoded)) throw new GenerationError({ reason: "Invalid SSE data schema" })
return Schema.make<Schema.Top>(encoded)
const replaceEncoding: unknown = Reflect.get(SchemaAST, "replaceEncoding")
if (typeof replaceEncoding !== "function") throw new GenerationError({ reason: "Invalid SSE data schema" })
const ast: unknown = replaceEncoding(streamDataAst(schema.events.ast), undefined)
if (!SchemaAST.isAST(ast)) throw new GenerationError({ reason: "Invalid SSE data schema" })
return Schema.toEncoded(Schema.make<Schema.Top>(ast))
}
function streamDataAst(ast: SchemaAST.AST) {
@@ -1733,12 +1844,15 @@ function renderSchemas(slots: ReadonlyArray<Slot>) {
]
const [first, ...rest] = expanded
const document = SchemaRepresentation.toCodeDocument(
SchemaRepresentation.fromASTs([first.schema.ast, ...rest.map((slot) => slot.schema.ast)]),
SchemaRepresentation.toRepresentations(codegenAsts(expanded.map((slot) => slot.schema.ast)) as [
SchemaAST.AST,
...Array<SchemaAST.AST>,
]),
)
const artifacts = document.artifacts.flatMap((artifact) => {
if (artifact._tag === "Import") return [artifact.importDeclaration]
if (artifact._tag === "Enum") return [artifact.generation.runtime]
return [`const ${artifact.identifier} = ${artifact.generation.runtime}`]
if (artifact._tag === "Enum") return [artifact.code.runtime]
return [`const ${artifact.identifier} = ${artifact.code.runtime}`]
})
const references = [
...document.references.nonRecursives.map(({ $ref, code }) => `const ${$ref} = ${code.runtime}`),
@@ -1761,7 +1875,7 @@ function renderSchemas(slots: ReadonlyArray<Slot>) {
annotations.length === 0
? ""
: `.annotate({ ${annotations.map(([key, value]) => `${JSON.stringify(key)}: ${JSON.stringify(value)}`).join(", ")} })`
return `class ${slot.name}Class extends Schema.TaggedErrorClass<${slot.name}Class>(${JSON.stringify(tagged.identifier)})(${JSON.stringify(tagged.tag)}, { ${fields} }) {}\nconst ${slot.name} = ${slot.name}Class${annotate}`
return `class ${slot.name}Class extends Schema.TaggedError<${slot.name}Class>(${JSON.stringify(tagged.identifier)})(${JSON.stringify(tagged.tag)}, { ${fields} }) {}\nconst ${slot.name} = ${slot.name}Class${annotate}`
})
return [...artifacts, ...references, ...declarations].join("\n\n")
}
+1 -1
View File
@@ -1,7 +1,7 @@
import { Schema } from "effect"
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiSchema } from "effect/unstable/httpapi"
export class Missing extends Schema.TaggedErrorClass<Missing>()("Missing", {
export class Missing extends Schema.TaggedError<Missing>()("Missing", {
message: Schema.String,
}) {}
+73 -10
View File
@@ -504,7 +504,7 @@ describe("HttpApiCodegen.generate", () => {
})
test("preserves optional keys in Promise error types", () => {
class OptionalError extends Schema.TaggedErrorClass<OptionalError>()(
class OptionalError extends Schema.TaggedError<OptionalError>()(
"OptionalError",
{ message: Schema.String, detail: Schema.String.pipe(Schema.optional) },
{ httpApiStatus: 400 },
@@ -519,7 +519,7 @@ describe("HttpApiCodegen.generate", () => {
})
test("supports name-discriminated Promise errors", () => {
class NamedError extends Schema.ErrorClass<NamedError>("NamedError")(
class NamedError extends Schema.Error<NamedError>("NamedError")(
{ name: Schema.Literal("NamedError"), message: Schema.String },
{ httpApiStatus: 400 },
) {}
@@ -535,7 +535,7 @@ describe("HttpApiCodegen.generate", () => {
})
test("preserves reflected default error statuses", () => {
class MissingStatus extends Schema.TaggedErrorClass<MissingStatus>()("MissingStatus", {
class MissingStatus extends Schema.TaggedError<MissingStatus>()("MissingStatus", {
message: Schema.String,
}) {}
const output = emitPromise(
@@ -579,10 +579,14 @@ describe("HttpApiCodegen.generate", () => {
const Referenced = Schema.Struct({ value: Schema.String }).annotate({ identifier: "Referenced" })
const output = emitPromise(
compileContract(
api(
HttpApiEndpoint.get("get", "/session", {
success: Schema.Struct({ data: Referenced }),
}),
HttpApi.make("test").add(
HttpApiGroup.make("session")
.add(HttpApiEndpoint.get("get", "/session", { success: Schema.Struct({ data: Referenced }) }))
.add(
HttpApiEndpoint.get("list", "/sessions", {
success: Schema.Struct({ data: Schema.Array(Referenced) }),
}),
),
),
),
)
@@ -590,6 +594,21 @@ describe("HttpApiCodegen.generate", () => {
const types = output.files.find((file) => file.path === "types.ts")?.content
expect(types).toContain('export type Referenced = { readonly "value": string }')
expect(types).toContain('export type SessionGetOutput = ({ readonly "data": Referenced })["data"]')
expect(types).not.toContain("Referenced1")
})
test("inlines shared anonymous Promise wire types", () => {
const Shared = Schema.Struct({ value: Schema.String })
const output = emitPromise(
compileContract(
api(HttpApiEndpoint.get("get", "/session", { success: Schema.Struct({ first: Shared, second: Shared }) })),
),
)
const types = output.files.find((file) => file.path === "types.ts")?.content
expect(types).toContain('readonly "first": ({ readonly "value": string })')
expect(types).toContain('readonly "second": ({ readonly "value": string })')
expect(types).not.toContain("export type Objects")
})
test("emits mutable Promise outputs without restricting inputs", () => {
@@ -647,6 +666,37 @@ describe("HttpApiCodegen.generate", () => {
expect(types).toContain("export type ExampleName2 = string")
})
test("keeps conflicting Promise reference identifiers distinct", () => {
const First = Schema.Struct({ value: Schema.String }).annotate({ identifier: "Shared" })
const Second = Schema.Struct({ value: Schema.Number }).annotate({ identifier: "Shared" })
const output = emitPromise(
compileContract(
api(HttpApiEndpoint.get("get", "/session", { success: Schema.Struct({ first: First, second: Second }) })),
),
)
const types = output.files.find((file) => file.path === "types.ts")?.content
expect(types).toContain('export type Shared = { readonly "value": string }')
expect(types).toContain('export type Shared1 = { readonly "value": number }')
expect(types).toContain('readonly "first": Shared, readonly "second": Shared1')
})
test("deduplicates equivalent Promise references with the same identifier", () => {
const First = Schema.String.annotate({ identifier: "Shared", description: "first" })
const Second = Schema.String.annotate({ identifier: "Shared", description: "second" })
const output = emitPromise(
compileContract(
api(HttpApiEndpoint.get("get", "/session", { success: Schema.Struct({ first: First, second: Second }) })),
),
)
const types = output.files.find((file) => file.path === "types.ts")?.content
expect(types).toContain("export type Shared = string")
expect(types).not.toContain("export type Shared1")
expect(types).toContain('readonly "first": Shared, readonly "second": Shared')
})
test("emits Effect Json schemas as standalone Promise types", () => {
const output = emitPromise(
compileContract(
@@ -1347,6 +1397,19 @@ describe("HttpApiCodegen.generate", () => {
).toThrow("Effect schema requires authoritative import: session.get")
})
test("rejects same-shape custom transformations", () => {
const Trimmed = Schema.String.pipe(
Schema.decodeTo(Schema.String, {
decode: SchemaGetter.transform((value) => value.trim()),
encode: SchemaGetter.transform((value) => value),
}),
)
expect(() => compile(api(HttpApiEndpoint.get("get", "/session", { success: Trimmed })))).toThrow(
"Effect schema requires authoritative import: session.get",
)
})
test("rejects custom validation checks without portable metadata", () => {
const Positive = Schema.Number.check(Schema.makeFilter((value) => (value > 0 ? undefined : "positive")))
@@ -1404,7 +1467,7 @@ describe("HttpApiCodegen.generate", () => {
})
test("preserves errors from server-only middleware", () => {
class Unauthorized extends Schema.TaggedErrorClass<Unauthorized>()("Unauthorized", {}) {}
class Unauthorized extends Schema.TaggedError<Unauthorized>()("Unauthorized", {}) {}
class Authorization extends HttpApiMiddleware.Service<Authorization>()("Authorization", {
error: Unauthorized,
}) {}
@@ -1415,12 +1478,12 @@ describe("HttpApiCodegen.generate", () => {
expect(output.operations[0]).toBeDefined()
expect(output.files.find((file) => file.path === "session.ts")?.content).toContain(
'extends Schema.TaggedErrorClass<Endpoint0Error0Class>("Unauthorized")',
'extends Schema.TaggedError<Endpoint0Error0Class>("Unauthorized")',
)
})
test("preserves tagged error response statuses", () => {
class Missing extends Schema.TaggedErrorClass<Missing>()("Missing", {}) {}
class Missing extends Schema.TaggedError<Missing>()("Missing", {}) {}
const output = compile(
api(
HttpApiEndpoint.get("get", "/session", {
@@ -1,5 +1,5 @@
import { Schema } from "effect"
export class ClientError extends Schema.TaggedErrorClass<ClientError>()("ClientError", {
export class ClientError extends Schema.TaggedError<ClientError>()("ClientError", {
cause: Schema.Defect(),
}) {}
@@ -15,7 +15,7 @@ const Endpoint2Params = Schema.Struct({ sessionID: Schema.String })
const Endpoint2Success = Schema.Struct({ data: Schema.String })
class Endpoint2Error0Class extends Schema.TaggedErrorClass<Endpoint2Error0Class>("Missing")("Missing", {
class Endpoint2Error0Class extends Schema.TaggedError<Endpoint2Error0Class>("Missing")("Missing", {
message: Schema.String,
}) {}
const Endpoint2Error0 = Endpoint2Error0Class.annotate({ httpApiStatus: 404 })
+22 -22
View File
@@ -1,7 +1,7 @@
import { Schema } from "effect"
import { Skill } from "@opencode-ai/schema/skill"
export class InvalidRequestError extends Schema.TaggedErrorClass<InvalidRequestError>()(
export class InvalidRequestError extends Schema.TaggedError<InvalidRequestError>()(
"InvalidRequestError",
{
message: Schema.String,
@@ -11,13 +11,13 @@ export class InvalidRequestError extends Schema.TaggedErrorClass<InvalidRequestE
{ httpApiStatus: 400 },
) {}
export class UnauthorizedError extends Schema.TaggedErrorClass<UnauthorizedError>()(
export class UnauthorizedError extends Schema.TaggedError<UnauthorizedError>()(
"UnauthorizedError",
{ message: Schema.String },
{ httpApiStatus: 401 },
) {}
export class ConflictError extends Schema.TaggedErrorClass<ConflictError>()(
export class ConflictError extends Schema.TaggedError<ConflictError>()(
"ConflictError",
{
message: Schema.String,
@@ -26,7 +26,7 @@ export class ConflictError extends Schema.TaggedErrorClass<ConflictError>()(
{ httpApiStatus: 409 },
) {}
export class SessionBusyError extends Schema.TaggedErrorClass<SessionBusyError>()(
export class SessionBusyError extends Schema.TaggedError<SessionBusyError>()(
"SessionBusyError",
{
sessionID: Schema.String,
@@ -35,7 +35,7 @@ export class SessionBusyError extends Schema.TaggedErrorClass<SessionBusyError>(
{ httpApiStatus: 409 },
) {}
export class ServiceUnavailableError extends Schema.TaggedErrorClass<ServiceUnavailableError>()(
export class ServiceUnavailableError extends Schema.TaggedError<ServiceUnavailableError>()(
"ServiceUnavailableError",
{
message: Schema.String,
@@ -44,7 +44,7 @@ export class ServiceUnavailableError extends Schema.TaggedErrorClass<ServiceUnav
{ httpApiStatus: 503 },
) {}
export class UnknownError extends Schema.TaggedErrorClass<UnknownError>()(
export class UnknownError extends Schema.TaggedError<UnknownError>()(
"UnknownError",
{
message: Schema.String,
@@ -53,7 +53,7 @@ export class UnknownError extends Schema.TaggedErrorClass<UnknownError>()(
{ httpApiStatus: 500 },
) {}
export class ProviderNotFoundError extends Schema.TaggedErrorClass<ProviderNotFoundError>()(
export class ProviderNotFoundError extends Schema.TaggedError<ProviderNotFoundError>()(
"ProviderNotFoundError",
{
providerID: Schema.String,
@@ -62,7 +62,7 @@ export class ProviderNotFoundError extends Schema.TaggedErrorClass<ProviderNotFo
{ httpApiStatus: 404 },
) {}
export class AgentNotFoundError extends Schema.TaggedErrorClass<AgentNotFoundError>()(
export class AgentNotFoundError extends Schema.TaggedError<AgentNotFoundError>()(
"AgentNotFoundError",
{
agentID: Schema.String,
@@ -71,7 +71,7 @@ export class AgentNotFoundError extends Schema.TaggedErrorClass<AgentNotFoundErr
{ httpApiStatus: 404 },
) {}
export class SessionNotFoundError extends Schema.TaggedErrorClass<SessionNotFoundError>()(
export class SessionNotFoundError extends Schema.TaggedError<SessionNotFoundError>()(
"SessionNotFoundError",
{
sessionID: Schema.String,
@@ -80,7 +80,7 @@ export class SessionNotFoundError extends Schema.TaggedErrorClass<SessionNotFoun
{ httpApiStatus: 404 },
) {}
export class MessageNotFoundError extends Schema.TaggedErrorClass<MessageNotFoundError>()(
export class MessageNotFoundError extends Schema.TaggedError<MessageNotFoundError>()(
"MessageNotFoundError",
{
sessionID: Schema.String,
@@ -90,7 +90,7 @@ export class MessageNotFoundError extends Schema.TaggedErrorClass<MessageNotFoun
{ httpApiStatus: 404 },
) {}
export class SkillNotFoundError extends Schema.TaggedErrorClass<SkillNotFoundError>()(
export class SkillNotFoundError extends Schema.TaggedError<SkillNotFoundError>()(
"SkillNotFoundError",
{
skill: Skill.ID,
@@ -99,7 +99,7 @@ export class SkillNotFoundError extends Schema.TaggedErrorClass<SkillNotFoundErr
{ httpApiStatus: 404 },
) {}
export class McpServerNotFoundError extends Schema.TaggedErrorClass<McpServerNotFoundError>()(
export class McpServerNotFoundError extends Schema.TaggedError<McpServerNotFoundError>()(
"McpServerNotFoundError",
{
server: Schema.String,
@@ -108,7 +108,7 @@ export class McpServerNotFoundError extends Schema.TaggedErrorClass<McpServerNot
{ httpApiStatus: 404 },
) {}
export class CommandNotFoundError extends Schema.TaggedErrorClass<CommandNotFoundError>()(
export class CommandNotFoundError extends Schema.TaggedError<CommandNotFoundError>()(
"CommandNotFoundError",
{
command: Schema.String,
@@ -117,7 +117,7 @@ export class CommandNotFoundError extends Schema.TaggedErrorClass<CommandNotFoun
{ httpApiStatus: 404 },
) {}
export class CommandEvaluationError extends Schema.TaggedErrorClass<CommandEvaluationError>()(
export class CommandEvaluationError extends Schema.TaggedError<CommandEvaluationError>()(
"CommandEvaluationError",
{
command: Schema.String,
@@ -126,13 +126,13 @@ export class CommandEvaluationError extends Schema.TaggedErrorClass<CommandEvalu
{ httpApiStatus: 500 },
) {}
export class InvalidCursorError extends Schema.TaggedErrorClass<InvalidCursorError>()(
export class InvalidCursorError extends Schema.TaggedError<InvalidCursorError>()(
"InvalidCursorError",
{ message: Schema.String },
{ httpApiStatus: 400 },
) {}
export class PermissionNotFoundError extends Schema.TaggedErrorClass<PermissionNotFoundError>()(
export class PermissionNotFoundError extends Schema.TaggedError<PermissionNotFoundError>()(
"PermissionNotFoundError",
{
requestID: Schema.String,
@@ -141,7 +141,7 @@ export class PermissionNotFoundError extends Schema.TaggedErrorClass<PermissionN
{ httpApiStatus: 404 },
) {}
export class FormNotFoundError extends Schema.TaggedErrorClass<FormNotFoundError>()(
export class FormNotFoundError extends Schema.TaggedError<FormNotFoundError>()(
"FormNotFoundError",
{
id: Schema.String,
@@ -150,7 +150,7 @@ export class FormNotFoundError extends Schema.TaggedErrorClass<FormNotFoundError
{ httpApiStatus: 404 },
) {}
export class FormAlreadySettledError extends Schema.TaggedErrorClass<FormAlreadySettledError>()(
export class FormAlreadySettledError extends Schema.TaggedError<FormAlreadySettledError>()(
"FormAlreadySettledError",
{
id: Schema.String,
@@ -159,7 +159,7 @@ export class FormAlreadySettledError extends Schema.TaggedErrorClass<FormAlready
{ httpApiStatus: 409 },
) {}
export class FormInvalidAnswerError extends Schema.TaggedErrorClass<FormInvalidAnswerError>()(
export class FormInvalidAnswerError extends Schema.TaggedError<FormInvalidAnswerError>()(
"FormInvalidAnswerError",
{
id: Schema.String,
@@ -168,13 +168,13 @@ export class FormInvalidAnswerError extends Schema.TaggedErrorClass<FormInvalidA
{ httpApiStatus: 400 },
) {}
export class ForbiddenError extends Schema.TaggedErrorClass<ForbiddenError>()(
export class ForbiddenError extends Schema.TaggedError<ForbiddenError>()(
"ForbiddenError",
{ message: Schema.String },
{ httpApiStatus: 403 },
) {}
export class PtyNotFoundError extends Schema.TaggedErrorClass<PtyNotFoundError>()(
export class PtyNotFoundError extends Schema.TaggedError<PtyNotFoundError>()(
"PtyNotFoundError",
{
ptyID: Schema.String,
@@ -183,7 +183,7 @@ export class PtyNotFoundError extends Schema.TaggedErrorClass<PtyNotFoundError>(
{ httpApiStatus: 404 },
) {}
export class ShellNotFoundError extends Schema.TaggedErrorClass<ShellNotFoundError>()(
export class ShellNotFoundError extends Schema.TaggedError<ShellNotFoundError>()(
"ShellNotFoundError",
{
id: Schema.String,
+1 -1
View File
@@ -5,7 +5,7 @@ import { HttpApiEndpoint, HttpApiGroup, HttpApiSchema, OpenApi } from "effect/un
const root = "/api/worktree/:projectID"
export class WorktreeError extends Schema.ErrorClass<WorktreeError>("WorktreeError")(
export class WorktreeError extends Schema.Error<WorktreeError>("WorktreeError")(
{
name: Schema.Literal("WorktreeError"),
data: Schema.Struct({
+4 -4
View File
@@ -60,7 +60,7 @@ export namespace JsonRpc {
}
}
export class SimulationRequestError extends Schema.TaggedErrorClass<SimulationRequestError>()(
export class SimulationRequestError extends Schema.TaggedError<SimulationRequestError>()(
"SimulationRequestError",
{
method: Schema.String,
@@ -131,7 +131,7 @@ export namespace Handshake {
readonly capabilities: ReadonlyArray<Capability>
}
export class RoleMismatchError extends Schema.TaggedErrorClass<RoleMismatchError>()(
export class RoleMismatchError extends Schema.TaggedError<RoleMismatchError>()(
"SimulationHandshake.RoleMismatchError",
{
expected: EndpointRole,
@@ -140,7 +140,7 @@ export namespace Handshake {
},
) {}
export class UnsupportedProtocolError extends Schema.TaggedErrorClass<UnsupportedProtocolError>()(
export class UnsupportedProtocolError extends Schema.TaggedError<UnsupportedProtocolError>()(
"SimulationHandshake.UnsupportedProtocolError",
{
offered: Schema.Array(Schema.Number),
@@ -149,7 +149,7 @@ export namespace Handshake {
},
) {}
export class MissingCapabilityError extends Schema.TaggedErrorClass<MissingCapabilityError>()(
export class MissingCapabilityError extends Schema.TaggedError<MissingCapabilityError>()(
"SimulationHandshake.MissingCapabilityError",
{
missing: Schema.Array(Capability),
+1 -1
View File
@@ -21,7 +21,7 @@ export interface Info extends Schema.Schema.Type<typeof Info> {}
export const MaxValueBytes = 8 * 1024
export class ValueTooLargeError extends Schema.TaggedErrorClass<ValueTooLargeError>()(
export class ValueTooLargeError extends Schema.TaggedError<ValueTooLargeError>()(
"InstructionEntryValueTooLargeError",
{
actualBytes: Schema.Int,
+1 -1
View File
@@ -56,7 +56,7 @@ type OutputValue<S> = S extends undefined
? A
: any
export class Error extends Schema.TaggedErrorClass<Error>()("Tool.Error", {
export class Error extends Schema.TaggedError<Error>()("Tool.Error", {
message: Schema.String,
error: Schema.optional(Schema.Defect()),
metadata: Schema.optional(Schema.Record(Schema.String, Schema.Unknown)),
+2 -2
View File
@@ -7,12 +7,12 @@ import { Cause, Context, Effect, Layer, Queue, Schema, Scope, Stream } from "eff
export const SubscriberCapacity = 4_096
export class SubscriberOverflowError extends Schema.TaggedErrorClass<SubscriberOverflowError>()(
export class SubscriberOverflowError extends Schema.TaggedError<SubscriberOverflowError>()(
"EventFeed.SubscriberOverflow",
{ capacity: Schema.Int },
) {}
export class EncodingError extends Schema.TaggedErrorClass<EncodingError>()("EventFeed.EncodingError", {
export class EncodingError extends Schema.TaggedError<EncodingError>()("EventFeed.EncodingError", {
eventID: Event.ID,
eventType: Schema.String,
cause: Schema.Defect(),
@@ -32,7 +32,7 @@ export type ProviderResponseEvent =
| SimulationProtocol.Backend.Item
| { readonly type: "finish"; readonly reason: SimulationProtocol.Backend.FinishReason }
export class ProviderDisconnectedError extends Schema.TaggedErrorClass<ProviderDisconnectedError>()(
export class ProviderDisconnectedError extends Schema.TaggedError<ProviderDisconnectedError>()(
"SimulatedProvider.ProviderDisconnectedError",
{ message: Schema.String },
) {}
@@ -132,22 +132,22 @@ interface ToolDriver {
readonly shutdown: Effect.Effect<void>
}
class InvocationNotFoundError extends Schema.TaggedErrorClass<InvocationNotFoundError>()(
class InvocationNotFoundError extends Schema.TaggedError<InvocationNotFoundError>()(
"SimulatedProvider.InvocationNotFoundError",
{ id: Schema.String, message: Schema.String },
) {}
class ControllerDisconnectedError extends Schema.TaggedErrorClass<ControllerDisconnectedError>()(
class ControllerDisconnectedError extends Schema.TaggedError<ControllerDisconnectedError>()(
"SimulatedProvider.ControllerDisconnectedError",
{ message: Schema.String },
) {}
class ToolInvocationNotFoundError extends Schema.TaggedErrorClass<ToolInvocationNotFoundError>()(
class ToolInvocationNotFoundError extends Schema.TaggedError<ToolInvocationNotFoundError>()(
"SimulatedProvider.ToolInvocationNotFoundError",
{ id: Schema.String, message: Schema.String },
) {}
class ToolControllerError extends Schema.TaggedErrorClass<ToolControllerError>()(
class ToolControllerError extends Schema.TaggedError<ToolControllerError>()(
"SimulatedProvider.ToolControllerError",
{ message: Schema.String },
) {}
+1 -1
View File
@@ -43,7 +43,7 @@ export const Manifest = Schema.Struct({
})
export interface Manifest extends Schema.Schema.Type<typeof Manifest> {}
export class ResolveError extends Schema.TaggedErrorClass<ResolveError>()("DriveManifest.ResolveError", {
export class ResolveError extends Schema.TaggedError<ResolveError>()("DriveManifest.ResolveError", {
reason: Schema.Literals(["config", "not-found", "read", "decode"]),
path: Schema.optionalKey(Schema.String),
message: Schema.String,
+1 -1
View File
@@ -26,7 +26,7 @@ import type {
} from "./index.js"
import { selectTheme, selectThemeMode } from "./select.js"
const decodeThemeDefinitionSchema = Schema.decodeUnknownSync(ThemeDefinition)
const decodeThemeDefinitionSchema = Schema.decodeUnknownSync(ThemeDefinition, { reportInput: true })
function decodeThemeDefinition(input: unknown) {
try {
+1 -1
View File
@@ -13,7 +13,7 @@ let customThemes: Record<string, ThemeDocumentSource> = {}
let systemTheme: ThemeDocumentSource | undefined
const listeners = new Set<(themes: Record<string, ThemeDocumentSource>) => void>()
const parsed = new WeakMap<object, ThemeDocument>()
const decodeThemeDocument = Schema.decodeUnknownSync(ThemeDocument)
const decodeThemeDocument = Schema.decodeUnknownSync(ThemeDocument, { reportInput: true })
function listThemes() {
// Priority: defaults < plugin installs < custom files < generated system.
+4 -4
View File
@@ -14,15 +14,15 @@ export namespace EffectFlock {
// Errors
// ---------------------------------------------------------------------------
export class LockTimeoutError extends Schema.TaggedErrorClass<LockTimeoutError>()("LockTimeoutError", {
export class LockTimeoutError extends Schema.TaggedError<LockTimeoutError>()("LockTimeoutError", {
key: Schema.String,
}) {}
export class LockCompromisedError extends Schema.TaggedErrorClass<LockCompromisedError>()("LockCompromisedError", {
export class LockCompromisedError extends Schema.TaggedError<LockCompromisedError>()("LockCompromisedError", {
detail: Schema.String,
}) {}
class ReleaseError extends Schema.TaggedErrorClass<ReleaseError>()("ReleaseError", {
class ReleaseError extends Schema.TaggedError<ReleaseError>()("ReleaseError", {
detail: Schema.String,
cause: Schema.optional(Schema.Defect()),
}) {
@@ -32,7 +32,7 @@ export namespace EffectFlock {
}
/** Internal: signals "lock is held, retry later". Never leaks to callers. */
class NotAcquired extends Schema.TaggedErrorClass<NotAcquired>()("NotAcquired", {}) {}
class NotAcquired extends Schema.TaggedError<NotAcquired>()("NotAcquired", {}) {}
export type LockError = LockTimeoutError | LockCompromisedError
+1 -1
View File
@@ -11,7 +11,7 @@ import { makeGlobalNode } from "./effect/app-node.js"
import { filesystem } from "./effect/app-node-platform.js"
export namespace FSUtil {
export class FileSystemError extends Schema.TaggedErrorClass<FileSystemError>()("FileSystemError", {
export class FileSystemError extends Schema.TaggedError<FileSystemError>()("FileSystemError", {
method: Schema.String,
cause: Schema.optional(Schema.Defect()),
}) {
+1 -1
View File
@@ -13,7 +13,7 @@ import { makeRuntime } from "./effect/runtime.js"
import { NpmConfig } from "./npm-config.js"
import { resolveModule } from "#runtime-import"
export class InstallFailedError extends Schema.TaggedErrorClass<InstallFailedError>()("NpmInstallFailedError", {
export class InstallFailedError extends Schema.TaggedError<InstallFailedError>()("NpmInstallFailedError", {
add: Schema.Array(Schema.String).pipe(Schema.optional),
dir: Schema.String,
cause: Schema.optional(Schema.Defect()),
+2 -1
View File
@@ -4,7 +4,7 @@ import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem"
import { LayerNode } from "./effect/layer-node.js"
import { Effect, Layer, Logger, References, Schema } from "effect"
import { FetchHttpClient } from "effect/unstable/http"
import { OtlpSerialization } from "effect/unstable/observability"
import { OtlpExporter, OtlpSerialization } from "effect/unstable/observability"
import { Logging } from "./observability/logging.js"
import { Otlp } from "./observability/otlp.js"
@@ -42,6 +42,7 @@ export function layer(
Layer.provide(NodeFileSystem.layer),
Layer.provide(OtlpSerialization.layerJson),
Layer.provide(FetchHttpClient.layer),
Layer.provide(OtlpExporter.layerFlusher),
Layer.orDie,
Layer.merge(Layer.succeed(References.MinimumLogLevel, Logging.minimumLogLevel())),
)
+2 -2
View File
@@ -3,7 +3,7 @@ export * as Patch from "./patch.js"
import { Result, Schema } from "effect"
import { Bom } from "./bom.js"
export class BoundaryError extends Schema.TaggedErrorClass<BoundaryError>()("Patch.BoundaryError", {
export class BoundaryError extends Schema.TaggedError<BoundaryError>()("Patch.BoundaryError", {
boundary: Schema.Literals(["first", "last"]),
}) {
override get message() {
@@ -11,7 +11,7 @@ export class BoundaryError extends Schema.TaggedErrorClass<BoundaryError>()("Pat
}
}
export class InvalidHunkError extends Schema.TaggedErrorClass<InvalidHunkError>()("Patch.InvalidHunkError", {
export class InvalidHunkError extends Schema.TaggedError<InvalidHunkError>()("Patch.InvalidHunkError", {
line: Schema.String,
lineNumber: Schema.Number,
reason: Schema.optional(Schema.String),
+1 -1
View File
@@ -5,7 +5,7 @@ import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner
import { CrossSpawnSpawner } from "./cross-spawn-spawner.js"
import { makeGlobalNode } from "./effect/app-node.js"
export class AppProcessError extends Schema.TaggedErrorClass<AppProcessError>()("AppProcessError", {
export class AppProcessError extends Schema.TaggedError<AppProcessError>()("AppProcessError", {
command: Schema.String,
exitCode: Schema.optional(Schema.Number),
stderr: Schema.optional(Schema.String),
+42
View File
@@ -0,0 +1,42 @@
diff --git a/cache/core/cache-effect.cjs b/cache/core/cache-effect.cjs
--- a/cache/core/cache-effect.cjs
+++ b/cache/core/cache-effect.cjs
@@ -103,1 +103,1 @@
-var EffectCacheError = class extends effect_Schema.TaggedErrorClass()("EffectCacheError", { cause: effect_Schema.Unknown }) {
+var EffectCacheError = class extends effect_Schema.TaggedError()("EffectCacheError", { cause: effect_Schema.Unknown }) {
diff --git a/cache/core/cache-effect.js b/cache/core/cache-effect.js
--- a/cache/core/cache-effect.js
+++ b/cache/core/cache-effect.js
@@ -97,1 +97,1 @@
-var EffectCacheError = class extends Schema.TaggedErrorClass()("EffectCacheError", { cause: Schema.Unknown }) {
+var EffectCacheError = class extends Schema.TaggedError()("EffectCacheError", { cause: Schema.Unknown }) {
diff --git a/effect-core/errors.cjs b/effect-core/errors.cjs
--- a/effect-core/errors.cjs
+++ b/effect-core/errors.cjs
@@ -8,1 +8,1 @@
-var EffectDrizzleError = class extends effect_Schema.TaggedErrorClass()("EffectDrizzleError", {
+var EffectDrizzleError = class extends effect_Schema.TaggedError()("EffectDrizzleError", {
@@ -14,1 +14,1 @@
-var EffectDrizzleQueryError = class EffectDrizzleQueryError extends effect_Schema.TaggedErrorClass()("EffectDrizzleQueryError", {
+var EffectDrizzleQueryError = class EffectDrizzleQueryError extends effect_Schema.TaggedError()("EffectDrizzleQueryError", {
@@ -28,1 +28,1 @@
-var EffectTransactionRollbackError = class extends effect_Schema.TaggedErrorClass()("EffectTransactionRollbackError", {}) {
+var EffectTransactionRollbackError = class extends effect_Schema.TaggedError()("EffectTransactionRollbackError", {}) {
@@ -32,1 +32,1 @@
-var MigratorInitError = class extends effect_Schema.TaggedErrorClass()("MigratorInitError", { exitCode: effect_Schema.Literals(["databaseMigrations", "localMigrations"]) }) {
+var MigratorInitError = class extends effect_Schema.TaggedError()("MigratorInitError", { exitCode: effect_Schema.Literals(["databaseMigrations", "localMigrations"]) }) {
diff --git a/effect-core/errors.js b/effect-core/errors.js
--- a/effect-core/errors.js
+++ b/effect-core/errors.js
@@ -5,1 +5,1 @@
-var EffectDrizzleError = class extends Schema.TaggedErrorClass()("EffectDrizzleError", {
+var EffectDrizzleError = class extends Schema.TaggedError()("EffectDrizzleError", {
@@ -11,1 +11,1 @@
-var EffectDrizzleQueryError = class EffectDrizzleQueryError extends Schema.TaggedErrorClass()("EffectDrizzleQueryError", {
+var EffectDrizzleQueryError = class EffectDrizzleQueryError extends Schema.TaggedError()("EffectDrizzleQueryError", {
@@ -25,1 +25,1 @@
-var EffectTransactionRollbackError = class extends Schema.TaggedErrorClass()("EffectTransactionRollbackError", {}) {
+var EffectTransactionRollbackError = class extends Schema.TaggedError()("EffectTransactionRollbackError", {}) {
@@ -29,1 +29,1 @@
-var MigratorInitError = class extends Schema.TaggedErrorClass()("MigratorInitError", { exitCode: Schema.Literals(["databaseMigrations", "localMigrations"]) }) {
+var MigratorInitError = class extends Schema.TaggedError()("MigratorInitError", { exitCode: Schema.Literals(["databaseMigrations", "localMigrations"]) }) {
-37
View File
@@ -1,37 +0,0 @@
diff --git a/dist/Deferred.js b/dist/Deferred.js
index dd5334d6e42b0881f411fca56688e639cd49c176..ea200a80d6186f07a29d0d231ff1f038433bfec3 100644
--- a/dist/Deferred.js
+++ b/dist/Deferred.js
@@ -81,8 +81,12 @@ const _await = self => internalEffect.callback(resume => {
self.resumes ??= [];
self.resumes.push(resume);
return internalEffect.sync(() => {
+ // Completion resumes every waiter and clears the array, so a cleanup
+ // that runs after completion (an interrupt racing the resume) has
+ // nothing to unregister.
+ if (!self.resumes) return;
const index = self.resumes.indexOf(resume);
- self.resumes.splice(index, 1);
+ if (index >= 0) self.resumes.splice(index, 1);
});
});
export {
diff --git a/src/Deferred.ts b/src/Deferred.ts
index f6d37948bfbe690a7998b06c562e434e1b8ae084..da91e4dc0fd32e534fbc72f7beb0514e67e4ce74 100644
--- a/src/Deferred.ts
+++ b/src/Deferred.ts
@@ -188,8 +188,12 @@ const _await = <A, E>(self: Deferred<A, E>): Effect<A, E> =>
self.resumes ??= []
self.resumes.push(resume)
return internalEffect.sync(() => {
- const index = self.resumes!.indexOf(resume)
- self.resumes!.splice(index, 1)
+ // Completion resumes every waiter and clears the array, so a cleanup
+ // that runs after completion (an interrupt racing the resume) has
+ // nothing to unregister.
+ if (!self.resumes) return
+ const index = self.resumes.indexOf(resume)
+ if (index >= 0) self.resumes.splice(index, 1)
})
})