mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-28 13:43:33 +00:00
chore: upgrade Effect to beta.98 (#37498)
This commit is contained in:
parent
b26d948b76
commit
44f7bb71c1
37 changed files with 316 additions and 138 deletions
56
bun.lock
56
bun.lock
|
|
@ -185,7 +185,7 @@
|
|||
"effect": "catalog:",
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "4.0.0-beta.83",
|
||||
"effect": "4.0.0-beta.98",
|
||||
},
|
||||
"optionalPeers": [
|
||||
"effect",
|
||||
|
|
@ -569,7 +569,7 @@
|
|||
"name": "@opencode-ai/http-recorder",
|
||||
"version": "1.18.3",
|
||||
"dependencies": {
|
||||
"@effect/platform-node-shared": "4.0.0-beta.83",
|
||||
"@effect/platform-node-shared": "4.0.0-beta.98",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@effect/platform-node": "catalog:",
|
||||
|
|
@ -1180,12 +1180,12 @@
|
|||
"@modelcontextprotocol/sdk@1.29.0": "patches/@modelcontextprotocol%2Fsdk@1.29.0.patch",
|
||||
"gcp-metadata@8.1.2": "patches/gcp-metadata@8.1.2.patch",
|
||||
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
|
||||
"effect@4.0.0-beta.83": "patches/effect@4.0.0-beta.83.patch",
|
||||
"@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",
|
||||
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch",
|
||||
"@ai-sdk/google@3.0.73": "patches/@ai-sdk%2Fgoogle@3.0.73.patch",
|
||||
"pacote@21.5.0": "patches/pacote@21.5.0.patch",
|
||||
"effect@4.0.0-beta.98": "patches/effect@4.0.0-beta.98.patch",
|
||||
},
|
||||
"overrides": {
|
||||
"@opentui/core": "catalog:",
|
||||
|
|
@ -1197,9 +1197,9 @@
|
|||
"catalog": {
|
||||
"@cloudflare/workers-types": "4.20251008.0",
|
||||
"@corvu/drawer": "0.2.4",
|
||||
"@effect/opentelemetry": "4.0.0-beta.83",
|
||||
"@effect/platform-node": "4.0.0-beta.83",
|
||||
"@effect/sql-sqlite-bun": "4.0.0-beta.83",
|
||||
"@effect/opentelemetry": "4.0.0-beta.98",
|
||||
"@effect/platform-node": "4.0.0-beta.98",
|
||||
"@effect/sql-sqlite-bun": "4.0.0-beta.98",
|
||||
"@hono/standard-validator": "0.2.0",
|
||||
"@hono/zod-validator": "0.4.2",
|
||||
"@kobalte/core": "0.13.11",
|
||||
|
|
@ -1235,7 +1235,7 @@
|
|||
"dompurify": "3.3.1",
|
||||
"drizzle-kit": "1.0.0-rc.2",
|
||||
"drizzle-orm": "1.0.0-rc.2",
|
||||
"effect": "4.0.0-beta.83",
|
||||
"effect": "4.0.0-beta.98",
|
||||
"fuzzysort": "3.1.0",
|
||||
"get-east-asian-width": "1.6.0",
|
||||
"hono": "4.10.7",
|
||||
|
|
@ -1639,13 +1639,13 @@
|
|||
|
||||
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.11.0", "", {}, "sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg=="],
|
||||
|
||||
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.83", "", { "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.83" }, "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-cPfCfp/ghu0itbX6Dqjdr4N0rbjng5ON4sUpnLHV5JJySG8zZpWmuOZLWIrfrNKT2ctYR1BYmp1aYCgkItaJLw=="],
|
||||
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.98", "", { "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.98" }, "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-ITfK8xhcl+9GXOvPwzADWkOQ+dgUGZrJNefT3r2+uLFmzjyKRLtHzhLOl6lZaLSsf5io13+nmt8adfMRQPq+oA=="],
|
||||
|
||||
"@effect/platform-node": ["@effect/platform-node@4.0.0-beta.83", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.83", "mime": "^4.1.0", "undici": "^8.2.0" }, "peerDependencies": { "effect": "^4.0.0-beta.83", "ioredis": "^5.7.0" } }, "sha512-RmpVGu/+X/Bif3/g1Rzj8oFzTOknoVB3yHCa0b179vytPpKe+Kj9ZwKNcAnKWqHUDkbSPBq1Ca60mvOHr2/+LQ=="],
|
||||
"@effect/platform-node": ["@effect/platform-node@4.0.0-beta.98", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.98", "mime": "^4.1.0", "undici": "^8.7.0" }, "peerDependencies": { "effect": "^4.0.0-beta.98", "ioredis": "^5.7.0" } }, "sha512-IQu1TiLXQEDSGkDBllyYjVadf+UqdjptryqX4mmktVTTbGDq7X4uVxe7cSgXuqZvyfG6kagTzwj2lfynxOaKQg=="],
|
||||
|
||||
"@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.83", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.20.0" }, "peerDependencies": { "effect": "^4.0.0-beta.83" } }, "sha512-+yr/+PJmKTgmJq1QOINSBPgLu7Cjc4CZcotBXnGjyDEizOmimFgTkN2B8PBJAKIKUWYWfobjXqC+58/VhhPKAw=="],
|
||||
"@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-beta.98", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.21.0" }, "peerDependencies": { "effect": "^4.0.0-beta.98" } }, "sha512-iySXaffnCJX1sNAIp79ghhIeui9E5qwUQyqd1VLPkB9UNO4vdpd9B5fTEXwe7S/GusL4jsk9vSvX38XJgRFG1w=="],
|
||||
|
||||
"@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.83", "", { "peerDependencies": { "effect": "^4.0.0-beta.83" } }, "sha512-6OaxLsWffxkh9pXYUSyj/AxjVb9URY2rG9U6atjxClWy30Jx77R9Pm3Rrc7cQ63kQurePavEw1bQbzQ/SILiQQ=="],
|
||||
"@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-beta.98", "", { "peerDependencies": { "effect": "^4.0.0-beta.98" } }, "sha512-cc41uLhYBqexdbTNu4dlui+31E8hcVLEapLySa0C8d60FmBY8IEAV/RD3oF+6pqPslKEZ9p1+XVLdDm0iflw5Q=="],
|
||||
|
||||
"@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=="],
|
||||
|
||||
|
|
@ -4037,7 +4037,7 @@
|
|||
|
||||
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
|
||||
|
||||
"effect": ["effect@4.0.0-beta.83", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.8.0", "find-my-way-ts": "^0.1.6", "ini": "^7.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^2.0.1", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^14.0.0", "yaml": "^2.9.0" } }, "sha512-0wsak8RtgGAr9UWSbVDgJHZcUqMSvicHcvaZv1MbMM7MCGgW4Rn/137J1MHQbwYPcwYGxT/IqehFd+UbYuj78w=="],
|
||||
"effect": ["effect@4.0.0-beta.98", "", { "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-oz+bsG5h+6RNrw4t5GMfQrk/xBS8ROoqkYsuvRhBr5O7mCOrpvH/hbw+QrDzvKIpX4HJClwm86F94c87W0sJxg=="],
|
||||
|
||||
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
|
||||
|
||||
|
|
@ -4213,7 +4213,7 @@
|
|||
|
||||
"extsprintf": ["extsprintf@1.4.1", "", {}, "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA=="],
|
||||
|
||||
"fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="],
|
||||
"fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="],
|
||||
|
||||
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
|
||||
|
||||
|
|
@ -5077,7 +5077,7 @@
|
|||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"msgpackr": ["msgpackr@2.0.2", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-c5hYOXFbP79Slh6Dzd2wzk+jnV7mX1UxfMYtilnY1NmalXPqG8DGb5cYCMBrW4AsH3zekBBZd4QrKz9NhtvYLQ=="],
|
||||
"msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="],
|
||||
|
||||
"msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="],
|
||||
|
||||
|
|
@ -5085,7 +5085,7 @@
|
|||
|
||||
"multicast-dns": ["multicast-dns@7.2.5", "", { "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" }, "bin": { "multicast-dns": "cli.js" } }, "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg=="],
|
||||
|
||||
"multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="],
|
||||
"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=="],
|
||||
|
||||
|
|
@ -5985,7 +5985,7 @@
|
|||
|
||||
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||
|
||||
"toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="],
|
||||
"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=="],
|
||||
|
||||
|
|
@ -6071,7 +6071,7 @@
|
|||
|
||||
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
|
||||
|
||||
"undici": ["undici@8.3.0", "", {}, "sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q=="],
|
||||
"undici": ["undici@8.7.0", "", {}, "sha512-N7iQtfyLhIMOFgQubvmLV26svHpO0bqKnAiWotTQCVKCmWrcGbBotPuW1x+xwYZ2VHdSTVUfPQQnlEt1/LouTQ=="],
|
||||
|
||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
||||
|
||||
|
|
@ -6153,7 +6153,7 @@
|
|||
|
||||
"utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
|
||||
|
||||
"uuid": ["uuid@14.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg=="],
|
||||
"uuid": ["uuid@14.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew=="],
|
||||
|
||||
"valibot": ["valibot@1.4.1", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-klCmFTz2jeDluy9RwX+F884TCiogtdBJ/YaxSx1EOBYXa3NXNWj8kR1jjN8rzluwojJVWWaHJ4r1U5LfICnM3g=="],
|
||||
|
||||
|
|
@ -8363,6 +8363,26 @@
|
|||
|
||||
"@solidjs/start/shiki/@shikijs/types": ["@shikijs/types@1.29.2", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.1", "@types/hast": "^3.0.4" } }, "sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw=="],
|
||||
|
||||
"@standard-community/standard-json/effect/fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="],
|
||||
|
||||
"@standard-community/standard-json/effect/msgpackr": ["msgpackr@2.0.2", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-c5hYOXFbP79Slh6Dzd2wzk+jnV7mX1UxfMYtilnY1NmalXPqG8DGb5cYCMBrW4AsH3zekBBZd4QrKz9NhtvYLQ=="],
|
||||
|
||||
"@standard-community/standard-json/effect/multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="],
|
||||
|
||||
"@standard-community/standard-json/effect/toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="],
|
||||
|
||||
"@standard-community/standard-json/effect/uuid": ["uuid@14.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg=="],
|
||||
|
||||
"@standard-community/standard-openapi/effect/fast-check": ["fast-check@4.8.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg=="],
|
||||
|
||||
"@standard-community/standard-openapi/effect/msgpackr": ["msgpackr@2.0.2", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-c5hYOXFbP79Slh6Dzd2wzk+jnV7mX1UxfMYtilnY1NmalXPqG8DGb5cYCMBrW4AsH3zekBBZd4QrKz9NhtvYLQ=="],
|
||||
|
||||
"@standard-community/standard-openapi/effect/multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="],
|
||||
|
||||
"@standard-community/standard-openapi/effect/toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="],
|
||||
|
||||
"@standard-community/standard-openapi/effect/uuid": ["uuid@14.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg=="],
|
||||
|
||||
"@stoplight/spectral-core/minimatch/brace-expansion": ["brace-expansion@1.1.15", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg=="],
|
||||
|
||||
"@storybook/addon-docs/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -37,9 +37,9 @@
|
|||
"packages/slack"
|
||||
],
|
||||
"catalog": {
|
||||
"@effect/opentelemetry": "4.0.0-beta.83",
|
||||
"@effect/platform-node": "4.0.0-beta.83",
|
||||
"@effect/sql-sqlite-bun": "4.0.0-beta.83",
|
||||
"@effect/opentelemetry": "4.0.0-beta.98",
|
||||
"@effect/platform-node": "4.0.0-beta.98",
|
||||
"@effect/sql-sqlite-bun": "4.0.0-beta.98",
|
||||
"@npmcli/arborist": "9.4.0",
|
||||
"@types/bun": "1.3.13",
|
||||
"@types/cross-spawn": "6.0.6",
|
||||
|
|
@ -69,7 +69,7 @@
|
|||
"dompurify": "3.3.1",
|
||||
"drizzle-kit": "1.0.0-rc.2",
|
||||
"drizzle-orm": "1.0.0-rc.2",
|
||||
"effect": "4.0.0-beta.83",
|
||||
"effect": "4.0.0-beta.98",
|
||||
"ai": "6.0.168",
|
||||
"cross-spawn": "7.0.6",
|
||||
"hono": "4.10.7",
|
||||
|
|
@ -166,7 +166,7 @@
|
|||
"@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.83": "patches/effect@4.0.0-beta.83.patch",
|
||||
"effect@4.0.0-beta.98": "patches/effect@4.0.0-beta.98.patch",
|
||||
"@tanstack/virtual-core@3.17.3": "patches/@tanstack%2Fvirtual-core@3.17.3.patch"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,9 +191,7 @@ test("concurrent service processes elect one server", async () => {
|
|||
),
|
||||
).toEqual({ timeSuspended: null })
|
||||
expect(await waitForExecutionStart(database, sessionID)).toBe(1)
|
||||
await Effect.runPromise(
|
||||
Service.stop({ file: registration }).pipe(Effect.provide(NodeFileSystem.layer)),
|
||||
)
|
||||
await Effect.runPromise(Service.stop({ file: registration }).pipe(Effect.provide(NodeFileSystem.layer)))
|
||||
await winner?.exited
|
||||
} finally {
|
||||
processes.forEach((process) => process.kill("SIGTERM"))
|
||||
|
|
@ -271,7 +269,7 @@ function waitForExecutionStart(file: string, sessionID: SessionV2.ID) {
|
|||
),
|
||||
Effect.filterOrFail((rows) => rows.length > 0),
|
||||
Effect.map((rows) => rows.length),
|
||||
Effect.retry(Schedule.spaced("50 millis").pipe(Schedule.both(Schedule.recurs(200)))),
|
||||
Effect.retry(Schedule.max([Schedule.spaced("50 millis"), Schedule.recurs(200)])),
|
||||
)
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
"@opencode-ai/protocol": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "4.0.0-beta.83"
|
||||
"effect": "4.0.0-beta.98"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"effect": {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@ import { Effect, FileSystem, Option, Schedule, Schema } from "effect"
|
|||
import { spawn, type ChildProcess } from "node:child_process"
|
||||
import { homedir } from "node:os"
|
||||
import { join } from "node:path"
|
||||
import type {
|
||||
DiscoverOptions,
|
||||
Endpoint,
|
||||
EnsureOptions,
|
||||
StopOptions,
|
||||
} from "../service.js"
|
||||
import type { DiscoverOptions, Endpoint, EnsureOptions, StopOptions } from "../service.js"
|
||||
|
||||
export * from "../service.js"
|
||||
/** Contents of the local service registration file. */
|
||||
|
|
@ -82,7 +77,8 @@ export const ensure = Effect.fn("service.ensure")(function* (options: EnsureOpti
|
|||
spawnDelay = 5_000
|
||||
const compatible = !service.legacy && (options.version === undefined || service.version === options.version)
|
||||
if (compatible && service.state === "ready") return Option.some(service)
|
||||
if (compatible && service.state === "failed") return yield* Effect.fail(new Error("Background service failed to start"))
|
||||
if (compatible && service.state === "failed")
|
||||
return yield* Effect.fail(new Error("Background service failed to start"))
|
||||
if (compatible) return Option.none<LocalService>()
|
||||
yield* announce("version-mismatch", service.version)
|
||||
yield* kill(service, options).pipe(Effect.ignore)
|
||||
|
|
@ -221,7 +217,7 @@ const find = Effect.fnUntraced(function* (options: { readonly file?: string }) {
|
|||
|
||||
// 50ms cadence bounded at ~5s, shared by stop escalation and each ensure
|
||||
// discovery window.
|
||||
const poll = Schedule.spaced("50 millis").pipe(Schedule.both(Schedule.recurs(100)))
|
||||
const poll = Schedule.max([Schedule.spaced("50 millis"), Schedule.recurs(100)])
|
||||
|
||||
const signal = (pid: number, name: NodeJS.Signals) =>
|
||||
Effect.try({ try: () => process.kill(pid, name), catch: (cause) => cause }).pipe(Effect.ignore)
|
||||
|
|
@ -238,10 +234,7 @@ function same(left: Info, right: Info) {
|
|||
return left.id === right.id && left.version === right.version && left.url === right.url && left.pid === right.pid
|
||||
}
|
||||
|
||||
const kill = Effect.fnUntraced(function* (
|
||||
service: LocalService,
|
||||
options: { readonly file?: string },
|
||||
) {
|
||||
const kill = Effect.fnUntraced(function* (service: LocalService, options: { readonly file?: string }) {
|
||||
const requested = yield* requestStop(service)
|
||||
if (requested === "rejected") return
|
||||
if (requested === "unsupported") {
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ function expandHome(resource: string, home: string) {
|
|||
function discover(fs: FSUtil.Interface, directory: string) {
|
||||
return Effect.forEach(legacySources, (source) =>
|
||||
fs
|
||||
.glob(source.pattern, { cwd: directory, absolute: true, dot: true, symlink: true })
|
||||
.scan(source.pattern, { cwd: directory, absolute: true, dot: true, symlink: true })
|
||||
.pipe(
|
||||
Effect.map((files) => files.toSorted().map((filepath) => ({ directory, filepath, primary: source.primary }))),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export const Plugin = define({
|
|||
function loadDirectory(fs: FSUtil.Interface, directory: string) {
|
||||
return Effect.gen(function* () {
|
||||
const files = yield* fs
|
||||
.glob("{command,commands}/**/*.md", { cwd: directory, absolute: true, dot: true, symlink: true })
|
||||
.scan("{command,commands}/**/*.md", { cwd: directory, absolute: true, dot: true, symlink: true })
|
||||
.pipe(Effect.catch(() => Effect.succeed([] as string[])))
|
||||
return yield* Effect.forEach(files.toSorted(), (filepath) =>
|
||||
fs.readFileStringSafe(filepath).pipe(
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ const make = (options: Config) =>
|
|||
executeValues(query, params) {
|
||||
return runValues(query, params)
|
||||
},
|
||||
executeValuesUnprepared(query, params) {
|
||||
return runValues(query, params)
|
||||
},
|
||||
executeUnprepared(query, params, transformRows) {
|
||||
return this.execute(query, params, transformRows)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ const make = (options: Config) =>
|
|||
executeValues(query, params) {
|
||||
return runValues(query, params)
|
||||
},
|
||||
executeValuesUnprepared(query, params) {
|
||||
return runValues(query, params)
|
||||
},
|
||||
executeUnprepared(query, params, transformRows) {
|
||||
return this.execute(query, params, transformRows)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export namespace FSUtil {
|
|||
readonly findUp: (target: string, start: string, stop?: string) => Effect.Effect<string[], Error>
|
||||
readonly up: (options: { targets: string[]; start: string; stop?: string }) => Effect.Effect<string[], Error>
|
||||
readonly globUp: (pattern: string, start: string, stop?: string) => Effect.Effect<string[], Error>
|
||||
readonly glob: (pattern: string, options?: Glob.Options) => Effect.Effect<string[], Error>
|
||||
readonly scan: (pattern: string, options?: Glob.Options) => Effect.Effect<string[], Error>
|
||||
readonly globMatch: (pattern: string, filepath: string) => boolean
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ export namespace FSUtil {
|
|||
export const use = serviceUse(Service)
|
||||
|
||||
// Exported so simulation can wrap this layer and override the methods that
|
||||
// bypass the injected FileSystem (readDirectoryEntries, glob, globUp).
|
||||
// bypass the injected FileSystem (readDirectoryEntries, scan, globUp).
|
||||
export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
|
|
@ -146,7 +146,7 @@ export namespace FSUtil {
|
|||
if (mode) yield* fs.chmod(path, mode)
|
||||
})
|
||||
|
||||
const glob = Effect.fn("FileSystem.glob")(function* (pattern: string, options?: Glob.Options) {
|
||||
const scan = Effect.fn("FileSystem.scan")(function* (pattern: string, options?: Glob.Options) {
|
||||
return yield* Effect.tryPromise({
|
||||
try: () => Glob.scan(pattern, options),
|
||||
catch: (cause) => new FileSystemError({ method: "glob", cause }),
|
||||
|
|
@ -187,7 +187,7 @@ export namespace FSUtil {
|
|||
const result: string[] = []
|
||||
let current = start
|
||||
while (true) {
|
||||
const matches = yield* glob(pattern, { cwd: current, absolute: true, include: "file", dot: true }).pipe(
|
||||
const matches = yield* scan(pattern, { cwd: current, absolute: true, include: "file", dot: true }).pipe(
|
||||
Effect.catch(() => Effect.succeed([] as string[])),
|
||||
)
|
||||
result.push(...matches)
|
||||
|
|
@ -214,7 +214,7 @@ export namespace FSUtil {
|
|||
findUp,
|
||||
up,
|
||||
globUp,
|
||||
glob,
|
||||
scan,
|
||||
globMatch: Glob.match,
|
||||
})
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ const configuredPlugins = Effect.fn("SkillPlugin.configuredPlugins")(function* (
|
|||
}
|
||||
if (entry.type !== "directory") return Effect.succeed([])
|
||||
return fs
|
||||
.glob("{plugin,plugins}/*.{ts,js}", {
|
||||
.scan("{plugin,plugins}/*.{ts,js}", {
|
||||
cwd: entry.path,
|
||||
absolute: true,
|
||||
include: "file",
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ const load = Effect.fn("PluginSupervisor.load")(function* (operation: Extract<Op
|
|||
function discoverDirectory(fs: FSUtil.Interface, directory: string) {
|
||||
return Effect.gen(function* () {
|
||||
const files = yield* fs
|
||||
.glob("{plugin,plugins}/*.{ts,js}", {
|
||||
.scan("{plugin,plugins}/*.{ts,js}", {
|
||||
cwd: directory,
|
||||
absolute: true,
|
||||
include: "file",
|
||||
|
|
|
|||
|
|
@ -44,12 +44,11 @@ const retryAfter = (failure: RetryableFailure) => {
|
|||
}
|
||||
|
||||
export const schedule = (events: EventV2.Interface, sessionID: SessionSchema.ID) =>
|
||||
Schedule.exponential("2 seconds").pipe(
|
||||
Schedule.take(4),
|
||||
Schedule.max([Schedule.exponential("2 seconds"), Schedule.recurs(4)]).pipe(
|
||||
Schedule.setInputType<RetryableFailure | SessionRunner.RunError>(),
|
||||
Schedule.passthrough,
|
||||
Schedule.while(({ input }) => input instanceof RetryableFailure),
|
||||
Schedule.modifyDelay((failure, delay) => {
|
||||
Schedule.modifyDelay(({ input: failure, duration: delay }) => {
|
||||
const minimum = failure instanceof RetryableFailure ? retryAfter(failure) : undefined
|
||||
return Effect.succeed(minimum === undefined ? delay : Duration.max(delay, Duration.millis(minimum)))
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ const layer = Layer.effect(
|
|||
const directories = source.type === "directory" ? [source.path] : yield* discovery.pull(source.url)
|
||||
for (const directory of directories) {
|
||||
const files = yield* fs
|
||||
.glob("{*.md,**/SKILL.md}", { cwd: directory, absolute: true, include: "file", symlink: true, dot: true })
|
||||
.scan("{*.md,**/SKILL.md}", { cwd: directory, absolute: true, include: "file", symlink: true, dot: true })
|
||||
.pipe(Effect.catch(() => Effect.succeed([] as string[])))
|
||||
for (const filepath of files.toSorted()) {
|
||||
const content = yield* fs.readFileStringSafe(filepath).pipe(Effect.catch(() => Effect.succeed(undefined)))
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ export const Plugin = {
|
|||
const directory = path.dirname(skill.location)
|
||||
const files =
|
||||
path.basename(skill.location) === "SKILL.md"
|
||||
? (yield* fs.glob("**/*", { cwd: directory, absolute: true, include: "file", dot: true }))
|
||||
? (yield* fs.scan("**/*", { cwd: directory, absolute: true, include: "file", dot: true }))
|
||||
.filter((file) => path.basename(file) !== "SKILL.md")
|
||||
.toSorted()
|
||||
.slice(0, FILE_LIMIT)
|
||||
|
|
|
|||
|
|
@ -50,11 +50,14 @@ export namespace EffectFlock {
|
|||
const BASE_DELAY_MS = 100
|
||||
const MAX_DELAY_MS = 2_000
|
||||
|
||||
const retrySchedule = (timeoutMs: number) => Schedule.exponential(BASE_DELAY_MS, 1.7).pipe(
|
||||
Schedule.either(Schedule.spaced(Math.min(MAX_DELAY_MS, Math.max(BASE_DELAY_MS, Math.floor(timeoutMs / 10))))),
|
||||
Schedule.jittered,
|
||||
Schedule.while((meta) => meta.elapsed < timeoutMs),
|
||||
)
|
||||
const retrySchedule = (timeoutMs: number) =>
|
||||
Schedule.min([
|
||||
Schedule.exponential(BASE_DELAY_MS, 1.7),
|
||||
Schedule.spaced(Math.min(MAX_DELAY_MS, Math.max(BASE_DELAY_MS, Math.floor(timeoutMs / 10)))),
|
||||
]).pipe(
|
||||
Schedule.jittered,
|
||||
Schedule.while((meta) => meta.elapsed < timeoutMs),
|
||||
)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Lock metadata schema
|
||||
|
|
|
|||
|
|
@ -280,7 +280,7 @@ describe("FSUtil", () => {
|
|||
yield* filesys.writeFileString(path.join(tmp, "b.ts"), "b")
|
||||
yield* filesys.writeFileString(path.join(tmp, "c.json"), "c")
|
||||
|
||||
const result = yield* fs.glob("*.ts", { cwd: tmp })
|
||||
const result = yield* fs.scan("*.ts", { cwd: tmp })
|
||||
expect(result.sort()).toEqual(["a.ts", "b.ts"])
|
||||
}),
|
||||
)
|
||||
|
|
@ -293,7 +293,7 @@ describe("FSUtil", () => {
|
|||
const tmp = yield* filesys.makeTempDirectoryScoped()
|
||||
yield* filesys.writeFileString(path.join(tmp, "file.txt"), "hello")
|
||||
|
||||
const result = yield* fs.glob("*.txt", { cwd: tmp, absolute: true })
|
||||
const result = yield* fs.scan("*.txt", { cwd: tmp, absolute: true })
|
||||
expect(result).toEqual([path.join(tmp, "file.txt")])
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ export const make = (
|
|||
executeValues(sql, params) {
|
||||
return runValues(sql, params)
|
||||
},
|
||||
executeValuesUnprepared(sql, params) {
|
||||
return runValues(sql, params)
|
||||
},
|
||||
executeUnprepared(sql, params, transformRows) {
|
||||
return this.execute(sql, params, transformRows)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
"typescript": "catalog:"
|
||||
},
|
||||
"dependencies": {
|
||||
"@effect/platform-node-shared": "4.0.0-beta.83"
|
||||
"@effect/platform-node-shared": "4.0.0-beta.98"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "catalog:"
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export type Endpoint = {
|
|||
readonly group: string
|
||||
readonly sourceGroup: string
|
||||
readonly topLevel: boolean
|
||||
readonly endpoint: HttpApiEndpoint.AnyWithProps
|
||||
readonly endpoint: HttpApiEndpoint.Top
|
||||
readonly params: Schema.Top | undefined
|
||||
readonly query: Schema.Top | undefined
|
||||
readonly headers: Schema.Top | undefined
|
||||
|
|
@ -83,7 +83,7 @@ const resolveContentSchema = SchemaAST.resolveAt<SchemaAST.AST>("contentSchema")
|
|||
const Manifest = Schema.fromJsonString(Schema.Array(Schema.String))
|
||||
const manifestName = ".httpapi-codegen.json"
|
||||
|
||||
export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
||||
export function compile<Id extends string, Groups extends HttpApiGroup.Constraint>(
|
||||
api: HttpApi.HttpApi<Id, Groups>,
|
||||
options?: {
|
||||
readonly groupNames?: Readonly<Record<string, string>>
|
||||
|
|
@ -96,9 +96,9 @@ export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
|||
HttpApi.reflect(api, {
|
||||
onGroup() {},
|
||||
onEndpoint({ endpoint, errors, group, middleware }) {
|
||||
if (options?.omitEndpoints?.has(endpoint.name)) return
|
||||
if (options?.omitEndpoints?.has(endpoint.identifier)) return
|
||||
const groupName = options?.groupNames?.[group.identifier] ?? group.identifier
|
||||
const name = `${groupName}.${endpoint.name}`
|
||||
const name = `${groupName}.${endpoint.identifier}`
|
||||
const required = Array.from(middleware).find((item) => item.requiredForClient)
|
||||
if (required !== undefined) {
|
||||
throw new GenerationError({ reason: `Client middleware requires adapter: ${required.key}` })
|
||||
|
|
@ -151,7 +151,7 @@ export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
|
|||
const clientPath = clientEndpointPath(
|
||||
group.identifier,
|
||||
Context.getOrElse(endpoint.annotations, OpenApi.Identifier, () =>
|
||||
group.topLevel ? endpoint.name : `${group.identifier}.${endpoint.name}`,
|
||||
group.topLevel ? endpoint.identifier : `${group.identifier}.${endpoint.identifier}`,
|
||||
),
|
||||
)
|
||||
endpoints.push({
|
||||
|
|
@ -263,7 +263,7 @@ export function emitEffect(contract: Contract): Output {
|
|||
const endpoint = contract.groups.flatMap((group) => group.endpoints).find((endpoint) => !endpoint.effectPortable)
|
||||
if (endpoint !== undefined) {
|
||||
throw new GenerationError({
|
||||
reason: `Effect schema requires authoritative import: ${endpoint.group}.${endpoint.endpoint.name}`,
|
||||
reason: `Effect schema requires authoritative import: ${endpoint.group}.${endpoint.endpoint.identifier}`,
|
||||
})
|
||||
}
|
||||
return { operations: operations(contract.groups), files: renderEffectFiles(contract.groups) }
|
||||
|
|
@ -332,7 +332,7 @@ function renderEffectShape(groups: ReadonlyArray<Group>, options: { readonly mod
|
|||
const request =
|
||||
endpoint.operation.inputMode === "none"
|
||||
? ""
|
||||
: `type ${prefix}Request = Parameters<${rawGroup}[${JSON.stringify(endpoint.endpoint.name)}]>[0]`
|
||||
: `type ${prefix}Request = Parameters<${rawGroup}[${JSON.stringify(endpoint.endpoint.identifier)}]>[0]`
|
||||
const input = endpoint.input
|
||||
.map(
|
||||
(field) =>
|
||||
|
|
@ -340,7 +340,7 @@ function renderEffectShape(groups: ReadonlyArray<Group>, options: { readonly mod
|
|||
)
|
||||
.join("; ")
|
||||
const inputType = endpoint.operation.inputMode === "none" ? "" : `export type ${prefix}Input = { ${input} }`
|
||||
const rawOutput = `EffectValue<ReturnType<${rawGroup}[${JSON.stringify(endpoint.endpoint.name)}]>>`
|
||||
const rawOutput = `EffectValue<ReturnType<${rawGroup}[${JSON.stringify(endpoint.endpoint.identifier)}]>>`
|
||||
const outputType = isStreamSchema(endpoint.successes[0])
|
||||
? `export type ${prefix}Output = StreamValue<${rawOutput}>`
|
||||
: `export type ${prefix}Output = ${endpoint.unwrapData ? `(${rawOutput})["data"]` : rawOutput}`
|
||||
|
|
@ -399,7 +399,7 @@ function groupShapeTypeName(group: Group, endpoint: Endpoint) {
|
|||
}
|
||||
|
||||
function assertPromiseEndpoint(endpoint: Endpoint) {
|
||||
const name = `${endpoint.group}.${endpoint.endpoint.name}`
|
||||
const name = `${endpoint.group}.${endpoint.endpoint.identifier}`
|
||||
const payload = endpoint.payloads[0]
|
||||
const payloadEncoding = payload === undefined ? undefined : resolveHttpApiEncoding(payload.ast)
|
||||
if (
|
||||
|
|
@ -493,9 +493,9 @@ function renderImportedEffectFiles(
|
|||
item.operation.inputMode === "none"
|
||||
? ""
|
||||
: `input${item.operation.inputMode === "optional" ? "?" : ""}: ${prefix}Input`
|
||||
const rawCall = `raw[${JSON.stringify(item.endpoint.name)}]({ ${request} })`
|
||||
const rawCall = `raw[${JSON.stringify(item.endpoint.identifier)}]({ ${request} })`
|
||||
const mapped = `${rawCall}.pipe(Effect.mapError(mapClientError)${item.unwrapData ? ", Effect.map((value) => value.data)" : ""})`
|
||||
return `${item.operation.inputMode === "none" ? "" : `type ${prefix}Request = Parameters<${rawGroup}[${JSON.stringify(item.endpoint.name)}]>[0]\ntype ${prefix}Input = { ${input} }\n`}const ${prefix} = (raw: ${rawGroup}) => (${argument}) => ${item.operation.success === "stream" ? `Stream.unwrap(${rawCall}.pipe(Effect.mapError(mapClientError), Effect.map((stream) => stream.pipe(Stream.mapError(mapClientError)))))` : mapped}`
|
||||
return `${item.operation.inputMode === "none" ? "" : `type ${prefix}Request = Parameters<${rawGroup}[${JSON.stringify(item.endpoint.identifier)}]>[0]\ntype ${prefix}Input = { ${input} }\n`}const ${prefix} = (raw: ${rawGroup}) => (${argument}) => ${item.operation.success === "stream" ? `Stream.unwrap(${rawCall}.pipe(Effect.mapError(mapClientError), Effect.map((stream) => stream.pipe(Stream.mapError(mapClientError)))))` : mapped}`
|
||||
})
|
||||
const fields = renderClientTree(
|
||||
group.endpoints,
|
||||
|
|
@ -548,10 +548,10 @@ function renderImportedGroup(group: string) {
|
|||
function renderImportedProjection(groups: ReadonlyArray<Group>, endpoints: Readonly<Record<string, string>>) {
|
||||
const imports = groups.flatMap((group) =>
|
||||
group.endpoints.map((endpoint) => {
|
||||
const name = endpoints[`${group.identifier}.${endpoint.endpoint.name}`]
|
||||
const name = endpoints[`${group.identifier}.${endpoint.endpoint.identifier}`]
|
||||
if (name === undefined) {
|
||||
throw new GenerationError({
|
||||
reason: `Missing imported endpoint: ${group.identifier}.${endpoint.endpoint.name}`,
|
||||
reason: `Missing imported endpoint: ${group.identifier}.${endpoint.endpoint.identifier}`,
|
||||
})
|
||||
}
|
||||
return name
|
||||
|
|
@ -560,7 +560,7 @@ function renderImportedProjection(groups: ReadonlyArray<Group>, endpoints: Reado
|
|||
const source = `const Api = HttpApi.make("generated").${groups
|
||||
.map((group) => {
|
||||
const options = group.endpoints[0]?.topLevel ? ", { topLevel: true }" : ""
|
||||
return `add(HttpApiGroup.make(${JSON.stringify(group.identifier)}${options})${group.endpoints.map((endpoint) => `.add(${endpoints[`${group.identifier}.${endpoint.endpoint.name}`]})`).join("")})`
|
||||
return `add(HttpApiGroup.make(${JSON.stringify(group.identifier)}${options})${group.endpoints.map((endpoint) => `.add(${endpoints[`${group.identifier}.${endpoint.endpoint.identifier}`]})`).join("")})`
|
||||
})
|
||||
.join(".")}\n\n`
|
||||
return { imports: [...new Set(imports)], source }
|
||||
|
|
@ -633,7 +633,7 @@ function renderPromiseTypes(
|
|||
isStreamSchema(successSchema) && successSchema._tag === "StreamSse"
|
||||
? successSchema.sseMode === "data"
|
||||
? streamEncodedDataSchema(successSchema)
|
||||
: successSchema.events
|
||||
: Schema.make<Schema.Top>(successSchema.events.ast)
|
||||
: successSchema,
|
||||
)
|
||||
return [
|
||||
|
|
@ -660,7 +660,9 @@ function renderPromiseTypes(
|
|||
rendered.types.reduce((result, type, index) => result.replaceAll(`__PROMISE_TYPE_${index}__`, type), source)
|
||||
const resolvedErrors = errorTypes.map(resolve)
|
||||
const resolvedOperations = resolve(operations)
|
||||
const json = [...rendered.definitions, ...resolvedErrors, resolvedOperations].some((type) => type.includes("JsonValue"))
|
||||
const json = [...rendered.definitions, ...resolvedErrors, resolvedOperations].some((type) =>
|
||||
type.includes("JsonValue"),
|
||||
)
|
||||
? `export type JsonValue = null | boolean | number | string | ${mutableOutputs ? "Array<JsonValue> | { [key: string]: JsonValue }" : "ReadonlyArray<JsonValue> | { readonly [key: string]: JsonValue }"}`
|
||||
: ""
|
||||
const imports = [...new Set(Object.values(outputTypes ?? {}).map((override) => override.import))]
|
||||
|
|
@ -705,7 +707,7 @@ function renderPromiseClient(groups: ReadonlyArray<Group>) {
|
|||
const success = endpoint.successes[0]
|
||||
if (!isStreamSchema(success) || success._tag !== "StreamSse" || success.sseMode !== "data") {
|
||||
throw new GenerationError({
|
||||
reason: `Promise stream emission is not implemented: ${group.identifier}.${endpoint.endpoint.name}`,
|
||||
reason: `Promise stream emission is not implemented: ${group.identifier}.${endpoint.endpoint.identifier}`,
|
||||
})
|
||||
}
|
||||
return `(${argument}): AsyncIterable<${prefix}Output> => sse<${prefix}Output>(${descriptor}, requestOptions)`
|
||||
|
|
@ -956,7 +958,7 @@ function uniqueModule(base: string, index: number, modules: ReadonlySet<string>)
|
|||
function normalizeTransport(
|
||||
schema: Schema.Top | undefined,
|
||||
source: InputField["source"] | "success" | "error",
|
||||
endpoint: HttpApiEndpoint.AnyWithProps,
|
||||
endpoint: HttpApiEndpoint.Top,
|
||||
operation: string,
|
||||
) {
|
||||
if (schema === undefined) return undefined
|
||||
|
|
@ -968,14 +970,33 @@ function normalizeTransport(
|
|||
if (!isPathInput(endpoint.path)) {
|
||||
throw new GenerationError({ reason: `Invalid endpoint path: ${operation}` })
|
||||
}
|
||||
const rebuilt = HttpApiEndpoint.make(endpoint.method)(endpoint.name, endpoint.path, {
|
||||
...(source === "params" ? { params: decoded } : undefined),
|
||||
...(source === "query" ? { query: decoded } : undefined),
|
||||
...(source === "headers" ? { headers: decoded } : undefined),
|
||||
...(source === "payload" ? { payload: decoded } : undefined),
|
||||
...(source === "success" ? { success: decoded } : { success: Schema.String }),
|
||||
...(source === "error" ? { error: decoded } : undefined),
|
||||
})
|
||||
const rebuilt =
|
||||
source === "params"
|
||||
? HttpApiEndpoint.make(endpoint.method)(endpoint.identifier, endpoint.path, {
|
||||
params: decoded,
|
||||
success: Schema.String,
|
||||
})
|
||||
: source === "query"
|
||||
? HttpApiEndpoint.make(endpoint.method)(endpoint.identifier, endpoint.path, {
|
||||
query: decoded,
|
||||
success: Schema.String,
|
||||
})
|
||||
: source === "headers"
|
||||
? HttpApiEndpoint.make(endpoint.method)(endpoint.identifier, endpoint.path, {
|
||||
headers: decoded,
|
||||
success: Schema.String,
|
||||
})
|
||||
: source === "payload"
|
||||
? HttpApiEndpoint.make(endpoint.method)(endpoint.identifier, endpoint.path, {
|
||||
payload: decoded,
|
||||
success: Schema.String,
|
||||
})
|
||||
: source === "success"
|
||||
? HttpApiEndpoint.make(endpoint.method)(endpoint.identifier, endpoint.path, { success: decoded })
|
||||
: HttpApiEndpoint.make(endpoint.method)(endpoint.identifier, endpoint.path, {
|
||||
success: Schema.String,
|
||||
error: decoded,
|
||||
})
|
||||
const normalized =
|
||||
source === "params"
|
||||
? rebuilt.params
|
||||
|
|
@ -1115,7 +1136,7 @@ function isSafeOutputPath(path: string) {
|
|||
return path !== manifestName && !isAbsolute(path) && path !== "." && path !== ".." && !/[\\/]/.test(path)
|
||||
}
|
||||
|
||||
export function generate<Id extends string, Groups extends HttpApiGroup.Any>(
|
||||
export function generate<Id extends string, Groups extends HttpApiGroup.Constraint>(
|
||||
api: HttpApi.HttpApi<Id, Groups>,
|
||||
options: { readonly directory: string },
|
||||
): Effect.Effect<void, GenerationError | PlatformError.PlatformError, FileSystem.FileSystem> {
|
||||
|
|
@ -1147,7 +1168,7 @@ function responseSchemas(schema: Schema.Top, path: string): Array<readonly [stri
|
|||
if (HttpApiSchema.isNoContent(schema.ast)) return []
|
||||
if (!isStreamSchema(schema)) return [[path, schema]]
|
||||
if (schema._tag === "StreamUint8Array") return []
|
||||
const value = schema.sseMode === "data" ? streamDataSchema(schema) : schema.events
|
||||
const value = schema.sseMode === "data" ? streamDataSchema(schema) : Schema.make<Schema.Top>(schema.events.ast)
|
||||
return [
|
||||
[`${path}.${schema.sseMode}`, value],
|
||||
[`${path}.error`, schema.error],
|
||||
|
|
@ -1306,7 +1327,7 @@ function declaredErrorFields(schema: Schema.Top) {
|
|||
fields: fields.propertySignatures.flatMap((field) =>
|
||||
field.name === key || typeof field.name !== "string"
|
||||
? []
|
||||
: [[field.name, Schema.make(field.type), SchemaAST.isOptional(field.type)] as const],
|
||||
: [[field.name, Schema.make<Schema.Top>(field.type), SchemaAST.isOptional(field.type)] as const],
|
||||
),
|
||||
}
|
||||
}
|
||||
|
|
@ -1327,7 +1348,7 @@ function isStreamSchema(schema: Schema.Top): schema is HttpApiSchema.StreamSchem
|
|||
}
|
||||
|
||||
function streamDataSchema(schema: Extract<HttpApiSchema.StreamSchema, { readonly _tag: "StreamSse" }>) {
|
||||
return Schema.make(streamDataAst(Schema.toType(schema.events).ast))
|
||||
return Schema.make<Schema.Top>(streamDataAst(Schema.toType(schema.events).ast))
|
||||
}
|
||||
|
||||
function streamEncodedDataSchema(schema: Extract<HttpApiSchema.StreamSchema, { readonly _tag: "StreamSse" }>) {
|
||||
|
|
@ -1336,7 +1357,7 @@ function streamEncodedDataSchema(schema: Extract<HttpApiSchema.StreamSchema, { r
|
|||
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(encoded)
|
||||
return Schema.make<Schema.Top>(encoded)
|
||||
}
|
||||
|
||||
function streamDataAst(ast: SchemaAST.AST) {
|
||||
|
|
@ -1393,7 +1414,7 @@ function renderGroup(group: Group, groupIndex: number) {
|
|||
.map((field) => {
|
||||
const slot = schemaBySource[field.source]
|
||||
if (slot === undefined) {
|
||||
throw new GenerationError({ reason: `Missing input schema: ${group.identifier}.${endpoint.name}` })
|
||||
throw new GenerationError({ reason: `Missing input schema: ${group.identifier}.${endpoint.identifier}` })
|
||||
}
|
||||
return `readonly ${JSON.stringify(field.name)}${field.optional ? "?" : ""}: (typeof ${slot.name}.Type)[${JSON.stringify(field.name)}]`
|
||||
})
|
||||
|
|
@ -1418,13 +1439,13 @@ function renderGroup(group: Group, groupIndex: number) {
|
|||
const declared = [...errorSlots, ...(success.streamError === undefined ? [] : [success.streamError])]
|
||||
const declaredSchema =
|
||||
declared.length === 0 ? "Schema.Never" : `Schema.Union([${declared.map((slot) => slot.name).join(", ")}])`
|
||||
const rawCall = `raw[${JSON.stringify(endpoint.name)}]({ ${request} })`
|
||||
const rawCall = `raw[${JSON.stringify(endpoint.identifier)}]({ ${request} })`
|
||||
const mapped = `${rawCall}.pipe(Effect.mapError(map${prefix}Error)${operation.unwrapData ? ", Effect.map((value) => value.data)" : ""})`
|
||||
const inputDeclaration = operation.operation.inputMode === "none" ? "" : `type ${prefix}Input = { ${inputType} }\n`
|
||||
adapters.push(
|
||||
`${inputDeclaration}const ${prefix}DeclaredError = ${declaredSchema}\nconst map${prefix}Error = (error: unknown) => HttpClientError.isHttpClientError(error) || Schema.isSchemaError(error) || Sse.Retry.is(error) ? new ClientError({ cause: error }) : Schema.is(${prefix}DeclaredError)(error) ? error : new ClientError({ cause: error })\nconst ${prefix} = (raw: RawGroup) => (${argument}) => ${operation.operation.success === "stream" ? `Stream.unwrap(${rawCall}.pipe(Effect.mapError(map${prefix}Error), Effect.map((stream) => stream.pipe(Stream.mapError(map${prefix}Error)))))` : mapped}`,
|
||||
)
|
||||
return `HttpApiEndpoint.make(${JSON.stringify(endpoint.method)})(${JSON.stringify(endpoint.name)}, ${JSON.stringify(endpoint.path)}, { ${options.join(", ")} })`
|
||||
return `HttpApiEndpoint.make(${JSON.stringify(endpoint.method)})(${JSON.stringify(endpoint.identifier)}, ${JSON.stringify(endpoint.path)}, { ${options.join(", ")} })`
|
||||
})
|
||||
|
||||
function addSlot(schema: Schema.Top | undefined, name: string) {
|
||||
|
|
@ -1444,7 +1465,7 @@ function renderGroup(group: Group, groupIndex: number) {
|
|||
}
|
||||
}
|
||||
const value = addSlot(
|
||||
schema.sseMode === "data" ? streamDataSchema(schema) : schema.events,
|
||||
schema.sseMode === "data" ? streamDataSchema(schema) : Schema.make<Schema.Top>(schema.events.ast),
|
||||
`${name}${schema.sseMode === "data" ? "Data" : "Events"}`,
|
||||
)!
|
||||
const error = addSlot(schema.error, `${name}Error`)!
|
||||
|
|
@ -1465,7 +1486,7 @@ function renderGroup(group: Group, groupIndex: number) {
|
|||
)
|
||||
const rawGroup = group.endpoints[0]?.topLevel
|
||||
? `HttpApiClient.Client<typeof Group${groupIndex}>`
|
||||
: `HttpApiClient.Client.Group<typeof Group${groupIndex}, ${JSON.stringify(group.identifier)}, never, never>`
|
||||
: `HttpApiClient.Client.Group<typeof Group${groupIndex}, never, never>`
|
||||
const usesStream = group.endpoints.some((item) => item.operation.success === "stream")
|
||||
return `// Generated by @opencode-ai/httpapi-codegen. Do not edit.\nimport { Effect, Schema${usesStream ? ", Stream" : ""} } from "effect"\nimport { Sse } from "effect/unstable/encoding"\nimport { HttpClientError } from "effect/unstable/http"\nimport { HttpApiClient, HttpApiEndpoint, HttpApiGroup${usesHttpApiSchema ? ", HttpApiSchema" : ""} } from "effect/unstable/httpapi"\nimport { ClientError } from "./client-error"\n\n${declarations}\n\nexport const Group${groupIndex} = ${groupSource}\n\ntype RawGroup = ${rawGroup}\n\n${adapters.join("\n\n")}\n\nexport const adaptGroup${groupIndex} = (raw: RawGroup) => ({ ${methods} })\n`
|
||||
}
|
||||
|
|
@ -1528,7 +1549,7 @@ function renderClient(groups: ReadonlyArray<Group>) {
|
|||
if (!group.endpoints[0]?.topLevel) {
|
||||
return [`${JSON.stringify(group.identifier)}: adaptGroup${index}(raw[${JSON.stringify(group.identifier)}])`]
|
||||
}
|
||||
const raw = `{ ${group.endpoints.map((item) => `${JSON.stringify(item.endpoint.name)}: raw[${JSON.stringify(item.endpoint.name)}]`).join(", ")} }`
|
||||
const raw = `{ ${group.endpoints.map((item) => `${JSON.stringify(item.endpoint.identifier)}: raw[${JSON.stringify(item.endpoint.identifier)}]`).join(", ")} }`
|
||||
return [`...adaptGroup${index}(${raw})`]
|
||||
})
|
||||
return `// Generated by @opencode-ai/httpapi-codegen. Do not edit.\nimport { Effect } from "effect"\nimport { HttpApi, HttpApiClient } from "effect/unstable/httpapi"\n${imports}\n\nconst Api = ${api}\nconst adaptClient = (raw: HttpApiClient.ForApi<typeof Api>) => ({ ${fields.join(", ")} })\n\nexport const make = (options?: { readonly baseUrl?: URL | string }) =>\n HttpApiClient.make(Api, options).pipe(Effect.map(adaptClient))\n`
|
||||
|
|
|
|||
|
|
@ -3,7 +3,14 @@ import { mkdtemp, rm } from "node:fs/promises"
|
|||
import { tmpdir } from "node:os"
|
||||
import { join } from "node:path"
|
||||
import { Effect, FileSystem, Schema, SchemaAST, SchemaGetter } from "effect"
|
||||
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, OpenApi } from "effect/unstable/httpapi"
|
||||
import {
|
||||
HttpApi,
|
||||
HttpApiEndpoint,
|
||||
HttpApiGroup,
|
||||
HttpApiMiddleware,
|
||||
HttpApiSchema,
|
||||
OpenApi,
|
||||
} from "effect/unstable/httpapi"
|
||||
import { format } from "prettier"
|
||||
import {
|
||||
compile as compileContract,
|
||||
|
|
@ -17,11 +24,11 @@ import {
|
|||
import { it } from "./effect"
|
||||
import { Api as FixtureApi, Missing } from "./fixture"
|
||||
|
||||
function api(endpoint: HttpApiEndpoint.Any) {
|
||||
function api(endpoint: HttpApiEndpoint.Constraint) {
|
||||
return HttpApi.make("test").add(HttpApiGroup.make("session").add(endpoint))
|
||||
}
|
||||
|
||||
function compile<Id extends string, Groups extends HttpApiGroup.Any>(source: HttpApi.HttpApi<Id, Groups>) {
|
||||
function compile<Id extends string, Groups extends HttpApiGroup.Constraint>(source: HttpApi.HttpApi<Id, Groups>) {
|
||||
return emitEffect(compileContract(source))
|
||||
}
|
||||
|
||||
|
|
@ -385,7 +392,7 @@ describe("HttpApiCodegen.generate", () => {
|
|||
)
|
||||
const contract = compileContract(source, { omitEndpoints: new Set(["pty.connect"]) })
|
||||
|
||||
expect(contract.groups[0]?.endpoints.map((endpoint) => endpoint.endpoint.name)).toEqual(["pty.get"])
|
||||
expect(contract.groups[0]?.endpoints.map((endpoint) => endpoint.endpoint.identifier)).toEqual(["pty.get"])
|
||||
})
|
||||
|
||||
test("uses bracket access for input field names", () => {
|
||||
|
|
@ -528,7 +535,9 @@ describe("HttpApiCodegen.generate", () => {
|
|||
const types = output.files.find((file) => file.path === "types.ts")?.content
|
||||
|
||||
expect(types).toContain('readonly "values": ReadonlyArray<string>')
|
||||
expect(types).toContain('export type SessionCreateOutput = ({ "data": Array<{ "values": Array<string> }> })["data"]')
|
||||
expect(types).toContain(
|
||||
'export type SessionCreateOutput = ({ "data": Array<{ "values": Array<string> }> })["data"]',
|
||||
)
|
||||
})
|
||||
|
||||
test("retains distinct Promise references at identifier boundaries", () => {
|
||||
|
|
@ -1193,7 +1202,7 @@ describe("HttpApiCodegen.generate", () => {
|
|||
new SchemaAST.Link(Schema.String.check(Schema.isMinLength(2)).ast, link.transformation),
|
||||
])
|
||||
if (!SchemaAST.isAST(ast)) throw new Error("Expected altered schema AST")
|
||||
const Altered = Schema.make(ast)
|
||||
const Altered = Schema.make<Schema.Top>(ast)
|
||||
|
||||
expect(() => compile(api(HttpApiEndpoint.get("get", "/session", { success: Altered })))).toThrow(
|
||||
"Effect schema requires authoritative import: session.get",
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export const Group1 = HttpApiGroup.make("event", { topLevel: false }).add(
|
|||
}),
|
||||
)
|
||||
|
||||
type RawGroup = HttpApiClient.Client.Group<typeof Group1, "event", never, never>
|
||||
type RawGroup = HttpApiClient.Client.Group<typeof Group1, never, never>
|
||||
|
||||
const Endpoint0DeclaredError = Schema.Union([Endpoint0SuccessError])
|
||||
const mapEndpoint0Error = (error: unknown) =>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export const Group0 = HttpApiGroup.make("session", { topLevel: false })
|
|||
}),
|
||||
)
|
||||
|
||||
type RawGroup = HttpApiClient.Client.Group<typeof Group0, "session", never, never>
|
||||
type RawGroup = HttpApiClient.Client.Group<typeof Group0, never, never>
|
||||
|
||||
const Endpoint0DeclaredError = Schema.Never
|
||||
const mapEndpoint0Error = (error: unknown) =>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { Skill } from "../skill"
|
|||
import { Effect, Context, Layer, Schema } from "effect"
|
||||
import { InstanceState } from "@/effect/instance-state"
|
||||
import * as Option from "effect/Option"
|
||||
import * as OtelTracer from "@effect/opentelemetry/Tracer"
|
||||
import * as OtelTracer from "@effect/opentelemetry/OtelTracer"
|
||||
import { AbsolutePath, type DeepMutable } from "@opencode-ai/core/schema"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ const layer = Layer.effect(
|
|||
if (input.icon?.url) return
|
||||
|
||||
const matches = yield* fs
|
||||
.glob("**/favicon.{ico,png,svg,jpg,jpeg,webp}", {
|
||||
.scan("**/favicon.{ico,png,svg,jpg,jpeg,webp}", {
|
||||
cwd: input.worktree,
|
||||
absolute: true,
|
||||
include: "file",
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ export const ExperimentalApi = HttpApi.make("experimental")
|
|||
),
|
||||
HttpApiEndpoint.post("worktreeCreate", ExperimentalPaths.worktree, {
|
||||
disableCodecs: true,
|
||||
query: WorkspaceRoutingQuery,
|
||||
query: WorkspaceRoutingQueryFields,
|
||||
payload: [HttpApiSchema.NoContent, Worktree.CreateInput],
|
||||
success: described(Worktree.Info, "Worktree created"),
|
||||
error: WorktreeApiError,
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ const layer: Layer.Layer<
|
|||
const instruction = raw.startsWith("~/") ? path.join(global.home, raw.slice(2)) : raw
|
||||
const matches = yield* (
|
||||
path.isAbsolute(instruction)
|
||||
? fs.glob(path.basename(instruction), {
|
||||
? fs.scan(path.basename(instruction), {
|
||||
cwd: path.dirname(instruction),
|
||||
absolute: true,
|
||||
include: "file",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import { Auth } from "@/auth"
|
|||
import { EffectBridge } from "@/effect/bridge"
|
||||
import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
import * as Option from "effect/Option"
|
||||
import * as OtelTracer from "@effect/opentelemetry/Tracer"
|
||||
import * as OtelTracer from "@effect/opentelemetry/OtelTracer"
|
||||
import { LLMAISDK } from "./llm/ai-sdk"
|
||||
import { LLMNativeRuntime } from "./llm/native-runtime"
|
||||
import { LLMRequestPrep } from "./llm/request"
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ const MIGRATIONS: Migration[] = [
|
|||
Effect.fn("Storage.migration.1")(function* (dir: string, fs: FSUtil.Interface, git: Git.Interface) {
|
||||
const project = path.resolve(dir, "../project")
|
||||
if (!(yield* fs.isDir(project))) return
|
||||
const projectDirs = yield* fs.glob("*", {
|
||||
const projectDirs = yield* fs.scan("*", {
|
||||
cwd: project,
|
||||
include: "all",
|
||||
})
|
||||
|
|
@ -94,7 +94,7 @@ const MIGRATIONS: Migration[] = [
|
|||
let worktree = "/"
|
||||
|
||||
if (projectID !== "global") {
|
||||
for (const msgFile of yield* fs.glob("storage/session/message/*/*.json", {
|
||||
for (const msgFile of yield* fs.scan("storage/session/message/*/*.json", {
|
||||
cwd: full,
|
||||
absolute: true,
|
||||
})) {
|
||||
|
|
@ -136,7 +136,7 @@ const MIGRATIONS: Migration[] = [
|
|||
)
|
||||
|
||||
yield* Effect.logInfo(`migrating sessions for project ${projectID}`)
|
||||
for (const sessionFile of yield* fs.glob("storage/session/info/*.json", {
|
||||
for (const sessionFile of yield* fs.scan("storage/session/info/*.json", {
|
||||
cwd: full,
|
||||
absolute: true,
|
||||
})) {
|
||||
|
|
@ -147,7 +147,7 @@ const MIGRATIONS: Migration[] = [
|
|||
yield* fs.writeWithDirs(dest, JSON.stringify(session, null, 2))
|
||||
if (Option.isNone(info)) continue
|
||||
yield* Effect.logInfo(`migrating messages for session ${info.value.id}`)
|
||||
for (const msgFile of yield* fs.glob(`storage/session/message/${info.value.id}/*.json`, {
|
||||
for (const msgFile of yield* fs.scan(`storage/session/message/${info.value.id}/*.json`, {
|
||||
cwd: full,
|
||||
absolute: true,
|
||||
})) {
|
||||
|
|
@ -162,7 +162,7 @@ const MIGRATIONS: Migration[] = [
|
|||
if (Option.isNone(item)) continue
|
||||
|
||||
yield* Effect.logInfo(`migrating parts for message ${item.value.id}`)
|
||||
for (const partFile of yield* fs.glob(`storage/session/part/${info.value.id}/${item.value.id}/*.json`, {
|
||||
for (const partFile of yield* fs.scan(`storage/session/part/${info.value.id}/${item.value.id}/*.json`, {
|
||||
cwd: full,
|
||||
absolute: true,
|
||||
})) {
|
||||
|
|
@ -180,7 +180,7 @@ const MIGRATIONS: Migration[] = [
|
|||
}
|
||||
}),
|
||||
Effect.fn("Storage.migration.2")(function* (dir: string, fs: FSUtil.Interface) {
|
||||
for (const item of yield* fs.glob("session/*/*.json", {
|
||||
for (const item of yield* fs.scan("session/*/*.json", {
|
||||
cwd: dir,
|
||||
absolute: true,
|
||||
})) {
|
||||
|
|
@ -302,7 +302,7 @@ const layer = Layer.effect(
|
|||
const dir = (yield* state).dir
|
||||
const cwd = path.join(dir, ...prefix)
|
||||
const result = yield* fs
|
||||
.glob("**/*", {
|
||||
.scan("**/*", {
|
||||
cwd,
|
||||
include: "file",
|
||||
})
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ describe("FSUtil", () => {
|
|||
yield* fs.writeFileString(path.join(tmp, "b.ts"), "b")
|
||||
yield* fs.writeFileString(path.join(tmp, "c.json"), "c")
|
||||
|
||||
const result = yield* fs.glob("*.ts", { cwd: tmp })
|
||||
const result = yield* fs.scan("*.ts", { cwd: tmp })
|
||||
expect(result.sort()).toEqual(["a.ts", "b.ts"])
|
||||
}),
|
||||
)
|
||||
|
|
@ -232,7 +232,7 @@ describe("FSUtil", () => {
|
|||
const tmp = yield* fs.makeTempDirectoryScoped()
|
||||
yield* fs.writeFileString(path.join(tmp, "file.txt"), "hello")
|
||||
|
||||
const result = yield* fs.glob("*.txt", { cwd: tmp, absolute: true })
|
||||
const result = yield* fs.scan("*.txt", { cwd: tmp, absolute: true })
|
||||
expect(result).toEqual([path.join(tmp, "file.txt")])
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ export function withCliFixture<A, E>(
|
|||
yield* Effect.addFinalizer(() =>
|
||||
fs
|
||||
.remove(home, { recursive: true })
|
||||
.pipe(Effect.retry(Schedule.spaced("50 millis").pipe(Schedule.both(Schedule.recurs(20)))), Effect.ignore),
|
||||
.pipe(Effect.retry(Schedule.max([Schedule.spaced("50 millis"), Schedule.recurs(20)])), Effect.ignore),
|
||||
)
|
||||
|
||||
const env = isolatedEnv(home)
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ function remappedFs(root: string) {
|
|||
writeWithDirs: (file, content, mode) => fs.writeWithDirs(remap(root, file), content, mode),
|
||||
readFileString: (file) => fs.readFileString(remap(root, file)),
|
||||
remove: (file) => fs.remove(remap(root, file)),
|
||||
glob: (pattern, options) =>
|
||||
fs.glob(pattern, options?.cwd ? { ...options, cwd: remap(root, options.cwd) } : options),
|
||||
scan: (pattern, options) =>
|
||||
fs.scan(pattern, options?.cwd ? { ...options, cwd: remap(root, options.cwd) } : options),
|
||||
})
|
||||
}),
|
||||
).pipe(Layer.provide(LayerNode.compile(FSUtil.node)))
|
||||
|
|
|
|||
|
|
@ -68,9 +68,7 @@ type MixedMiddlewareGroups<
|
|||
SessionLocationId extends HttpApiMiddleware.AnyId,
|
||||
SessionLocationService,
|
||||
> =
|
||||
| ReturnType<
|
||||
typeof makePermissionGroup<LocationId, LocationService, SessionLocationId, SessionLocationService>
|
||||
>
|
||||
| ReturnType<typeof makePermissionGroup<LocationId, LocationService, SessionLocationId, SessionLocationService>>
|
||||
| ReturnType<typeof makeQuestionGroup<LocationId, LocationService, SessionLocationId, SessionLocationService>>
|
||||
|
||||
type ApiGroups<
|
||||
|
|
@ -80,7 +78,7 @@ type ApiGroups<
|
|||
FormLocationService,
|
||||
SessionLocationId extends HttpApiMiddleware.AnyId,
|
||||
SessionLocationService,
|
||||
Event extends HttpApiGroup.Any,
|
||||
Event extends HttpApiGroup.Constraint,
|
||||
> =
|
||||
| typeof HealthGroup
|
||||
| typeof ServerGroup
|
||||
|
|
@ -100,7 +98,7 @@ export type Api<
|
|||
FormLocationService,
|
||||
SessionLocationId extends HttpApiMiddleware.AnyId,
|
||||
SessionLocationService,
|
||||
Event extends HttpApiGroup.Any,
|
||||
Event extends HttpApiGroup.Constraint,
|
||||
> = HttpApi.HttpApi<
|
||||
"server",
|
||||
HttpApiGroup.AddMiddleware<
|
||||
|
|
@ -122,7 +120,7 @@ export type Api<
|
|||
|
||||
// Protocol owns middleware placement, while Server injects concrete keys so Core service identities stay downstream.
|
||||
const makeApiFromGroup = <
|
||||
const Group extends HttpApiGroup.Any,
|
||||
const Group extends HttpApiGroup.Constraint,
|
||||
LocationId extends HttpApiMiddleware.AnyId,
|
||||
LocationService,
|
||||
FormLocationId extends HttpApiMiddleware.AnyId,
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ if (sessionMessagesTypesPatched === sessionListTypesPatched) {
|
|||
throw new Error("Session messages numeric query patch did not apply")
|
||||
}
|
||||
const eventSubscribeTypesPatched = sessionMessagesTypesPatched.replace(
|
||||
/(export type V2EventSubscribeResponses = \{\s*\/\*\*[\s\S]*?\*\/\s*200: )\{\s*id: string \| null;?\s*event: string;?\s*data: V2EventStream(?:V2)?;?\s*\};?/,
|
||||
/(export type V2EventSubscribeResponses = \{\s*\/\*\*[\s\S]*?\*\/\s*200: )\{\s*id: string \| null;?\s*event: string;?\s*data: (?:V2EventStream(?:V2)?|V2EventJsonString);?\s*\};?/,
|
||||
"$1V2Event",
|
||||
)
|
||||
if (eventSubscribeTypesPatched === sessionMessagesTypesPatched) {
|
||||
|
|
|
|||
|
|
@ -398,6 +398,8 @@ import type {
|
|||
V2SessionFormReplyResponses,
|
||||
V2SessionFormStateErrors,
|
||||
V2SessionFormStateResponses,
|
||||
V2SessionGenerateErrors,
|
||||
V2SessionGenerateResponses,
|
||||
V2SessionGetErrors,
|
||||
V2SessionGetResponses,
|
||||
V2SessionInstructionsEntryListErrors,
|
||||
|
|
@ -6475,6 +6477,41 @@ export class Session3 extends HeyApiClient {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate text from session context
|
||||
*
|
||||
* Generate transient text from the current session context without mutating session history.
|
||||
*/
|
||||
public generate<ThrowOnError extends boolean = false>(
|
||||
parameters: {
|
||||
sessionID: string
|
||||
prompt?: string
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "path", key: "sessionID" },
|
||||
{ in: "body", key: "prompt" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<V2SessionGenerateResponses, V2SessionGenerateErrors, ThrowOnError>({
|
||||
url: "/api/session/{sessionID}/generate",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the session log
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2089,6 +2089,7 @@ export type Config = {
|
|||
batch_tool?: boolean
|
||||
openTelemetry?: boolean
|
||||
primary_tools?: Array<string>
|
||||
subagent_depth?: number
|
||||
continue_loop_on_deny?: boolean
|
||||
mcp_timeout?: number
|
||||
}
|
||||
|
|
@ -2888,9 +2889,15 @@ export type InstructionEntryValueTooLargeError = {
|
|||
message: string
|
||||
}
|
||||
|
||||
export type SessionGenerateResponse = {
|
||||
data: {
|
||||
text: string
|
||||
}
|
||||
}
|
||||
|
||||
export type SessionLogItem = SessionEventDurable | EventLogSynced
|
||||
|
||||
export type SessionLogItemStream = string
|
||||
export type SessionLogItemJsonString = string
|
||||
|
||||
export type SessionMessagesResponse = {
|
||||
data: Array<SessionMessageInfo>
|
||||
|
|
@ -3102,7 +3109,7 @@ export type V2Event =
|
|||
| ServerConnected
|
||||
| GlobalDisposed
|
||||
|
||||
export type V2EventStream = string
|
||||
export type V2EventJsonString = string
|
||||
|
||||
export type ForbiddenError = {
|
||||
_tag: "ForbiddenError"
|
||||
|
|
@ -5552,6 +5559,27 @@ export type SessionRevertCommitted = {
|
|||
}
|
||||
}
|
||||
|
||||
export type SessionUsageRecorded = {
|
||||
id: string
|
||||
created: number
|
||||
metadata?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
type: "session.usage.recorded"
|
||||
durable: {
|
||||
aggregateID: string
|
||||
seq: number
|
||||
version: 1
|
||||
}
|
||||
location?: LocationRef
|
||||
data: {
|
||||
sessionID: string
|
||||
source: "title" | "compaction"
|
||||
cost: MoneyUsd
|
||||
tokens: TokenUsageInfo
|
||||
}
|
||||
}
|
||||
|
||||
export type SessionEventDurable =
|
||||
| SessionAgentSelected
|
||||
| SessionModelSelected
|
||||
|
|
@ -5591,6 +5619,7 @@ export type SessionEventDurable =
|
|||
| SessionRevertStaged
|
||||
| SessionRevertCleared
|
||||
| SessionRevertCommitted
|
||||
| SessionUsageRecorded
|
||||
|
||||
export type EventLogSynced = {
|
||||
type: "log.synced"
|
||||
|
|
@ -9892,6 +9921,27 @@ export type SessionRevertCommittedV2 = {
|
|||
}
|
||||
}
|
||||
|
||||
export type SessionUsageRecordedV2 = {
|
||||
id: string
|
||||
created: number
|
||||
metadata?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
type: "session.usage.recorded"
|
||||
durable: {
|
||||
aggregateID: string
|
||||
seq: number
|
||||
version: 1
|
||||
}
|
||||
location?: LocationRefV2
|
||||
data: {
|
||||
sessionID: string
|
||||
source: "title" | "compaction"
|
||||
cost: MoneyUsd
|
||||
tokens: TokenUsageInfo
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marker emitted once when a log read reaches its captured watermark. The reader holds every event committed at or below seq.
|
||||
*/
|
||||
|
|
@ -16373,6 +16423,47 @@ export type V2SessionInstructionsEntryPutResponses = {
|
|||
export type V2SessionInstructionsEntryPutResponse =
|
||||
V2SessionInstructionsEntryPutResponses[keyof V2SessionInstructionsEntryPutResponses]
|
||||
|
||||
export type V2SessionGenerateData = {
|
||||
body: {
|
||||
prompt: string
|
||||
}
|
||||
path: {
|
||||
sessionID: string
|
||||
}
|
||||
query?: never
|
||||
url: "/api/session/{sessionID}/generate"
|
||||
}
|
||||
|
||||
export type V2SessionGenerateErrors = {
|
||||
/**
|
||||
* InvalidRequestError
|
||||
*/
|
||||
400: InvalidRequestErrorV2
|
||||
/**
|
||||
* UnauthorizedError
|
||||
*/
|
||||
401: UnauthorizedError
|
||||
/**
|
||||
* SessionNotFoundError
|
||||
*/
|
||||
404: SessionNotFoundError
|
||||
/**
|
||||
* ServiceUnavailableError
|
||||
*/
|
||||
503: ServiceUnavailableErrorV2
|
||||
}
|
||||
|
||||
export type V2SessionGenerateError = V2SessionGenerateErrors[keyof V2SessionGenerateErrors]
|
||||
|
||||
export type V2SessionGenerateResponses = {
|
||||
/**
|
||||
* SessionGenerateResponse
|
||||
*/
|
||||
200: SessionGenerateResponse
|
||||
}
|
||||
|
||||
export type V2SessionGenerateResponse = V2SessionGenerateResponses[keyof V2SessionGenerateResponses]
|
||||
|
||||
export type V2SessionLogData = {
|
||||
body?: never
|
||||
path: {
|
||||
|
|
@ -16409,7 +16500,7 @@ export type V2SessionLogResponses = {
|
|||
200: {
|
||||
id: string | null
|
||||
event: string
|
||||
data: SessionLogItemStream
|
||||
data: SessionLogItemJsonString
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
diff --git a/dist/unstable/httpapi/HttpApiSchema.js b/dist/unstable/httpapi/HttpApiSchema.js
|
||||
index ecb6603d1ee4e89e92174b3a1100e8c9c720b3f3..08b832b6b3e9e4d10df156eca36b16f571f67f6e 100644
|
||||
index c51851b..2100420 100644
|
||||
--- a/dist/unstable/httpapi/HttpApiSchema.js
|
||||
+++ b/dist/unstable/httpapi/HttpApiSchema.js
|
||||
@@ -151,7 +151,7 @@ export const StreamSse = options => {
|
||||
|
|
@ -27,10 +27,10 @@ index ecb6603d1ee4e89e92174b3a1100e8c9c720b3f3..08b832b6b3e9e4d10df156eca36b16f5
|
|||
* Creates a streaming `Uint8Array` success response schema.
|
||||
*
|
||||
diff --git a/src/unstable/httpapi/HttpApiSchema.ts b/src/unstable/httpapi/HttpApiSchema.ts
|
||||
index f2920365cf0328146523ce2e2dba04d6a8809a4a..5482d635cdf01a72063ff683d244fab891910211 100644
|
||||
index aae6cd5..f05e3ed 100644
|
||||
--- a/src/unstable/httpapi/HttpApiSchema.ts
|
||||
+++ b/src/unstable/httpapi/HttpApiSchema.ts
|
||||
@@ -433,7 +433,7 @@ export const StreamSse: {
|
||||
@@ -407,7 +407,7 @@ export const StreamSse: {
|
||||
const events = options.events ?? (options.data === undefined ? undefined : Schema.Struct({
|
||||
id: Schema.UndefinedOr(Schema.String),
|
||||
event: Schema.String,
|
||||
|
|
@ -39,7 +39,7 @@ index f2920365cf0328146523ce2e2dba04d6a8809a4a..5482d635cdf01a72063ff683d244fab8
|
|||
}))
|
||||
if (events === undefined) {
|
||||
throw new Error("StreamSse requires either an events schema or a data schema")
|
||||
@@ -449,6 +449,15 @@ export const StreamSse: {
|
||||
@@ -423,6 +423,15 @@ export const StreamSse: {
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue