diff --git a/bun.lock b/bun.lock index e5eac7ce6..9bba4e1d7 100644 --- a/bun.lock +++ b/bun.lock @@ -84,8 +84,8 @@ }, "dependencies": { "@codebuff/sdk": "workspace:*", - "@opentui/core": "^0.1.28", - "@opentui/react": "^0.1.28", + "@opentui/core": "0.1.33", + "@opentui/react": "0.1.33", "@tanstack/react-query": "^5.62.8", "commander": "^14.0.1", "immer": "^10.1.3", @@ -432,7 +432,7 @@ "@ai-sdk/openai": ["@ai-sdk/openai@2.0.11", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.2" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-t4i+vS825EC0Gc2DdTsC5UkXIu1ScOi363noTD8DuFZp6WFPHRnW6HCyEQKxEm6cNjv3BW89rdXWqq932IFJhA=="], - "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.22", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.12" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-Q+lwBIeMprc/iM+vg1yGjvzRrp74l316wDpqWdbmd4VXXlllblzGsUgBLTeKvcEapFTgqk0FRETvSb58Y6dsfA=="], + "@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@1.0.25", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@ai-sdk/provider-utils": "3.0.15" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-VPylb5ytkOu9Bs1UnVmz4x0wr1VtS30Pw6ghh6GxpGH6lo4GOWqVnYuB+8M755dkof74c5LULZq5C1n/1J4Kvg=="], "@ai-sdk/provider": ["@ai-sdk/provider@2.0.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA=="], @@ -450,27 +450,27 @@ "@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.60.0", "", { "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-9zu/TXaUy8BZhXedDtt1wT3H4LOlpKDO1/ftiFpeR3N1PCr3KJFKkxxlQWWt1NNp08xSwUNJ3JNY8yhl8av6eQ=="], - "@auth/core": ["@auth/core@0.41.0", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "jose": "^6.0.6", "oauth4webapi": "^3.3.0", "preact": "10.24.3", "preact-render-to-string": "6.5.11" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^6.8.0" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-Wd7mHPQ/8zy6Qj7f4T46vg3aoor8fskJm6g2Zyj064oQ3+p0xNZXAV60ww0hY+MbTesfu29kK14Zk5d5JTazXQ=="], + "@auth/core": ["@auth/core@0.41.1", "", { "dependencies": { "@panva/hkdf": "^1.2.1", "jose": "^6.0.6", "oauth4webapi": "^3.3.0", "preact": "10.24.3", "preact-render-to-string": "6.5.11" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^7.0.7" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-t9cJ2zNYAdWMacGRMT6+r4xr1uybIdmYa49calBPeTqwgAFPV/88ac9TEvCR85pvATiSPt8VaNf+Gt24JIT/uw=="], - "@auth/drizzle-adapter": ["@auth/drizzle-adapter@1.11.0", "", { "dependencies": { "@auth/core": "0.41.0" } }, "sha512-7YHi5bTZZs4+D6TQIT/AWgZ2PLL7Zc9fS7bteHKMrsEMemarbdv3H5eF8RfF1FpRtyK8MAj4EQV4BWf0gCzAYw=="], + "@auth/drizzle-adapter": ["@auth/drizzle-adapter@1.11.1", "", { "dependencies": { "@auth/core": "0.41.1" } }, "sha512-cQTvDZqsyF7RPhDm/B6SvqdVP9EzQhy3oM4Muu7fjjmSYFLbSR203E6dH631ZHSKDn2b4WZkfMnjPDzRsPSAeA=="], "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], - "@babel/compat-data": ["@babel/compat-data@7.28.4", "", {}, "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw=="], + "@babel/compat-data": ["@babel/compat-data@7.28.5", "", {}, "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA=="], - "@babel/core": ["@babel/core@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.4", "@babel/types": "^7.28.4", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA=="], + "@babel/core": ["@babel/core@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.4", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw=="], - "@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="], + "@babel/generator": ["@babel/generator@7.28.5", "", { "dependencies": { "@babel/parser": "^7.28.5", "@babel/types": "^7.28.5", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.27.3", "", { "dependencies": { "@babel/types": "^7.27.3" } }, "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg=="], "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "dependencies": { "@babel/compat-data": "^7.27.2", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="], - "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.3", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.3", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg=="], + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/traverse": "^7.28.5", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ=="], "@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="], - "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA=="], + "@babel/helper-member-expression-to-functions": ["@babel/helper-member-expression-to-functions@7.28.5", "", { "dependencies": { "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5" } }, "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg=="], "@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="], @@ -486,13 +486,13 @@ "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], - "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], "@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="], "@babel/helpers": ["@babel/helpers@7.28.4", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.4" } }, "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w=="], - "@babel/parser": ["@babel/parser@7.28.4", "", { "dependencies": { "@babel/types": "^7.28.4" }, "bin": "./bin/babel-parser.js" }, "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg=="], + "@babel/parser": ["@babel/parser@7.28.5", "", { "dependencies": { "@babel/types": "^7.28.5" }, "bin": "./bin/babel-parser.js" }, "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ=="], "@babel/plugin-syntax-async-generators": ["@babel/plugin-syntax-async-generators@7.8.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw=="], @@ -528,17 +528,17 @@ "@babel/plugin-syntax-typescript": ["@babel/plugin-syntax-typescript@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ=="], - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg=="], + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.28.5", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-create-class-features-plugin": "^7.28.5", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA=="], "@babel/runtime": ["@babel/runtime@7.28.4", "", {}, "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ=="], "@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="], - "@babel/traverse": ["@babel/traverse@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/types": "^7.28.4", "debug": "^4.3.1" } }, "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ=="], + "@babel/traverse": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], - "@babel/traverse--for-generate-function-map": ["@babel/traverse@7.28.4", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.4", "@babel/template": "^7.27.2", "@babel/types": "^7.28.4", "debug": "^4.3.1" } }, "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ=="], + "@babel/traverse--for-generate-function-map": ["@babel/traverse@7.28.5", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.5", "@babel/template": "^7.27.2", "@babel/types": "^7.28.5", "debug": "^4.3.1" } }, "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ=="], - "@babel/types": ["@babel/types@7.28.4", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q=="], + "@babel/types": ["@babel/types@7.28.5", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA=="], "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], @@ -636,7 +636,7 @@ "@dimforge/rapier3d-compat": ["@dimforge/rapier3d-compat@0.12.0", "", {}, "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow=="], - "@discordjs/builders": ["@discordjs/builders@1.12.2", "", { "dependencies": { "@discordjs/formatters": "^0.6.1", "@discordjs/util": "^1.1.1", "@sapphire/shapeshift": "^4.0.0", "discord-api-types": "^0.38.26", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.4", "tslib": "^2.6.3" } }, "sha512-AugKmrgRJOHXEyMkABH/hXpAmIBKbYokCEl9VAM4Kh6FvkdobQ+Zhv7AR6K+y5hS7+VQ7gKXPYCe1JQmV07H1g=="], + "@discordjs/builders": ["@discordjs/builders@1.13.0", "", { "dependencies": { "@discordjs/formatters": "^0.6.1", "@discordjs/util": "^1.1.1", "@sapphire/shapeshift": "^4.0.0", "discord-api-types": "^0.38.31", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.4", "tslib": "^2.6.3" } }, "sha512-COK0uU6ZaJI+LA67H/rp8IbEkYwlZf3mAoBI5wtPh5G5cbEQGNhVpzINg2f/6+q/YipnNIKy6fJDg6kMUKUw4Q=="], "@discordjs/collection": ["@discordjs/collection@1.5.3", "", {}, "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ=="], @@ -660,9 +660,9 @@ "@effect-ts/system": ["@effect-ts/system@0.57.5", "", {}, "sha512-/crHGujo0xnuHIYNc1VgP0HGJGFSoSqq88JFXe6FmFyXPpWt8Xu39LyLg7rchsxfXFeEdA9CrIZvLV5eswXV5g=="], - "@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], + "@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="], - "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], + "@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="], "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], @@ -724,7 +724,7 @@ "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], - "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], "@eslint/eslintrc": ["@eslint/eslintrc@2.1.4", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ=="], @@ -924,7 +924,7 @@ "@mermaid-js/parser": ["@mermaid-js/parser@0.6.3", "", { "dependencies": { "langium": "3.3.1" } }, "sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA=="], - "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.20.0", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-kOQ4+fHuT4KbR2iq2IjeV32HiihueuOf1vJkq18z08CLZ1UQrTc8BXJpVfxZkq45+inLLD+D4xx4nBjUelJa4Q=="], + "@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.20.2", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-6rqTdFt67AAAzln3NOKsXRmv5ZzPkgbfaebKBqUbts7vK1GZudqnrun5a8d3M/h955cam9RHZ6Jb4Y1XhnmFPg=="], "@monogrid/gainmap-js": ["@monogrid/gainmap-js@3.1.0", "", { "dependencies": { "promise-worker-transferable": "^1.0.4" }, "peerDependencies": { "three": ">= 0.159.0" } }, "sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw=="], @@ -934,7 +934,7 @@ "@next/eslint-plugin-next": ["@next/eslint-plugin-next@14.2.25", "", { "dependencies": { "glob": "10.3.10" } }, "sha512-L2jcdEEa0bTv1DhE67Cdx1kLLkL0iLL9ILdBYx0j7noi2AUJM7bwcqmcN8awGg+8uyKGAGof/OkFom50x+ZyZg=="], - "@next/mdx": ["@next/mdx@15.5.5", "", { "dependencies": { "source-map": "^0.7.0" }, "peerDependencies": { "@mdx-js/loader": ">=0.15.0", "@mdx-js/react": ">=0.15.0" }, "optionalPeers": ["@mdx-js/loader", "@mdx-js/react"] }, "sha512-+niIZwo1ObCj8YJCR31FwF3gUXnyQZTnrrt5DnJGF/nj6yW7VE0hhmhT2yWW244MuBKqL3SbXjaFX+GqWOPXfA=="], + "@next/mdx": ["@next/mdx@15.5.6", "", { "dependencies": { "source-map": "^0.7.0" }, "peerDependencies": { "@mdx-js/loader": ">=0.15.0", "@mdx-js/react": ">=0.15.0" }, "optionalPeers": ["@mdx-js/loader", "@mdx-js/react"] }, "sha512-lyzXcnZWPjYxbkz/5tv1bRlCOjKYX1lFg3LIuoIf9ERTOUBDzkCvUnWjtRsmFRxKv1/6uwpLVQvrJDd54gVDBw=="], "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@14.2.25", "", { "os": "darwin", "cpu": "arm64" }, "sha512-09clWInF1YRd6le00vt750s3m7SEYNehz9C4PUcSu3bAdCTpjIV4aTYQZ25Ehrr83VR1rZeqtKUPWSI7GfuKZQ=="], @@ -964,27 +964,27 @@ "@nx/devkit": ["@nx/devkit@20.8.2", "", { "dependencies": { "ejs": "^3.1.7", "enquirer": "~2.3.6", "ignore": "^5.0.4", "minimatch": "9.0.3", "semver": "^7.5.3", "tmp": "~0.2.1", "tslib": "^2.3.0", "yargs-parser": "21.1.1" }, "peerDependencies": { "nx": ">= 19 <= 21" } }, "sha512-rr9p2/tZDQivIpuBUpZaFBK6bZ+b5SAjZk75V4tbCUqGW3+5OPuVvBPm+X+7PYwUF6rwSpewxkjWNeGskfCe+Q=="], - "@nx/nx-darwin-arm64": ["@nx/nx-darwin-arm64@21.6.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Ra24qHf55i9ogJ8wDymRzQL0kLK8uEXjntwKHD0stZtyiYO1tCKLgvxn5oOhiyn1sAk7aKT238s2y9zJ5bYPnQ=="], + "@nx/nx-darwin-arm64": ["@nx/nx-darwin-arm64@21.6.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-MG5bhSYhG49r+e0mLuztQVHz1sEy7cs8BvZJ56mm7JNQ1VfbaTyLAR7VcNw8O/1mJA8jYcg9fmxOIZOUnY1cEQ=="], - "@nx/nx-darwin-x64": ["@nx/nx-darwin-x64@21.6.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-4tzVVu+2arCpu7RGqdb4JR3fvKyTrHUn0fX33kMtds2TGvzERbfgBPzEzrqbLiflpYdxqCZX8l0yPRsvjuCojA=="], + "@nx/nx-darwin-x64": ["@nx/nx-darwin-x64@21.6.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-e9oXVTd6U6RFEc3k22PGoe5OSy40fyyytl+svSJQmK+5rxZalvAUna/mXtFcQC9m6No2daqqpfAZlyN5nG6WHw=="], - "@nx/nx-freebsd-x64": ["@nx/nx-freebsd-x64@21.6.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-DqeQn//aHLdvqkd5uTpAm6/TGW54XBg3UEfvCD5LFLMXWVdToi6CbIFnRIhufdFLEboQH0Nm22fdJnGwAPV+Xw=="], + "@nx/nx-freebsd-x64": ["@nx/nx-freebsd-x64@21.6.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-gK3rsTXQj0hHCyaAvZmPZeCPkb3jzesgtkXuZf+7pCm5b4wiEA1i22ufp1UzwaTmWgbub/6NVMEDOGsVcay8mA=="], - "@nx/nx-linux-arm-gnueabihf": ["@nx/nx-linux-arm-gnueabihf@21.6.4", "", { "os": "linux", "cpu": "arm" }, "sha512-6m82VzjrVVvwZtS5rFj0j7CcDrYaSkZ4yk0lf1NIvRqWjgnTnfaG58XQQxLo8wxH8mKiPDQzlDuer9HNNIxKCw=="], + "@nx/nx-linux-arm-gnueabihf": ["@nx/nx-linux-arm-gnueabihf@21.6.8", "", { "os": "linux", "cpu": "arm" }, "sha512-TXt3HTFhM4kuL9larxBuo3XpSngoA1JCtHavfYLRC3A8knACi7LwNQwnF5RWAcYgKMVE3/8IAhV8LuemXrPKKw=="], - "@nx/nx-linux-arm64-gnu": ["@nx/nx-linux-arm64-gnu@21.6.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-Ohlh3YdzbmWnXjlDZd6yw20mNMWvZ1CGW/iQ5suerfyJZGjO+ToPjw3Mp8HgBoesHaWPGi81GhjAEyiZmEAHug=="], + "@nx/nx-linux-arm64-gnu": ["@nx/nx-linux-arm64-gnu@21.6.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-QwZREYIhqhDVEIf+KAv2VFipxMUoULXXS3qyLX3/q/4u8Y32fyM5wd+FXpv89cRCiveVsZp8io2W178R6lfKng=="], - "@nx/nx-linux-arm64-musl": ["@nx/nx-linux-arm64-musl@21.6.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-OLvEpJYo7n8nHGaBSl7Fb+Oz68wmPfRP+i6voQbM8qV/g5No9vE/QtAdSTlyFXOCGwSekCGpc2Ef2KOvpmYUTg=="], + "@nx/nx-linux-arm64-musl": ["@nx/nx-linux-arm64-musl@21.6.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-UZJyrZ6utU8g1W7E31iHDhWj1SjMidmDNyrVP4xK6IUrotx6qGrwfwWqzqvphhc1cA7w4Zz9N/rCCPQkdHzjLw=="], - "@nx/nx-linux-x64-gnu": ["@nx/nx-linux-x64-gnu@21.6.4", "", { "os": "linux", "cpu": "x64" }, "sha512-TYC5a5VnXhEGGVAtPVwdG5qLzf9p7SZyOrOdQMZlAZCchFpL37gmV1OMH1Eb5eM32o+mGF/DDIgbyNXAErTN5g=="], + "@nx/nx-linux-x64-gnu": ["@nx/nx-linux-x64-gnu@21.6.8", "", { "os": "linux", "cpu": "x64" }, "sha512-HXINTg4P0/Yj76vsvqBAb7MNlLpkH1pl9JF2blXScOFXWzNoStd7b6xyrpCROdmi0Hk8y3UEwc8OIyLFIfixJg=="], - "@nx/nx-linux-x64-musl": ["@nx/nx-linux-x64-musl@21.6.4", "", { "os": "linux", "cpu": "x64" }, "sha512-2ZG3DUadDpP79oW5DIYMZPKFMCGSRbqLKeHlW8miYORbPJ6VinUp6wTVDx6cAoL2IhP9biD6dItc9Dcfn5Hj2g=="], + "@nx/nx-linux-x64-musl": ["@nx/nx-linux-x64-musl@21.6.8", "", { "os": "linux", "cpu": "x64" }, "sha512-2YbXLhuSlElCtQTR1Ib94O3T4fX9uzSIkUMYGL3n04agG0HemXoxJa91TWwwOUMbEZffkhcPsJBOh2S5l47s9Q=="], - "@nx/nx-win32-arm64-msvc": ["@nx/nx-win32-arm64-msvc@21.6.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-o64p5hVavJhD+ISxCfwCKhKccgXalEnvfXfqXBV6yZiud6kDnYphPp2SPzyf9NgZyuFJdeFRvJ1XtuEzW3VcXg=="], + "@nx/nx-win32-arm64-msvc": ["@nx/nx-win32-arm64-msvc@21.6.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-/VSGtqa1oGHo5n24R39ZuGxMrGyf7pxFuCtL5hAzBHdTxFg/VZomPGd7BeV5VN5SbIw+fie+nTGkC5q3TOPGXw=="], - "@nx/nx-win32-x64-msvc": ["@nx/nx-win32-x64-msvc@21.6.4", "", { "os": "win32", "cpu": "x64" }, "sha512-g+YwOFd9sjTjf6LCaN8hq6plvNo4BfwmTurnKBzJ/Q/hCbxffYpo1Vdos+OfHBuMsJN2yIMX97LwB0d9w2I8Ag=="], + "@nx/nx-win32-x64-msvc": ["@nx/nx-win32-x64-msvc@21.6.8", "", { "os": "win32", "cpu": "x64" }, "sha512-xeBL7PcDqHH/Zw4d2A2qP7eLImzzcMO3hiKs5G42Wi92ACejAdUqpIduTL4RpArsXIHm5VEbE4KvHNii1mMU1A=="], - "@oclif/core": ["@oclif/core@4.5.5", "", { "dependencies": { "ansi-escapes": "^4.3.2", "ansis": "^3.17.0", "clean-stack": "^3.0.1", "cli-spinners": "^2.9.2", "debug": "^4.4.3", "ejs": "^3.1.10", "get-package-type": "^0.1.0", "indent-string": "^4.0.0", "is-wsl": "^2.2.0", "lilconfig": "^3.1.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "string-width": "^4.2.3", "supports-color": "^8", "tinyglobby": "^0.2.14", "widest-line": "^3.1.0", "wordwrap": "^1.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-iQzlaJQgPeUXrtrX71OzDwxPikQ7c2FhNd8U8rBB7BCtj2XYfmzBT/Hmbc+g9OKDIG/JkbJT0fXaWMMBrhi+1A=="], + "@oclif/core": ["@oclif/core@4.8.0", "", { "dependencies": { "ansi-escapes": "^4.3.2", "ansis": "^3.17.0", "clean-stack": "^3.0.1", "cli-spinners": "^2.9.2", "debug": "^4.4.3", "ejs": "^3.1.10", "get-package-type": "^0.1.0", "indent-string": "^4.0.0", "is-wsl": "^2.2.0", "lilconfig": "^3.1.3", "minimatch": "^9.0.5", "semver": "^7.7.3", "string-width": "^4.2.3", "supports-color": "^8", "tinyglobby": "^0.2.14", "widest-line": "^3.1.0", "wordwrap": "^1.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-jteNUQKgJHLHFbbz806aGZqf+RJJ7t4gwF4MYa8fCwCxQ8/klJNWc0MvaJiBebk7Mc+J39mdlsB4XraaCKznFw=="], "@oclif/errors": ["@oclif/errors@1.3.6", "", { "dependencies": { "clean-stack": "^3.0.0", "fs-extra": "^8.1", "indent-string": "^4.0.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-fYaU4aDceETd89KXP+3cLyg9EHZsLD3RxF2IU9yxahhBpspWjkWi3Dy3bTgcwZ3V47BgxQaGapzJWDM33XIVDQ=="], @@ -1026,31 +1026,33 @@ "@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.37.0", "", {}, "sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA=="], - "@opentui/core": ["@opentui/core@0.1.28", "", { "dependencies": { "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.28", "@opentui/core-darwin-x64": "0.1.28", "@opentui/core-linux-arm64": "0.1.28", "@opentui/core-linux-x64": "0.1.28", "@opentui/core-win32-arm64": "0.1.28", "@opentui/core-win32-x64": "0.1.28", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": ">=0.26.0" } }, "sha512-3GOnETvNeYcWcQPGaauNpPxgvglnvCfK4mmr7gkNsnVY5NEnrBbh7yuVHDXRNuzRldG4Aj5JEq7pWRexNhnL6g=="], + "@opentui/core": ["@opentui/core@0.1.33", "", { "dependencies": { "bun-ffi-structs": "^0.1.0", "jimp": "1.6.0", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.33", "@opentui/core-darwin-x64": "0.1.33", "@opentui/core-linux-arm64": "0.1.33", "@opentui/core-linux-x64": "0.1.33", "@opentui/core-win32-arm64": "0.1.33", "@opentui/core-win32-x64": "0.1.33", "bun-webgpu": "0.1.3", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-vwHdrPIqnsY6YnG2JTNhenHSsx+HUPYrQTBZdmEfCj9ROGVzKgUKbSDH1xGK2OtSNRb2KVBg4XaMpq0bie6afQ=="], - "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.28", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ivJmq6NLNzWRiottzBE5DVLe/fOklj3WwGkFhnRTFDG2nDcc1/uyvvpCZRwkJcb+TpV5zpB8YWzzs3XahGA0oQ=="], + "@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.33", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JBvzcP2V7fT9KxFAMenHRd/t72qPP5IL5kzge2uok1T7t2nw3Wa+CWI5s6FYP42p2b1W9qZkv5Fno5gA7OAYuQ=="], - "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.28", "", { "os": "darwin", "cpu": "x64" }, "sha512-tiIiX9S5Gdz0DFfzqOv5WRjJsr+zEHWiYYoUlJ7/H9IRw0cj3Wq9V1LruZKd3WwbXwEVNkrdo9PoGotNGDSUxQ=="], + "@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.33", "", { "os": "darwin", "cpu": "x64" }, "sha512-x7DY6VCkAky10z/2o4UkkuNW/nIvoX7uAh3dJOHWZCLbiKywSFvFk3QZVVcH5BMk4tOOophYTzika4s4HpaeMg=="], - "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.28", "", { "os": "linux", "cpu": "arm64" }, "sha512-jZ6848fyF8wVElIsCiAC5hBvPjOWlVlpXQFL8XBiu4U47bI/Le6vpp9f/kg9iipFaq2pGxKYcQak1/35Ns+5UQ=="], + "@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.33", "", { "os": "linux", "cpu": "arm64" }, "sha512-bBc1EdkVxsLBtqGjXM2BYpBJLa57ogcrSADSZbc5cQkPu0muSGzUwBbVnVZJUjWEfk6n5jcd4dDmLezVoQga0A=="], - "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.28", "", { "os": "linux", "cpu": "x64" }, "sha512-xcQhFfCJZGZeq00ODflyRO1EcK1myb0CUaC0grpP2pvKdulHshn6gnLod7EoEHGboP3zzQrffPRjvYgd6JWKJg=="], + "@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.33", "", { "os": "linux", "cpu": "x64" }, "sha512-3oVL5mrLlKLUc1lc4v7xS3BJ9N7PnnimbGwAvlnVpfaAygotAs1XkPcjsUe6ItMnSJyi0FWiDHUE2+GiDtM5Nw=="], - "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.28", "", { "os": "win32", "cpu": "arm64" }, "sha512-SuDBSOZVaU/bS9ngs9ADQJaFfg3TmCTl4OBKQgrpGErGpG0fNZJMS4NqJTlBcGOGiT/JxgMIZly/Ku/Q2gdz5A=="], + "@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.33", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q68v7wssE+r0OG1KIGfi7m3fnu8KOK4ZNg9ML6EwE47VF9/bqgUe+6fPiXh5mmHzTwof7nAOdXCf052av5/upQ=="], - "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.28", "", { "os": "win32", "cpu": "x64" }, "sha512-oMO2d9+7HlGuQFX4j9ex31JkS7AiEkktUL0cjQsgqK09zyUz8tQdlb3l/5yzJ2dPJ00K7Ae1K+0HO+5ClADcuQ=="], + "@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.33", "", { "os": "win32", "cpu": "x64" }, "sha512-PvuchmUnbMCUXXMzfle/WTzhNGIdJ6RGCCoclx3YVUyNUVuUicPf42OEV+td2m81/Hr3CgcLn98HYX1TLIzPrw=="], - "@opentui/react": ["@opentui/react@0.1.28", "", { "dependencies": { "@opentui/core": "0.1.28", "react-reconciler": "^0.32.0" }, "peerDependencies": { "react": ">=19.0.0" } }, "sha512-ubHPv8ZCgb9nBI6Ibh9FYXAK6A49Wt4ab6AdJW0eIeWOUHAKb+5LlWNO6YS11h+HkPzkcYFZC0uUY08/YXv6qw=="], + "@opentui/react": ["@opentui/react@0.1.33", "", { "dependencies": { "@opentui/core": "0.1.33", "react-reconciler": "^0.32.0" }, "peerDependencies": { "react": ">=19.0.0" } }, "sha512-1zTXedsXnIBFs0euR2JtILuzCr9evQbxMUclx+t3CCGyAccOhoekGxO2los9aQOxVSLHZ+YR7aPgpTsPlGqmGg=="], "@panva/hkdf": ["@panva/hkdf@1.2.1", "", {}, "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw=="], + "@pinojs/redact": ["@pinojs/redact@0.4.0", "", {}, "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg=="], + "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], "@pkgr/core": ["@pkgr/core@0.2.9", "", {}, "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA=="], - "@playwright/test": ["@playwright/test@1.56.0", "", { "dependencies": { "playwright": "1.56.0" }, "bin": { "playwright": "cli.js" } }, "sha512-Tzh95Twig7hUwwNe381/K3PggZBZblKUe2wv25oIpzWLr6Z0m4KgV1ZVIjnR6GM9ANEqjZD7XsZEa6JL/7YEgg=="], + "@playwright/test": ["@playwright/test@1.56.1", "", { "dependencies": { "playwright": "1.56.1" }, "bin": { "playwright": "cli.js" } }, "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg=="], - "@posthog/core": ["@posthog/core@1.3.0", "", {}, "sha512-hxLL8kZNHH098geedcxCz8y6xojkNYbmJEW+1vFXsmPcExyCXIUUJ/34X6xa9GcprKxd0Wsx3vfJQLQX4iVPhw=="], + "@posthog/core": ["@posthog/core@1.5.0", "", {}, "sha512-oxfV20QMNwH30jKybUyqi3yGuMghULQz1zkJgQG3rjpHDxhD2vDN6E7UpmaqgphMIvGG3Q+DgfU10zfSPA7w7w=="], "@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="], @@ -1160,25 +1162,25 @@ "@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="], - "@react-native/assets-registry": ["@react-native/assets-registry@0.82.0", "", {}, "sha512-SHRZxH+VHb6RwcHNskxyjso6o91Lq0DPgOpE5cDrppn1ziYhI723rjufFgh59RcpH441eci0/cXs/b0csXTtnw=="], + "@react-native/assets-registry": ["@react-native/assets-registry@0.82.1", "", {}, "sha512-B1SRwpntaAcckiatxbjzylvNK562Ayza05gdJCjDQHTiDafa1OABmyB5LHt7qWDOpNkaluD+w11vHF7pBmTpzQ=="], - "@react-native/codegen": ["@react-native/codegen@0.82.0", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.25.3", "glob": "^7.1.1", "hermes-parser": "0.32.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "yargs": "^17.6.2" } }, "sha512-DJKDwyr6s0EtoPKmAaOsx2EnS2sV/qICNWn/KA+8lohSY6gJF1wuA+DOjitivBfU0soADoo8tqGq50C5rlzmCA=="], + "@react-native/codegen": ["@react-native/codegen@0.82.1", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.25.3", "glob": "^7.1.1", "hermes-parser": "0.32.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "yargs": "^17.6.2" } }, "sha512-ezXTN70ygVm9l2m0i+pAlct0RntoV4afftWMGUIeAWLgaca9qItQ54uOt32I/9dBJvzBibT33luIR/pBG0dQvg=="], - "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.82.0", "", { "dependencies": { "@react-native/dev-middleware": "0.82.0", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.83.1", "metro-config": "^0.83.1", "metro-core": "^0.83.1", "semver": "^7.1.3" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "*" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-n5dxQowsRAjruG5sNl6MEPUzANUiVERaL7w4lHGmm/pz/ey1JOM9sFxL6RpZp1FJSVu4QKmbx6sIHrKb2MCekg=="], + "@react-native/community-cli-plugin": ["@react-native/community-cli-plugin@0.82.1", "", { "dependencies": { "@react-native/dev-middleware": "0.82.1", "debug": "^4.4.0", "invariant": "^2.2.4", "metro": "^0.83.1", "metro-config": "^0.83.1", "metro-core": "^0.83.1", "semver": "^7.1.3" }, "peerDependencies": { "@react-native-community/cli": "*", "@react-native/metro-config": "*" }, "optionalPeers": ["@react-native-community/cli", "@react-native/metro-config"] }, "sha512-H/eMdtOy9nEeX7YVeEG1N2vyCoifw3dr9OV8++xfUElNYV7LtSmJ6AqxZUUfxGJRDFPQvaU/8enmJlM/l11VxQ=="], - "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.82.0", "", {}, "sha512-rlTDcjf0ecjOHmygdBACAQCqPG0z/itAxnbhk8ZiQts7m4gRJiA/iCGFyC8/T9voUA0azAX6QCl4tHlnuUy7mQ=="], + "@react-native/debugger-frontend": ["@react-native/debugger-frontend@0.82.1", "", {}, "sha512-a2O6M7/OZ2V9rdavOHyCQ+10z54JX8+B+apYKCQ6a9zoEChGTxUMG2YzzJ8zZJVvYf1ByWSNxv9Se0dca1hO9A=="], - "@react-native/debugger-shell": ["@react-native/debugger-shell@0.82.0", "", { "dependencies": { "cross-spawn": "^7.0.6", "fb-dotslash": "0.5.8" } }, "sha512-XbXABIMzaH7SvapNWcW+zix1uHeSX/MoXYKKWWTs99a12TgwNuTeLKKTEj/ZkAjWtaCCqb/sMI4aJDLXKppCGg=="], + "@react-native/debugger-shell": ["@react-native/debugger-shell@0.82.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "fb-dotslash": "0.5.8" } }, "sha512-fdRHAeqqPT93bSrxfX+JHPpCXHApfDUdrXMXhoxlPgSzgXQXJDykIViKhtpu0M6slX6xU/+duq+AtP/qWJRpBw=="], - "@react-native/dev-middleware": ["@react-native/dev-middleware@0.82.0", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.82.0", "@react-native/debugger-shell": "0.82.0", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.2.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^6.2.3" } }, "sha512-SHvpo89RSzH06yZCmY3Xwr1J82EdUljC2lcO4YvXfHmytFG453Nz6kyZQcDEqGCfWDjznIUFUyT2UcLErmRWQg=="], + "@react-native/dev-middleware": ["@react-native/dev-middleware@0.82.1", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.82.1", "@react-native/debugger-shell": "0.82.1", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.2.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^6.2.3" } }, "sha512-wuOIzms/Qg5raBV6Ctf2LmgzEOCqdP3p1AYN4zdhMT110c39TVMbunpBaJxm0Kbt2HQ762MQViF9naxk7SBo4w=="], - "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.82.0", "", {}, "sha512-PTfmQ6cYsJgMXJ49NzB4Sz/DmRUtwatGtcA6MuskRvQpSinno/00Sns7wxphkTVMHGAwk3Xh0t0SFNd1d1HCyw=="], + "@react-native/gradle-plugin": ["@react-native/gradle-plugin@0.82.1", "", {}, "sha512-KkF/2T1NSn6EJ5ALNT/gx0MHlrntFHv8YdooH9OOGl9HQn5NM0ZmQSr86o5utJsGc7ME3R6p3SaQuzlsFDrn8Q=="], - "@react-native/js-polyfills": ["@react-native/js-polyfills@0.82.0", "", {}, "sha512-7K1K64rfq0sKoGxB2DTsZROxal0B04Q+ftia0JyCOGOto/tyBQIQqiQgVtMVEBZSEXZyXmGx3HzF4EEPlvrEtw=="], + "@react-native/js-polyfills": ["@react-native/js-polyfills@0.82.1", "", {}, "sha512-tf70X7pUodslOBdLN37J57JmDPB/yiZcNDzS2m+4bbQzo8fhx3eG9QEBv5n4fmzqfGAgSB4BWRHgDMXmmlDSVA=="], - "@react-native/normalize-colors": ["@react-native/normalize-colors@0.82.0", "", {}, "sha512-oinsK6TYEz5RnFTSk9P+hJ/N/E0pOG76O0euU0Gf3BlXArDpS8m3vrGcTjqeQvajRIaYVHIRAY9hCO6q+exyLg=="], + "@react-native/normalize-colors": ["@react-native/normalize-colors@0.82.1", "", {}, "sha512-CCfTR1uX+Z7zJTdt3DNX9LUXr2zWXsNOyLbwupW2wmRzrxlHRYfmLgTABzRL/cKhh0Ubuwn15o72MQChvCRaHw=="], - "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.82.0", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.1.1", "react": "*", "react-native": "*" }, "optionalPeers": ["@types/react"] }, "sha512-fReDITtqwWdN29doPHhmeQEqa12ATJ4M2Y1MrT8Q1Hoy5a0H3oEn9S7fknGr7Pj+/I77yHyJajUbCupnJ8vkFA=="], + "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.82.1", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.1.1", "react": "*", "react-native": "*" }, "optionalPeers": ["@types/react"] }, "sha512-f5zpJg9gzh7JtCbsIwV+4kP3eI0QBuA93JGmwFRd4onQ3DnCjV2J5pYqdWtM95sjSKK1dyik59Gj01lLeKqs1Q=="], "@react-spring/animated": ["@react-spring/animated@9.7.5", "", { "dependencies": { "@react-spring/shared": "~9.7.5", "@react-spring/types": "~9.7.5" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg=="], @@ -1206,7 +1208,7 @@ "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], - "@rushstack/eslint-patch": ["@rushstack/eslint-patch@1.14.0", "", {}, "sha512-WJFej426qe4RWOm9MMtP4V3CV4AucXolQty+GRgAWLgQXmpCuwzs7hEpxxhSc/znXUSxum9d/P/32MW0FlAAlA=="], + "@rushstack/eslint-patch": ["@rushstack/eslint-patch@1.14.1", "", {}, "sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ=="], "@sapphire/async-queue": ["@sapphire/async-queue@1.5.5", "", {}, "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg=="], @@ -1236,9 +1238,9 @@ "@tailwindcss/typography": ["@tailwindcss/typography@0.5.19", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg=="], - "@tanstack/query-core": ["@tanstack/query-core@5.90.3", "", {}, "sha512-HtPOnCwmx4dd35PfXU8jjkhwYrsHfuqgC8RCJIwWglmhIUIlzPP0ZcEkDAc+UtAWCiLm7T8rxeEfHZlz3hYMCA=="], + "@tanstack/query-core": ["@tanstack/query-core@5.90.5", "", {}, "sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w=="], - "@tanstack/react-query": ["@tanstack/react-query@5.90.3", "", { "dependencies": { "@tanstack/query-core": "5.90.3" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-i/LRL6DtuhG6bjGzavIMIVuKKPWx2AnEBIsBfuMm3YoHne0a20nWmsatOCBcVSaT0/8/5YFjNkebHAPLVUSi0Q=="], + "@tanstack/react-query": ["@tanstack/react-query@5.90.5", "", { "dependencies": { "@tanstack/query-core": "5.90.5" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q=="], "@tanstack/react-virtual": ["@tanstack/react-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA=="], @@ -1294,13 +1296,13 @@ "@types/braces": ["@types/braces@3.0.5", "", {}, "sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w=="], - "@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="], + "@types/bun": ["@types/bun@1.3.1", "", { "dependencies": { "bun-types": "1.3.1" } }, "sha512-4jNMk2/K9YJtfqwoAa28c8wK+T7nvJFOjxI4h/7sORWcypRNxBpr+TPNaCfVWq70tLCJsqoFwcf0oI0JU/fvMQ=="], "@types/caseless": ["@types/caseless@0.12.5", "", {}, "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg=="], "@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="], - "@types/conventional-commits-parser": ["@types/conventional-commits-parser@5.0.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ=="], + "@types/conventional-commits-parser": ["@types/conventional-commits-parser@5.0.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g=="], "@types/cors": ["@types/cors@2.8.19", "", { "dependencies": { "@types/node": "*" } }, "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg=="], @@ -1376,7 +1378,7 @@ "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], - "@types/express": ["@types/express@4.17.23", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "*" } }, "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ=="], + "@types/express": ["@types/express@4.17.25", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", "@types/serve-static": "^1" } }, "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw=="], "@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.7", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg=="], @@ -1414,13 +1416,13 @@ "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="], - "@types/micromatch": ["@types/micromatch@4.0.9", "", { "dependencies": { "@types/braces": "*" } }, "sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg=="], + "@types/micromatch": ["@types/micromatch@4.0.10", "", { "dependencies": { "@types/braces": "*" } }, "sha512-5jOhFDElqr4DKTrTEbnW8DZ4Hz5LRUEmyrGpCMrD/NphYv3nUnaF08xmSLx1rGGnyEs/kFnhiw6dCgcDqMr5PQ=="], "@types/mime": ["@types/mime@1.3.5", "", {}, "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w=="], "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], - "@types/node": ["@types/node@22.18.10", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-anNG/V/Efn/YZY4pRzbACnKxNKoBng2VTFydVu8RRs5hQjikP8CQfaeAV59VFSCzKNp90mXiVXW2QzV56rwMrg=="], + "@types/node": ["@types/node@22.18.13", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-Bo45YKIjnmFtv6I1TuC8AaHBbqXtIo+Om5fE4QiU1Tj8QR/qt+8O3BAtOimG5IFmwaWiPmB3Mv3jtYzBA4Us2A=="], "@types/node-fetch": ["@types/node-fetch@2.6.13", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.4" } }, "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw=="], @@ -1430,7 +1432,7 @@ "@types/parse5": ["@types/parse5@6.0.3", "", {}, "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g=="], - "@types/pg": ["@types/pg@8.15.5", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ=="], + "@types/pg": ["@types/pg@8.15.6", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ=="], "@types/prismjs": ["@types/prismjs@1.26.5", "", {}, "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ=="], @@ -1444,9 +1446,9 @@ "@types/react-dom": ["@types/react-dom@18.3.7", "", { "peerDependencies": { "@types/react": "^18.0.0" } }, "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ=="], - "@types/react-reconciler": ["@types/react-reconciler@0.32.1", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-RsqPttsBQ+6af0nATFXJJpemYQH7kL9+xLNm1z+0MjQFDKBZDM2R6SBrjdvRmHu9i9fM6povACj57Ft+pKRNOA=="], + "@types/react-reconciler": ["@types/react-reconciler@0.32.2", "", { "peerDependencies": { "@types/react": "*" } }, "sha512-gjcm6O0aUknhYaogEl8t5pecPfiOTD8VQkbjOhgbZas/E6qGY+veW9iuJU/7p4Y1E0EuQ0mArga7VEOUWSlVRA=="], - "@types/readable-stream": ["@types/readable-stream@4.0.21", "", { "dependencies": { "@types/node": "*" } }, "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ=="], + "@types/readable-stream": ["@types/readable-stream@4.0.22", "", { "dependencies": { "@types/node": "*" } }, "sha512-/FFhJpfCLAPwAcN3mFycNUa77ddnr8jTgF5VmSNetaemWB2cIlfCA9t0YTM3JAT0wOcv8D4tjPo7pkDhK3EJIg=="], "@types/request": ["@types/request@2.48.13", "", { "dependencies": { "@types/caseless": "*", "@types/node": "*", "@types/tough-cookie": "*", "form-data": "^2.5.5" } }, "sha512-FGJ6udDNUCjd19pp0Q3iTiDkwhYup7J8hpMW9c4k53NrccQFFWKRho6hvtPPEhnXWKvukfwAlB6DbDz4yhH5Gg=="], @@ -1456,15 +1458,15 @@ "@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="], - "@types/send": ["@types/send@1.2.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ=="], + "@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="], - "@types/serve-static": ["@types/serve-static@1.15.9", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA=="], + "@types/serve-static": ["@types/serve-static@1.15.10", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="], "@types/stack-utils": ["@types/stack-utils@2.0.3", "", {}, "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw=="], "@types/stats.js": ["@types/stats.js@0.17.4", "", {}, "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA=="], - "@types/three": ["@types/three@0.180.0", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": "*", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~0.22.0" } }, "sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg=="], + "@types/three": ["@types/three@0.181.0", "", { "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", "@types/stats.js": "*", "@types/webxr": "*", "@webgpu/types": "*", "fflate": "~0.8.2", "meshoptimizer": "~0.22.0" } }, "sha512-MLF1ks8yRM2k71D7RprFpDb9DOX0p22DbdPqT/uAkc6AtQXjxWCVDjCy23G9t1o8HcQPk7woD2NIyiaWcWPYmA=="], "@types/tinycolor2": ["@types/tinycolor2@1.4.6", "", {}, "sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw=="], @@ -1478,7 +1480,7 @@ "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], - "@types/yargs": ["@types/yargs@17.0.33", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA=="], + "@types/yargs": ["@types/yargs@17.0.34", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A=="], "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], @@ -1486,19 +1488,19 @@ "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@6.21.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.5.1", "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/type-utils": "6.21.0", "@typescript-eslint/utils": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", "natural-compare": "^1.4.0", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", "@typescript-eslint/typescript-estree": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.1", "@typescript-eslint/types": "^8.46.1", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.2", "@typescript-eslint/types": "^8.46.2", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg=="], "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@6.21.0", "", { "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0" } }, "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag=="], "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@6.21.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "6.21.0", "@typescript-eslint/utils": "6.21.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.46.1", "", {}, "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.46.2", "", {}, "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.1", "@typescript-eslint/tsconfig-utils": "8.46.1", "@typescript-eslint/types": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.2", "@typescript-eslint/tsconfig-utils": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ=="], "@typescript-eslint/utils": ["@typescript-eslint/utils@6.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", "@typescript-eslint/scope-manager": "6.21.0", "@typescript-eslint/types": "6.21.0", "@typescript-eslint/typescript-estree": "6.21.0", "semver": "^7.5.4" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ=="], @@ -1696,9 +1698,9 @@ "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - "bare-events": ["bare-events@2.8.0", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-AOhh6Bg5QmFIXdViHbMc2tLDsBIRxdkIaIddPslJF9Z5De3APBScuqGP2uThXnIpqFrgoxMNC6km7uXNIMLHXA=="], + "bare-events": ["bare-events@2.8.1", "", { "peerDependencies": { "bare-abort-controller": "*" }, "optionalPeers": ["bare-abort-controller"] }, "sha512-oxSAxTS1hRfnyit2CL5QpAOS5ixfBjj6ex3yTNvXyY/kE719jQ/IjuESJBK2w5v4wwQRAHGseVJXx9QBYOtFGQ=="], - "bare-fs": ["bare-fs@4.4.10", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-arqVF+xX/rJHwrONZaSPhlzleT2gXwVs9rsAe1p1mIVwWZI2A76/raio+KwwxfWMO8oV9Wo90EaUkS2QwVmy4w=="], + "bare-fs": ["bare-fs@4.5.0", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4", "bare-url": "^2.2.2", "fast-fifo": "^1.3.2" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-GljgCjeupKZJNetTqxKaQArLK10vpmK28or0+RwWjEl5Rk+/xG3wkpmkv+WrcBm3q1BwHKlnhXzR8O37kcvkXQ=="], "bare-os": ["bare-os@3.6.2", "", {}, "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A=="], @@ -1706,11 +1708,11 @@ "bare-stream": ["bare-stream@2.7.0", "", { "dependencies": { "streamx": "^2.21.0" }, "peerDependencies": { "bare-buffer": "*", "bare-events": "*" }, "optionalPeers": ["bare-buffer", "bare-events"] }, "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A=="], - "bare-url": ["bare-url@2.3.0", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-c+RCqMSZbkz97Mw1LWR0gcOqwK82oyYKfLoHJ8k13ybi1+I80ffdDzUy0TdAburdrR/kI0/VuN8YgEnJqX+Nyw=="], + "bare-url": ["bare-url@2.3.2", "", { "dependencies": { "bare-path": "^3.0.0" } }, "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw=="], "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.8.16", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.8.22", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-/tk9kky/d8T8CTXIQYASLyhAxR5VwL3zct1oAoVTaOUHwrmsGnfbRwNdEq+vOl2BN8i3PcDdP0o4Q+jjKQoFbQ=="], "basic-ftp": ["basic-ftp@5.0.5", "", {}, "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg=="], @@ -1732,7 +1734,7 @@ "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - "browserslist": ["browserslist@4.26.3", "", { "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", "electron-to-chromium": "^1.5.227", "node-releases": "^2.0.21", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w=="], + "browserslist": ["browserslist@4.27.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", "electron-to-chromium": "^1.5.238", "node-releases": "^2.0.26", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw=="], "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], @@ -1744,7 +1746,9 @@ "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], - "bun-types": ["bun-types@1.3.0", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ=="], + "bun-ffi-structs": ["bun-ffi-structs@0.1.0", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-NoRfJ81pgLIHCzw624/2GS2FuxcU0G4SRJww/4PXvheNVUPSIUjkOC6v1/8rk66tJVCb9oR0D6rDNKK0qT5O2Q=="], + + "bun-types": ["bun-types@1.3.1", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-NMrcy7smratanWJ2mMXdpatalovtxVggkj11bScuWuiOoXTiKIu2eVS1/7qbyI/4yHedtsn175n4Sm4JcdHLXw=="], "bun-webgpu": ["bun-webgpu@0.1.3", "", { "dependencies": { "@webgpu/types": "^0.1.60" }, "optionalDependencies": { "bun-webgpu-darwin-arm64": "^0.1.3", "bun-webgpu-darwin-x64": "^0.1.3", "bun-webgpu-linux-x64": "^0.1.3", "bun-webgpu-win32-x64": "^0.1.3" } }, "sha512-IXFxaIi4rgsEEpl9n/QVDm5RajCK/0FcOXZeMb52YRjoiAR1YVYK5hLrXT8cm+KDi6LVahA9GJFqOR4yiloVCw=="], @@ -1778,7 +1782,7 @@ "camera-controls": ["camera-controls@2.10.1", "", { "peerDependencies": { "three": ">=0.126.1" } }, "sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w=="], - "caniuse-lite": ["caniuse-lite@1.0.30001750", "", {}, "sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ=="], + "caniuse-lite": ["caniuse-lite@1.0.30001752", "", {}, "sha512-vKUk7beoukxE47P5gcVNKkDRzXdVofotshHwfR9vmpeFKxmI5PBpgOMC18LUJUA/DvJ70Y7RveasIBraqsyO/g=="], "cardinal": ["cardinal@1.0.0", "", { "dependencies": { "ansicolors": "~0.2.1", "redeyed": "~1.0.0" }, "bin": { "cdl": "./bin/cdl.js" } }, "sha512-INsuF4GyiFLk8C91FPokbKTc/rwHqV4JnfatVZ6GPhguP1qmkRWX2dp5tepYboYdPpGWisLVLI+KsXoXFPRSMg=="], @@ -1804,7 +1808,7 @@ "chrome-launcher": ["chrome-launcher@0.15.2", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ=="], - "chromium-bidi": ["chromium-bidi@9.1.0", "", { "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-rlUzQ4WzIAWdIbY/viPShhZU2n21CxDUgazXVbw4Hu1MwaeUSEksSeM6DqPgpRjCLXRk702AVRxJxoOz0dw4OA=="], + "chromium-bidi": ["chromium-bidi@10.5.1", "", { "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-rlj6OyhKhVTnk4aENcUme3Jl9h+cq4oXu4AzBcvr8RMmT6BR4a3zSNT9dbIfXr9/BS6ibzRyDhowuw4n2GgzsQ=="], "chromium-edge-launcher": ["chromium-edge-launcher@0.2.0", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0", "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-JfJjUnq25y9yg4FABRRVPmBGWPZZi+AQXT4mxupb67766/0UlhG8PAZCz6xzEMXTbW3CsSoE8PcCWA49n35mKg=="], @@ -1846,7 +1850,7 @@ "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], - "collect-v8-coverage": ["collect-v8-coverage@1.0.2", "", {}, "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q=="], + "collect-v8-coverage": ["collect-v8-coverage@1.0.3", "", {}, "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw=="], "color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], @@ -1860,7 +1864,7 @@ "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], - "commander": ["commander@14.0.1", "", {}, "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A=="], + "commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], "comment-json": ["comment-json@4.4.1", "", { "dependencies": { "array-timsort": "^1.0.3", "core-util-is": "^1.0.3", "esprima": "^4.0.1" } }, "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg=="], @@ -2002,7 +2006,7 @@ "d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="], - "dagre-d3-es": ["dagre-d3-es@7.0.11", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw=="], + "dagre-d3-es": ["dagre-d3-es@7.0.13", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q=="], "damerau-levenshtein": ["damerau-levenshtein@1.0.8", "", {}, "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA=="], @@ -2020,7 +2024,7 @@ "data-view-byte-offset": ["data-view-byte-offset@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" } }, "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ=="], - "dayjs": ["dayjs@1.11.18", "", {}, "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA=="], + "dayjs": ["dayjs@1.11.19", "", {}, "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw=="], "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], @@ -2068,7 +2072,7 @@ "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - "devtools-protocol": ["devtools-protocol@0.0.1508733", "", {}, "sha512-QJ1R5gtck6nDcdM+nlsaJXcelPEI7ZxSMw1ujHpO1c4+9l+Nue5qlebi9xO1Z2MGr92bFOQTW7/rrheh5hHxDg=="], + "devtools-protocol": ["devtools-protocol@0.0.1521046", "", {}, "sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w=="], "didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="], @@ -2080,9 +2084,9 @@ "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], - "discord-api-types": ["discord-api-types@0.38.30", "", {}, "sha512-KhAqlBrg+rVK+Ob7INMF5o63yW4/GUzRatG/AjyVsIO8lgcLyR8qCl2HokIVzWwmzkJYG0CEPXsKMOqau3E8NA=="], + "discord-api-types": ["discord-api-types@0.38.31", "", {}, "sha512-kC94ANsk8ackj8ENTuO8joTNEL0KtymVhHy9dyEC/s4QAZ7GCx40dYEzQaadyo8w+oP0X8QydE/nzAWRylTGtQ=="], - "discord.js": ["discord.js@14.23.2", "", { "dependencies": { "@discordjs/builders": "^1.12.1", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.1", "@discordjs/rest": "^2.6.0", "@discordjs/util": "^1.1.1", "@discordjs/ws": "^1.2.3", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.38.29", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-tU2NFr823X3TXEc8KyR/4m296KLxPai4nirN3q9kHCpY4TKj96n9lHZnyLzRNMui8EbL07jg9hgH2PWWfKMGIg=="], + "discord.js": ["discord.js@14.24.2", "", { "dependencies": { "@discordjs/builders": "^1.13.0", "@discordjs/collection": "1.5.3", "@discordjs/formatters": "^0.6.1", "@discordjs/rest": "^2.6.0", "@discordjs/util": "^1.1.1", "@discordjs/ws": "^1.2.3", "@sapphire/snowflake": "3.5.3", "discord-api-types": "^0.38.31", "fast-deep-equal": "3.1.3", "lodash.snakecase": "4.1.1", "magic-bytes.js": "^1.10.0", "tslib": "^2.6.3", "undici": "6.21.3" } }, "sha512-VMEDbmguRdX/EeMaTsf9Mb0IQA90WdYF2cn4QDfslQFXgQ6LFtmlPn0FSotnS0kcFbFp+JBSIxtnF+bnAHG/hQ=="], "dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="], @@ -2122,7 +2126,7 @@ "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.235", "", {}, "sha512-i/7ntLFwOdoHY7sgjlTIDo4Sl8EdoTjWIaKinYOVfC6bOp71bmwenyZthWHcasxgHDNWbWxvG9M3Ia116zIaYQ=="], + "electron-to-chromium": ["electron-to-chromium@1.5.244", "", {}, "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw=="], "emittery": ["emittery@0.13.1", "", {}, "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ=="], @@ -2200,7 +2204,7 @@ "eslint-plugin-tailwindcss": ["eslint-plugin-tailwindcss@3.18.2", "", { "dependencies": { "fast-glob": "^3.2.5", "postcss": "^8.4.4" }, "peerDependencies": { "tailwindcss": "^3.4.0" } }, "sha512-QbkMLDC/OkkjFQ1iz/5jkMdHfiMu/uwujUHLAJK5iwNHD8RTxVTlsUezE0toTZ6VhybNBsk+gYGPDq2agfeRNA=="], - "eslint-plugin-unused-imports": ["eslint-plugin-unused-imports@4.2.0", "", { "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", "eslint": "^9.0.0 || ^8.0.0" }, "optionalPeers": ["@typescript-eslint/eslint-plugin"] }, "sha512-hLbJ2/wnjKq4kGA9AUaExVFIbNzyxYdVo49QZmKCnhk5pc9wcYRbfgLHvWJ8tnsdcseGhoUAddm9gn/lt+d74w=="], + "eslint-plugin-unused-imports": ["eslint-plugin-unused-imports@4.3.0", "", { "peerDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", "eslint": "^9.0.0 || ^8.0.0" }, "optionalPeers": ["@typescript-eslint/eslint-plugin"] }, "sha512-ZFBmXMGBYfHttdRtOG9nFFpmUvMtbHSjsKrS20vdWdbfiVYsO3yA2SGYy9i9XmZJDfMGBflZGBCm70SEnFQtOA=="], "eslint-scope": ["eslint-scope@7.2.2", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg=="], @@ -2392,7 +2396,7 @@ "get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="], - "get-tsconfig": ["get-tsconfig@4.12.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw=="], + "get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="], "get-uri": ["get-uri@6.0.5", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4" } }, "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg=="], @@ -2518,7 +2522,7 @@ "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], - "immer": ["immer@10.1.3", "", {}, "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw=="], + "immer": ["immer@10.2.0", "", {}, "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], @@ -2662,7 +2666,7 @@ "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - "isomorphic-git": ["isomorphic-git@1.34.0", "", { "dependencies": { "async-lock": "^1.4.1", "clean-git-ref": "^2.0.1", "crc-32": "^1.2.0", "diff3": "0.0.3", "ignore": "^5.1.4", "is-git-ref-name-valid": "^1.0.0", "minimisted": "^2.0.0", "pako": "^1.0.10", "path-browserify": "^1.0.1", "pify": "^4.0.1", "readable-stream": "^3.4.0", "sha.js": "^2.4.12", "simple-get": "^4.0.1" }, "bin": { "isogit": "cli.cjs" } }, "sha512-J82yRa/4wm9VuOWSlI37I9Sa+n1gWaSWuKQk8zhpo6RqTW+ZTcK5c/KubLMcuVU3Btc+maRCa3YlRKqqY9q7qQ=="], + "isomorphic-git": ["isomorphic-git@1.34.2", "", { "dependencies": { "async-lock": "^1.4.1", "clean-git-ref": "^2.0.1", "crc-32": "^1.2.0", "diff3": "0.0.3", "ignore": "^5.1.4", "is-git-ref-name-valid": "^1.0.0", "minimisted": "^2.0.0", "pako": "^1.0.10", "path-browserify": "^1.0.1", "pify": "^4.0.1", "readable-stream": "^3.4.0", "sha.js": "^2.4.12", "simple-get": "^4.0.1" }, "bin": { "isogit": "cli.cjs" } }, "sha512-wPKs5a4sLn18SGd8MPNKe089wTnI4agfAY8et+q0GabtgJyNLRdC3ukHZ4EEC5XnczIwJOZ2xPvvTFgPXm80wg=="], "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], @@ -2796,7 +2800,7 @@ "kolorist": ["kolorist@1.8.0", "", {}, "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ=="], - "konva": ["konva@10.0.2", "", {}, "sha512-NrZED6YG5BX5h3Xu8EZgLqhQ/+ZhxANYXmlIhMOfpBf+0ToExcdwE+Y46LyJOO/JR7FVeR3YTqon3eirnuo44A=="], + "konva": ["konva@10.0.8", "", {}, "sha512-kQqErBIj2mR/srYDheRD2hq5v0gkwqoJZvbPz3DhCcyRNJfMEnd/AzLhWz2f567BB9vtL2p2EqKwI6n+MyM9Hw=="], "langium": ["langium@3.3.1", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w=="], @@ -2896,7 +2900,7 @@ "markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="], - "marked": ["marked@16.4.0", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-CTPAcRBq57cn3R8n3hwc2REddc28hjR7RzDXQ+lXLmMJYqn20BaI2cGw6QjgZGIgVfp2Wdfw4aMzgNteQ6qJgQ=="], + "marked": ["marked@16.4.1", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-ntROs7RaN3EvWfy3EZi14H4YxmT6A5YvywfhO+0pm+cH/dnSQRmdAmoFIc3B9aiwTehyk7pESH4ofyBY+V5hZg=="], "marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="], @@ -2958,7 +2962,7 @@ "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - "mermaid": ["mermaid@11.12.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.1", "@mermaid-js/parser": "^0.6.2", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", "dayjs": "^1.11.18", "dompurify": "^3.2.5", "katex": "^0.16.22", "khroma": "^2.1.0", "lodash-es": "^4.17.21", "marked": "^16.2.1", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-ZudVx73BwrMJfCFmSSJT84y6u5brEoV8DOItdHomNLz32uBjNrelm7mg95X7g+C6UoQH/W6mBLGDEDv73JdxBg=="], + "mermaid": ["mermaid@11.12.1", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.1", "@mermaid-js/parser": "^0.6.3", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.13", "dayjs": "^1.11.18", "dompurify": "^3.2.5", "katex": "^0.16.22", "khroma": "^2.1.0", "lodash-es": "^4.17.21", "marked": "^16.2.1", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-UlIZrRariB11TY1RtTgUWp65tphtBv4CSq7vyS2ZZ2TgoMjs2nloq+wFqxiwcxlhHUvs7DPGgMjs2aeQxz5h9g=="], "meshline": ["meshline@3.3.1", "", { "peerDependencies": { "three": ">=0.137" } }, "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ=="], @@ -3120,7 +3124,7 @@ "next": ["next@14.2.25", "", { "dependencies": { "@next/env": "14.2.25", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "graceful-fs": "^4.2.11", "postcss": "8.4.31", "styled-jsx": "5.1.1" }, "optionalDependencies": { "@next/swc-darwin-arm64": "14.2.25", "@next/swc-darwin-x64": "14.2.25", "@next/swc-linux-arm64-gnu": "14.2.25", "@next/swc-linux-arm64-musl": "14.2.25", "@next/swc-linux-x64-gnu": "14.2.25", "@next/swc-linux-x64-musl": "14.2.25", "@next/swc-win32-arm64-msvc": "14.2.25", "@next/swc-win32-ia32-msvc": "14.2.25", "@next/swc-win32-x64-msvc": "14.2.25" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-N5M7xMc4wSb4IkPvEV5X2BRRXUmhVHNyaXwEM86+voXthSZz8ZiRyQW4p9mwAoAPIm6OzuVZtn7idgEJeAJN3Q=="], - "next-auth": ["next-auth@4.24.11", "", { "dependencies": { "@babel/runtime": "^7.20.13", "@panva/hkdf": "^1.0.2", "cookie": "^0.7.0", "jose": "^4.15.5", "oauth": "^0.9.15", "openid-client": "^5.4.0", "preact": "^10.6.3", "preact-render-to-string": "^5.1.19", "uuid": "^8.3.2" }, "peerDependencies": { "@auth/core": "0.34.2", "next": "^12.2.5 || ^13 || ^14 || ^15", "nodemailer": "^6.6.5", "react": "^17.0.2 || ^18 || ^19", "react-dom": "^17.0.2 || ^18 || ^19" }, "optionalPeers": ["@auth/core", "nodemailer"] }, "sha512-pCFXzIDQX7xmHFs4KVH4luCjaCbuPRtZ9oBUjUhOk84mZ9WVPf94n87TxYI4rSRf9HmfHEF8Yep3JrYDVOo3Cw=="], + "next-auth": ["next-auth@4.24.13", "", { "dependencies": { "@babel/runtime": "^7.20.13", "@panva/hkdf": "^1.0.2", "cookie": "^0.7.0", "jose": "^4.15.5", "oauth": "^0.9.15", "openid-client": "^5.4.0", "preact": "^10.6.3", "preact-render-to-string": "^5.1.19", "uuid": "^8.3.2" }, "peerDependencies": { "@auth/core": "0.34.3", "next": "^12.2.5 || ^13 || ^14 || ^15 || ^16", "nodemailer": "^7.0.7", "react": "^17.0.2 || ^18 || ^19", "react-dom": "^17.0.2 || ^18 || ^19" }, "optionalPeers": ["@auth/core", "nodemailer"] }, "sha512-sgObCfcfL7BzIK76SS5TnQtc3yo2Oifp/yIpfv6fMfeBOiBJkDWF3A2y9+yqnmJ4JKc2C+nMjSjmgDeTwgN1rQ=="], "next-contentlayer": ["next-contentlayer@0.3.4", "", { "dependencies": { "@contentlayer/core": "0.3.4", "@contentlayer/utils": "0.3.4" }, "peerDependencies": { "contentlayer": "0.3.4", "next": "^12 || ^13", "react": "*", "react-dom": "*" } }, "sha512-UtUCwgAl159KwfhNaOwyiI7Lg6sdioyKMeh+E7jxx0CJ29JuXGxBEYmCI6+72NxFGIFZKx8lvttbbQhbnYWYSw=="], @@ -3138,7 +3142,7 @@ "node-machine-id": ["node-machine-id@1.1.12", "", {}, "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ=="], - "node-releases": ["node-releases@2.0.23", "", {}, "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg=="], + "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], @@ -3150,7 +3154,7 @@ "nwsapi": ["nwsapi@2.2.22", "", {}, "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ=="], - "nx": ["nx@21.6.4", "", { "dependencies": { "@napi-rs/wasm-runtime": "0.2.4", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "3.0.2", "@zkochan/js-yaml": "0.0.7", "axios": "^1.12.0", "chalk": "^4.1.0", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^8.0.1", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "enquirer": "~2.3.6", "figures": "3.2.0", "flat": "^5.0.2", "front-matter": "^4.0.2", "ignore": "^5.0.4", "jest-diff": "^30.0.2", "jsonc-parser": "3.2.0", "lines-and-columns": "2.0.3", "minimatch": "9.0.3", "node-machine-id": "1.1.12", "npm-run-path": "^4.0.1", "open": "^8.4.0", "ora": "5.3.0", "resolve.exports": "2.0.3", "semver": "^7.5.3", "string-width": "^4.2.3", "tar-stream": "~2.2.0", "tmp": "~0.2.1", "tree-kill": "^1.2.2", "tsconfig-paths": "^4.1.2", "tslib": "^2.3.0", "yaml": "^2.6.0", "yargs": "^17.6.2", "yargs-parser": "21.1.1" }, "optionalDependencies": { "@nx/nx-darwin-arm64": "21.6.4", "@nx/nx-darwin-x64": "21.6.4", "@nx/nx-freebsd-x64": "21.6.4", "@nx/nx-linux-arm-gnueabihf": "21.6.4", "@nx/nx-linux-arm64-gnu": "21.6.4", "@nx/nx-linux-arm64-musl": "21.6.4", "@nx/nx-linux-x64-gnu": "21.6.4", "@nx/nx-linux-x64-musl": "21.6.4", "@nx/nx-win32-arm64-msvc": "21.6.4", "@nx/nx-win32-x64-msvc": "21.6.4" }, "peerDependencies": { "@swc-node/register": "^1.8.0", "@swc/core": "^1.3.85" }, "optionalPeers": ["@swc-node/register", "@swc/core"], "bin": { "nx": "bin/nx.js", "nx-cloud": "bin/nx-cloud.js" } }, "sha512-RVQ7x/bTfJmGWS1rnGMpLDeaW7MnM8eja0qfSbZooP55GWPE6g4uwMKqfX+uqU/dV9GBNOBn77y8h0dEIZtMhg=="], + "nx": ["nx@21.6.8", "", { "dependencies": { "@napi-rs/wasm-runtime": "0.2.4", "@yarnpkg/lockfile": "^1.1.0", "@yarnpkg/parsers": "3.0.2", "@zkochan/js-yaml": "0.0.7", "axios": "^1.12.0", "chalk": "^4.1.0", "cli-cursor": "3.1.0", "cli-spinners": "2.6.1", "cliui": "^8.0.1", "dotenv": "~16.4.5", "dotenv-expand": "~11.0.6", "enquirer": "~2.3.6", "figures": "3.2.0", "flat": "^5.0.2", "front-matter": "^4.0.2", "ignore": "^5.0.4", "jest-diff": "^30.0.2", "jsonc-parser": "3.2.0", "lines-and-columns": "2.0.3", "minimatch": "9.0.3", "node-machine-id": "1.1.12", "npm-run-path": "^4.0.1", "open": "^8.4.0", "ora": "5.3.0", "resolve.exports": "2.0.3", "semver": "^7.5.3", "string-width": "^4.2.3", "tar-stream": "~2.2.0", "tmp": "~0.2.1", "tree-kill": "^1.2.2", "tsconfig-paths": "^4.1.2", "tslib": "^2.3.0", "yaml": "^2.6.0", "yargs": "^17.6.2", "yargs-parser": "21.1.1" }, "optionalDependencies": { "@nx/nx-darwin-arm64": "21.6.8", "@nx/nx-darwin-x64": "21.6.8", "@nx/nx-freebsd-x64": "21.6.8", "@nx/nx-linux-arm-gnueabihf": "21.6.8", "@nx/nx-linux-arm64-gnu": "21.6.8", "@nx/nx-linux-arm64-musl": "21.6.8", "@nx/nx-linux-x64-gnu": "21.6.8", "@nx/nx-linux-x64-musl": "21.6.8", "@nx/nx-win32-arm64-msvc": "21.6.8", "@nx/nx-win32-x64-msvc": "21.6.8" }, "peerDependencies": { "@swc-node/register": "^1.8.0", "@swc/core": "^1.3.85" }, "optionalPeers": ["@swc-node/register", "@swc/core"], "bin": { "nx": "bin/nx.js", "nx-cloud": "bin/nx-cloud.js" } }, "sha512-NilGEk1Cngs3Se9JW+f9cDeN6RBvmABhpEtgMvOK8RAAZszq6B380oCzKcQljhnrbQ6+v6j/Vb7hBPTCvXb0Ng=="], "oauth": ["oauth@0.9.15", "", {}, "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="], @@ -3188,7 +3192,7 @@ "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], - "oo-ascii-tree": ["oo-ascii-tree@1.116.0", "", {}, "sha512-GI0n8coDIoZPywmZp5l2qPO1tqZxN40/tFPYBxWD2vpPeciKiB/nxZ7blDjp97ejxtmdkNouvAmtg4nCYgZihg=="], + "oo-ascii-tree": ["oo-ascii-tree@1.118.0", "", {}, "sha512-ATGzZ+AxeHuGdNlniQNn9xvaVDo8IfET84Xep0XS33KXr19EZum7VpzBuKtcfNM/NQ7uk1d4ePXMqyiHeA9Dxw=="], "open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], @@ -3212,9 +3216,7 @@ "pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="], - "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], - - "package-manager-detector": ["package-manager-detector@1.4.0", "", {}, "sha512-rRZ+pR1Usc+ND9M2NkmCvE/LYJS+8ORVV9X0KuNSY/gFsp7RBHJM/ADh9LYq4Vvfq6QkKrW6/weuh8SMEtN5gw=="], + "package-manager-detector": ["package-manager-detector@1.5.0", "", {}, "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw=="], "pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="], @@ -3314,9 +3316,9 @@ "planck": ["planck@1.4.2", "", { "peerDependencies": { "stage-js": "^1.0.0-alpha.12" } }, "sha512-mNbhnV3g8X2rwGxzcesjmN8BDA6qfXgQxXVMkWau9MCRlQY0RLNEkyHlVp6yFy/X6qrzAXyNONCnZ1cGDLrNew=="], - "playwright": ["playwright@1.56.0", "", { "dependencies": { "playwright-core": "1.56.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-X5Q1b8lOdWIE4KAoHpW3SE8HvUB+ZZsUoN64ZhjnN8dOb1UpujxBtENGiZFE+9F/yhzJwYa+ca3u43FeLbboHA=="], + "playwright": ["playwright@1.56.1", "", { "dependencies": { "playwright-core": "1.56.1" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw=="], - "playwright-core": ["playwright-core@1.56.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-1SXl7pMfemAMSDn5rkPeZljxOCYAmQnYLBTExuh6E8USHXGSX3dx6lYZN/xPpTz1vimXmPA9CDnILvmJaB8aSQ=="], + "playwright-core": ["playwright-core@1.56.1", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ=="], "plimit-lit": ["plimit-lit@1.6.1", "", { "dependencies": { "queue-lit": "^1.5.1" } }, "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA=="], @@ -3354,7 +3356,7 @@ "postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="], - "posthog-js": ["posthog-js@1.275.3", "", { "dependencies": { "@posthog/core": "1.3.0", "core-js": "^3.38.1", "fflate": "^0.4.8", "preact": "^10.19.3", "web-vitals": "^4.2.4" }, "peerDependencies": { "@rrweb/types": "2.0.0-alpha.17", "rrweb-snapshot": "2.0.0-alpha.17" }, "optionalPeers": ["@rrweb/types", "rrweb-snapshot"] }, "sha512-LitwVprl0Q8p0fN4O4ThvlOuO6r+TBzLfkGbSyI5tR/YhlWzX3yFf4KKHPXJgxge99sxKa0fuVKNzcspYsDzcg=="], + "posthog-js": ["posthog-js@1.283.0", "", { "dependencies": { "@posthog/core": "1.5.0", "core-js": "^3.38.1", "fflate": "^0.4.8", "preact": "^10.19.3", "web-vitals": "^4.2.4" } }, "sha512-CJJiqK6wPCRTHkmCJ7i8zEDFYded1CURqZ1JSDL4au97TBFX8J50nxw5wI9jHoNlHlkIgfiBPPMDOlBsiIHpMQ=="], "posthog-node": ["posthog-node@4.18.0", "", { "dependencies": { "axios": "^1.8.2" } }, "sha512-XROs1h+DNatgKh/AlIlCtDxWzwrKdYDb2mOs58n4yN8BkGN9ewqeQwG5ApS4/IzwCb7HPttUkOVulkYatd2PIw=="], @@ -3408,7 +3410,7 @@ "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], - "puppeteer-core": ["puppeteer-core@24.24.1", "", { "dependencies": { "@puppeteer/browsers": "2.10.12", "chromium-bidi": "9.1.0", "debug": "^4.4.3", "devtools-protocol": "0.0.1508733", "typed-query-selector": "^2.12.0", "webdriver-bidi-protocol": "0.3.7", "ws": "^8.18.3" } }, "sha512-4R9/hCjmyUBbQqjrCa+y4Pzgl3LneLfqB+Whh2JujA5Wzg+prnO60GxDPjAJmM+uirYxDx/8jIm0hGu8yDTyiA=="], + "puppeteer-core": ["puppeteer-core@24.27.0", "", { "dependencies": { "@puppeteer/browsers": "2.10.12", "chromium-bidi": "10.5.1", "debug": "^4.4.3", "devtools-protocol": "0.0.1521046", "typed-query-selector": "^2.12.0", "webdriver-bidi-protocol": "0.3.8", "ws": "^8.18.3" } }, "sha512-yubwj2XXmTM3wRIpbhO5nCjbByPgpFHlgrsD4IK+gMPqO7/a5FfnoSXDKjmqi8A2M1Ewusz0rTI/r+IN0GU0MA=="], "pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="], @@ -3446,7 +3448,7 @@ "react-konva": ["react-konva@18.2.14", "", { "dependencies": { "@types/react-reconciler": "^0.28.2", "its-fine": "^1.1.1", "react-reconciler": "~0.29.0", "scheduler": "^0.23.0" }, "peerDependencies": { "konva": "^8.0.1 || ^7.2.5 || ^9.0.0 || ^10.0.0", "react": ">=18.0.0", "react-dom": ">=18.0.0" } }, "sha512-lBDe/5fTgquMdg1AHI0B16YZdAOvEhWMBWuo12ioyY0icdxcz9Cf12j86fsCJCHdnvjUOlZeC0f5q+siyHbD4Q=="], - "react-native": ["react-native@0.82.0", "", { "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.82.0", "@react-native/codegen": "0.82.0", "@react-native/community-cli-plugin": "0.82.0", "@react-native/gradle-plugin": "0.82.0", "@react-native/js-polyfills": "0.82.0", "@react-native/normalize-colors": "0.82.0", "@react-native/virtualized-lists": "0.82.0", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-jest": "^29.7.0", "babel-plugin-syntax-hermes-parser": "0.32.0", "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", "glob": "^7.1.1", "hermes-compiler": "0.0.0", "invariant": "^2.2.4", "jest-environment-node": "^29.7.0", "memoize-one": "^5.0.0", "metro-runtime": "^0.83.1", "metro-source-map": "^0.83.1", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", "scheduler": "0.26.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0", "ws": "^6.2.3", "yargs": "^17.6.2" }, "peerDependencies": { "@types/react": "^19.1.1", "react": "^19.1.1" }, "optionalPeers": ["@types/react"], "bin": { "react-native": "cli.js" } }, "sha512-E+sBFDgpwzoZzPn86gSGRBGLnS9Q6r4y6Xk5I57/QbkqkDOxmQb/bzQq/oCdUCdHImKiow2ldC3WJfnvAKIfzg=="], + "react-native": ["react-native@0.82.1", "", { "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.82.1", "@react-native/codegen": "0.82.1", "@react-native/community-cli-plugin": "0.82.1", "@react-native/gradle-plugin": "0.82.1", "@react-native/js-polyfills": "0.82.1", "@react-native/normalize-colors": "0.82.1", "@react-native/virtualized-lists": "0.82.1", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", "babel-jest": "^29.7.0", "babel-plugin-syntax-hermes-parser": "0.32.0", "base64-js": "^1.5.1", "commander": "^12.0.0", "flow-enums-runtime": "^0.0.6", "glob": "^7.1.1", "hermes-compiler": "0.0.0", "invariant": "^2.2.4", "jest-environment-node": "^29.7.0", "memoize-one": "^5.0.0", "metro-runtime": "^0.83.1", "metro-source-map": "^0.83.1", "nullthrows": "^1.1.1", "pretty-format": "^29.7.0", "promise": "^8.3.0", "react-devtools-core": "^6.1.5", "react-refresh": "^0.14.0", "regenerator-runtime": "^0.13.2", "scheduler": "0.26.0", "semver": "^7.1.3", "stacktrace-parser": "^0.1.10", "whatwg-fetch": "^3.0.0", "ws": "^6.2.3", "yargs": "^17.6.2" }, "peerDependencies": { "@types/react": "^19.1.1", "react": "^19.1.1" }, "optionalPeers": ["@types/react"], "bin": { "react-native": "cli.js" } }, "sha512-tFAqcU7Z4g49xf/KnyCEzI4nRTu1Opcx05Ov2helr8ZTg1z7AJR/3sr2rZ+AAVlAs2IXk+B0WOxXGmdD3+4czA=="], "react-reconciler": ["react-reconciler@0.32.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ=="], @@ -3522,7 +3524,7 @@ "resize-observer-polyfill": ["resize-observer-polyfill@1.5.1", "", {}, "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="], - "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], + "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], "resolve-cwd": ["resolve-cwd@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="], @@ -3630,8 +3632,6 @@ "slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="], - "slow-redact": ["slow-redact@0.3.2", "", {}, "sha512-MseHyi2+E/hBRqdOi5COy6wZ7j7DxXRz9NkseavNYSvvWC06D8a5cidVZX3tcG5eCW3NIyVU4zT63hw0Q486jw=="], - "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], "socks": ["socks@2.8.7", "", { "dependencies": { "ip-address": "^10.0.1", "smart-buffer": "^4.2.0" } }, "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A=="], @@ -3780,11 +3780,11 @@ "three-geojson-geometry": ["three-geojson-geometry@2.1.1", "", { "dependencies": { "d3-geo": "1 - 3", "d3-interpolate": "1 - 3", "earcut": "3" }, "peerDependencies": { "three": ">=0.72.0" } }, "sha512-dC7bF3ri1goDcihYhzACHOBQqu7YNNazYLa2bSydVIiJUb3jDFojKSy+gNj2pMkqZNSVjssSmdY9zlmnhEpr1w=="], - "three-globe": ["three-globe@2.44.1", "", { "dependencies": { "@tweenjs/tween.js": "18 - 25", "accessor-fn": "1", "d3-array": "3", "d3-color": "3", "d3-geo": "3", "d3-interpolate": "3", "d3-scale": "4", "d3-scale-chromatic": "3", "data-bind-mapper": "1", "frame-ticker": "1", "h3-js": "4", "index-array-by": "1", "kapsule": "^1.16", "three-conic-polygon-geometry": "2", "three-geojson-geometry": "2", "three-slippy-map-globe": "1", "tinycolor2": "1" }, "peerDependencies": { "three": ">=0.154" } }, "sha512-v0Q4tgEulvKyjj5P73v9/cH/3CjhStgHhSsoK7owj9ktaf56DiZC+oITi7x8pB3zAmUJlLJjj8I1BOCzzk9RNg=="], + "three-globe": ["three-globe@2.45.0", "", { "dependencies": { "@tweenjs/tween.js": "18 - 25", "accessor-fn": "1", "d3-array": "3", "d3-color": "3", "d3-geo": "3", "d3-interpolate": "3", "d3-scale": "4", "d3-scale-chromatic": "3", "data-bind-mapper": "1", "frame-ticker": "1", "h3-js": "4", "index-array-by": "1", "kapsule": "^1.16", "three-conic-polygon-geometry": "2", "three-geojson-geometry": "2", "three-slippy-map-globe": "1", "tinycolor2": "1" }, "peerDependencies": { "three": ">=0.154" } }, "sha512-Ur6BVkezvmHnvsEg8fbq6gIscSZtknSQMWwDRbiJ95o6OSDjDbGTc4oO6nP7mOM9aAA3YrF7YZyOwSkP4T56QA=="], "three-mesh-bvh": ["three-mesh-bvh@0.7.8", "", { "peerDependencies": { "three": ">= 0.151.0" } }, "sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw=="], - "three-slippy-map-globe": ["three-slippy-map-globe@1.0.3", "", { "dependencies": { "d3-geo": "1 - 3", "d3-octree": "^1.1", "d3-scale": "1 - 4" }, "peerDependencies": { "three": ">=0.154" } }, "sha512-Y9WCA/tTL8yH8FHVSXVQss/P0V36utTNhuixzFPj0Bs0SXxO+Vui133oAQmMpx4BLXYZpWZwcqHM2i3MfFlYWw=="], + "three-slippy-map-globe": ["three-slippy-map-globe@1.0.4", "", { "dependencies": { "d3-geo": "1 - 3", "d3-octree": "^1.1", "d3-scale": "1 - 4" }, "peerDependencies": { "three": ">=0.154" } }, "sha512-am8A4PP38AfTdrhXBDucwPRHLTbBl93yhpjIs56K1TLs9VuUWzg68oim4Dibs9QC1riXbj5SoBp/okA1VN9eYg=="], "three-stdlib": ["three-stdlib@2.36.0", "", { "dependencies": { "@types/draco3d": "^1.4.0", "@types/offscreencanvas": "^2019.6.4", "@types/webxr": "^0.5.2", "draco3d": "^1.4.1", "fflate": "^0.6.9", "potpack": "^1.0.1" }, "peerDependencies": { "three": ">=0.128.0" } }, "sha512-kv0Byb++AXztEGsULgMAs8U2jgUdz6HPpAB/wDJnLiLlaWQX2APHhiTJIN7rqW+Of0eRgcp7jn05U1BsCP3xBA=="], @@ -3846,7 +3846,7 @@ "ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="], - "ts-pattern": ["ts-pattern@5.8.0", "", {}, "sha512-kIjN2qmWiHnhgr5DAkAafF9fwb0T5OhMVSWrm8XEdTFnX6+wfXwYOFjeF86UZ54vduqiR7BfqScFmXSzSaH8oA=="], + "ts-pattern": ["ts-pattern@5.9.0", "", {}, "sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg=="], "tsc-alias": ["tsc-alias@1.7.0", "", { "dependencies": { "chokidar": "^3.5.3", "commander": "^9.0.0", "globby": "^11.0.4", "mylas": "^2.1.9", "normalize-path": "^3.0.0", "plimit-lit": "^1.2.6" }, "bin": { "tsc-alias": "dist/bin/index.js" } }, "sha512-n/K6g8S7Ec7Y/A2Z77Ikp2Uv1S1ERtT63ni69XV4W1YPT4rnNmz8ItgIiJYvKfFnKfqcZQ81UPjoKpMTxaC/rg=="], @@ -3902,7 +3902,7 @@ "unist-util-generated": ["unist-util-generated@2.0.1", "", {}, "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A=="], - "unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], @@ -3914,7 +3914,7 @@ "unist-util-visit": ["unist-util-visit@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], - "unist-util-visit-parents": ["unist-util-visit-parents@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="], + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], @@ -3922,7 +3922,7 @@ "unrs-resolver": ["unrs-resolver@1.11.1", "", { "dependencies": { "napi-postinstall": "^0.3.0" }, "optionalDependencies": { "@unrs/resolver-binding-android-arm-eabi": "1.11.1", "@unrs/resolver-binding-android-arm64": "1.11.1", "@unrs/resolver-binding-darwin-arm64": "1.11.1", "@unrs/resolver-binding-darwin-x64": "1.11.1", "@unrs/resolver-binding-freebsd-x64": "1.11.1", "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", "@unrs/resolver-binding-linux-x64-musl": "1.11.1", "@unrs/resolver-binding-wasm32-wasi": "1.11.1", "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg=="], - "update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="], + "update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], @@ -3990,7 +3990,7 @@ "web-vitals": ["web-vitals@4.2.4", "", {}, "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw=="], - "webdriver-bidi-protocol": ["webdriver-bidi-protocol@0.3.7", "", {}, "sha512-wIx5Gu/LLTeexxilpk8WxU2cpGAKlfbWRO5h+my6EMD1k5PYqM1qQO1MHUFf4f3KRnhBvpbZU7VkizAgeSEf7g=="], + "webdriver-bidi-protocol": ["webdriver-bidi-protocol@0.3.8", "", {}, "sha512-21Yi2GhGntMc671vNBCjiAeEVknXjVRoyu+k+9xOMShu+ZQfpGQwnBqbNz/Sv4GXZ6JmutlPAi2nIJcrymAWuQ=="], "webgl-constants": ["webgl-constants@1.1.1", "", {}, "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="], @@ -4080,7 +4080,7 @@ "@ai-sdk/gateway/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.0", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.3", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.25.76 || ^4" } }, "sha512-BoQZtGcBxkeSH1zK+SRYNDtJPIPpacTeiMZqnG4Rv6xXjEwM0FH4MGs9c+PlhyEWmQCzjRM2HAotEydFhD4dYw=="], - "@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.12", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.5" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZtbdvYxdMoria+2SlNarEk6Hlgyf+zzcznlD55EAl+7VZvJaSg2sqPvwArY7L6TfDEDJsnCq0fdhBSkYo0Xqdg=="], + "@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@3.0.15", "", { "dependencies": { "@ai-sdk/provider": "2.0.0", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-kOc6Pxb7CsRlNt+sLZKL7/VGQUd7ccl3/tIK+Bqf5/QhHR0Qm3qRBMz1IwU1RmjJEZA73x+KB5cUckbDl2WF7Q=="], "@auth/core/jose": ["jose@6.1.0", "", {}, "sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA=="], @@ -4108,7 +4108,7 @@ "@codebuff/common/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], - "@codebuff/common/posthog-node": ["posthog-node@5.10.0", "", { "dependencies": { "@posthog/core": "1.3.0" } }, "sha512-uNN+YUuOdbDSbDMGk/Wq57o2YBEH0Unu1kEq2PuYmqFmnu+oYsKyJBrb58VNwEuYsaXVJmk4FtbD+Tl8BT69+w=="], + "@codebuff/common/posthog-node": ["posthog-node@5.11.0", "", { "dependencies": { "@posthog/core": "1.5.0" } }, "sha512-9+gmWp/7AEryJMi0+/ywJjKQhpkmcjxf+eT030fTIIPvFTF84zeeagdZBGNC/Nh2Jc0grIAW6O1n5lxXiX3daA=="], "@codebuff/evals/diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], @@ -4132,11 +4132,11 @@ "@codebuff/sdk/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="], - "@codebuff/web/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/type-utils": "8.46.1", "@typescript-eslint/utils": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ=="], + "@codebuff/web/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/type-utils": "8.46.2", "@typescript-eslint/utils": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.2", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w=="], "@codebuff/web/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="], - "@codebuff/web/pino": ["pino@9.13.1", "", { "dependencies": { "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "slow-redact": "^0.3.0", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-Szuj+ViDTjKPQYiKumGmEn3frdl+ZPSdosHyt9SnUevFosOkMY2b7ipxlEctNKPmMD/VibeBI+ZcZCJK+4DPuw=="], + "@codebuff/web/pino": ["pino@9.14.0", "", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w=="], "@codebuff/web/prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="], @@ -4308,14 +4308,10 @@ "@react-three/drei/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], - "@react-three/drei/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], - "@react-three/fiber/@types/react-reconciler": ["@types/react-reconciler@0.26.7", "", { "dependencies": { "@types/react": "*" } }, "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ=="], "@react-three/fiber/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], - "@react-three/fiber/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], - "@react-three/fiber/react-reconciler": ["react-reconciler@0.27.0", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.21.0" }, "peerDependencies": { "react": "^18.0.0" } }, "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA=="], "@react-three/fiber/scheduler": ["scheduler@0.21.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ=="], @@ -4342,23 +4338,21 @@ "@types/request/form-data": ["form-data@2.5.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.35", "safe-buffer": "^5.2.1" } }, "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A=="], - "@types/serve-static/@types/send": ["@types/send@0.17.5", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w=="], - "@types/three/@tweenjs/tween.js": ["@tweenjs/tween.js@23.1.3", "", {}, "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA=="], "@types/three/fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], "@typescript-eslint/eslint-plugin/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], - "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1" } }, "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A=="], + "@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2" } }, "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA=="], - "@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA=="], + "@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="], "@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@6.21.0", "", {}, "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg=="], "@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@6.21.0", "", { "dependencies": { "@typescript-eslint/types": "6.21.0", "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "9.0.3", "semver": "^7.5.4", "ts-api-utils": "^1.0.1" } }, "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ=="], - "@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA=="], + "@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -4452,7 +4446,7 @@ "eslint/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "eslint-config-next/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/type-utils": "8.46.1", "@typescript-eslint/utils": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ=="], + "eslint-config-next/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/type-utils": "8.46.2", "@typescript-eslint/utils": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.2", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w=="], "eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], @@ -4662,15 +4656,13 @@ "next-auth/uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="], - "next-contentlayer/next": ["next@14.2.13", "", { "dependencies": { "@next/env": "14.2.13", "@swc/helpers": "0.5.5", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "graceful-fs": "^4.2.11", "postcss": "8.4.31", "styled-jsx": "5.1.1" }, "optionalDependencies": { "@next/swc-darwin-arm64": "14.2.13", "@next/swc-darwin-x64": "14.2.13", "@next/swc-linux-arm64-gnu": "14.2.13", "@next/swc-linux-arm64-musl": "14.2.13", "@next/swc-linux-x64-gnu": "14.2.13", "@next/swc-linux-x64-musl": "14.2.13", "@next/swc-win32-arm64-msvc": "14.2.13", "@next/swc-win32-ia32-msvc": "14.2.13", "@next/swc-win32-x64-msvc": "14.2.13" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-BseY9YNw8QJSwLYD7hlZzl6QVDoSFHL/URN5K64kVEVpCsSOWeyjbIGK+dZUaRViHTaMQX8aqmnn0PHBbGZezg=="], - "next-themes/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], "next-themes/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], "nextjs-linkedin-insight-tag/typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="], - "nx/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + "nx/axios": ["axios@1.13.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw=="], "nx/cli-spinners": ["cli-spinners@2.6.1", "", {}, "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g=="], @@ -4720,7 +4712,7 @@ "postcss-nested/postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="], - "posthog-node/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + "posthog-node/axios": ["axios@1.13.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw=="], "preact-render-to-string/pretty-format": ["pretty-format@3.8.0", "", {}, "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="], @@ -4816,12 +4808,8 @@ "strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "stripe/qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="], - "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], - "sucrase/glob": ["glob@10.4.5", "", { "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-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], - "sucrase/lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "tailwindcss/arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="], @@ -4898,17 +4886,17 @@ "@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], - "@codebuff/cli/posthog-node/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + "@codebuff/cli/posthog-node/axios": ["axios@1.13.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw=="], - "@codebuff/npm-app/posthog-node/axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="], + "@codebuff/npm-app/posthog-node/axios": ["axios@1.13.1", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-hU4EGxxt+j7TQijx1oYdAjw4xuIp1wRQSsbMFwSthCWeBQur1eF+qJ5iQ5sN3Tw8YRzQNKb8jszgBdMDVqwJcw=="], - "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1" } }, "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A=="], + "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2" } }, "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA=="], - "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "@typescript-eslint/typescript-estree": "8.46.1", "@typescript-eslint/utils": "8.46.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw=="], + "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/utils": "8.46.2", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA=="], - "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", "@typescript-eslint/typescript-estree": "8.46.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ=="], + "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg=="], - "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA=="], + "@codebuff/web/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="], "@codebuff/web/@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -5166,10 +5154,6 @@ "@react-spring/zdog/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - "@react-three/drei/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - - "@react-three/fiber/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - "@testing-library/dom/pretty-format/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "@testing-library/dom/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], @@ -5224,13 +5208,13 @@ "dts-bundle-generator/yargs/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=="], - "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "@typescript-eslint/visitor-keys": "8.46.1" } }, "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A=="], + "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2" } }, "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA=="], - "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "@typescript-eslint/typescript-estree": "8.46.1", "@typescript-eslint/utils": "8.46.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw=="], + "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/utils": "8.46.2", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA=="], - "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", "@typescript-eslint/typescript-estree": "8.46.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ=="], + "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg=="], - "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.1", "", { "dependencies": { "@typescript-eslint/types": "8.46.1", "eslint-visitor-keys": "^4.2.1" } }, "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA=="], + "eslint-config-next/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="], "eslint-config-next/@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], @@ -5352,32 +5336,6 @@ "mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], - "next-contentlayer/next/@next/env": ["@next/env@14.2.13", "", {}, "sha512-s3lh6K8cbW1h5Nga7NNeXrbe0+2jIIYK9YaA9T7IufDWnZpozdFUp6Hf0d5rNWUKu4fEuSX2rCKlGjCrtylfDw=="], - - "next-contentlayer/next/@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@14.2.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IkAmQEa2Htq+wHACBxOsslt+jMoV3msvxCn0WFSfJSkv/scy+i/EukBKNad36grRxywaXUYJc9mxEGkeIs8Bzg=="], - - "next-contentlayer/next/@next/swc-darwin-x64": ["@next/swc-darwin-x64@14.2.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dv1RBGs2TTjkwEnFMVL5XIfJEavnLqqwYSD6LXgTPdEy/u6FlSrLBSSfe1pcfqhFEXRAgVL3Wpjibe5wXJzWog=="], - - "next-contentlayer/next/@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@14.2.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-yB1tYEFFqo4ZNWkwrJultbsw7NPAAxlPXURXioRl9SdW6aIefOLS+0TEsKrWBtbJ9moTDgU3HRILL6QBQnMevg=="], - - "next-contentlayer/next/@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@14.2.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-v5jZ/FV/eHGoWhMKYrsAweQ7CWb8xsWGM/8m1mwwZQ/sutJjoFaXchwK4pX8NqwImILEvQmZWyb8pPTcP7htWg=="], - - "next-contentlayer/next/@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@14.2.13", "", { "os": "linux", "cpu": "x64" }, "sha512-aVc7m4YL7ViiRv7SOXK3RplXzOEe/qQzRA5R2vpXboHABs3w8vtFslGTz+5tKiQzWUmTmBNVW0UQdhkKRORmGA=="], - - "next-contentlayer/next/@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@14.2.13", "", { "os": "linux", "cpu": "x64" }, "sha512-4wWY7/OsSaJOOKvMsu1Teylku7vKyTuocvDLTZQq0TYv9OjiYYWt63PiE1nTuZnqQ4RPvME7Xai+9enoiN0Wrg=="], - - "next-contentlayer/next/@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@14.2.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-uP1XkqCqV2NVH9+g2sC7qIw+w2tRbcMiXFEbMihkQ8B1+V6m28sshBwAB0SDmOe0u44ne1vFU66+gx/28RsBVQ=="], - - "next-contentlayer/next/@next/swc-win32-ia32-msvc": ["@next/swc-win32-ia32-msvc@14.2.13", "", { "os": "win32", "cpu": "ia32" }, "sha512-V26ezyjPqQpDBV4lcWIh8B/QICQ4v+M5Bo9ykLN+sqeKKBxJVDpEc6biDVyluTXTC40f5IqCU0ttth7Es2ZuMw=="], - - "next-contentlayer/next/@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@14.2.13", "", { "os": "win32", "cpu": "x64" }, "sha512-WwzOEAFBGhlDHE5Z73mNU8CO8mqMNLqaG+AO9ETmzdCQlJhVtWZnOl2+rqgVQS+YHunjOWptdFmNfbpwcUuEsw=="], - - "next-contentlayer/next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="], - - "next-contentlayer/next/react": ["react@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ=="], - - "next-contentlayer/next/react-dom": ["react-dom@18.3.1", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" }, "peerDependencies": { "react": "^18.3.1" } }, "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw=="], - "next-themes/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], "next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], @@ -5440,10 +5398,6 @@ "string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "sucrase/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], - - "sucrase/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "teeny-request/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0" } }, "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA=="], @@ -5664,12 +5618,6 @@ "metro/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "next-contentlayer/next/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], - - "next-contentlayer/next/postcss/picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - - "next-contentlayer/next/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="], - "nx/ora/log-symbols/is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], "nx/ora/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], @@ -5690,8 +5638,6 @@ "remark-frontmatter/unified/vfile/vfile-message": ["vfile-message@3.1.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^3.0.0" } }, "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw=="], - "sucrase/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@7.18.0", "", {}, "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ=="], "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^1.3.0" } }, "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA=="], diff --git a/cli/knowledge.md b/cli/knowledge.md index f856d13d6..a901b8fe7 100644 --- a/cli/knowledge.md +++ b/cli/knowledge.md @@ -507,7 +507,36 @@ The bug occurred when tool toggles were rendered. Agent toggles worked fine, but ## Toggle Branch Rendering -Agent and tool toggles in the TUI render inside `` components. Expanded content must resolve to plain strings or StyledText-compatible fragments (``, ``, ``). +Agent and tool toggles in the TUI render inside `` components. Expanded content must resolve to plain strings or StyledText-compatible fragments (``, ``, ``). Any React tree we pass into a toggle must either already be a `` node or be wrapped in one so that downstream child elements never escape a text container. If we hand off plain markdown React fragments directly to ``, OpenTUI will crash because the fragments often expand to bare `` elements. + +Example: +Tool markdown output (via `renderMarkdown`) now gets wrapped in a `` element before reaching `BranchItem`. Without this wrapper, the renderer emits `` nodes that hit `` and cause `Component of type "span" must be created inside of a text node`. Wrapping the markdown and then composing it with any extra metadata keeps OpenTUI happy. + + ```tsx + const displayContent = renderContentWithMarkdown(fullContent, false, options) + + const renderableDisplayContent = + displayContent + ? ( + + {displayContent} + + ) + : null + + const combinedContent = toolRenderConfig.content ? ( + + + {toolRenderConfig.content} + + {renderableDisplayContent} + + ) : renderableDisplayContent + ``` ### TextNodeRenderable Constraint diff --git a/cli/package.json b/cli/package.json index adbde6d11..d6b230a90 100644 --- a/cli/package.json +++ b/cli/package.json @@ -33,8 +33,8 @@ }, "dependencies": { "@codebuff/sdk": "workspace:*", - "@opentui/core": "^0.1.28", - "@opentui/react": "^0.1.28", + "@opentui/core": "0.1.33", + "@opentui/react": "0.1.33", "@tanstack/react-query": "^5.62.8", "commander": "^14.0.1", "immer": "^10.1.3", diff --git a/cli/src/chat.tsx b/cli/src/chat.tsx index 1abbd4d59..d62ea0972 100644 --- a/cli/src/chat.tsx +++ b/cli/src/chat.tsx @@ -31,7 +31,7 @@ import { useMessageRenderer } from './hooks/use-message-renderer' import { useChatScrollbox } from './hooks/use-scroll-management' import { useSendMessage } from './hooks/use-send-message' import { useSuggestionEngine } from './hooks/use-suggestion-engine' -import { useSystemThemeDetector } from './hooks/use-system-theme-detector' +import { useTheme, useResolvedThemeName } from './hooks/use-theme' import { useChatStore } from './state/chat-store' import { flushAnalytics } from './utils/analytics' import { getUserCredentials } from './utils/auth' @@ -45,11 +45,23 @@ import { import { logger } from './utils/logger' import { buildMessageTree } from './utils/message-tree-utils' import { openFileAtPath } from './utils/open-file' -import { chatThemes, createMarkdownPalette } from './utils/theme-system' +import { handleSlashCommands } from './utils/slash-commands' +import { + chatThemes, + createMarkdownPalette, +} from './utils/theme-system' +import { env } from '@codebuff/common/env' +import { clientEnvVars } from '@codebuff/common/env-schema' import { formatValidationError } from './utils/validation-error-formatting' +import { getCodebuffClient } from './utils/codebuff-client' import type { SendMessageTimerEvent } from './hooks/use-send-message' -import type { ChatMessage, ContentBlock } from './types/chat' +import type { + ChatMessage, + ContentBlock, + ChatVariant, + AgentMessage, +} from './types/chat' import type { SendMessageFn } from './types/contracts/send-message' import type { User } from './utils/auth' import type { ScrollBoxRenderable } from '@opentui/core' @@ -91,14 +103,19 @@ export const App = ({ const terminalWidth = resolvedTerminalWidth const separatorWidth = Math.max(1, Math.floor(terminalWidth) - 2) + // Use theme hooks (transparent variant is default) + const theme = useTheme() + const resolvedThemeName = useResolvedThemeName() + + const markdownPalette = useMemo( + () => createMarkdownPalette(theme), + [theme], + ) + // Get formatted logo for display in chat messages const contentMaxWidth = Math.max(10, Math.min(terminalWidth - 4, 80)) const { textBlock: logoBlock } = useLogo({ availableWidth: contentMaxWidth }) - const themeName = useSystemThemeDetector() - const theme = chatThemes[themeName] - const markdownPalette = useMemo(() => createMarkdownPalette(theme), [theme]) - // Set up agent validation (manual trigger) const { validationErrors: liveValidationErrors, validate: validateAgents } = useAgentValidation(validationErrors) @@ -114,7 +131,12 @@ export const App = ({ const authQuery = useAuthQuery() const logoutMutation = useLogoutMutation() - const [isAuthenticated, setIsAuthenticated] = useState(requireAuth === false) + // If requireAuth is null (checking), defer showing auth UI until resolved + const initialAuthState = + requireAuth === false ? true : requireAuth === true ? false : null + const [isAuthenticated, setIsAuthenticated] = useState( + initialAuthState, + ) const [user, setUser] = useState(null) // Update authentication state when requireAuth changes @@ -175,19 +197,37 @@ export const App = ({ } }, [logoBlock]) - // Initialize with loaded agents message + // Initialize and update loaded agents message when theme changes useEffect(() => { - if (loadedAgentsData && messages.length === 0) { - const agentListId = 'loaded-agents-list' - const userCredentials = getUserCredentials() - const greeting = userCredentials?.name?.trim().length - ? `Welcome back, ${userCredentials.name.trim()}!` - : null + if (!loadedAgentsData) { + return + } + + const agentListId = 'loaded-agents-list' + const userCredentials = getUserCredentials() + const greeting = userCredentials?.name?.trim().length + ? `Welcome back, ${userCredentials.name.trim()}!` + : null + + const baseTextColor = theme.foreground + + const homeDir = os.homedir() + const repoRoot = path.dirname(loadedAgentsData.agentsDir) + const relativePath = path.relative(homeDir, repoRoot) + const displayPath = relativePath.startsWith('..') + ? repoRoot + : `~/${relativePath}` + const agentSectionHeader = agentId + ? `**Active agent: ${agentId}**` + : `**Active agent:** *fast default (base2-fast)*` + + const buildBlocks = (listId: string): ContentBlock[] => { const blocks: ContentBlock[] = [ { type: 'text', content: '\n\n' + logoBlock, + color: theme.foreground, }, ] @@ -195,70 +235,114 @@ export const App = ({ blocks.push({ type: 'text', content: greeting, + color: baseTextColor, }) } - // Calculate path from home directory to repository root - // agentsDir is typically in the root, so use its parent as the repository root - const homeDir = os.homedir() - const repoRoot = path.dirname(loadedAgentsData.agentsDir) - const relativePath = path.relative(homeDir, repoRoot) - const displayPath = relativePath.startsWith('..') - ? repoRoot // If outside home dir, show absolute path - : `~/${relativePath}` - - const renderRepoPathInfo = () => ( - - Codebuff can read and write files in{' '} - openFileAtPath(repoRoot)} - /> - , and run terminal commands to help you build. - - ) + // Log all client environment variables (works with both dev and binary modes) + const envVarsList = clientEnvVars + .map((key) => { + const value = env[key] + const displayValue = + typeof value === 'string' && value.length > 50 + ? value.substring(0, 47) + '...' + : value + return ` ${key}=${displayValue}` + }) + .join('\n') + + blocks.push({ + type: 'text', + content: `\nCLI Environment variables:\n${envVarsList}`, + marginTop: 1, + color: baseTextColor, + }) + + // Display SDK environment variables when the client is available + const client = getCodebuffClient() + const envGetter = client ? (client as any)?.getEnvironmentInfo : null + + if (typeof envGetter === 'function') { + const sdkEnv = envGetter.call(client) as { + rawEnv: Record + computed: Record + } + const sdkEnvLines = [ + 'Raw SDK env vars:', + ...Object.entries(sdkEnv.rawEnv).map( + ([key, value]) => ` ${key}=${value}`, + ), + '', + 'Computed SDK constants:', + ...Object.entries(sdkEnv.computed).map(([key, value]) => { + const displayValue = + typeof value === 'string' && value.length > 50 + ? value.substring(0, 47) + '...' + : String(value) + return ` ${key}=${displayValue}` + }), + ].join('\n') + + blocks.push({ + type: 'text', + content: `\nSDK Environment:\n${sdkEnvLines}`, + marginTop: 1, + color: baseTextColor, + }) + } blocks.push({ type: 'html', - render: renderRepoPathInfo, + render: () => ( + + + Codebuff can read and write files in{' '} + openFileAtPath(repoRoot)} + /> + , and run terminal commands to help you build. + + + ), }) + + blocks.push({ type: 'agent-list', - id: agentListId, + id: listId, agents: loadedAgentsData.agents, agentsDir: loadedAgentsData.agentsDir, }) - const agentDisplayId = agentId ?? 'base2-fast' - const agentSectionHeader = agentId - ? `**Active agent: ${agentId}**` - : `**Active agent:** *fast default (base2-fast)*` - blocks.push({ type: 'text', content: agentSectionHeader, marginTop: 1, marginBottom: 0, + color: baseTextColor, }) + return blocks + } + + if (messages.length === 0) { + const initialBlocks = buildBlocks(agentListId) const initialMessage: ChatMessage = { id: `system-loaded-agents-${Date.now()}`, variant: 'ai', - content: '', // Content is in the block - blocks, + content: '', + blocks: initialBlocks, timestamp: new Date().toISOString(), } - // Set as collapsed by default setCollapsedAgents((prev) => new Set([...prev, agentListId])) const messagesToAdd: ChatMessage[] = [initialMessage] - // Add validation error message if there are errors if (validationErrors.length > 0) { const errorBlocks = createValidationErrorBlocks({ errors: validationErrors, @@ -278,8 +362,47 @@ export const App = ({ } setMessages(messagesToAdd) + return } - }, [loadedAgentsData, validationErrors]) // Run when loadedAgentsData or validationErrors change + + setMessages((prev) => { + if (prev.length === 0) { + return prev + } + + const [firstMessage, ...rest] = prev + if (!firstMessage.blocks) { + return prev + } + + const agentListBlock = firstMessage.blocks.find( + (block): block is Extract => + block.type === 'agent-list', + ) + + if (!agentListBlock) { + return prev + } + + const updatedBlocks = buildBlocks(agentListBlock.id) + + return [ + { + ...firstMessage, + blocks: updatedBlocks, + }, + ...rest, + ] + }) + }, [ + agentId, + loadedAgentsData, + logoBlock, + resolvedThemeName, + separatorWidth, + theme, + validationErrors, + ]) const { inputValue, @@ -376,7 +499,7 @@ export const App = ({ ) useEffect(() => { - if (!isAuthenticated) return + if (isAuthenticated !== true) return setInputFocused(true) @@ -421,10 +544,6 @@ export const App = ({ activeSubagentsRef.current = activeSubagents }, [activeSubagents]) - useEffect(() => { - renderer?.setBackgroundColor(theme.background) - }, [renderer, theme.background]) - useEffect(() => { if (exitArmedRef.current && inputValue.length > 0) { exitArmedRef.current = false @@ -870,6 +989,7 @@ export const App = ({ stopStreaming, }), [ + agentMode, inputValue, isStreaming, sendMessage, @@ -960,8 +1080,11 @@ export const App = ({ const virtualizationNotice = shouldVirtualize && hiddenTopLevelCount > 0 ? ( - - + + Showing latest {virtualTopLevelMessages.length} of{' '} {topLevelMessages.length} messages. Scroll up to load more. @@ -975,7 +1098,6 @@ export const App = ({ const statusIndicatorNode = ( {/* Header */} @@ -1063,7 +1188,7 @@ export const App = ({ paddingBottom: 0, }} > - + {`⚠️ ${errorCount === 1 ? '1 agent has validation issues' : `${errorCount} agents have validation issues`}`} {hasMoreErrors && ` (showing ${MAX_VISIBLE_ERRORS} of ${errorCount})`} @@ -1071,7 +1196,7 @@ export const App = ({ {/* Error list - build as single text with newlines */} - + {visibleErrors.map(formatErrorLine).join('')} @@ -1083,7 +1208,7 @@ export const App = ({ paddingTop: 0, }} > - + {`... and ${errorCount - MAX_VISIBLE_ERRORS} more`} @@ -1110,7 +1235,7 @@ export const App = ({ paddingRight: 0, paddingTop: 0, paddingBottom: 0, - backgroundColor: theme.panelBg, + backgroundColor: 'transparent', }} > @@ -1155,7 +1280,7 @@ export const App = ({ flexShrink: 0, paddingLeft: 0, paddingRight: 0, - backgroundColor: theme.panelBg, + backgroundColor: 'transparent', }} > {shouldShowStatusLine && ( @@ -1166,15 +1291,15 @@ export const App = ({ width: '100%', }} > - + {hasStatus && statusIndicatorNode} {hasStatus && (exitWarning || shouldShowQueuePreview) && ' '} {exitWarning && ( - {exitWarning} + {exitWarning} )} {exitWarning && shouldShowQueuePreview && ' '} {shouldShowQueuePreview && ( - + {' '} {formatQueuedPreview( queuedMessages, @@ -1185,7 +1310,7 @@ export const App = ({ )} - + {agentMode === 'PLAN' && hasReceivedPlanResponse && ( @@ -1208,7 +1332,6 @@ export const App = ({ @@ -1216,11 +1339,11 @@ export const App = ({ - + @@ -1242,19 +1365,17 @@ export const App = ({ > - + {/* Login Modal Overlay - show when not authenticated and done checking */} - {requireAuth !== null && !isAuthenticated && ( + {requireAuth !== null && isAuthenticated === false && ( )} diff --git a/cli/src/commands/router.ts b/cli/src/commands/router.ts index 0c169755c..24d10a69e 100644 --- a/cli/src/commands/router.ts +++ b/cli/src/commands/router.ts @@ -25,7 +25,7 @@ export function routeUserPrompt(params: { setCanProcessQueue: (value: React.SetStateAction) => void setInputFocused: (focused: boolean) => void setInputValue: (value: string | ((prev: string) => string)) => void - setIsAuthenticated: (value: React.SetStateAction) => void + setIsAuthenticated: (value: React.SetStateAction) => void setMessages: ( value: ChatMessage[] | ((prev: ChatMessage[]) => ChatMessage[]), ) => void diff --git a/cli/src/components/__tests__/message-block.completion.test.tsx b/cli/src/components/__tests__/message-block.completion.test.tsx index adf6d3835..660b95f60 100644 --- a/cli/src/components/__tests__/message-block.completion.test.tsx +++ b/cli/src/components/__tests__/message-block.completion.test.tsx @@ -4,6 +4,7 @@ import { describe, test, expect } from 'bun:test' import { renderToStaticMarkup } from 'react-dom/server' import { MessageBlock } from '../message-block' +import '../../state/theme-store' // Initialize theme store import { chatThemes, createMarkdownPalette } from '../../utils/theme-system' import type { MarkdownPalette } from '../../utils/markdown-renderer' @@ -13,8 +14,8 @@ const basePalette = createMarkdownPalette(theme) const palette: MarkdownPalette = { ...basePalette, - inlineCodeFg: theme.messageAiText, - codeTextFg: theme.messageAiText, + inlineCodeFg: theme.foreground, + codeTextFg: theme.foreground, } const baseProps = { @@ -34,9 +35,8 @@ const baseProps = { elapsedSeconds: 0, startTime: null, }, - theme, - textColor: theme.messageAiText, - timestampColor: theme.timestampAi, + textColor: theme.foreground, + timestampColor: theme.muted, markdownOptions: { codeBlockWidth: 72, palette, diff --git a/cli/src/components/__tests__/message-block.streaming.test.tsx b/cli/src/components/__tests__/message-block.streaming.test.tsx index 5efee1b19..46d0045c8 100644 --- a/cli/src/components/__tests__/message-block.streaming.test.tsx +++ b/cli/src/components/__tests__/message-block.streaming.test.tsx @@ -4,6 +4,7 @@ import { describe, test, expect } from 'bun:test' import { renderToStaticMarkup } from 'react-dom/server' import { MessageBlock } from '../message-block' +import '../../state/theme-store' // Initialize theme store import { chatThemes, createMarkdownPalette } from '../../utils/theme-system' import type { MarkdownPalette } from '../../utils/markdown-renderer' @@ -13,8 +14,8 @@ const basePalette = createMarkdownPalette(theme) const palette: MarkdownPalette = { ...basePalette, - inlineCodeFg: theme.messageAiText, - codeTextFg: theme.messageAiText, + inlineCodeFg: theme.foreground, + codeTextFg: theme.foreground, } const baseProps = { @@ -27,9 +28,8 @@ const baseProps = { timestamp: '12:00', completionTime: undefined, credits: undefined, - theme, - textColor: theme.messageAiText, - timestampColor: theme.timestampAi, + textColor: theme.foreground, + timestampColor: theme.muted, markdownOptions: { codeBlockWidth: 72, palette, diff --git a/cli/src/components/__tests__/status-indicator.timer.test.tsx b/cli/src/components/__tests__/status-indicator.timer.test.tsx index 2336ca77e..5c5c0e327 100644 --- a/cli/src/components/__tests__/status-indicator.timer.test.tsx +++ b/cli/src/components/__tests__/status-indicator.timer.test.tsx @@ -13,12 +13,10 @@ import { } from 'bun:test' import { StatusIndicator } from '../status-indicator' -import { chatThemes } from '../../utils/theme-system' +import '../../state/theme-store' // Initialize theme store import { renderToStaticMarkup } from 'react-dom/server' import * as codebuffClient from '../../utils/codebuff-client' -const theme = chatThemes.dark - const createTimer = (elapsedSeconds: number, started: boolean) => ({ start: () => {}, stop: () => {}, @@ -42,7 +40,6 @@ describe('StatusIndicator timer rendering', () => { test('shows elapsed seconds when timer is active', () => { const markup = renderToStaticMarkup( { const inactiveMarkup = renderToStaticMarkup( { test('clipboard message takes priority over timer output', () => { const markup = renderToStaticMarkup( void + titleSuffix?: string +} + +const containerBorderChars: BorderCharacters = { + topLeft: '╭', + topRight: '╮', + bottomLeft: '╰', + bottomRight: '╯', + horizontal: '─', + vertical: '│', + topT: '┬', + bottomT: '┴', + leftT: '├', + rightT: '┤', + cross: '┼', +} + +export const AgentBranchItem = ({ + name, + content, + prompt, + agentId, + isCollapsed, + isStreaming, + streamingPreview, + finishedPreview, + branchChar = '', + statusLabel, + statusColor, + statusIndicator = '●', + onToggle, + titleSuffix, +}: AgentBranchItemProps) => { + const theme = useTheme() + + const baseTextAttributes = theme.messageTextAttributes ?? 0 + const getAttributes = (extra: number = 0): number | undefined => { + const combined = baseTextAttributes | extra + return combined === 0 ? undefined : combined + } + + const isExpanded = !isCollapsed + const toggleFrameColor = isExpanded + ? theme.agentToggleExpandedBg + : theme.muted + const toggleIconColor = isStreaming ? theme.primary : theme.foreground + const toggleIndicator = onToggle ? (isCollapsed ? '▸ ' : '▾ ') : '' + const toggleLabel = `${branchChar}${toggleIndicator}` + const collapseButtonFrame = theme.agentToggleExpandedBg + const collapseButtonText = collapseButtonFrame + const statusText = + statusLabel && statusLabel.length > 0 + ? statusIndicator === '✓' + ? `${statusLabel} ${statusIndicator}` + : `${statusIndicator} ${statusLabel}` + : null + const showCollapsedPreview = + (isStreaming && !!streamingPreview) || (!isStreaming && !!finishedPreview) + + const isTextRenderable = (value: ReactNode): boolean => { + if (value === null || value === undefined || typeof value === 'boolean') { + return false + } + + if (typeof value === 'string' || typeof value === 'number') { + return true + } + + if (Array.isArray(value)) { + return value.every((child) => isTextRenderable(child)) + } + + if (React.isValidElement(value)) { + if (value.type === React.Fragment) { + return isTextRenderable(value.props.children) + } + + if (typeof value.type === 'string') { + if ( + value.type === 'span' || + value.type === 'strong' || + value.type === 'em' + ) { + return isTextRenderable(value.props.children) + } + + return false + } + } + + return false + } + + const renderExpandedContent = (value: ReactNode): ReactNode => { + if ( + value === null || + value === undefined || + value === false || + value === true + ) { + return null + } + + if (isTextRenderable(value)) { + return ( + + {value} + + ) + } + + if (React.isValidElement(value)) { + if (value.key === null || value.key === undefined) { + return ( + + {value} + + ) + } + return value + } + + if (Array.isArray(value)) { + return ( + + {value.map((child, idx) => ( + + {child} + + ))} + + ) + } + + return ( + + {value} + + ) + } + + return ( + + + {prompt ? ( + + Prompt + + {prompt} + + + ) : null} + + + + {toggleLabel} + + + {name} + + {titleSuffix ? ( + + {` ${titleSuffix}`} + + ) : null} + {statusText ? ( + + {` ${statusText}`} + + ) : null} + + + + {isCollapsed ? ( + showCollapsedPreview ? ( + + + {isStreaming ? streamingPreview : finishedPreview} + + + ) : null + ) : ( + + {prompt && ( + + + Prompt + + + {prompt} + + {content && ( + + Response + + )} + + )} + {renderExpandedContent(content)} + {onToggle && ( + + + + )} + + )} + + + ) +} diff --git a/cli/src/components/agent-mode-toggle.tsx b/cli/src/components/agent-mode-toggle.tsx index 874d5514a..18dc4916b 100644 --- a/cli/src/components/agent-mode-toggle.tsx +++ b/cli/src/components/agent-mode-toggle.tsx @@ -1,39 +1,45 @@ -import type { ChatTheme } from '../types/theme-system' +import { RaisedPill } from './raised-pill' +import { useTheme } from '../hooks/use-theme' + import type { AgentMode } from '../utils/constants' +import type { ChatTheme } from '../types/theme-system' + +const getModeConfig = (theme: ChatTheme) => + ({ + FAST: { + frameColor: theme.modeFastBg, + textColor: theme.modeFastText, + label: 'FAST', + }, + MAX: { + frameColor: theme.modeMaxBg, + textColor: theme.modeMaxText, + label: '💪 MAX', + }, + PLAN: { + frameColor: theme.modePlanBg, + textColor: theme.modePlanText, + label: '📋 PLAN', + }, + }) as const export const AgentModeToggle = ({ mode, - theme, onToggle, }: { mode: AgentMode - theme: ChatTheme onToggle: () => void }) => { - const isFast = mode === 'FAST' - const isMax = mode === 'MAX' - const isPlan = mode === 'PLAN' - - const bgColor = isFast ? '#0a6515' : isMax ? '#ac1626' : '#1e40af' - const textColor = '#ffffff' - const label = isFast ? 'FAST' : isMax ? '💪 MAX' : 'PLAN' - - const needsPadding = isFast || isPlan + const theme = useTheme() + const config = getModeConfig(theme) + const { frameColor, textColor, label } = config[mode] return ( - - - {label} - - + ) } diff --git a/cli/src/components/branch-item.tsx b/cli/src/components/branch-item.tsx deleted file mode 100644 index 626f40991..000000000 --- a/cli/src/components/branch-item.tsx +++ /dev/null @@ -1,241 +0,0 @@ -import { TextAttributes, type BorderCharacters } from '@opentui/core' -import React, { type ReactNode } from 'react' - -import type { ChatTheme } from '../types/theme-system' - -const borderCharsWithoutVertical: BorderCharacters = { - topLeft: '┌', - topRight: '┐', - bottomLeft: '└', - bottomRight: '┘', - horizontal: '─', - vertical: ' ', - topT: ' ', - bottomT: ' ', - leftT: ' ', - rightT: ' ', - cross: ' ', -} - -interface BranchItemProps { - name: string - content: ReactNode - prompt?: string - agentId?: string - isCollapsed: boolean - isStreaming: boolean - branchChar: string - streamingPreview: string - finishedPreview: string - theme: ChatTheme - onToggle: () => void -} - -export const BranchItem = ({ - name, - content, - prompt, - agentId, - isCollapsed, - isStreaming, - branchChar, - streamingPreview, - finishedPreview, - theme, - onToggle, -}: BranchItemProps) => { - const cornerColor = theme.agentPrefix - - const toggleBackground = isStreaming - ? theme.agentToggleHeaderBg - : isCollapsed - ? theme.agentResponseCount - : theme.agentPrefix - const toggleTextColor = - (isStreaming ? theme.agentToggleHeaderText : theme.agentToggleText) ?? - theme.agentToggleText - const toggleLabel = `${isCollapsed ? '▸' : '▾'} ` - - const isTextRenderable = (value: ReactNode): boolean => { - if (value === null || value === undefined || typeof value === 'boolean') { - return false - } - - if (typeof value === 'string' || typeof value === 'number') { - return true - } - - if (Array.isArray(value)) { - return value.every((child) => isTextRenderable(child)) - } - - if (React.isValidElement(value)) { - if (value.type === React.Fragment) { - return isTextRenderable(value.props.children) - } - - if (typeof value.type === 'string') { - if ( - value.type === 'span' || - value.type === 'strong' || - value.type === 'em' - ) { - return isTextRenderable(value.props.children) - } - - return false - } - } - - return false - } - - const renderExpandedContent = (value: ReactNode): ReactNode => { - if ( - value === null || - value === undefined || - value === false || - value === true - ) { - return null - } - - if (isTextRenderable(value)) { - return ( - - {value} - - ) - } - - if (React.isValidElement(value)) { - if (value.key === null || value.key === undefined) { - return ( - - {value} - - ) - } - return value - } - - if (Array.isArray(value)) { - return ( - - {value.map((child, idx) => ( - - {child} - - ))} - - ) - } - - return ( - - {value} - - ) - } - - return ( - - - - - {toggleLabel} - - {name} - - - - - {isCollapsed && - (isStreaming ? streamingPreview : finishedPreview) && ( - - {isStreaming ? streamingPreview : finishedPreview} - - )} - {!isCollapsed && ( - - {content && ( - - {prompt && ( - - - Prompt - - - {prompt} - - - - Response - - - )} - {renderExpandedContent(content)} - - )} - - - - Collapse - - - - - )} - - - - ) -} diff --git a/cli/src/components/build-mode-buttons.tsx b/cli/src/components/build-mode-buttons.tsx index 3c0fc7bbd..6ae1e9d59 100644 --- a/cli/src/components/build-mode-buttons.tsx +++ b/cli/src/components/build-mode-buttons.tsx @@ -29,7 +29,7 @@ export const BuildModeButtons = ({ }} onMouseDown={onBuildFast} > - + Build Fast @@ -43,7 +43,7 @@ export const BuildModeButtons = ({ }} onMouseDown={onBuildMax} > - + Build Max diff --git a/cli/src/components/login-modal-utils.ts b/cli/src/components/login-modal-utils.ts index b3afb0074..f28f5e18b 100644 --- a/cli/src/components/login-modal-utils.ts +++ b/cli/src/components/login-modal-utils.ts @@ -2,22 +2,6 @@ * Utility functions for the login screen component */ -/** - * Calculates the relative luminance of a hex color to determine if it's light or dark mode - */ -export function isLightModeColor(hexColor: string): boolean { - if (!hexColor) return false - - const hex = hexColor.replace('#', '') - const r = parseInt(hex.substring(0, 2), 16) - const g = parseInt(hex.substring(2, 4), 16) - const b = parseInt(hex.substring(4, 6), 16) - - // Calculate relative luminance - const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255 - return luminance > 0.5 -} - /** * Formats a URL for display by wrapping it at logical breakpoints */ diff --git a/cli/src/components/login-modal.tsx b/cli/src/components/login-modal.tsx index f0d699846..384588807 100644 --- a/cli/src/components/login-modal.tsx +++ b/cli/src/components/login-modal.tsx @@ -9,12 +9,8 @@ import { useLoginKeyboardHandlers } from '../hooks/use-login-keyboard-handlers' import { useLoginPolling } from '../hooks/use-login-polling' import { useLogo } from '../hooks/use-logo' import { useSheenAnimation } from '../hooks/use-sheen-animation' +import { useTheme } from '../hooks/use-theme' import { - LINK_COLOR_DEFAULT, - LINK_COLOR_CLICKED, - COPY_SUCCESS_COLOR, - COPY_ERROR_COLOR, - WARNING_COLOR, DEFAULT_TERMINAL_HEIGHT, MODAL_VERTICAL_MARGIN, MAX_MODAL_BASE_HEIGHT, @@ -23,7 +19,6 @@ import { import { formatUrl, generateFingerprintId, - isLightModeColor, calculateResponsiveLayout, calculateModalDimensions, } from '../login/utils' @@ -31,21 +26,19 @@ import { useLoginStore } from '../state/login-store' import { copyTextToClipboard } from '../utils/clipboard' import { logger } from '../utils/logger' -import type { ChatTheme } from '../types/theme-system' import type { User } from '../utils/auth' interface LoginModalProps { onLoginSuccess: (user: User) => void - theme: ChatTheme hasInvalidCredentials?: boolean | null } export const LoginModal = ({ onLoginSuccess, - theme, hasInvalidCredentials = false, }: LoginModalProps) => { const renderer = useRenderer() + const theme = useTheme() // Use zustand store for all state const { @@ -219,15 +212,6 @@ export const LoginModal = ({ } }, [hasOpenedBrowser, loginUrl, copyToClipboard]) - // Determine if we're in light mode by checking background color luminance - const isLightMode = useMemo( - () => isLightModeColor(theme.background), - [theme.background], - ) - - // Use pure black/white for logo - const logoColor = isLightMode ? '#000000' : '#ffffff' - // Calculate terminal width and height for responsive display const terminalWidth = renderer?.width || 80 const terminalHeight = renderer?.height || 24 @@ -265,7 +249,7 @@ export const LoginModal = ({ // Use custom hook for sheen animation const { applySheenToChar } = useSheenAnimation({ - logoColor, + logoColor: theme.foreground, terminalWidth: renderer?.width, sheenPosition, setSheenPosition, @@ -275,7 +259,7 @@ export const LoginModal = ({ const { component: logoComponent } = useLogo({ availableWidth: contentMaxWidth, applySheenToChar, - textColor: theme.chromeText, + textColor: theme.foreground, }) // Calculate modal dimensions @@ -288,17 +272,22 @@ export const LoginModal = ({ WARNING_BANNER_HEIGHT, ) + // Calculate modal width and center position + const modalWidth = Math.floor(terminalWidth * 0.95) + const modalLeft = Math.floor((terminalWidth - modalWidth) / 2) + const modalTop = Math.floor((terminalHeight - modalHeight) / 2) + // Format URL for display (wrap if needed) return ( - - + + {isNarrow ? "⚠ Found API key but it's invalid. Please log in again." : '⚠ We found an API key but it appears to be invalid. Please log in again to continue.'} @@ -362,8 +351,8 @@ export const LoginModal = ({ flexShrink: 0, }} > - - Loading... + + Loading... )} @@ -379,12 +368,12 @@ export const LoginModal = ({ flexShrink: 0, }} > - + Error: {error} {!isVerySmall && ( - - + + {isNarrow ? 'Please try again' : 'Please restart the CLI and try again'} @@ -405,8 +394,8 @@ export const LoginModal = ({ flexShrink: 0, }} > - - + + {isNarrow ? 'Press ENTER to login...' : 'Press ENTER to open your browser and finish logging in...'} @@ -427,8 +416,8 @@ export const LoginModal = ({ gap: isVerySmall ? 0 : 1, }} > - - + + {isNarrow ? 'Click to copy:' : 'Click link to copy:'} @@ -443,8 +432,8 @@ export const LoginModal = ({ text={loginUrl} maxWidth={maxUrlWidth} formatLines={formatLoginUrlLines} - color={hasClickedLink ? LINK_COLOR_CLICKED : LINK_COLOR_DEFAULT} - activeColor={LINK_COLOR_CLICKED} + color={hasClickedLink ? theme.success : theme.info} + activeColor={theme.success} underlineOnHover={true} isActive={justCopied} onActivate={handleActivateLoginUrl} @@ -464,12 +453,12 @@ export const LoginModal = ({ flexShrink: 0, }} > - + {copyMessage} diff --git a/cli/src/components/message-block.tsx b/cli/src/components/message-block.tsx index da42e3059..ef10430bc 100644 --- a/cli/src/components/message-block.tsx +++ b/cli/src/components/message-block.tsx @@ -1,9 +1,14 @@ -import { pluralize } from '@codebuff/common/util/string' import { TextAttributes } from '@opentui/core' import React, { type ReactNode } from 'react' +import stringWidth from 'string-width' + +import { pluralize } from '@codebuff/common/util/string' -import { BranchItem } from './branch-item' +import { AgentBranchItem } from './agent-branch-item' +import { ToolCallItem } from './tool-call-item' +import { useTheme } from '../hooks/use-theme' import { getToolDisplayInfo } from '../utils/codebuff-client' +import { getToolRenderConfig } from './tool-renderer' import { renderMarkdown, renderStreamingMarkdown, @@ -13,7 +18,7 @@ import { import type { ElapsedTimeTracker } from '../hooks/use-elapsed-time' import type { ContentBlock } from '../types/chat' -import type { ChatTheme } from '../types/theme-system' +import type { ChatTheme, ThemeColor } from '../types/theme-system' const trimTrailingNewlines = (value: string): string => value.replace(/[\r\n]+$/g, '') @@ -33,8 +38,7 @@ interface MessageBlockProps { completionTime?: string credits?: number timer: ElapsedTimeTracker - theme: ChatTheme - textColor: string + textColor?: ThemeColor timestampColor: string markdownOptions: { codeBlockWidth: number; palette: MarkdownPalette } availableWidth: number @@ -57,7 +61,6 @@ export const MessageBlock = ({ completionTime, credits, timer, - theme, textColor, timestampColor, markdownOptions, @@ -68,10 +71,20 @@ export const MessageBlock = ({ onToggleCollapsed, registerAgentRef, }: MessageBlockProps): ReactNode => { + const theme = useTheme() + const resolvedTextColor = textColor ?? theme.foreground + // Get elapsed time from timer for streaming AI messages const elapsedSeconds = timer.elapsedSeconds - const computeBranchChar = (indentLevel: number, isLastBranch: boolean) => - `${' '.repeat(indentLevel)}${isLastBranch ? '└─ ' : '├─ '}` + const computeBranchChar = ( + ancestorBranchStates: boolean[], + isLastBranch: boolean, + ) => { + const ancestorPrefix = ancestorBranchStates + .map((ancestorIsLast) => (ancestorIsLast ? ' ' : '│ ')) + .join('') + return `${ancestorPrefix}${isLastBranch ? '└ ' : '├ '}` + } const renderContentWithMarkdown = ( rawContent: string, @@ -127,8 +140,8 @@ export const MessageBlock = ({ codeBlockWidth: Math.max(10, availableWidth - 12 - indentationOffset), palette: { ...markdownPalette, - inlineCodeFg: theme.agentText, - codeTextFg: theme.agentText, + inlineCodeFg: theme.foreground, + codeTextFg: theme.foreground, }, } } @@ -138,6 +151,7 @@ export const MessageBlock = ({ indentLevel: number, isLastBranch: boolean, keyPrefix: string, + ancestorBranchStates: boolean[], ): React.ReactNode => { if (toolBlock.toolName === 'end_turn') { return null @@ -165,15 +179,47 @@ export const MessageBlock = ({ ? `$ ${(toolBlock.input as any).command.trim()}` : null - const streamingPreview = isStreaming + const branchChar = computeBranchChar(ancestorBranchStates, isLastBranch) + const indentPrefix = branchChar.replace(/[├└]\s*$/, '') + const previewBasePrefix = + indentPrefix.length > 0 ? `${indentPrefix}│ ` : ' │ ' + const branchIndentWidth = stringWidth(branchChar) + const headerPrefixWidth = stringWidth(branchChar) + const previewBaseWidth = stringWidth(previewBasePrefix) + const alignmentPadding = Math.max(0, headerPrefixWidth - previewBaseWidth) + const paddedPreviewPrefix = `${previewBasePrefix}${' '.repeat(alignmentPadding)}` + const blankPreviewPrefix = + previewBasePrefix.replace(/\s+$/, '') || previewBasePrefix + const toolRenderConfig = getToolRenderConfig(toolBlock, theme, { + availableWidth, + indentationOffset: branchIndentWidth, + previewPrefix: previewBasePrefix, + labelWidth: headerPrefixWidth, + }) + const formatPreview = (value: string | null): string => { + if (!value) return '' + const rawLines = value.split('\n') + const decorated = rawLines.map((line) => + line.trim().length > 0 + ? `${paddedPreviewPrefix}${line}` + : blankPreviewPrefix, + ) + if (!decorated.some((line) => line.trim().length === 0)) { + decorated.push(blankPreviewPrefix) + } + return decorated.join('\n') + } + const rawStreamingPreview = isStreaming ? commandPreview ?? `${sanitizePreview(firstLine)}...` : '' - + const streamingPreview = isStreaming + ? formatPreview(rawStreamingPreview) + : '' + const collapsedPreviewBase = + toolRenderConfig.collapsedPreview ?? + getToolFinishedPreview(toolBlock, commandPreview, lastLine) const finishedPreview = - !isStreaming && isCollapsed - ? getToolFinishedPreview(toolBlock, commandPreview, lastLine) - : '' - + !isStreaming ? formatPreview(collapsedPreviewBase) : '' const agentMarkdownOptions = getAgentMarkdownOptions(indentLevel) const displayContent = renderContentWithMarkdown( fullContent, @@ -181,24 +227,57 @@ export const MessageBlock = ({ agentMarkdownOptions, ) - const branchChar = computeBranchChar(indentLevel, isLastBranch) + const renderableDisplayContent = + displayContent === null || + displayContent === undefined || + displayContent === false || + displayContent === '' + ? null + : ( + + {displayContent} + + ) + + const combinedContent = toolRenderConfig.content ? ( + + + {toolRenderConfig.content} + + {renderableDisplayContent} + + ) : renderableDisplayContent + + const headerName = displayInfo.name return ( registerAgentRef(toolBlock.toolCallId, el)} > - onToggleCollapsed(toolBlock.toolCallId)} + titleSuffix={toolRenderConfig.path} /> ) @@ -209,6 +288,7 @@ export const MessageBlock = ({ indentLevel: number, isLastBranch: boolean, keyPrefix: string, + ancestorBranchStates: boolean[], ): React.ReactNode { const isCollapsed = collapsedAgents.has(agentBlock.agentId) const isStreaming = @@ -234,18 +314,28 @@ export const MessageBlock = ({ ? sanitizePreview(agentBlock.initialPrompt) : '' - const branchChar = computeBranchChar(indentLevel, isLastBranch) + const branchChar = '' + const nextAncestorBranches = [...ancestorBranchStates, isLastBranch] const childNodes = renderAgentBody( agentBlock, indentLevel + 1, keyPrefix, isStreaming, + nextAncestorBranches, ) const displayContent = childNodes.length > 0 ? ( {childNodes} ) : null + const isActive = isStreaming || agentBlock.status === 'running' + const statusLabel = isActive + ? 'running' + : agentBlock.status === 'complete' + ? 'completed' + : agentBlock.status + const statusColor = isActive ? theme.primary : theme.muted + const statusIndicator = isActive ? '●' : '✓' return ( registerAgentRef(agentBlock.agentId, el)} style={{ flexDirection: 'column', gap: 0 }} > - onToggleCollapsed(agentBlock.agentId)} /> @@ -307,7 +399,7 @@ export const MessageBlock = ({ ) => { const identifier = formatIdentifier(agent) return ( - + {` • ${identifier}`} ) @@ -339,7 +431,7 @@ export const MessageBlock = ({ key={keyPrefix} ref={(el: any) => registerAgentRef(agentListBlock.id, el)} > - onToggleCollapsed(agentListBlock.id)} /> @@ -360,6 +451,7 @@ export const MessageBlock = ({ indentLevel: number, keyPrefix: string, parentIsStreaming: boolean, + ancestorBranchStates: boolean[], ): React.ReactNode[] { const nestedBlocks = agentBlock.blocks ?? [] const nodes: React.ReactNode[] = [] @@ -383,14 +475,21 @@ export const MessageBlock = ({ isNestedStreamingText, markdownOptionsForLevel, ) + const marginTop = nestedBlock.marginTop ?? 0 const marginBottom = nestedBlock.marginBottom ?? 0 + const explicitColor = + typeof (nestedBlock as any).color === 'string' + ? ((nestedBlock as any).color as string) + : undefined + const nestedTextColor = explicitColor ?? theme.foreground nodes.push( @@ -413,7 +512,10 @@ export const MessageBlock = ({ marginBottom, }} > - {nestedBlock.render({ textColor: theme.agentText, theme })} + {nestedBlock.render({ + textColor: theme.foreground, + theme, + })} , ) break @@ -427,6 +529,7 @@ export const MessageBlock = ({ indentLevel, isLastBranch, `${keyPrefix}-tool-${nestedBlock.toolCallId}`, + ancestorBranchStates, ), ) break @@ -440,6 +543,7 @@ export const MessageBlock = ({ indentLevel, isLastBranch, `${keyPrefix}-agent-${nestedIdx}`, + ancestorBranchStates, ), ) break @@ -461,7 +565,10 @@ export const MessageBlock = ({ markdownOptions, ) return ( - + {displayContent} ) @@ -486,11 +593,15 @@ export const MessageBlock = ({ ? 0 : block.marginTop ?? 0 const marginBottom = block.marginBottom ?? 0 + const explicitColor = + typeof (block as any).color === 'string' + ? ((block as any).color as string) + : undefined + const blockTextColor = explicitColor ?? resolvedTextColor return ( {renderedContent} @@ -511,7 +622,7 @@ export const MessageBlock = ({ width: '100%', }} > - {block.render({ textColor, theme })} + {block.render({ textColor: resolvedTextColor, theme })} ) } @@ -523,6 +634,7 @@ export const MessageBlock = ({ 0, isLastBranch, `${messageId}-tool-${block.toolCallId}`, + [], ) } @@ -533,6 +645,7 @@ export const MessageBlock = ({ 0, isLastBranch, `${messageId}-agent-${block.agentId}`, + [], ) } @@ -554,9 +667,9 @@ export const MessageBlock = ({ <> {isUser && ( 0 && ( { - const parseHex = (hex: string) => { - const normalized = hex.trim().replace('#', '') - const full = - normalized.length === 3 - ? normalized - .split('') - .map((ch) => ch + ch) - .join('') - : normalized - const value = parseInt(full, 16) - return { - r: (value >> 16) & 0xff, - g: (value >> 8) & 0xff, - b: value & 0xff, - } - } - - const clamp = (value: number) => Math.max(0, Math.min(255, Math.round(value))) - - try { - const fg = parseHex(foreground) - const bg = parseHex(background) - - const blend = { - r: clamp(alpha * fg.r + (1 - alpha) * bg.r), - g: clamp(alpha * fg.g + (1 - alpha) * bg.g), - b: clamp(alpha * fg.b + (1 - alpha) * bg.b), - } - - const toHex = (value: number) => value.toString(16).padStart(2, '0') - return `#${toHex(blend.r)}${toHex(blend.g)}${toHex(blend.b)}` - } catch { - return foreground - } -} - // Helper functions for text manipulation function findLineStart(text: string, cursor: number): number { let pos = Math.max(0, Math.min(cursor, text.length)) @@ -104,7 +64,7 @@ function findNextWordBoundary(text: string, cursor: number): number { return pos } -const CURSOR_CHAR = '▏' +const CURSOR_CHAR = '┃' interface MultilineInputProps { value: string @@ -122,15 +82,8 @@ interface MultilineInputProps { placeholder?: string focused?: boolean maxHeight?: number - theme: { - inputBg: string - inputFocusedBg: string - inputFg: string - inputFocusedFg: string - inputPlaceholder: string - cursor: string - } width: number + textAttributes?: number } export type MultilineInputHandle = { @@ -148,12 +101,13 @@ export const MultilineInput = forwardRef< placeholder = '', focused = true, maxHeight = 5, - theme, width, + textAttributes, onKeyIntercept, }: MultilineInputProps, forwardedRef, ) { + const theme = useTheme() const scrollBoxRef = useRef(null) const [cursorPosition, setCursorPosition] = useState(value.length) useImperativeHandle( @@ -587,11 +541,6 @@ export const MultilineInput = forwardRef< const beforeCursor = showCursor ? displayValue.slice(0, cursorPosition) : '' const afterCursor = showCursor ? displayValue.slice(cursorPosition) : '' const activeChar = afterCursor.charAt(0) || ' ' - const highlightBg = mixColors( - theme.cursor, - isPlaceholder ? theme.inputBg : theme.inputFocusedBg, - 0.4, - ) const shouldHighlight = showCursor && !isPlaceholder && @@ -625,6 +574,26 @@ export const MultilineInput = forwardRef< maxHeight, ]) + const inputColor = isPlaceholder + ? theme.muted + : focused + ? theme.inputFocusedFg + : theme.inputFg + + const textStyle: Record = { + bg: 'transparent', + fg: inputColor, + } + + if (isPlaceholder) { + textStyle.attributes = TextAttributes.DIM + } else if (textAttributes !== undefined && textAttributes !== 0) { + textStyle.attributes = textAttributes + } + + const cursorFg = theme.info + const highlightBg = '#7dd3fc' // Lighter blue for highlight background + return ( - + {showCursor ? ( <> {beforeCursor} {shouldHighlight ? ( - + {activeChar === ' ' ? '\u00a0' : activeChar} ) : ( - + {CURSOR_CHAR} )} diff --git a/cli/src/components/raised-pill.tsx b/cli/src/components/raised-pill.tsx new file mode 100644 index 000000000..621815964 --- /dev/null +++ b/cli/src/components/raised-pill.tsx @@ -0,0 +1,93 @@ +import React from 'react' +import stringWidth from 'string-width' + +type PillSegment = { + text: string + fg?: string + attr?: number +} + +interface RaisedPillProps { + segments: PillSegment[] + frameColor: string + textColor: string + fillColor?: string + padding?: number + onPress?: () => void + style?: Record +} + +const buildHorizontal = (length: number): string => { + if (length <= 0) return '' + return '─'.repeat(length) +} + +export const RaisedPill = ({ + segments, + frameColor, + textColor, + fillColor, + padding = 2, + onPress, + style, +}: RaisedPillProps): React.ReactNode => { + const leftRightPadding = + padding > 0 + ? [{ text: ' '.repeat(padding), fg: textColor }] + : [] + + const normalizedSegments: Array<{ + text: string + fg?: string + attr?: number + }> = [ + ...leftRightPadding, + ...segments.map((segment) => ({ + text: segment.text, + fg: segment.fg ?? textColor, + attr: segment.attr, + })), + ...leftRightPadding, + ] + + const contentText = normalizedSegments.map((segment) => segment.text).join('') + const contentWidth = Math.max(0, stringWidth(contentText)) + const horizontal = buildHorizontal(contentWidth) + + return ( + + + {`╭${horizontal}╮`} + + + + │ + + {normalizedSegments.map((segment, idx) => ( + + {segment.text} + + ))} + + │ + + + + {`╰${horizontal}╯`} + + + ) +} diff --git a/cli/src/components/separator.tsx b/cli/src/components/separator.tsx index 82a785e89..014d00435 100644 --- a/cli/src/components/separator.tsx +++ b/cli/src/components/separator.tsx @@ -1,18 +1,18 @@ import React from 'react' -import type { ChatTheme } from '../types/theme-system' +import { useTheme } from '../hooks/use-theme' interface SeparatorProps { - theme: ChatTheme width: number } -export const Separator = ({ theme, width }: SeparatorProps) => { +export const Separator = ({ width }: SeparatorProps) => { + const theme = useTheme() + return ( ) } diff --git a/cli/src/components/shimmer-text.tsx b/cli/src/components/shimmer-text.tsx index 4379debfd..ba7e60473 100644 --- a/cli/src/components/shimmer-text.tsx +++ b/cli/src/components/shimmer-text.tsx @@ -1,18 +1,7 @@ import { TextAttributes } from '@opentui/core' import React, { useEffect, useMemo, useState } from 'react' -export const DEFAULT_SHIMMER_COLORS = [ - '#ff8c00', - '#ff9100', - '#ff9500', - '#ff9a00', - '#ffa500', - '#ffa000', - '#ff9500', - '#ff8c00', - '#ff8300', - '#ff7700', -] +import { useTheme } from '../hooks/use-theme' const clamp = (value: number, min: number, max: number): number => Math.min(max, Math.max(min, value)) @@ -113,10 +102,12 @@ const rgbToHex = (r: number, g: number, b: number): string => { const generatePaletteFromPrimary = ( primaryColor: string, size: number, + fallbackColor: string, ): string[] => { const baseRgb = hexToRgb(primaryColor) if (!baseRgb) { - return DEFAULT_SHIMMER_COLORS + // If we can't parse the color, return a simple palette using the fallback + return Array.from({ length: size }, () => fallbackColor) } const { h, s, l } = rgbToHsl(baseRgb.r, baseRgb.g, baseRgb.b) @@ -148,6 +139,7 @@ export const ShimmerText = ({ colors?: string[] primaryColor?: string }) => { + const theme = useTheme() const [pulse, setPulse] = useState(0) const chars = text.split('') const numChars = chars.length @@ -163,7 +155,7 @@ export const ShimmerText = ({ const generateColors = (length: number, colorPalette: string[]): string[] => { if (length === 0) return [] if (colorPalette.length === 0) { - return Array.from({ length }, () => '#ffffff') + return Array.from({ length }, () => theme.muted) } if (colorPalette.length === 1) { return Array.from({ length }, () => colorPalette[0]) @@ -186,10 +178,12 @@ export const ShimmerText = ({ } if (primaryColor) { const paletteSize = Math.max(8, Math.min(20, Math.ceil(numChars * 1.5))) - return generatePaletteFromPrimary(primaryColor, paletteSize) + return generatePaletteFromPrimary(primaryColor, paletteSize, theme.muted) } - return DEFAULT_SHIMMER_COLORS - }, [colors, primaryColor, numChars]) + // Use theme shimmer color as default + const paletteSize = Math.max(8, Math.min(20, Math.ceil(numChars * 1.5))) + return generatePaletteFromPrimary(theme.info, paletteSize, theme.muted) + }, [colors, primaryColor, numChars, theme.info, theme.muted]) const generateAttributes = (length: number): number[] => { const attributes: number[] = [] diff --git a/cli/src/components/status-indicator.tsx b/cli/src/components/status-indicator.tsx index 829d4d492..35e19c261 100644 --- a/cli/src/components/status-indicator.tsx +++ b/cli/src/components/status-indicator.tsx @@ -1,10 +1,11 @@ import React, { useEffect, useState } from 'react' import { ShimmerText } from './shimmer-text' +import { useTheme } from '../hooks/use-theme' import { getCodebuffClient } from '../utils/codebuff-client' +import { logger } from '../utils/logger' import type { ElapsedTimeTracker } from '../hooks/use-elapsed-time' -import type { ChatTheme } from '../types/theme-system' const useConnectionStatus = () => { const [isConnected, setIsConnected] = useState(true) @@ -36,21 +37,20 @@ const useConnectionStatus = () => { } export const StatusIndicator = ({ - theme, clipboardMessage, isActive = false, timer, }: { - theme: ChatTheme clipboardMessage?: string | null isActive?: boolean timer: ElapsedTimeTracker }) => { + const theme = useTheme() const isConnected = useConnectionStatus() const elapsedSeconds = timer.elapsedSeconds if (clipboardMessage) { - return {clipboardMessage} + return {clipboardMessage} } const hasStatus = isConnected === false || isActive @@ -66,7 +66,7 @@ export const StatusIndicator = ({ if (isActive) { // If we have elapsed time > 0, show it if (elapsedSeconds > 0) { - return {elapsedSeconds}s + return {elapsedSeconds}s } // Otherwise show thinking... @@ -74,7 +74,7 @@ export const StatusIndicator = ({ ) } diff --git a/cli/src/components/suggestion-menu.tsx b/cli/src/components/suggestion-menu.tsx index 856ab42d4..2308ad55b 100644 --- a/cli/src/components/suggestion-menu.tsx +++ b/cli/src/components/suggestion-menu.tsx @@ -1,8 +1,7 @@ import React from 'react' import { HighlightedSubsequenceText } from './highlighted-text' - -import type { ChatTheme } from '../types/theme-system' +import { useTheme } from '../hooks/use-theme' export interface SuggestionItem { id: string @@ -15,7 +14,6 @@ export interface SuggestionItem { interface SuggestionMenuProps { items: SuggestionItem[] selectedIndex: number - theme: ChatTheme maxVisible?: number prefix?: string } @@ -27,6 +25,7 @@ export const SuggestionMenu = ({ maxVisible = 10, prefix = '/', }: SuggestionMenuProps) => { + const theme = useTheme() if (items.length === 0) { return null } @@ -54,11 +53,9 @@ export const SuggestionMenu = ({ const labelLength = effectivePrefix.length + item.label.length const paddingLength = Math.max(maxLabelLength - labelLength + 2, 2) const padding = ' '.repeat(paddingLength) - const textColor = isSelected ? theme.agentContentText : theme.inputFg - const descriptionColor = isSelected - ? theme.agentContentText - : theme.timestampUser - const highlightColor = theme.agentPrefix + const textColor = isSelected ? theme.foreground : theme.inputFg + const descriptionColor = isSelected ? theme.foreground : theme.muted + const highlightColor = theme.primary return ( - {effectivePrefix} + {effectivePrefix} @@ -117,7 +113,7 @@ export const SuggestionMenu = ({ style={{ flexDirection: 'column', gap: 0, - backgroundColor: theme.messageBg, + backgroundColor: theme.background, width: '100%', }} > diff --git a/cli/src/components/terminal-link.tsx b/cli/src/components/terminal-link.tsx index 99992e10c..5bf4e37ee 100644 --- a/cli/src/components/terminal-link.tsx +++ b/cli/src/components/terminal-link.tsx @@ -1,5 +1,7 @@ import React, { useCallback, useMemo, useState } from 'react' +import { useTheme } from '../hooks/use-theme' + type FormatLinesFn = (text: string, maxWidth?: number) => string[] export interface TerminalLinkProps { @@ -22,8 +24,8 @@ export const TerminalLink: React.FC = ({ text, maxWidth, formatLines = defaultFormatLines, - color = '#3b82f6', - activeColor = '#22c55e', + color, + activeColor, underlineOnHover = true, isActive = false, onActivate, @@ -31,6 +33,11 @@ export const TerminalLink: React.FC = ({ lineWrap = false, inline = false, }) => { + const theme = useTheme() + + // Use theme colors as defaults if not provided + const linkColor = color ?? theme.info + const linkActiveColor = activeColor ?? theme.success const [isHovered, setIsHovered] = useState(false) const displayLines = useMemo(() => { @@ -41,7 +48,7 @@ export const TerminalLink: React.FC = ({ return formatted.filter((line) => line.trim().length > 0) }, [formatLines, maxWidth, text]) - const displayColor = isActive ? activeColor : color + const displayColor = isActive ? linkActiveColor : linkColor const shouldUnderline = underlineOnHover && isHovered const handleActivate = useCallback(() => { @@ -71,7 +78,7 @@ export const TerminalLink: React.FC = ({ {displayLines.map((line: string, index: number) => { const coloredText = {line} return ( - + {shouldUnderline ? {coloredText} : coloredText} ) diff --git a/cli/src/components/tool-call-item.tsx b/cli/src/components/tool-call-item.tsx new file mode 100644 index 000000000..3db81092e --- /dev/null +++ b/cli/src/components/tool-call-item.tsx @@ -0,0 +1,229 @@ +import { TextAttributes } from '@opentui/core' +import React, { type ReactNode } from 'react' + +import { useTheme } from '../hooks/use-theme' +import type { ChatTheme } from '../types/theme-system' + +interface ToolCallItemProps { + name: string + content: ReactNode + isCollapsed: boolean + isStreaming: boolean + branchChar: string + streamingPreview: string + finishedPreview: string + onToggle?: () => void + titleSuffix?: string +} + +const isTextRenderable = (value: ReactNode): boolean => { + if (value === null || value === undefined || typeof value === 'boolean') { + return false + } + + if (typeof value === 'string' || typeof value === 'number') { + return true + } + + if (Array.isArray(value)) { + return value.every((child) => isTextRenderable(child)) + } + + if (React.isValidElement(value)) { + if (value.type === React.Fragment) { + return isTextRenderable(value.props.children) + } + + if (typeof value.type === 'string') { + if ( + value.type === 'span' || + value.type === 'strong' || + value.type === 'em' + ) { + return isTextRenderable(value.props.children) + } + + return false + } + } + + return false +} + +const renderExpandedContent = ( + value: ReactNode, + theme: ChatTheme, + getAttributes: (extra?: number) => number | undefined, +): ReactNode => { + if ( + value === null || + value === undefined || + value === false || + value === true + ) { + return null + } + + if (isTextRenderable(value)) { + return ( + + {value} + + ) + } + + if (React.isValidElement(value)) { + if (value.key === null || value.key === undefined) { + return ( + + {value} + + ) + } + return value + } + + if (Array.isArray(value)) { + return ( + + {value.map((child, idx) => ( + + {child} + + ))} + + ) + } + + return ( + + {value} + + ) +} + +export const ToolCallItem = ({ + name, + content, + isCollapsed, + isStreaming, + branchChar, + streamingPreview, + finishedPreview, + onToggle, + titleSuffix, +}: ToolCallItemProps) => { + const theme = useTheme() + + const baseTextAttributes = theme.messageTextAttributes ?? 0 + const getAttributes = (extra: number = 0): number | undefined => { + const combined = baseTextAttributes | extra + return combined === 0 ? undefined : combined + } + + const isExpanded = !isCollapsed + const toggleIndicator = onToggle ? (isCollapsed ? '▸ ' : '▾ ') : '' + const toggleLabel = `${branchChar}${toggleIndicator}` + const collapsedPreviewText = isStreaming ? streamingPreview : finishedPreview + const showCollapsedPreview = collapsedPreviewText.length > 0 + + return ( + + + + + + {toggleLabel} + + + {name} + + {titleSuffix ? ( + + {` ${titleSuffix}`} + + ) : null} + {isStreaming ? ( + + {' running'} + + ) : null} + + + + {isCollapsed ? ( + showCollapsedPreview ? ( + + + {collapsedPreviewText} + + + ) : null + ) : ( + + {renderExpandedContent(content, theme, getAttributes)} + + )} + + + ) +} diff --git a/cli/src/components/tool-item.tsx b/cli/src/components/tool-item.tsx new file mode 100644 index 000000000..ccd403f44 --- /dev/null +++ b/cli/src/components/tool-item.tsx @@ -0,0 +1,210 @@ +import { TextAttributes } from '@opentui/core' +import React, { type ReactNode } from 'react' + +import { useTheme } from '../hooks/use-theme' +import type { ChatTheme } from '../types/theme-system' + +export interface ToolBranchMeta { + hasPrevious: boolean + hasNext: boolean +} + +interface ToolItemProps { + name: string + titleAccessory?: ReactNode + content: ReactNode + isCollapsed: boolean + isStreaming: boolean + streamingPreview: string + finishedPreview: string + branchMeta: ToolBranchMeta + onToggle: () => void + titleColor?: string +} + +const renderContent = (value: ReactNode, theme: ChatTheme): ReactNode => { + const contentFg = theme.foreground + const contentAttributes = + theme.messageTextAttributes !== undefined && theme.messageTextAttributes !== 0 + ? theme.messageTextAttributes + : undefined + + if ( + value === null || + value === undefined || + value === false || + value === true + ) { + return null + } + + if (typeof value === 'string' || typeof value === 'number') { + return ( + + {value} + + ) + } + + if (Array.isArray(value)) { + return ( + + {value.map((child, index) => ( + + {renderContent(child, theme)} + + ))} + + ) + } + + if (React.isValidElement(value)) { + return value + } + + return ( + + {value as any} + + ) +} + +export const ToolItem = ({ + name, + titleAccessory, + content, + isCollapsed, + isStreaming, + streamingPreview, + finishedPreview, + branchMeta, + onToggle, + titleColor: customTitleColor, +}: ToolItemProps) => { + const theme = useTheme() + + const branchColor = theme.muted + const branchAttributes = TextAttributes.DIM + const titleColor = customTitleColor ?? theme.secondary + const previewColor = isStreaming ? theme.foreground : theme.muted + const baseTextAttributes = theme.messageTextAttributes ?? 0 + const connectorSymbol = branchMeta.hasNext ? '├' : '└' + const continuationPrefix = branchMeta.hasNext ? '│ ' : ' ' + const showBranchAbove = branchMeta.hasPrevious + const hasTitleAccessory = + titleAccessory !== undefined && titleAccessory !== null + + const renderBranchSpacer = () => { + if (!showBranchAbove) { + return null + } + + return ( + + + + │ + + + + ) + } + + const renderConnectedSection = (node: ReactNode) => { + if (!node) { + return null + } + + return ( + + + + {continuationPrefix} + + + + {node} + + + ) + } + + const renderedContent = renderContent(content, theme) + const previewText = isStreaming ? streamingPreview : finishedPreview + const hasPreview = + typeof previewText === 'string' ? previewText.length > 0 : false + const previewNode = hasPreview ? ( + { + const combined = baseTextAttributes | TextAttributes.ITALIC + return combined === 0 ? undefined : combined + })()} + > + {previewText} + + ) : null + + return ( + + {renderBranchSpacer()} + + + + {`${connectorSymbol} `} + + + {name} + + {hasTitleAccessory && titleAccessory ? titleAccessory : null} + + + {isCollapsed ? renderConnectedSection(previewNode) : null} + {!isCollapsed ? renderConnectedSection(renderedContent) : null} + + ) +} diff --git a/cli/src/components/tool-renderer.tsx b/cli/src/components/tool-renderer.tsx new file mode 100644 index 000000000..5251c679f --- /dev/null +++ b/cli/src/components/tool-renderer.tsx @@ -0,0 +1,195 @@ +import { TextAttributes } from '@opentui/core' +import React from 'react' +import stringWidth from 'string-width' + +import type { ContentBlock } from '../types/chat' +import type { ChatTheme } from '../types/theme-system' + +type ToolBlock = Extract + +export type ToolRenderConfig = { + path?: string + content?: React.ReactNode + collapsedPreview?: string +} + +export type ToolRenderOptions = { + availableWidth: number + indentationOffset: number + previewPrefix?: string + labelWidth: number +} + +const isRecord = (value: unknown): value is Record => { + return typeof value === 'object' && value !== null +} + +const extractPath = (toolBlock: ToolBlock, resultValue: unknown): string | null => { + if (isRecord(toolBlock.input) && typeof toolBlock.input.path === 'string') { + const trimmed = toolBlock.input.path.trim() + if (trimmed.length > 0) { + return trimmed + } + } + + if (isRecord(resultValue) && typeof resultValue.path === 'string') { + const trimmed = resultValue.path.trim() + if (trimmed.length > 0) { + return trimmed + } + } + + return null +} + +const summarizeFiles = ( + entries: unknown, + maxItems: number, + options: ToolRenderOptions, +): string | null => { + const previewPrefix = options.previewPrefix ?? '' + const previewPrefixWidth = stringWidth(previewPrefix) + const alignmentPadding = Math.max( + 0, + options.labelWidth - previewPrefixWidth, + ) + const totalPrefixWidth = previewPrefixWidth + alignmentPadding + const maxWidth = Math.max( + 20, + options.availableWidth - options.indentationOffset - totalPrefixWidth - 6, + ) + + if (!Array.isArray(entries) || entries.length === 0) { + return null + } + + const validNames = entries + .filter((entry): entry is string => typeof entry === 'string') + .map((entry) => entry.trim()) + .filter((entry) => entry.length > 0) + + if (validNames.length === 0) { + return null + } + + const summaryNames: string[] = [] + let widthUsed = 0 + + for (let index = 0; index < validNames.length; index += 1) { + if (summaryNames.length >= maxItems) { + break + } + + const name = validNames[index] + const prefix = summaryNames.length === 0 ? '' : ', ' + const candidate = `${prefix}${name}` + const candidateWidth = stringWidth(candidate) + const wouldExceedWidth = widthUsed + candidateWidth > maxWidth + + if (summaryNames.length > 0 && wouldExceedWidth) { + break + } + + summaryNames.push(name) + widthUsed += candidateWidth + + if (summaryNames.length === 1 && wouldExceedWidth) { + break + } + } + + if (summaryNames.length === 0) { + summaryNames.push(validNames[0]) + } + + const hasMore = summaryNames.length < validNames.length + const summary = summaryNames.join(', ') + return hasMore ? `${summary}, ...` : summary +} + +const getListDirectoryRender = ( + toolBlock: ToolBlock, + theme: ChatTheme, + options: ToolRenderOptions, +): ToolRenderConfig => { + const MAX_ITEMS = 3 + const resultValue = Array.isArray(toolBlock.outputRaw) + ? (toolBlock.outputRaw[0] as any)?.value + : undefined + + if (!isRecord(resultValue)) { + return {} + } + + const filesLine = summarizeFiles(resultValue.files, MAX_ITEMS, options) + const fallbackLine = filesLine + ? null + : summarizeFiles(resultValue.directories, MAX_ITEMS, options) + const path = extractPath(toolBlock, resultValue) + + const summaryLine = filesLine ?? fallbackLine + + if (!summaryLine && !path) { + return {} + } + + const summaryColor = theme.foreground + const baseAttributes = theme.messageTextAttributes ?? 0 + const getAttributes = (extra: number = 0): number | undefined => { + const combined = baseAttributes | extra + return combined === 0 ? undefined : combined + } + + const previewPrefix = options.previewPrefix ?? '' + const previewPrefixWidth = stringWidth(previewPrefix) + const alignmentPadding = Math.max( + 0, + options.labelWidth - previewPrefixWidth, + ) + const alignmentSpaces = ' '.repeat(alignmentPadding) + const paddedPrefix = `${previewPrefix}${alignmentSpaces}` + const blankPrefix = + previewPrefix.replace(/\s+$/, '') || previewPrefix + const content = + summaryLine !== null ? ( + + + {`${paddedPrefix}${summaryLine}`} + + {previewPrefix ? ( + + {blankPrefix} + + ) : null} + + ) : null + + const collapsedPreview = summaryLine ?? undefined + + return { + path: path ?? undefined, + content, + collapsedPreview, + } +} + +export const getToolRenderConfig = ( + toolBlock: ToolBlock, + theme: ChatTheme, + options: ToolRenderOptions, +): ToolRenderConfig => { + switch (toolBlock.toolName) { + case 'list_directory': + return getListDirectoryRender(toolBlock, theme, options) + default: + return {} + } +} diff --git a/cli/src/hooks/use-logo.tsx b/cli/src/hooks/use-logo.tsx index f8487ef31..4069b6c7a 100644 --- a/cli/src/hooks/use-logo.tsx +++ b/cli/src/hooks/use-logo.tsx @@ -74,7 +74,7 @@ export const useLogo = ({ const displayText = availableWidth < 30 ? 'Codebuff' : 'Codebuff CLI' return ( - + {textColor ? ( {displayText} @@ -93,7 +93,7 @@ export const useLogo = ({ return ( <> {displayLines.map((line, lineIndex) => ( - + {applySheenToChar ? line .split('') diff --git a/cli/src/hooks/use-message-renderer.tsx b/cli/src/hooks/use-message-renderer.tsx index d32f1c8ed..02f568dad 100644 --- a/cli/src/hooks/use-message-renderer.tsx +++ b/cli/src/hooks/use-message-renderer.tsx @@ -88,8 +88,8 @@ export const useMessageRenderer = ( const agentCodeBlockWidth = Math.max(10, availableWidth - 12) const agentPalette: MarkdownPalette = { ...markdownPalette, - inlineCodeFg: theme.agentText, - codeTextFg: theme.agentText, + inlineCodeFg: theme.foreground, + codeTextFg: theme.foreground, } const agentMarkdownOptions = { codeBlockWidth: agentCodeBlockWidth, @@ -160,8 +160,8 @@ export const useMessageRenderer = ( flexShrink: 0, }} > - - {fullPrefix} + + {fullPrefix} - - + + {isCollapsed ? '▸ ' : '▾ '} {agentInfo.agentName} @@ -201,8 +201,7 @@ export const useMessageRenderer = ( > {isStreaming && isCollapsed && streamingPreview && ( {streamingPreview} @@ -210,8 +209,7 @@ export const useMessageRenderer = ( )} {!isStreaming && isCollapsed && finishedPreview && ( {finishedPreview} @@ -220,8 +218,7 @@ export const useMessageRenderer = ( {!isCollapsed && ( {displayContent} @@ -276,15 +273,15 @@ export const useMessageRenderer = ( const isError = message.variant === 'error' const lineColor = isError ? 'red' : isAi ? theme.aiLine : theme.userLine const textColor = isError - ? theme.messageAiText + ? theme.foreground : isAi - ? theme.messageAiText - : theme.messageUserText + ? theme.foreground + : theme.foreground const timestampColor = isError ? 'red' : isAi - ? theme.timestampAi - : theme.timestampUser + ? theme.muted + : theme.muted const estimatedMessageWidth = availableWidth const codeBlockWidth = Math.max(10, estimatedMessageWidth - 8) const paletteForMessage: MarkdownPalette = { @@ -340,7 +337,7 @@ export const useMessageRenderer = ( /> { - const [themeName, setThemeName] = useState(() => - detectSystemTheme(), - ) - const lastThemeRef = useRef(themeName) - const listenerRef = useRef(null) - - useEffect(() => { - logger.info({ themeName }, `[theme] initial theme ${themeName}`) - - const handleThemeChange = () => { - const currentTheme = detectSystemTheme() - - if (currentTheme !== lastThemeRef.current) { - } else { - } - - // Only update state if theme actually changed - if (currentTheme !== lastThemeRef.current) { - lastThemeRef.current = currentTheme - setThemeName(currentTheme) - } - } - - // Try to use macOS listener first (instant, event-driven) - if (process.platform === 'darwin') { - const listener = spawnMacOSThemeListener(handleThemeChange) - if (listener) { - listenerRef.current = listener - // Successfully spawned listener, no need for polling - return () => { - listenerRef.current?.kill() - listenerRef.current = null - } - } - } - - // Fall back to polling for non-macOS or if listener failed - const intervalId = setInterval(handleThemeChange, DEFAULT_POLL_INTERVAL_MS) - - return () => { - clearInterval(intervalId) - } - }, []) - - return themeName -} diff --git a/cli/src/hooks/use-theme.tsx b/cli/src/hooks/use-theme.tsx new file mode 100644 index 000000000..831b221a2 --- /dev/null +++ b/cli/src/hooks/use-theme.tsx @@ -0,0 +1,33 @@ +/** + * Theme Hooks + * + * Simple hooks for accessing theme from zustand store + */ + +import { useThemeStore } from '../state/theme-store' +import type { ChatTheme } from '../types/theme-system' + +/** + * Hook to access theme for the current component + * + * @returns Theme object + * + * @example + * const theme = useTheme() + * + */ +export const useTheme = (): ChatTheme => { + return useThemeStore((state) => state.theme) +} + +/** + * Hook to access the resolved theme name (dark or light) + * @returns 'dark' or 'light' based on auto-detection + * + * @example + * const themeName = useResolvedThemeName() + * // Use if you need conditional logic based on light/dark mode + */ +export const useResolvedThemeName = (): 'dark' | 'light' => { + return useThemeStore((state) => state.themeName) +} diff --git a/cli/src/index.tsx b/cli/src/index.tsx index 5f67d4fa2..898638083 100644 --- a/cli/src/index.tsx +++ b/cli/src/index.tsx @@ -11,6 +11,7 @@ import React from 'react' import { validateAgents } from '@codebuff/sdk' import { App } from './chat' +import './state/theme-store' // Initialize theme store and watchers import { getUserCredentials } from './utils/auth' import { getLoadedAgentsData } from './utils/local-agent-registry' import { clearLogFile } from './utils/logger' @@ -150,6 +151,9 @@ function startApp() { , + { + backgroundColor: 'transparent', + }, ) } diff --git a/cli/src/login/constants.ts b/cli/src/login/constants.ts index 4e0115b57..f60b6bc2b 100644 --- a/cli/src/login/constants.ts +++ b/cli/src/login/constants.ts @@ -21,12 +21,6 @@ export const LOGO_SMALL = ` ╚██████╗ ██████╔╝ ╚═════╝ ╚═════╝ ` -// UI Color constants -export const LINK_COLOR_DEFAULT = '#3b82f6' -export const LINK_COLOR_CLICKED = '#1e40af' -export const COPY_SUCCESS_COLOR = '#22c55e' -export const COPY_ERROR_COLOR = '#ef4444' -export const WARNING_COLOR = '#ef4444' // Shadow/border characters that receive the sheen animation effect export const SHADOW_CHARS = new Set([ diff --git a/cli/src/login/utils.ts b/cli/src/login/utils.ts index 78f1ad307..efbaf6c20 100644 --- a/cli/src/login/utils.ts +++ b/cli/src/login/utils.ts @@ -9,11 +9,14 @@ export function isLightModeColor(hexColor: string): boolean { if (!hexColor) return false const hex = hexColor.replace('#', '') + if (hex.length < 6) { + return false + } + const r = parseInt(hex.substring(0, 2), 16) const g = parseInt(hex.substring(2, 4), 16) const b = parseInt(hex.substring(4, 6), 16) - // Calculate relative luminance const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255 return luminance > 0.5 } diff --git a/cli/src/state/theme-store.ts b/cli/src/state/theme-store.ts new file mode 100644 index 000000000..cb36c7534 --- /dev/null +++ b/cli/src/state/theme-store.ts @@ -0,0 +1,50 @@ +import { create } from 'zustand' + +import { chatThemes, cloneChatTheme, detectSystemTheme, initializeThemeWatcher } from '../utils/theme-system' +import type { ChatTheme, ThemeName } from '../types/theme-system' +import { themeConfig, buildTheme } from '../utils/theme-config' + +export type ThemeStoreState = { + /** Current theme name (dark or light) */ + themeName: ThemeName + /** Built theme with customizations applied */ + theme: ChatTheme +} + +type ThemeStoreActions = { + /** Update theme to a specific mode (dark or light) */ + setThemeName: (name: ThemeName) => void +} + +type ThemeStore = ThemeStoreState & ThemeStoreActions + +// Build initial theme +const initialThemeName = detectSystemTheme() +const initialTheme = buildTheme( + cloneChatTheme(chatThemes[initialThemeName]), + initialThemeName, + themeConfig.customColors, + themeConfig.plugins, +) + +export const useThemeStore = create((set) => ({ + themeName: initialThemeName, + theme: initialTheme, + + setThemeName: (name: ThemeName) => { + const baseTheme = cloneChatTheme(chatThemes[name]) + const theme = buildTheme( + baseTheme, + name, + themeConfig.customColors, + themeConfig.plugins, + ) + set({ themeName: name, theme }) + }, +})) + +// Initialize theme watcher to enable reactive updates from system theme changes +initializeThemeWatcher((name: ThemeName) => { + // Always call setThemeName - it will handle building and updating the theme + useThemeStore.getState().setThemeName(name) +}) diff --git a/cli/src/types/chat.ts b/cli/src/types/chat.ts index e92557164..d92021a6f 100644 --- a/cli/src/types/chat.ts +++ b/cli/src/types/chat.ts @@ -8,8 +8,10 @@ export type ContentBlock = | { type: 'text' content: string + color?: string marginTop?: number marginBottom?: number + status?: 'running' | 'complete' } | { type: 'html' @@ -23,6 +25,7 @@ export type ContentBlock = toolName: ToolName input: any output?: string + outputRaw?: unknown agentId?: string } | { diff --git a/cli/src/types/theme-system.ts b/cli/src/types/theme-system.ts index 14a6f3d4d..07acfaeb7 100644 --- a/cli/src/types/theme-system.ts +++ b/cli/src/types/theme-system.ts @@ -2,6 +2,9 @@ export type ThemeName = 'dark' | 'light' export type MarkdownHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6 +// ThemeColor is always a resolved color string (never 'default' or undefined) +export type ThemeColor = string + export interface MarkdownThemeOverrides { codeBackground?: string codeHeaderFg?: string @@ -15,38 +18,119 @@ export interface MarkdownThemeOverrides { codeMonochrome?: boolean } +/** + * Semantic Color Theme Interface + * Inspired by Tailwind - uses semantic color roles instead of specific names + * This makes theming easier and more intuitive + */ export interface ChatTheme { + // ============================================================================ + // CORE SEMANTIC COLORS + // ============================================================================ + + /** Primary brand color - main actions, highlights, important elements */ + primary: string + + /** Secondary brand color - supporting elements, less emphasis */ + secondary: string + + /** Success color - checkmarks, completed states, positive feedback */ + success: string + + /** Error/danger color - errors, destructive actions, failures */ + error: string + + /** Warning color - cautions, alerts, validation issues */ + warning: string + + /** Info color - informational elements, links, hints */ + info: string + + // ============================================================================ + // NEUTRAL SCALE + // ============================================================================ + + /** Default text color */ + foreground: ThemeColor + + /** Base background color */ background: string - chromeBg: string - chromeText: string - accentBg: string - accentText: string - panelBg: string + + /** Subdued/secondary text color */ + muted: ThemeColor + + /** Border and divider color */ + border: string + + /** Surface color for panels, cards, chrome */ + surface: string + + /** Hover state for interactive surfaces */ + surfaceHover: string + + // ============================================================================ + // CONTEXT-SPECIFIC COLORS (Minimal - most use semantic colors) + // ============================================================================ + + // AI/User differentiation + /** AI message indicator line color */ aiLine: string + + /** User message indicator line color */ userLine: string - timestampAi: string - timestampUser: string - messageAiText: string - messageUserText: string - messageBg: string - statusAccent: string - statusSecondary: string - inputBg: string - inputFg: string - inputFocusedBg: string - inputFocusedFg: string - inputPlaceholder: string - cursor: string - agentPrefix: string - agentName: string - agentText: string - agentCheckmark: string - agentResponseCount: string - agentFocusedBg: string - agentContentText: string + + // Agent backgrounds (specific states that don't map to semantics) + /** Agent toggle header background */ agentToggleHeaderBg: string - agentToggleHeaderText: string - agentToggleText: string + + /** Agent toggle expanded background */ + agentToggleExpandedBg: string + + /** Agent focused background */ + agentFocusedBg: string + + /** Agent content background */ agentContentBg: string + + // Input specific + /** Input background */ + inputBg: string + + /** Input text color */ + inputFg: ThemeColor + + /** Focused input background */ + inputFocusedBg: string + + /** Focused input text color */ + inputFocusedFg: ThemeColor + + // Mode toggles (distinct UI elements) + /** Fast mode toggle background */ + modeFastBg: string + + /** Fast mode toggle text */ + modeFastText: string + + /** Max mode toggle background */ + modeMaxBg: string + + /** Max mode toggle text */ + modeMaxText: string + + /** Plan mode toggle background */ + modePlanBg: string + + /** Plan mode toggle text */ + modePlanText: string + + // ============================================================================ + // MARKDOWN + // ============================================================================ + + /** Markdown-specific styling */ markdown?: MarkdownThemeOverrides + + /** Text attributes (bold, dim, etc.) */ + messageTextAttributes?: number } diff --git a/cli/src/utils/codebuff-client.ts b/cli/src/utils/codebuff-client.ts index 2b615bf55..5e0bb1b57 100644 --- a/cli/src/utils/codebuff-client.ts +++ b/cli/src/utils/codebuff-client.ts @@ -41,12 +41,16 @@ export function getToolDisplayInfo(toolName: string): { name: string type: string } { + const TOOL_NAME_OVERRIDES: Record = { + list_directory: 'List Directories', + } + const capitalizeWords = (str: string) => { return str.replace(/_/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase()) } return { - name: capitalizeWords(toolName), + name: TOOL_NAME_OVERRIDES[toolName] ?? capitalizeWords(toolName), type: 'tool', } } diff --git a/cli/src/utils/create-validation-error-blocks.tsx b/cli/src/utils/create-validation-error-blocks.tsx index d22ca68ae..bee6cb75a 100644 --- a/cli/src/utils/create-validation-error-blocks.tsx +++ b/cli/src/utils/create-validation-error-blocks.tsx @@ -64,7 +64,7 @@ export function createValidationErrorBlocks( type: 'html', render: ({ textColor }) => ( - + {agentId} in{' '} ) => void setInputFocused: (focused: boolean) => void setInputValue: (value: string | ((prev: string) => string)) => void - setIsAuthenticated: (value: React.SetStateAction) => void + setIsAuthenticated: (value: React.SetStateAction) => void setMessages: ( value: ChatMessage[] | ((prev: ChatMessage[]) => ChatMessage[]), ) => void diff --git a/cli/src/utils/syntax-highlighter.tsx b/cli/src/utils/syntax-highlighter.tsx index 6f77326ba..07fd0f1dd 100644 --- a/cli/src/utils/syntax-highlighter.tsx +++ b/cli/src/utils/syntax-highlighter.tsx @@ -9,16 +9,11 @@ interface HighlightOptions { export function highlightCode( code: string, lang: string, - bg: string, options: HighlightOptions = {}, ): ReactNode { - const { fg = 'brightWhite' } = options + const { fg = '#d1d5db' } = options // For now, just return the code with basic styling // Can be enhanced later with actual syntax highlighting - return ( - - {code} - - ) + return {code} } diff --git a/cli/src/utils/theme-config.ts b/cli/src/utils/theme-config.ts new file mode 100644 index 000000000..e20179fe1 --- /dev/null +++ b/cli/src/utils/theme-config.ts @@ -0,0 +1,140 @@ +/** + * Theme Configuration System + * + * Provides plugin system and customization support for themes + */ + +import type { ChatTheme } from '../types/theme-system' + +/** + * Plugin interface for extending theme system + * Plugins can modify themes at runtime + */ +export interface ThemePlugin { + /** Unique plugin name */ + name: string + /** + * Apply plugin modifications to a theme + * @param theme - The base theme + * @param mode - The detected light/dark mode + * @returns Partial theme to merge + */ + apply: ( + theme: ChatTheme, + mode: 'dark' | 'light', + ) => Partial +} + +/** + * Main theme configuration interface + */ +export interface ThemeConfig { + /** Global color overrides applied to themes */ + customColors?: Partial + /** Registered plugins for theme extensions */ + plugins?: ThemePlugin[] +} + +/** + * Default theme configuration + */ +export const defaultThemeConfig: ThemeConfig = { + customColors: {}, + plugins: [], +} + +/** + * Active theme configuration + * Can be modified at runtime for customization + */ +export let themeConfig: ThemeConfig = defaultThemeConfig + +/** + * Update the active theme configuration + * @param config - New configuration (will be merged with defaults) + */ +export const setThemeConfig = (config: Partial): void => { + themeConfig = { + ...defaultThemeConfig, + ...config, + plugins: [...(defaultThemeConfig.plugins ?? []), ...(config.plugins ?? [])], + } +} + +/** + * Register a theme plugin + * @param plugin - Plugin to register + */ +export const registerThemePlugin = (plugin: ThemePlugin): void => { + if (!themeConfig.plugins) { + themeConfig.plugins = [] + } + // Check if plugin already registered + if (themeConfig.plugins.some((p) => p.name === plugin.name)) { + console.warn(`Theme plugin "${plugin.name}" is already registered`) + return + } + themeConfig.plugins.push(plugin) +} + +/** + * Resolve 'default' color values to fallback colors + * Components should never see 'default' - it's resolved during theme building + */ +const resolveThemeColors = (theme: ChatTheme, mode: 'dark' | 'light'): void => { + const defaultFallback = mode === 'dark' ? '#ffffff' : '#000000' + + const resolve = (value: string, fallback: string = defaultFallback): string => { + if (typeof value === 'string') { + const normalized = value.trim().toLowerCase() + if (normalized === 'default' || normalized.length === 0) { + return fallback + } + return value + } + return fallback + } + + // Resolve all ThemeColor properties to actual colors + theme.foreground = resolve(theme.foreground) + theme.muted = resolve(theme.muted) + theme.inputFg = resolve(theme.inputFg) + theme.inputFocusedFg = resolve(theme.inputFocusedFg) +} + +/** + * Build a complete theme by applying custom colors and plugins + * All 'default' color values are resolved to actual colors + * @param baseTheme - The base theme to start from + * @param mode - Current theme mode (dark or light) + * @param customColors - Optional custom color overrides + * @param plugins - Optional theme plugins to apply + * @returns Complete theme with all customizations applied + */ +export const buildTheme = ( + baseTheme: ChatTheme, + mode: 'dark' | 'light', + customColors?: Partial, + plugins?: ThemePlugin[], +): ChatTheme => { + // Start with cloned base theme (cloning handled by caller) + const theme = { ...baseTheme } + + // Layer 1: Apply global custom colors + if (customColors) { + Object.assign(theme, customColors) + } + + // Layer 2: Apply plugins + if (plugins) { + for (const plugin of plugins) { + const pluginOverrides = plugin.apply(theme, mode) + Object.assign(theme, pluginOverrides) + } + } + + // Final step: Resolve all 'default' values to actual colors + resolveThemeColors(theme, mode) + + return theme +} diff --git a/cli/src/utils/theme-listener-macos.ts b/cli/src/utils/theme-listener-macos.ts deleted file mode 100644 index a370d18d9..000000000 --- a/cli/src/utils/theme-listener-macos.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { existsSync, watch, type FSWatcher } from 'fs' - -import { getIDEThemeConfigPaths } from './theme-system' - -/** - * macOS theme change listener using polling - * Checks the system theme preference every 0.5 seconds - */ - -// Shell script that polls for theme changes -const WATCH_SCRIPT = ` -# Initial value -LAST_VALUE="" - -while true; do - # Check if AppleInterfaceStyle key exists (Dark mode) - CURRENT_VALUE=$(defaults read -g AppleInterfaceStyle 2>/dev/null || echo "Light") - - # If changed, output notification - if [ "$LAST_VALUE" != "" ] && [ "$CURRENT_VALUE" != "$LAST_VALUE" ]; then - echo "THEME_CHANGED" - fi - - LAST_VALUE="$CURRENT_VALUE" - - # Wait a bit before checking again (very lightweight) - sleep 0.5 -done -` - -const IDE_THEME_DEBOUNCE_MS = 200 - -interface IDEWatcherHandle { - watchers: FSWatcher[] - dispose: () => void -} - -const createIDEThemeWatchers = ( - onThemeChange: () => void, -): IDEWatcherHandle => { - const watchers: FSWatcher[] = [] - const targets = new Set(getIDEThemeConfigPaths()) - - if (targets.size === 0) { - return { - watchers, - dispose: () => {}, - } - } - - let debounceTimer: ReturnType | null = null - const scheduleNotify = () => { - if (debounceTimer) { - clearTimeout(debounceTimer) - } - - debounceTimer = setTimeout(() => { - debounceTimer = null - onThemeChange() - }, IDE_THEME_DEBOUNCE_MS) - } - - for (const path of targets) { - try { - if (!existsSync(path)) { - continue - } - - const watcher = watch(path, { persistent: false }, () => { - scheduleNotify() - }) - - watchers.push(watcher) - } catch { - // Ignore watcher failures (e.g., permissions) - } - } - - return { - watchers, - dispose: () => { - if (debounceTimer) { - clearTimeout(debounceTimer) - debounceTimer = null - } - }, - } -} - -export interface ThemeListenerProcess { - kill: () => void -} - -/** - * Spawns a shell script that watches for macOS theme changes - * @param onThemeChange - Callback invoked when theme changes - * @returns Process handle to clean up later - */ -export const spawnMacOSThemeListener = ( - onThemeChange: () => void, -): ThemeListenerProcess | null => { - if (typeof Bun === 'undefined') { - return null - } - - if (process.platform !== 'darwin') { - return null - } - - const bash = Bun.which('bash') - if (!bash) { - return null - } - - try { - const proc = Bun.spawn({ - cmd: [bash, '-c', WATCH_SCRIPT], - stdout: 'pipe', - stderr: 'pipe', - }) - - const watcherHandle = createIDEThemeWatchers(onThemeChange) - - // Read stderr to prevent blocking - const readStderr = async () => { - const reader = proc.stderr.getReader() - try { - while (true) { - const { done } = await reader.read() - if (done) break - } - } catch { - // Process was killed or errored, ignore - } - } - - readStderr() - - // Read stdout line by line - const readStdout = async () => { - const reader = proc.stdout.getReader() - const decoder = new TextDecoder() - let buffer = '' - - try { - while (true) { - const { done, value } = await reader.read() - if (done) break - - buffer += decoder.decode(value, { stream: true }) - const lines = buffer.split('\n') - buffer = lines.pop() || '' - - for (const line of lines) { - if (line.trim() === 'THEME_CHANGED') { - onThemeChange() - } - } - } - } catch { - // Process was killed or errored, ignore - } - } - - readStdout() - - return { - kill: () => { - try { - proc.kill() - } catch { - // Ignore errors when killing - } - - for (const watcher of watcherHandle.watchers) { - try { - watcher.close() - } catch { - // Ignore watcher closure errors - } - } - - watcherHandle.dispose() - }, - } - } catch { - return null - } -} diff --git a/cli/src/utils/theme-system.ts b/cli/src/utils/theme-system.ts index 7c7c812b5..c9a7b99e3 100644 --- a/cli/src/utils/theme-system.ts +++ b/cli/src/utils/theme-system.ts @@ -1,9 +1,17 @@ -import { existsSync, readFileSync, readdirSync, statSync } from 'fs' +import { existsSync, readFileSync, readdirSync, statSync, watch } from 'fs' import { homedir } from 'os' -import { join } from 'path' -import {ChatTheme, MarkdownHeadingLevel, MarkdownThemeOverrides, ThemeName} from "../types/theme-system" +import { dirname, join } from 'path' import type { MarkdownPalette } from './markdown-renderer' +import type { + ChatTheme, + MarkdownHeadingLevel, + MarkdownThemeOverrides, + ThemeName, +} from '../types/theme-system' + +// Re-export types for backward compatibility +export type { ChatTheme, ThemeColor } from '../types/theme-system' const IDE_THEME_INFERENCE = { dark: [ @@ -454,10 +462,6 @@ export const getIDEThemeConfigPaths = (): string[] => { return [...paths] } - - - - type ChatThemeOverrides = Partial> & { markdown?: MarkdownThemeOverrides } @@ -680,38 +684,47 @@ export const detectSystemTheme = (): ThemeName => { const DEFAULT_CHAT_THEMES: Record = { dark: { + // Core semantic colors + primary: '#facc15', + secondary: '#a3aed0', + success: '#22c55e', + error: '#ef4444', + warning: '#FFA500', + info: '#38bdf8', + + // Neutral scale + foreground: '#f1f5f9', background: '#000000', - chromeBg: '#000000', - chromeText: '#9ca3af', - accentBg: '#facc15', - accentText: '#1c1917', - panelBg: '#000000', + muted: '#9ca3af', + border: '#334155', + surface: '#000000', + surfaceHover: '#334155', + + // Context-specific aiLine: '#34d399', userLine: '#38bdf8', - timestampAi: '#4ade80', - timestampUser: '#60a5fa', - messageAiText: '#f1f5f9', - messageUserText: '#dbeafe', - messageBg: '#000000', - statusAccent: '#facc15', - statusSecondary: '#a3aed0', + + // Agent backgrounds + agentToggleHeaderBg: '#f97316', + agentToggleExpandedBg: '#1d4ed8', + agentFocusedBg: '#334155', + agentContentBg: '#000000', + + // Input inputBg: '#000000', inputFg: '#f5f5f5', inputFocusedBg: '#000000', inputFocusedFg: '#ffffff', - inputPlaceholder: '#a3a3a3', - cursor: '#22c55e', - agentPrefix: '#22c55e', - agentName: '#4ade80', - agentText: '#d1d5db', - agentCheckmark: '#22c55e', - agentResponseCount: '#9ca3af', - agentFocusedBg: '#334155', - agentContentText: '#ffffff', - agentToggleHeaderBg: '#f97316', - agentToggleHeaderText: '#ffffff', - agentToggleText: '#ffffff', - agentContentBg: '#000000', + + // Mode toggles + modeFastBg: '#f97316', + modeFastText: '#f97316', + modeMaxBg: '#dc2626', + modeMaxText: '#dc2626', + modePlanBg: '#1e40af', + modePlanText: '#1e40af', + + // Markdown markdown: { codeBackground: '#1f2933', codeHeaderFg: '#5b647a', @@ -733,38 +746,47 @@ const DEFAULT_CHAT_THEMES: Record = { }, }, light: { + // Core semantic colors + primary: '#f59e0b', + secondary: '#6b7280', + success: '#059669', + error: '#ef4444', + warning: '#F59E0B', + info: '#3b82f6', + + // Neutral scale + foreground: '#111827', background: '#ffffff', - chromeBg: '#f3f4f6', - chromeText: '#374151', - accentBg: '#f59e0b', - accentText: '#111827', - panelBg: '#ffffff', + muted: '#6b7280', + border: '#d1d5db', + surface: '#f3f4f6', + surfaceHover: '#e5e7eb', + + // AI/User context aiLine: '#059669', userLine: '#3b82f6', - timestampAi: '#047857', - timestampUser: '#2563eb', - messageAiText: '#111827', - messageUserText: '#1f2937', - messageBg: '#ffffff', - statusAccent: '#f59e0b', - statusSecondary: '#6b7280', + + // Agent context + agentToggleHeaderBg: '#ea580c', + agentToggleExpandedBg: '#1d4ed8', + agentFocusedBg: '#f3f4f6', + agentContentBg: '#ffffff', + + // Input inputBg: '#f9fafb', inputFg: '#111827', inputFocusedBg: '#ffffff', inputFocusedFg: '#000000', - inputPlaceholder: '#9ca3af', - cursor: '#3b82f6', - agentPrefix: '#059669', - agentName: '#047857', - agentText: '#1f2937', - agentCheckmark: '#059669', - agentResponseCount: '#6b7280', - agentFocusedBg: '#f3f4f6', - agentContentText: '#111827', - agentToggleHeaderBg: '#ea580c', - agentToggleHeaderText: '#ffffff', - agentToggleText: '#ffffff', - agentContentBg: '#ffffff', + + // Mode toggles + modeFastBg: '#f97316', + modeFastText: '#f97316', + modeMaxBg: '#dc2626', + modeMaxText: '#dc2626', + modePlanBg: '#1e40af', + modePlanText: '#1e40af', + + // Markdown markdown: { codeBackground: '#f3f4f6', codeHeaderFg: '#6b7280', @@ -797,30 +819,177 @@ export const chatThemes = (() => { export const createMarkdownPalette = (theme: ChatTheme): MarkdownPalette => { const headingDefaults: Record = { - 1: theme.statusAccent, - 2: theme.statusAccent, - 3: theme.statusAccent, - 4: theme.statusAccent, - 5: theme.statusAccent, - 6: theme.statusAccent, + 1: theme.primary, + 2: theme.primary, + 3: theme.primary, + 4: theme.primary, + 5: theme.primary, + 6: theme.primary, } const overrides = theme.markdown?.headingFg ?? {} return { - inlineCodeFg: theme.markdown?.inlineCodeFg ?? theme.messageAiText, - codeBackground: theme.markdown?.codeBackground ?? theme.messageBg, - codeHeaderFg: theme.markdown?.codeHeaderFg ?? theme.statusSecondary, + inlineCodeFg: theme.markdown?.inlineCodeFg ?? theme.foreground, + codeBackground: theme.markdown?.codeBackground ?? theme.background, + codeHeaderFg: theme.markdown?.codeHeaderFg ?? theme.secondary, headingFg: { ...headingDefaults, ...overrides, }, - listBulletFg: theme.markdown?.listBulletFg ?? theme.statusSecondary, - blockquoteBorderFg: - theme.markdown?.blockquoteBorderFg ?? theme.statusSecondary, - blockquoteTextFg: theme.markdown?.blockquoteTextFg ?? theme.messageAiText, - dividerFg: theme.markdown?.dividerFg ?? theme.statusSecondary, - codeTextFg: theme.markdown?.codeTextFg ?? theme.messageAiText, + listBulletFg: theme.markdown?.listBulletFg ?? theme.secondary, + blockquoteBorderFg: theme.markdown?.blockquoteBorderFg ?? theme.secondary, + blockquoteTextFg: theme.markdown?.blockquoteTextFg ?? theme.foreground, + dividerFg: theme.markdown?.dividerFg ?? theme.secondary, + codeTextFg: theme.markdown?.codeTextFg ?? theme.foreground, codeMonochrome: theme.markdown?.codeMonochrome ?? true, } } + +/** + * Exported utilities for theme system + */ + +/** + * Merge theme overrides with a base theme + * Alias for mergeTheme to match our hook API + */ +export const mergeThemeOverrides = mergeTheme + +/** + * Clone a ChatTheme object to avoid mutations + * Properly handles nested markdown configuration + */ +export const cloneChatTheme = (input: ChatTheme): ChatTheme => ({ + ...input, + markdown: input.markdown + ? { + ...input.markdown, + headingFg: input.markdown.headingFg + ? { ...input.markdown.headingFg } + : undefined, + } + : undefined, +}) + +/** + * Resolve a theme color value with optional fallback + * Returns undefined for 'default' values or empty strings + */ +export const resolveThemeColor = ( + color?: string, + fallback?: string, +): string | undefined => { + if (typeof color === 'string') { + const normalized = color.trim().toLowerCase() + if (normalized.length > 0 && normalized !== 'default') { + return color + } + } + + if (fallback !== undefined) { + return resolveThemeColor(fallback) + } + + return undefined +} + +/** + * Reactive Theme Detection + * Watches for system theme changes and updates zustand store + */ + +let lastDetectedTheme: ThemeName | null = null +let themeStoreUpdater: ((name: ThemeName) => void) | null = null + +/** + * Initialize theme store updater + * Called by theme-store on initialization to enable reactive updates + * @param setter - Function to call when theme changes + */ +export const initializeThemeWatcher = (setter: (name: ThemeName) => void) => { + themeStoreUpdater = setter +} + +/** + * Recompute system theme and update store if it changed + * @param source - Source of the recomputation (for debugging) + */ +const recomputeSystemTheme = (source: string) => { + // Only recompute if theme is auto-detected (not explicitly set) + const envPreference = process.env.OPEN_TUI_THEME ?? process.env.OPENTUI_THEME + if (envPreference && envPreference.toLowerCase() !== 'opposite') { + // User explicitly set theme, don't react to system changes + return + } + + const newTheme = detectSystemTheme() + + // Always call the updater and let it decide if an update is needed + lastDetectedTheme = newTheme + if (themeStoreUpdater) { + themeStoreUpdater(newTheme) + } +} + +// Initialize on module load +lastDetectedTheme = detectSystemTheme() + +/** + * Setup file watchers for theme changes + * Watches parent directories which reliably catches all file modifications + */ +const setupFileWatchers = () => { + const watchTargets: string[] = [] + const watchedDirs = new Set() + + // macOS system preferences + if (process.platform === 'darwin') { + watchTargets.push( + join(homedir(), 'Library/Preferences/.GlobalPreferences.plist'), + join(homedir(), 'Library/Preferences/com.apple.Terminal.plist'), + ) + } + + // IDE config files that we should watch + const ideConfigPaths = getIDEThemeConfigPaths() + watchTargets.push(...ideConfigPaths) + + // Watch parent directories instead of individual files + // Directory watches are more reliable for catching all modifications including plist key deletions + for (const target of watchTargets) { + if (existsSync(target)) { + const parentDir = dirname(target) + + // Only watch each directory once + if (watchedDirs.has(parentDir)) continue + watchedDirs.add(parentDir) + + try { + // Watch the directory - catches all file modifications + const watcher = watch(parentDir, { persistent: false }, (eventType, filename) => { + // Only respond to changes affecting our target files + if (filename && watchTargets.some((t) => t.endsWith(filename))) { + recomputeSystemTheme(`watch:${join(parentDir, filename)}:${eventType}`) + } + }) + + watcher.on('error', () => { + // Silently ignore watcher errors + }) + } catch { + // Silently ignore if we can't watch + } + } + } +} + +setupFileWatchers() + +/** + * SIGUSR2 signal handler for manual theme refresh + * Users can send `kill -USR2 ` to force theme recomputation + */ +process.on('SIGUSR2', () => { + recomputeSystemTheme('signal:SIGUSR2') +}) diff --git a/npm-app/src/browser-runner.ts b/npm-app/src/browser-runner.ts index df8623c57..dcb59c4f0 100644 --- a/npm-app/src/browser-runner.ts +++ b/npm-app/src/browser-runner.ts @@ -570,12 +570,13 @@ export class BrowserRunner { }) // Page errors - this.page.on('pageerror', (err) => { + this.page.on('pageerror', (err: unknown) => { + const error = err as Error this.logs.push({ type: 'error', - message: err.message, + message: error.message, timestamp: Date.now(), - stack: err.stack, + stack: error.stack, source: 'browser', }) this.jsErrorCount++ @@ -767,7 +768,7 @@ export class BrowserRunner { this.page = null try { await browser.close() - } catch (err) { + } catch (err: unknown) { console.error('Error closing browser:', err) logger.error( {