diff --git a/bun.lock b/bun.lock index de75b58..ab5b589 100644 --- a/bun.lock +++ b/bun.lock @@ -5,10 +5,11 @@ "": { "name": "owflow", "dependencies": { + "effect": "4.0.0-beta.98", "gray-matter": "^4.0.3", }, "devDependencies": { - "@opencode-ai/plugin": "^1.14.44", + "@opencode-ai/plugin": "^0.0.0-next-15919", "@types/bun": "^1.3.13", }, "peerDependencies": { @@ -17,21 +18,55 @@ }, }, "packages": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw=="], + "@ai-sdk/provider": ["@ai-sdk/provider@3.0.8", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-oGMAgGoQdBXbZqNG0Ze56CHjDZ1IDYOwGYxYjO5KLSlz5HiNQ9udIXsPZ61VWaHGZ5XW/jyjmr6t2xz2jGVwbQ=="], - "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw=="], + "@aws-crypto/crc32": ["@aws-crypto/crc32@5.2.0", "", { "dependencies": { "@aws-crypto/util": "^5.2.0", "@aws-sdk/types": "^3.222.0", "tslib": "^2.6.2" } }, "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg=="], - "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3", "", { "os": "linux", "cpu": "arm" }, "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw=="], + "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg=="], + "@aws-sdk/types": ["@aws-sdk/types@3.974.2", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-3W6IUtSxFbH6X7Wb7DzGCV5QiFQsd0g8bOfntpmDxQlzBoKWUMBu/JPQR0DwkE+Hpnxd6db1tXbOwdeHddG6cA=="], - "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3", "", { "os": "linux", "cpu": "x64" }, "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg=="], + "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], - "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3", "", { "os": "win32", "cpu": "x64" }, "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ=="], + "@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ=="], - "@opencode-ai/plugin": ["@opencode-ai/plugin@1.14.44", "", { "dependencies": { "@opencode-ai/sdk": "1.14.44", "effect": "4.0.0-beta.59", "zod": "4.1.8" }, "peerDependencies": { "@opentui/core": ">=0.2.6", "@opentui/keymap": ">=0.2.6", "@opentui/solid": ">=0.2.6" }, "optionalPeers": ["@opentui/core", "@opentui/keymap", "@opentui/solid"] }, "sha512-7uqSJWaDuP9GNvdUJ57E8AX0WNVP4C8PyCIJ2qvjtucjw6DFT/ErjXDXUrRiqwK3omImXRlTDb32xP9IMfk0dw=="], + "@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w=="], - "@opencode-ai/sdk": ["@opencode-ai/sdk@1.14.44", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-hpMCYhwEWk2B1b9THHYy5GRlrCJ9g67pvSyLt9O2b2pYj0HE6v8MeVOhg6ucn2T4QBIoVJ3ZDWnh7ApaeunNWg=="], + "@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw=="], + + "@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw=="], + + "@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ=="], + + "@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="], + + "@opencode-ai/ai": ["@opencode-ai/ai@0.0.0-next-15919", "", { "dependencies": { "@opencode-ai/schema": "0.0.0-next-15919", "@smithy/eventstream-codec": "4.2.14", "@smithy/util-utf8": "4.2.2", "aws4fetch": "1.0.20", "effect": "4.0.0-beta.98", "google-auth-library": "10.5.0" } }, "sha512-/Z5vwIluPemcU3ikfkg/CLxyJD72o9HF8UOSrYQA1Njp1x1zdikQaeFXuV1rxZeAJub3VJ9Xh8A5Ai4qHgJUlA=="], + + "@opencode-ai/client": ["@opencode-ai/client@0.0.0-next-15919", "", { "dependencies": { "@opencode-ai/protocol": "0.0.0-next-15919", "@opencode-ai/schema": "0.0.0-next-15919" }, "peerDependencies": { "effect": "4.0.0-beta.98" }, "optionalPeers": ["effect"] }, "sha512-iTrPwnjcqrshtzW4bqaSTWxoSL2ZwW6D3hSNIOjxautmoBrY/BbFLgV1Ze70iKqQdxKwqlWh1TqcAdxWq5QGZw=="], + + "@opencode-ai/plugin": ["@opencode-ai/plugin@0.0.0-next-15919", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@opencode-ai/ai": "0.0.0-next-15919", "@opencode-ai/client": "0.0.0-next-15919", "@opencode-ai/schema": "0.0.0-next-15919", "@opencode-ai/sdk": "0.0.0-next-15919", "@standard-schema/spec": "^1.1.0", "effect": "4.0.0-beta.98", "zod": "4.1.8" }, "peerDependencies": { "@opentui/core": ">=0.4.5", "@opentui/keymap": ">=0.4.5", "@opentui/solid": ">=0.4.5" }, "optionalPeers": ["@opentui/core", "@opentui/keymap", "@opentui/solid"] }, "sha512-78wfwdlB8eoMk3oa4n918dmt4jpaXoM2EgGoRR20oFjP1T22qMam0mgS9q9xkUxWdbY+MnrY4dtrqTWE29rt/g=="], + + "@opencode-ai/protocol": ["@opencode-ai/protocol@0.0.0-next-15919", "", { "dependencies": { "@opencode-ai/schema": "0.0.0-next-15919", "effect": "4.0.0-beta.98" } }, "sha512-RH3sL221xDpijfWLKc6egUi8H4Wfhy5WyHENwKonLZM3FZZCqR3AnMu//a2LaqzMjp09pYyjbjKkFndANvg4MA=="], + + "@opencode-ai/schema": ["@opencode-ai/schema@0.0.0-next-15919", "", { "dependencies": { "effect": "4.0.0-beta.98" } }, "sha512-+94WGnAsn69XDHJFr/rJFbpmLRAAYSWHeIAkkPPQXiOssdRxW3YNC5WTKcrFa7P/qridEZ5scXrF4G0JYatFIA=="], + + "@opencode-ai/sdk": ["@opencode-ai/sdk@0.0.0-next-15919", "", { "dependencies": { "cross-spawn": "7.0.6" } }, "sha512-9aKYphHv5vbutw3miUdjS2AoiqHfJiyfeqwEz5aaRnXxig3p9J6iO/ktsE/nPLqPvc3JPej0vwXzbUuVquWVuQ=="], + + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + + "@smithy/core": ["@smithy/core@3.29.6", "", { "dependencies": { "@smithy/types": "^4.16.1", "tslib": "^2.6.2" } }, "sha512-TO3w25cdGWBeYqKNDaqH3v4O3jjMPpKwf39YlG5X5xhqWfpOWJbi5gQi1lrllukuwohdhY0TPB8jBEv6UC50Vg=="], + + "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.14", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.14.1", "@smithy/util-hex-encoding": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw=="], + + "@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="], + + "@smithy/types": ["@smithy/types@4.16.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg=="], + + "@smithy/util-buffer-from": ["@smithy/util-buffer-from@4.4.11", "", { "dependencies": { "@smithy/core": "^3.29.6", "tslib": "^2.6.2" } }, "sha512-lDaLU75pkqH2xBZJGvcy02VWlMTukxCWrY3L56AMTFOFla8Jo89hyu2ia+yQsmZGC8Gw9QzCA0DFIUSaqPTgeA=="], + + "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.4.11", "", { "dependencies": { "@smithy/core": "^3.29.6", "tslib": "^2.6.2" } }, "sha512-oCnZKHTS2xUGjOLo2RmzDI19ReaC0aXWJ/u8FuvgYahHD0BvkEzXB3zJz1idgbk1sWjQdVRmaFMOvaQEMCQKBA=="], + + "@smithy/util-utf8": ["@smithy/util-utf8@4.2.2", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.2", "tslib": "^2.6.2" } }, "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw=="], "@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], @@ -39,72 +74,202 @@ "@types/node": ["@types/node@25.6.2", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-sokuT28dxf9JT5Kady1fsXOvI4HVpjZa95NKT5y9PNTIrs2AsobR4GFAA90ZG8M+nxVRLysCXsVj6eGC7Vbrlw=="], + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + "aws4fetch": ["aws4fetch@1.0.20", "", {}, "sha512-/djoAN709iY65ETD6LKCtyyEI04XIBP5xVvfmNxsEP0uJB5tyaGBztSryRr4HqMStr9R06PisQE7m9zDTXKu6g=="], + + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], + + "bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="], + + "brace-expansion": ["brace-expansion@2.1.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA=="], + + "buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="], + "bun-types": ["bun-types@1.3.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-QXKeHLlOLqQX9LgYaHJfzdBaV21T63HhFJnvuRCcjZiaUDpbs5ED1MgxbMra71CsryN/1dAoXuJJJwIv/2drVA=="], + "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "effect": ["effect@4.0.0-beta.59", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-xyUDLeHSe8d6lWGOvR6Fgn2HL6gYeTZ/S4Jzk9uc4ZUxMPPsNZlNXrvk0C7/utQFzeX7uAWcVnG2BjbA0SRoAA=="], + "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], + + "ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="], + + "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=="], + + "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], - "fast-check": ["fast-check@4.7.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ=="], + "fast-check": ["fast-check@4.9.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-7ms6T7SybUev/PQITciI0yLM2pOSFy5zpG8Ty7tQofcVaQUvrMXp6CBwqF6fThLCLOrfBtuHAtwq6Yu4XPCllg=="], + + "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], "find-my-way-ts": ["find-my-way-ts@0.1.6", "", {}, "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA=="], + "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + + "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + + "gaxios": ["gaxios@7.2.0", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2" } }, "sha512-CUVb4wcYe+771XevyH6HtGmXFAGGKkIC3kswAP8Z1JCe0j80JMaTPZH930DWFrvo0atjh18Arc0pEyUCWa5bfg=="], + + "gcp-metadata": ["gcp-metadata@8.1.3", "", { "dependencies": { "gaxios": "7.1.3", "google-logging-utils": "1.1.3", "json-bigint": "^1.0.0" } }, "sha512-ziTrzUhhpL9Zk5k0HHzgP/KIpWDJT0VMBC/ynt/QIBvTW+UUcSivQRl6VlwTf/EilDxtSWklHoRsKy1c4k+59w=="], + + "glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], + + "google-auth-library": ["google-auth-library@10.5.0", "", { "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "gaxios": "^7.0.0", "gcp-metadata": "^8.0.0", "google-logging-utils": "^1.0.0", "gtoken": "^8.0.0", "jws": "^4.0.0" } }, "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w=="], + + "google-logging-utils": ["google-logging-utils@1.1.4", "", {}, "sha512-LXxE6ND+JHhDPYtPFt3oeWrjxFPrnRZCZ4At6lpbi1ZDSAN7bmGET9s53vvARbxT93p+xpeDUbc/nCR4C+7vcw=="], + "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="], - "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], + "gtoken": ["gtoken@8.0.0", "", { "dependencies": { "gaxios": "^7.0.0", "jws": "^4.0.0" } }, "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "ini": ["ini@7.0.0", "", {}, "sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w=="], "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="], + + "json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="], + + "jwa": ["jwa@2.0.1", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg=="], + + "jws": ["jws@4.0.1", "", { "dependencies": { "jwa": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA=="], + "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], "kubernetes-types": ["kubernetes-types@1.30.0", "", {}, "sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q=="], - "msgpackr": ["msgpackr@1.11.12", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg=="], + "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], + + "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], - "msgpackr-extract": ["msgpackr-extract@3.0.3", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], - "multipasta": ["multipasta@0.2.7", "", {}, "sha512-KPA58d68KgGil15oDqXjkUBEBYc00XvbPj5/X+dyzeo/lWm9Nc25pQRlf1D+gv4OpK7NM0J1odrbu9JNNGvynA=="], + "msgpackr": ["msgpackr@2.0.4", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-o1C5KRmuRt+apqMr1HuGSqWStZoRBUpEsCsl15uM9VdAF1qHLtvMOU2En747EnTyEl6c4pzPewRMFF31s1CNbA=="], + + "msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="], + + "multipasta": ["multipasta@0.2.8", "", {}, "sha512-ZPWuMKyv0cSO29f7hozp+k6+crZbQijV8ipMvxNxRf2SwtYGTX1ZX89Kd20VV4H9Znonx+EQn+iy1wGQsJ+b+Q=="], + + "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], + + "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], + "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], + "rimraf": ["rimraf@5.0.10", "", { "dependencies": { "glob": "^10.3.7" }, "bin": { "rimraf": "dist/esm/bin.mjs" } }, "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ=="], + + "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], + "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + "string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + + "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + + "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], - "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], + "toml": ["toml@4.3.0", "", {}, "sha512-lVb8X9BsPVuH0M4BKeS91tXAmJvCjQ5UIyAbQFaxkKGyUFK2RPkhwaFSQH8vbpl1d23eu/IBH+dwVMHWaq9A5A=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "undici-types": ["undici-types@7.19.2", "", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="], - "uuid": ["uuid@13.0.2", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw=="], + "uuid": ["uuid@14.0.1", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew=="], + + "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - "yaml": ["yaml@2.8.4", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-ml/JPOj9fOQK8RNnWojA67GbZ0ApXAUlN2UQclwv2eVgTgn7O9gg9o7paZWKMp4g0H3nTLtS9LVzhkpOFIKzog=="], + "wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + + "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "yaml": ["yaml@2.9.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA=="], "zod": ["zod@4.1.8", "", {}, "sha512-5R1P+WwQqmmMIEACyzSvo4JXHY5WiAFHRMg+zBZKgKS+Q1viRa0C1hmUKtHltoIFKtIdki3pRxkmpP74jnNYHQ=="], + + "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], + + "gcp-metadata/gaxios": ["gaxios@7.1.3", "", { "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", "node-fetch": "^3.3.2", "rimraf": "^5.0.1" } }, "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ=="], + + "gcp-metadata/google-logging-utils": ["google-logging-utils@1.1.3", "", {}, "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA=="], + + "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], + + "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], } } diff --git a/package.json b/package.json index cf97b07..8906550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "owflow", - "version": "0.1.6", + "version": "0.2.0", "description": "Spec-driven development AI workflow for OpenCode", "type": "module", "module": "index.ts", @@ -15,7 +15,8 @@ "build": "rm -rf dist && tsc && bun run copy-markdowns", "copy-markdowns": "node ./scripts/copy-markdowns.js", "prepack": "bun run build", - "test": "bun test" + "test": "bun test", + "type-check": "tsc --noEmit" }, "keywords": [ "opencode", @@ -30,10 +31,11 @@ }, "license": "MIT", "dependencies": { + "effect": "4.0.0-beta.98", "gray-matter": "^4.0.3" }, "devDependencies": { - "@opencode-ai/plugin": "^1.14.44", + "@opencode-ai/plugin": "^0.0.0-next-15919", "@types/bun": "^1.3.13" }, "peerDependencies": { diff --git a/src/__tests__/verify_template.test.ts b/src/__tests__/verify_template.test.ts index f6796e4..a9e38f4 100644 --- a/src/__tests__/verify_template.test.ts +++ b/src/__tests__/verify_template.test.ts @@ -2,6 +2,7 @@ import { expect, test, describe, beforeAll, afterAll } from "bun:test"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; +import { Effect } from "effect"; import { verify_template } from "../tools/verify_template"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -11,6 +12,7 @@ describe("verify_template tool", () => { const testDir = path.join(__dirname, "test_tmp_dir"); const testTemplateName = "test-template.yml"; const testTemplatePath = path.join(templatesDir, testTemplateName); + const originalCwd = process.cwd(); beforeAll(() => { // Ensure templates dir exists @@ -31,9 +33,12 @@ key2: if (!fs.existsSync(testDir)) { fs.mkdirSync(testDir, { recursive: true }); } + + process.chdir(testDir); }); afterAll(() => { + process.chdir(originalCwd); // Cleanup if (fs.existsSync(testTemplatePath)) { fs.rmSync(testTemplatePath); @@ -44,10 +49,10 @@ key2: }); test("should return error if file not found", async () => { - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath: "nonexistent.yml", templateName: testTemplateName }, - { directory: testDir } as any, - ); + {} as any + )); expect((result as any).output).toContain( "File not found at nonexistent.yml", ); @@ -57,10 +62,10 @@ key2: const filePath = "target.yml"; fs.writeFileSync(path.join(testDir, filePath), "key1: value"); - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath, templateName: "nonexistent-template.yml" }, - { directory: testDir } as any, - ); + {} as any + )); expect((result as any).output).toContain( "Template 'nonexistent-template.yml' not found", ); @@ -70,10 +75,10 @@ key2: const filePath = "invalid.yml"; fs.writeFileSync(path.join(testDir, filePath), "key1: : value\n invalid"); - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath, templateName: testTemplateName }, - { directory: testDir } as any, - ); + {} as any + )); expect((result as any).output).toContain( "YAML Syntax Error in invalid.yml", ); @@ -84,10 +89,10 @@ key2: // Missing key2 fs.writeFileSync(path.join(testDir, filePath), "key1: some-value"); - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath, templateName: testTemplateName }, - { directory: testDir } as any, - ); + {} as any + )); expect((result as any).output).toContain( "YAML Structure Validation Failed", ); @@ -106,10 +111,10 @@ extraKey: this is fine `, ); - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath, templateName: testTemplateName }, - { directory: testDir } as any, - ); + {} as any + )); expect((result as any).output).toBe( "File exists and follows the correct YAML structure.", ); @@ -126,10 +131,10 @@ extraKey: this is fine "key: something\nother: 456", ); - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath, templateName: nullTemplateName }, - { directory: testDir } as any, - ); + {} as any + )); expect((result as any).output).toBe( "File exists and follows the correct YAML structure.", @@ -149,14 +154,22 @@ extraKey: this is fine // templates dir might not exist or be readable in some contexts, though beforeAll ensures it exists } + beforeAll(() => { + process.chdir(templatesDir); + }); + + afterAll(() => { + process.chdir(testDir); + }); + for (const templateName of templateFiles) { test(`should successfully validate a valid instance of ${templateName}`, async () => { // We use the templates directory as the working directory // and the template name as the filePath, effectively comparing the template to itself to ensure it's structurally valid. - const result = await verify_template.execute( + const result = await Effect.runPromise(verify_template.execute( { filePath: templateName, templateName }, - { directory: templatesDir } as any, - ); + {} as any + )); expect((result as any).output).toBe( "File exists and follows the correct YAML structure.", ); diff --git a/src/index.ts b/src/index.ts index 0e9f70e..39158a3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,60 +3,17 @@ * Registers skills/agents/commands via OpenCode's JS event system. */ -import type { Config, Plugin } from "@opencode-ai/plugin"; - -import path from "node:path"; +import { Plugin } from "@opencode-ai/plugin/v2/effect"; +import { Effect } from "effect"; import fs from "node:fs"; - -import { fileURLToPath } from "url"; -import type { OpenCodeConfig } from "./types/opencode-types"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import matter from "gray-matter"; import { verify_template } from "./tools/verify_template"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PLUGIN_ROOT = __dirname; // Points to dist/ where skills/commands/agents are copied -/** - * Resolves model aliases to the configured small_model value. - * Maps common small/fast model aliases to OpenCode's small_model config. - * - * @param {string} modelValue - The model value from agent frontmatter - * @param {string} smallModel - The small_model from OpenCode config - * @returns {string|undefined} - Resolved model value or undefined - */ -const resolveModelAlias = ( - modelValue: string, - smallModel: string, -): string | undefined => { - // Aliases that should map to small_model - const SMALL_MODEL_ALIASES = [ - "haiku", // Claude Code alias - "gpt-4o-mini", // OpenAI small model - "small", // Generic alias - "fast", // Generic alias - ]; - - // If no model specified or it's 'inherit', return undefined (let OpenCode decide) - if (!modelValue || modelValue === "inherit") { - return undefined; - } - - // If it's a small model alias and we have a configured small_model, use it - if (SMALL_MODEL_ALIASES.includes(modelValue.toLowerCase())) { - if (smallModel) { - return smallModel; - } - // If no small_model configured, return undefined (inherit) - console.warn( - `[owflow] Agent uses '${modelValue}' but no small_model configured in opencode.json - falling back to inherit`, - ); - return undefined; - } - - // Otherwise, pass through the original value - return modelValue; -}; - const loadMarkdownDir = (dirPath: string): matter.GrayMatterFile[] => { try { return fs @@ -71,18 +28,11 @@ const loadMarkdownDir = (dirPath: string): matter.GrayMatterFile[] => { } }; -const prepareAgent = ( - { data, content }: matter.GrayMatterFile, - smallModel: string, -) => { +const prepareAgent = ({ data, content }: matter.GrayMatterFile) => { return { prompt: content, ...(data.description && { description: data.description }), - // Resolve model aliases (haiku, gpt-4o-mini, etc.) to small_model - ...(() => { - const resolvedModel = resolveModelAlias(data.model, smallModel); - return resolvedModel ? { model: resolvedModel } : {}; - })(), + ...(data.model && { model: data.model }), ...(data.mode && { mode: data.mode }), // Add skills array if present ...(data.skills && Array.isArray(data.skills) && { skills: data.skills }), @@ -90,139 +40,94 @@ const prepareAgent = ( }; }; -const OwflowPlugin: Plugin = async ({ $, directory }) => { - const agentBySession = new Map(); - return { - tool: { - verify_template, - }, - /** - * Register owflow's skills, commands, and agents so OpenCode discovers - * them without requiring manual config file edits. - */ - config: async (config: unknown) => { - let typedConfig = config as OpenCodeConfig; - - // Get small_model config for alias resolution - // Try from config parameter first, fallback to reading opencode.json - let smallModel = typedConfig.small_model ?? ""; - - if (!smallModel) { - try { - // Check project-level opencode.json - const projectConfigPath = path.join(directory, "opencode.json"); - if (fs.existsSync(projectConfigPath)) { - const rawConfig = fs.readFileSync(projectConfigPath, "utf8"); - const opencodeConfig = JSON.parse(rawConfig); - smallModel = opencodeConfig.small_model; - } - } catch (error) { - console.warn( - `Couldn't read or parse opencode.json config - small_model remains undefined`, - ); - } - } - - // --- Skills --- - typedConfig.skills = typedConfig.skills || {}; - typedConfig.skills.paths = typedConfig.skills.paths || []; - const skillsDir = path.join(PLUGIN_ROOT, "skills"); - if (!typedConfig.skills.paths.includes(skillsDir)) { - typedConfig.skills.paths.push(skillsDir); - } +export default Plugin.define({ + id: "owflow", + effect: (ctx) => Effect.gen(function* () { + // Register tool + yield* ctx.tool.transform((draft) => { + draft.add("verify_template", verify_template); + }); + + // Register skills directory + yield* ctx.skill.transform((draft) => { + draft.source({ + type: "directory", + path: path.join(PLUGIN_ROOT, "skills") + }); + }); - // --- Commands --- - typedConfig.command = typedConfig.command || {}; + // Register commands + yield* ctx.command.transform((draft) => { const commandsDir = path.join(PLUGIN_ROOT, "commands"); for (const { data, content } of loadMarkdownDir(commandsDir)) { const name = data.name; if (!name) continue; - // Don't overwrite commands the user has explicitly configured - if (typedConfig.command[name]) continue; - typedConfig.command[name] = { - template: content, - ...(data.description && { description: data.description }), - ...(data.agent && { agent: data.agent }), - ...(data.model && { model: data.model }), - ...(data.subtask !== undefined && { - subtask: data.subtask === "true", - }), - }; + draft.update(name, (cmd) => { + cmd.template = content; + if (data.description) cmd.description = data.description; + if (data.agent) cmd.agent = data.agent; + if (data.model) cmd.model = data.model; + if (data.subtask !== undefined) cmd.subtask = data.subtask === "true"; + }); } + }); - // --- Agents --- - typedConfig.agent = typedConfig.agent || {}; + // Register agents + yield* ctx.agent.transform((draft) => { const agentsDir = path.join(PLUGIN_ROOT, "agents"); for (const markdown of loadMarkdownDir(agentsDir)) { const name = markdown.data.name; if (!name) continue; - // Don't overwrite agents the user has explicitly configured - if (typedConfig.agent[name]) continue; - try { - typedConfig.agent[name] = prepareAgent(markdown, smallModel); + draft.update(name, (agent) => { + Object.assign(agent, prepareAgent(markdown)); + }); } catch (error) { console.warn( - `[owflow] Failed to register agent '${name}': ${(error as Error).message}`, + `[owflow] Failed to register agent '${name}': ${(error as Error).message}` ); } } - - config = typedConfig; - }, - - /** - * Post-compaction reminder. - * Injects orchestrator state reminder into the compaction context so the - * AI knows to re-read orchestrator-state.yml after the context is rebuilt. - */ - "experimental.session.compacting": async (input, output) => { - const tasksDir = `${directory}/.owflow/tasks`; - try { - await $`test -d ${tasksDir}`; - output.context.push(`## owflow Workflow State -If an orchestrator workflow was active before compaction, you MUST re-read -orchestrator-state.yml in that task's directory to verify completed_phases -and determine the next phase. Use the question tool at Phase Gates.`); - } catch { - // No .owflow/tasks directory — not a owflow project, skip injection + }); + + // Tool Execute Hook (Intercepting Bash) + yield* ctx.tool.hook("execute.before", (event) => Effect.sync(() => { + if (event.tool !== "bash") return; + + const agentName = event.agent ?? "main"; + const WHITELIST = [ + "task-group-implementer", + "test-suite-runner", + "e2e-test-verifier", + "user-docs-generator", + "docs-operator", + ]; + if (WHITELIST.includes(agentName)) return; + + const input = event.input as { command?: string }; + const cmd = input.command ?? ""; + const DESTRUCTIVE = /git\s+stash|git\s+reset\s+--hard|git\s+checkout\s+--\s+\.|git\s+checkout\s+\.\s*(?:$|\s)|git\s+clean|git\s+push\s+(?:--force|-f)|rm\s+-[rf]{2}/i; + + if (DESTRUCTIVE.test(cmd)) { + throw new Error(`Blocked: destructive command not permitted for agent "${agentName}"`); } - }, + })); - "chat.message": async (input, _output) => { + // Session Hook (Compaction replacement) + yield* ctx.session.hook("context", (event) => Effect.sync(() => { + const tasksDir = path.join(process.cwd(), ".owflow/tasks"); try { - agentBySession.set(input.sessionID, input.agent ?? "main"); + if (fs.existsSync(tasksDir)) { + // Changed event.context.system.push to event.system.push + event.system.push({ + type: "text", + text: "## owflow Workflow State\nIf an orchestrator workflow was active before compaction, you MUST re-read orchestrator-state.yml in that task's directory to verify completed_phases and determine the next phase. Use the question tool at Phase Gates." + }); + } } catch { // ignore } - }, - - "tool.execute.before": async (input, output) => { - try { - if (input.tool !== "bash") return; - const agentName = agentBySession.get(input.sessionID) ?? "main"; - const WHITELIST = [ - "task-group-implementer", - "test-suite-runner", - "e2e-test-verifier", - "user-docs-generator", - "docs-operator", - ]; - if (WHITELIST.includes(agentName)) return; - const cmd = output?.args?.command ?? ""; - const DESTRUCTIVE = - /git\s+stash|git\s+reset\s+--hard|git\s+checkout\s+--\s+\.|git\s+checkout\s+\.\s*(?:$|\s)|git\s+clean|git\s+push\s+(?:--force|-f)|rm\s+-[rf]{2}/i; - if (DESTRUCTIVE.test(cmd)) { - throw new Error( - `Blocked: destructive command not permitted for agent "${agentName}"`, - ); - } - } catch (e) { - // Re-throw only intentional blocks; swallow unexpected errors - if ((e as Error).message?.startsWith("Blocked:")) throw e; - } - }, - }; -}; + })); -export default OwflowPlugin; + }) +}); diff --git a/src/tools/verify_template.ts b/src/tools/verify_template.ts index ed0678f..7271b56 100644 --- a/src/tools/verify_template.ts +++ b/src/tools/verify_template.ts @@ -1,4 +1,5 @@ -import { tool } from "@opencode-ai/plugin"; +import { make as makeTool } from "@opencode-ai/plugin/v2/effect/tool"; +import { Schema, Effect } from "effect"; import fs from "node:fs"; import path from "node:path"; import yaml from "yaml"; @@ -6,70 +7,100 @@ import { fileURLToPath } from "node:url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -export const verify_template = tool({ - description: "Check if file in the given path exists and follows correct YAML structure by checking against the template file from /templates.", - args: { - filePath: tool.schema.string().describe("Path to the file to check"), - templateName: tool.schema.string().describe("Name of the template from /templates (e.g. orchestrator-state-development.yml)"), - }, - async execute({ filePath, templateName }, context) { - const absolutePath = path.resolve(context.directory, filePath); - - if (!fs.existsSync(absolutePath)) { - return { output: `File not found at ${filePath}. Hint: Double-check the path, create the file if it's missing, or verify you are in the correct directory.` }; - } - - const templatePath = path.join(__dirname, "../templates", templateName); - - if (!fs.existsSync(templatePath)) { - return { output: `Template '${templateName}' not found. Hint: Verify the template name is correct and exists in the /templates folder (e.g., 'orchestrator-state-development.yml').` }; - } - - let targetYaml; - try { - const fileContent = fs.readFileSync(absolutePath, "utf8"); - targetYaml = yaml.parse(fileContent); - } catch (error: any) { - return { output: `YAML Syntax Error in ${filePath}: ${error.message}. Hint: Check the file content for invalid YAML formatting, such as incorrect indentation or unescaped strings, and fix them.` }; - } - - let templateYaml; - try { - const templateContent = fs.readFileSync(templatePath, "utf8"); - templateYaml = yaml.parse(templateContent); - } catch (error: any) { - return { output: `Internal Error: Failed to parse reference template YAML '${templateName}': ${error.message}. Hint: The template file itself contains invalid YAML syntax.` }; - } - - function checkStructure(templateObj: any, targetObj: any, currentPath: string = ""): string[] { - let errors: string[] = []; - - if (typeof templateObj !== 'object' || templateObj === null) { - return errors; +export const verify_template = makeTool({ + description: + "Check if file in the given path exists and follows correct YAML structure by checking against the template file from /templates.", + input: Schema.Struct({ + filePath: Schema.String, + templateName: Schema.String, + }), + output: Schema.Struct({ + output: Schema.String, + }), + execute: (input: { filePath: string; templateName: string }) => + Effect.sync(() => { + const { filePath, templateName } = input; + const absolutePath = path.resolve(process.cwd(), filePath); + + if (!fs.existsSync(absolutePath)) { + return { + output: `File not found at ${filePath}. Hint: Double-check the path, create the file if it's missing, or verify you are in the correct directory.`, + }; + } + + const templatePath = path.join(__dirname, "../templates", templateName); + + if (!fs.existsSync(templatePath)) { + return { + output: `Template '${templateName}' not found. Hint: Verify the template name is correct and exists in the /templates folder (e.g., 'orchestrator-state-development.yml').`, + }; + } + + let targetYaml; + try { + const fileContent = fs.readFileSync(absolutePath, "utf8"); + targetYaml = yaml.parse(fileContent); + } catch (error: any) { + return { + output: `YAML Syntax Error in ${filePath}: ${error.message}. Hint: Check the file content for invalid YAML formatting, such as incorrect indentation or unescaped strings, and fix them.`, + }; + } + + let templateYaml; + try { + const templateContent = fs.readFileSync(templatePath, "utf8"); + templateYaml = yaml.parse(templateContent); + } catch (error: any) { + return { + output: `Internal Error: Failed to parse reference template YAML '${templateName}': ${error.message}. Hint: The template file itself contains invalid YAML syntax.`, + }; } - for (const key of Object.keys(templateObj)) { - const newPath = currentPath ? `${currentPath}.${key}` : key; - - if (typeof targetObj !== 'object' || targetObj === null || !(key in targetObj)) { - errors.push(`Missing key: ${newPath}`); - continue; + function checkStructure( + templateObj: any, + targetObj: any, + currentPath: string = "", + ): string[] { + let errors: string[] = []; + + if (typeof templateObj !== "object" || templateObj === null) { + return errors; } - if (typeof templateObj[key] === 'object' && templateObj[key] !== null && !Array.isArray(templateObj[key])) { - errors.push(...checkStructure(templateObj[key], targetObj[key], newPath)); + for (const key of Object.keys(templateObj)) { + const newPath = currentPath ? `${currentPath}.${key}` : key; + + if ( + typeof targetObj !== "object" || + targetObj === null || + !(key in targetObj) + ) { + errors.push(`Missing key: ${newPath}`); + continue; + } + + if ( + typeof templateObj[key] === "object" && + templateObj[key] !== null && + !Array.isArray(templateObj[key]) + ) { + errors.push( + ...checkStructure(templateObj[key], targetObj[key], newPath), + ); + } } - } - return errors; - } + return errors; + } - const errors = checkStructure(templateYaml, targetYaml); + const errors = checkStructure(templateYaml, targetYaml); - if (errors.length > 0) { - return { output: `YAML Structure Validation Failed. Your file is missing the following required keys:\n- ${errors.join("\n- ")}\n\nHint: Update the file at ${filePath} to include these missing keys so it matches the structure of '${templateName}'.` }; - } + if (errors.length > 0) { + return { + output: `YAML Structure Validation Failed. Your file is missing the following required keys:\n- ${errors.join("\n- ")}\n\nHint: Update the file at ${filePath} to include these missing keys so it matches the structure of '${templateName}'.`, + }; + } - return { output: "File exists and follows the correct YAML structure." }; - } + return { output: "File exists and follows the correct YAML structure." }; + }), }); diff --git a/src/types/opencode-types.ts b/src/types/opencode-types.ts deleted file mode 100644 index b646dcb..0000000 --- a/src/types/opencode-types.ts +++ /dev/null @@ -1,16 +0,0 @@ -// workaround til something is not done with issue https://github.com/anomalyco/opencode/issues/24065 - -export interface OpenCodeConfig { - agent: any; - command: Record; - skills: any; - small_model?: string; -} - -export interface OpenCodeCommand { - template: string; - description?: string; - agent?: string; - model?: string; - subtask?: boolean; -}