diff --git a/eslint.config.mjs b/eslint.config.mjs index 77e3670f..27d45a4f 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -83,7 +83,6 @@ export default tseslint.config( 'node_modules', 'src/assets', 'src/schema/llm-compacted', - 'web-harness', '.agentcore', '**/.agentcore/**', '.venv', diff --git a/package-lock.json b/package-lock.json index eeadc553..eb36528f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4063,9 +4063,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", - "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", "cpu": [ "arm" ], @@ -4077,9 +4077,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", - "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", "cpu": [ "arm64" ], @@ -4091,9 +4091,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz", - "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ "arm64" ], @@ -4105,9 +4105,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", - "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", "cpu": [ "x64" ], @@ -4119,9 +4119,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", - "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", "cpu": [ "arm64" ], @@ -4133,9 +4133,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", - "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", "cpu": [ "x64" ], @@ -4147,9 +4147,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", - "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", "cpu": [ "arm" ], @@ -4161,9 +4161,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", - "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", "cpu": [ "arm" ], @@ -4175,9 +4175,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", - "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ "arm64" ], @@ -4189,9 +4189,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", - "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", "cpu": [ "arm64" ], @@ -4203,9 +4203,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", - "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", "cpu": [ "loong64" ], @@ -4217,9 +4217,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", - "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", "cpu": [ "loong64" ], @@ -4231,9 +4231,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", - "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", "cpu": [ "ppc64" ], @@ -4245,9 +4245,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", - "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", "cpu": [ "ppc64" ], @@ -4259,9 +4259,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", - "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", "cpu": [ "riscv64" ], @@ -4273,9 +4273,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", - "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", "cpu": [ "riscv64" ], @@ -4287,9 +4287,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", - "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", "cpu": [ "s390x" ], @@ -4301,9 +4301,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", - "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", "cpu": [ "x64" ], @@ -4315,9 +4315,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", - "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", "cpu": [ "x64" ], @@ -4329,9 +4329,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", - "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", "cpu": [ "x64" ], @@ -4343,9 +4343,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", - "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", "cpu": [ "arm64" ], @@ -4357,9 +4357,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", - "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", "cpu": [ "arm64" ], @@ -4371,9 +4371,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", - "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", "cpu": [ "ia32" ], @@ -4385,9 +4385,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", - "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", "cpu": [ "x64" ], @@ -4399,9 +4399,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", - "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", "cpu": [ "x64" ], @@ -11934,9 +11934,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", - "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { @@ -11950,31 +11950,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.57.1", - "@rollup/rollup-android-arm64": "4.57.1", - "@rollup/rollup-darwin-arm64": "4.57.1", - "@rollup/rollup-darwin-x64": "4.57.1", - "@rollup/rollup-freebsd-arm64": "4.57.1", - "@rollup/rollup-freebsd-x64": "4.57.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", - "@rollup/rollup-linux-arm-musleabihf": "4.57.1", - "@rollup/rollup-linux-arm64-gnu": "4.57.1", - "@rollup/rollup-linux-arm64-musl": "4.57.1", - "@rollup/rollup-linux-loong64-gnu": "4.57.1", - "@rollup/rollup-linux-loong64-musl": "4.57.1", - "@rollup/rollup-linux-ppc64-gnu": "4.57.1", - "@rollup/rollup-linux-ppc64-musl": "4.57.1", - "@rollup/rollup-linux-riscv64-gnu": "4.57.1", - "@rollup/rollup-linux-riscv64-musl": "4.57.1", - "@rollup/rollup-linux-s390x-gnu": "4.57.1", - "@rollup/rollup-linux-x64-gnu": "4.57.1", - "@rollup/rollup-linux-x64-musl": "4.57.1", - "@rollup/rollup-openbsd-x64": "4.57.1", - "@rollup/rollup-openharmony-arm64": "4.57.1", - "@rollup/rollup-win32-arm64-msvc": "4.57.1", - "@rollup/rollup-win32-ia32-msvc": "4.57.1", - "@rollup/rollup-win32-x64-gnu": "4.57.1", - "@rollup/rollup-win32-x64-msvc": "4.57.1", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, diff --git a/src/cli/AGENTS.md b/src/cli/AGENTS.md index d340b1a0..42f5ffff 100644 --- a/src/cli/AGENTS.md +++ b/src/cli/AGENTS.md @@ -56,17 +56,6 @@ The TUI is defined using ink, a library that converts React definitions to termi Ink supports a subset of React features and components should be directly imported from ink. -## Testing UI changes E2E - -At the top level `web-harness/` directory a shim over Ink, as well as a mock of Node API and CLI business logic is -defined. By running the vite local host dev server, a web app based on the same visual source of truth as the terminal -is hosted. Always launch a web-harness web server and use the browser MCP tool to test changes E2E. Create mocks as -appropriate to test the relevant surface area. - -If start up issues are encountered, read the console error to troubleshoot bugs and update the harness. - -## Dev Server Architecture - The `dev` command uses a strategy pattern with a `DevServer` base class and two implementations: - **CodeZipDevServer**: Runs uvicorn locally with Python venv hot-reload diff --git a/web-harness/AGENTS.md b/web-harness/AGENTS.md deleted file mode 100644 index e116f533..00000000 --- a/web-harness/AGENTS.md +++ /dev/null @@ -1,44 +0,0 @@ -# Web Harness Testing - -This directory contains a web-based harness for testing the CLI TUI components in a browser environment. - -## Usage - -1. Start the harness: `npm run dev` -2. Navigate to the URL shown in the terminal (usually http://localhost:5173 or similar) -3. Use playwright browser tools to interact with the TUI - -## CRITICAL: Console Error Protocol - -**BEFORE doing ANYTHING else after starting or restarting the harness, you MUST:** - -1. Open the browser or use playwright tools to check console errors -2. If ANY errors exist, STOP and FIX them before proceeding -3. Do NOT claim the harness is working until you have verified zero console errors - -### Checking for Errors - -Use playwright MCP tools to check console: - -``` -mcp__playwright__browser_console_messages with level: "error" -``` - -Or manually open http://localhost:5173 in a browser and check DevTools Console. - -### Common Errors and Fixes - -1. **"Invalid or unexpected token"** - Usually a missing mock in vite.config.ts -2. **Module not found / 404** - Add the module to the mocks in vite.config.ts -3. **React rendering errors** - Check component imports and props - -### After Making Code Changes - -After ANY code changes to TUI components: - -1. Rebuild packages: `npm run build:packages` (from repo root) -2. Restart harness: kill vite, run `npm run dev` -3. CHECK CONSOLE ERRORS before proceeding -4. Fix any errors that appear - -**This protocol is NON-NEGOTIABLE. Do not skip checking console errors.** diff --git a/web-harness/README.md b/web-harness/README.md deleted file mode 100644 index cee733a5..00000000 --- a/web-harness/README.md +++ /dev/null @@ -1,225 +0,0 @@ -# AgentCore CLI - Browser Test Harness - -A browser-based visual testing harness for the AgentCore CLI's Ink-based terminal UI. This allows you to render and -interact with the CLI interface in a web browser at multiple terminal sizes simultaneously. - -## Quick Start - -```bash -cd web-harness -npm install -npm run dev -# Opens http://localhost:5173 -``` - -## What is This? - -This harness renders the **real AgentCore CLI TUI components** in a browser environment by: - -1. **Shimming Ink** - Replacing Ink's terminal rendering with browser DOM elements -2. **Mocking Node.js APIs** - Providing browser-compatible stubs for `fs`, `path`, `child_process`, etc. -3. **Mocking CLI operations** - Simulating file I/O, shell commands, and AWS operations - -The result is a fully interactive UI that you can visually test without needing a real terminal or AWS infrastructure. - -## Intended Use: Visual Testing with Playwright MCP - -This harness is designed to be used with [Playwright MCP](https://github.com/anthropic/claude-code) for automated visual -testing via Claude Code. - -### Setup Playwright MCP - -```bash -claude mcp add playwright -- npx @playwright/mcp@latest -``` - -#### Headless Mode (no browser window) - -To run the browser invisibly in the background, edit the MCP config file: - -```bash -# Find and edit the config (location varies by installation) -~/.claude/plugins/.../playwright/.mcp.json -``` - -Add `--headless` to the args: - -```json -{ - "playwright": { - "command": "npx", - "args": ["@playwright/mcp@latest", "--headless"] - } -} -``` - -Then restart Claude Code or run `/mcp` to reconnect. - -### Example Usage with Claude - -Once the harness is running (`npm run dev`), you can ask Claude to: - -- "Navigate to http://localhost:5173 and screenshot the home screen" -- "Click on the 'init' option and verify the wizard renders correctly" -- "Test keyboard navigation through the menu" -- "Check how the UI looks at different terminal sizes" - -## Architecture - -### What's Real (from source) - -These are imported **directly from the CLI source code** - no mocking: - -| Component | Path | -| ------------------------- | --------------------------------------------- | -| `App` (main TUI) | `packages/agentcore-cli/src/tui/App.tsx` | -| All TUI screens | `packages/agentcore-cli/src/tui/screens/*` | -| All TUI components | `packages/agentcore-cli/src/tui/components/*` | -| TUI hooks | `packages/agentcore-cli/src/tui/hooks/*` | -| Schema types & validation | `packages/agentcore-schema/*` (via Zod) | - -### What's Mocked - -These are replaced with browser-compatible shims: - -| Module | Mock File | Purpose | -| ------------------------- | ---------------------- | -------------------------------------- | -| `ink` | `ink-browser-shim.tsx` | Box, Text, useInput, useApp, useStdout | -| `ink-spinner` | `ink-spinner-shim.tsx` | Animated spinner component | -| `fs`, `path`, `url`, etc. | `node-mocks.ts` | Node.js built-in modules | -| `child_process`, `net` | `node-mocks.ts` | Process/network operations | -| `@agentcore/lib` | `lib-mocks.ts` | ConfigIO, file utilities | -| `../cli` | `cli-mock.ts` | Commander program setup | -| `../shell` | `shell-mock.ts` | Shell command execution | -| AWS SDK clients | `external-mocks.ts` | CloudFormation, STS, Bedrock | -| `commander` | `external-mocks.ts` | CLI framework | -| `handlebars` | `external-mocks.ts` | Template rendering | - -### Mock Behavior - -- **File operations**: Return mock JSON data based on active scenario -- **Shell commands**: Simulate immediate success with mock output -- **ConfigIO**: Returns mock workspace data from scenario files -- **AWS operations**: Not executed, return mock responses - -## Mock Scenarios - -Configuration is centralized in `harness-env.ts`. Mock workspace data lives in `mocks/` with different scenarios: - -``` -mocks/ -├── demo-workspace/ # Full workspace with 2 agents, AWS targets, deployed state -│ ├── agentcore.json # DemoWorkspace with ResearchAssistant & CodeReviewer agents -│ ├── aws-targets.json # development (us-west-2) and production (us-east-1) -│ ├── mcp.json # main-gateway with ResearchAssistant -│ ├── mcp-defs.json # web-search and code-analyzer tools -│ └── deployed-state.json -└── empty-workspace/ # Fresh init state, no agents - ├── agentcore.json # EmptyWorkspace with no agents - ├── aws-targets.json # Empty array - ├── mcp.json # No gateways - ├── mcp-defs.json # No tools - └── deployed-state.json -``` - -### Switching Scenarios - -Edit `harness-env.ts` to change the active scenario: - -```typescript -// harness-env.ts -export const MOCK_SCENARIO: MockScenario = 'demo-workspace'; // or 'empty-workspace' -``` - -Then reload the browser to apply changes. - -### Adding New Scenarios - -1. Create a new directory under `mocks/` (e.g., `mocks/error-state/`) -2. Add the 5 schema JSON files: - - `agentcore.json` - Workspace spec with agents array - - `aws-targets.json` - AWS deployment targets - - `mcp.json` - MCP gateways configuration - - `mcp-defs.json` - MCP tool definitions - - `deployed-state.json` - Deployed resource state -3. Import the files in both `node-mocks.ts` and `lib-mocks.ts` -4. Add the scenario to the `MockScenario` type in `harness-env.ts` -5. Add the scenario data to `MOCK_FILES` in `node-mocks.ts` and `SCENARIO_DATA` in `lib-mocks.ts` - -## File Structure - -``` -web-harness/ -├── package.json # Dependencies (vite, react, zod) -├── vite.config.ts # Vite config with module aliasing -├── index.html # HTML entry point -├── tsconfig.json # TypeScript configuration -├── harness-env.ts # Harness configuration (scenario, paths, flags) -├── browser-entry.tsx # Main entry - VirtualTerminal wrapper -├── ink-browser-shim.tsx # Ink component/hook replacements -├── ink-spinner-shim.tsx # Spinner component -├── node-mocks.ts # fs, path, child_process, net, etc. -├── lib-mocks.ts # @agentcore/lib mocks (ConfigIO) -├── cli-mock.ts # Commander program mock -├── shell-mock.ts # Shell execution mock -├── external-mocks.ts # AWS SDK, commander, handlebars -├── cli-constants-mock.ts # CLI constants (uses Node.js 'module') -├── tui-process-mock.ts # TUI process utilities -├── template-root-mock.ts # Template path resolution -├── schema-text-mock.ts # Schema text file mock -└── mocks/ # Mock workspace data by scenario - ├── demo-workspace/ # Full workspace with agents - └── empty-workspace/ # Fresh init state -``` - -## Virtual Terminals - -The harness displays three terminal sizes simultaneously: - -| Name | Size | Use Case | -| -------- | ------ | ------------------------- | -| Standard | 80x24 | Default terminal size | -| Narrow | 50x20 | Split pane / small window | -| Large | 120x40 | Full HD terminal | - -Click a terminal to focus keyboard input to it. - -## Keyboard Navigation - -All standard Ink keyboard controls work: - -- **Arrow keys**: Navigate menus -- **Enter**: Select/confirm -- **Escape**: Go back/cancel -- **Tab**: Next field -- **Type**: Text input in forms - -## Limitations - -Since this runs in a browser with mocked backends: - -1. **No real file I/O** - Files aren't actually created/read -2. **No real shell commands** - Commands return mock output -3. **No AWS operations** - Deployments are simulated -4. **No persistent state** - Refreshing resets everything - -This is by design - the harness is for **visual/interaction testing**, not functional testing of backend operations. - -## Development - -### Adding New Mocks - -If you encounter a "Module externalized for browser compatibility" error: - -1. Identify the Node.js module in the error (e.g., `node:dns`) -2. Add it to the `mocks` object in `vite.config.ts` -3. Add stub exports to `node-mocks.ts` - -### Debugging Module Resolution - -The Vite plugin logs interceptions to the console. Check the terminal running `npm run dev` for: - -``` -[browser-mocks] INTERCEPTING cli import -> /path/to/cli-mock.ts -[browser-mocks] INTERCEPTING constants import -> /path/to/cli-constants-mock.ts -``` diff --git a/web-harness/browser-entry.tsx b/web-harness/browser-entry.tsx deleted file mode 100644 index 387ae0fe..00000000 --- a/web-harness/browser-entry.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import { App } from '../src/cli/tui/App'; -import { TerminalContext } from './ink-browser-shim'; -import React, { Component, ErrorInfo, ReactNode, useState } from 'react'; -import ReactDOM from 'react-dom/client'; - -// Error boundary to catch and display render errors -class ErrorBoundary extends Component<{ children: ReactNode }, { hasError: boolean; error: Error | null }> { - constructor(props: { children: ReactNode }) { - super(props); - this.state = { hasError: false, error: null }; - } - - static getDerivedStateFromError(error: Error) { - return { hasError: true, error }; - } - - componentDidCatch(error: Error, errorInfo: ErrorInfo) { - console.error('React Error Boundary caught:', error, errorInfo); - } - - render() { - if (this.state.hasError) { - return ( -
-
Render Error:
-
{this.state.error?.message}
-
{this.state.error?.stack}
-
- ); - } - return this.props.children; - } -} - -interface VirtualTerminalProps { - columns: number; - rows: number; - label: string; - children: React.ReactNode; - isActive?: boolean; - onFocus?: () => void; -} - -const VirtualTerminal = ({ columns, rows, label, children, isActive, onFocus }: VirtualTerminalProps) => ( -
-
- {label} ({columns}x{rows}) {isActive && '← active'} -
-
- {children} -
-
-); - -function TestHarness() { - const [activeTerminal, setActiveTerminal] = useState('standard'); - - return ( -
-

AgentCore CLI - Browser Test Harness

-

- Click a terminal to focus keyboard input. Test responsive layouts at different sizes. -

- -
- setActiveTerminal('standard')} - > - {activeTerminal === 'standard' && ( - - - - )} - - - setActiveTerminal('narrow')} - > - {activeTerminal === 'narrow' && ( - - - - )} - - - setActiveTerminal('large')} - > - {activeTerminal === 'large' && ( - - - - )} - -
-
- ); -} - -ReactDOM.createRoot(document.getElementById('root')!).render( - - - -); diff --git a/web-harness/cli-constants-mock.ts b/web-harness/cli-constants-mock.ts deleted file mode 100644 index 1fdd2054..00000000 --- a/web-harness/cli-constants-mock.ts +++ /dev/null @@ -1,28 +0,0 @@ -// Mock for CLI constants that use Node.js 'module' built-in - -export const PACKAGE_VERSION = '0.0.0-browser'; -export const CDK_PROJECT_DIR = 'cdk'; -export const CDK_APP_ENTRY = 'dist/bin/cdk.js'; -export const DEV_MODE = true; -export const DEV_LINK_PACKAGES = ['@agentcore/cdk', '@agentcore/lib', '@agentcore/schema']; -export const SCHEMA_VERSION = 1; - -export type DistroMode = 'PROD_DISTRO' | 'PRIVATE_DEV_DISTRO'; -export const DISTRO_MODE: DistroMode = 'PROD_DISTRO'; - -export const DISTRO_CONFIG = { - PROD_DISTRO: { - packageName: '@aws/agentcore', - registryUrl: 'https://registry.npmjs.org', - installCommand: 'npm install -g @aws/agentcore@latest', - }, - PRIVATE_DEV_DISTRO: { - packageName: '@aws/agentcore', - registryUrl: 'https://npm.pkg.github.com', - installCommand: 'npm install -g @aws/agentcore@latest --registry=https://npm.pkg.github.com', - }, -} as const; - -export function getDistroConfig() { - return DISTRO_CONFIG[DISTRO_MODE]; -} diff --git a/web-harness/cli-mock.ts b/web-harness/cli-mock.ts deleted file mode 100644 index 0990e3e4..00000000 --- a/web-harness/cli-mock.ts +++ /dev/null @@ -1,29 +0,0 @@ -// Mock for the CLI module that creates a Commander program -// This avoids importing the real cli.ts which has many Node.js dependencies - -// Mock CommandMeta type -export interface MockCommand { - name(): string; - description(): string; - commands: MockCommand[]; -} - -// Create a mock program with minimal commands for UI testing -export function createProgram(): MockCommand { - const mockCommands: MockCommand[] = [ - { name: () => 'init', description: () => 'Initialize a new AgentCore workspace', commands: [] }, - { name: () => 'create', description: () => 'Create a new agent or tool', commands: [] }, - { name: () => 'dev', description: () => 'Start local development server', commands: [] }, - { name: () => 'deploy', description: () => 'Deploy to AWS', commands: [] }, - { name: () => 'edit', description: () => 'Edit workspace configuration', commands: [] }, - { name: () => 'add', description: () => 'Add MCP tools or gateways', commands: [] }, - { name: () => 'status', description: () => 'Show workspace status', commands: [] }, - ]; - - return { - name: () => 'agentcore', - description: () => 'AgentCore CLI', - version: () => '0.0.0-browser', - commands: mockCommands, - } as MockCommand & { version: () => string }; -} diff --git a/web-harness/cli-schema-mock.ts b/web-harness/cli-schema-mock.ts deleted file mode 100644 index 2e406b84..00000000 --- a/web-harness/cli-schema-mock.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Mock for the CLI's schema document module (src/cli/schema). - * The real module uses fs/promises which is not available in browser. - */ - -export interface LoadDocumentResult { - content: string; - validationError?: string; -} - -export interface SaveDocumentResult { - ok: boolean; - content?: string; - error?: string; -} - -export async function loadSchemaDocument(_filePath: string, _schema: unknown): Promise { - console.log('[cli-schema-mock] loadSchemaDocument called'); - return { - content: '{}', - validationError: undefined, - }; -} - -export async function saveSchemaDocument( - _filePath: string, - content: string, - _schema: unknown -): Promise { - console.log('[cli-schema-mock] saveSchemaDocument called'); - return { ok: true, content }; -} diff --git a/web-harness/external-mocks.ts b/web-harness/external-mocks.ts deleted file mode 100644 index aec4873e..00000000 --- a/web-harness/external-mocks.ts +++ /dev/null @@ -1,318 +0,0 @@ -// Mock external packages that aren't needed for UI rendering - -// Mock terminal detection packages -export const supportsColor = { stdout: false, stderr: false }; -export const createSupportsColor = () => ({ stdout: false, stderr: false }); -export const supportsHyperlinks = { stdout: false, stderr: false }; - -// Mock @resvg/resvg-js -export class Resvg { - constructor(_svg: string, _options?: any) {} - render() { - return { asPng: () => new Uint8Array() }; - } -} - -// Mock commander -export class Command { - constructor() {} - name() { - return this; - } - description() { - return this; - } - version() { - return '0.0.0'; - } - option() { - return this; - } - action() { - return this; - } - command() { - return new Command(); - } - parse() {} - commands: Command[] = []; -} - -// Mock zod -export const z = { - string: () => ({ - min: () => z.string(), - max: () => z.string(), - regex: () => z.string(), - optional: () => z.string(), - default: () => z.string(), - describe: () => z.string(), - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), - number: () => ({ - min: () => z.number(), - max: () => z.number(), - optional: () => z.number(), - default: () => z.number(), - describe: () => z.number(), - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), - boolean: () => ({ - optional: () => z.boolean(), - default: () => z.boolean(), - describe: () => z.boolean(), - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), - object: (shape: any) => ({ - shape, - optional: () => z.object(shape), - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - extend: (ext: any) => z.object({ ...shape, ...ext }), - }), - array: (item: any) => ({ - element: item, - optional: () => z.array(item), - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), - enum: (values: string[]) => ({ - options: values, - optional: () => z.enum(values), - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), - union: (types: any[]) => ({ - options: types, - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), - literal: (value: any) => ({ - value, - parse: () => value, - safeParse: () => ({ success: true, data: value }), - }), - any: () => ({ - parse: (v: any) => v, - safeParse: (v: any) => ({ success: true, data: v }), - }), -}; - -// Mock AWS SDK clients -export class STSClient { - constructor(_config: any) {} - send(_command: any) { - return Promise.resolve({}); - } -} - -export class GetCallerIdentityCommand { - constructor(_input?: any) {} -} - -export class CloudFormationClient { - constructor(_config: any) {} - send(_command: any) { - return Promise.resolve({}); - } -} - -export class DescribeStacksCommand { - constructor(_input?: any) {} -} - -export class DescribeStackEventsCommand { - constructor(_input?: any) {} -} - -export class BedrockRuntimeClient { - constructor(_config: any) {} - send(_command: any) { - return Promise.resolve({}); - } -} - -export class InvokeModelCommand { - constructor(_input?: any) {} -} - -// Mock @aws-sdk/client-bedrock-agentcore -export class BedrockAgentCoreClient { - constructor(_config: any) {} - send(_command: any) { - return Promise.resolve({}); - } -} - -export class InvokeAgentRuntimeCommand { - constructor(_input?: any) {} -} - -// Mock @aws-sdk/client-bedrock-agentcore-control -export class BedrockAgentCoreControlClient { - constructor(_config: any) {} - send(_command: any) { - return Promise.resolve({}); - } -} - -export class GetAgentRuntimeCommand { - constructor(_input?: any) {} -} - -export class CreateApiKeyCredentialProviderCommand { - constructor(_input?: any) {} -} - -export class GetApiKeyCredentialProviderCommand { - constructor(_input?: any) {} -} - -// Mock AWS SDK exceptions -export class ResourceNotFoundException extends Error { - name = 'ResourceNotFoundException'; - constructor(message?: string) { - super(message || 'Resource not found'); - } -} - -// Mock credential providers -export const fromNodeProviderChain = () => async () => ({ - accessKeyId: 'mock', - secretAccessKey: 'mock', -}); - -export const fromEnv = () => async () => ({ - accessKeyId: 'mock', - secretAccessKey: 'mock', -}); - -// Mock shared ini file loader -export const loadSharedConfigFiles = async () => ({ - configFile: {}, - credentialsFile: {}, -}); - -// Mock @aws-sdk/client-resource-groups-tagging-api -export class ResourceGroupsTaggingAPIClient { - constructor(_config: any) {} - send(_command: any) { - return Promise.resolve({ ResourceTagMappingList: [] }); - } -} - -export class GetResourcesCommand { - constructor(_input?: any) {} -} - -// Mock CDK toolkit-lib -export const StackSelectionStrategy = { - ALL_STACKS: 'ALL_STACKS', - PATTERN_MUST_MATCH: 'PATTERN_MUST_MATCH', - PATTERN_MUST_MATCH_SINGLE: 'PATTERN_MUST_MATCH_SINGLE', - NONE: 'NONE', -}; - -export class Toolkit { - constructor(_options: any) {} - - async fromCdkApp(_command: string, _options?: any) { - // Return a mock ICloudAssemblySource - return { - produce: async () => ({ - cloudAssembly: { - directory: '/mock/cdk.out', - stacks: [{ stackName: 'MockStack' }], - }, - dispose: async () => {}, - }), - }; - } - - fromAssemblyDirectory(_directory: string) { - return { - produce: async () => ({ - cloudAssembly: { - directory: '/mock/cdk.out', - stacks: [{ stackName: 'MockStack' }], - }, - dispose: async () => {}, - }), - }; - } - - synth(_source: any, _options?: any) { - // Return a synth result that matches the expected interface - return Promise.resolve({ - produce: async () => ({ - cloudAssembly: { - directory: '/mock/cdk.out', - stacks: [{ stackName: 'AgentCoreStack-us-west-2' }, { stackName: 'AgentCoreStack-us-east-1' }], - }, - dispose: async () => {}, - }), - dispose: async () => {}, - }); - } - - deploy(_source: any, _options?: any) { - return Promise.resolve({}); - } - - destroy(_source: any, _options?: any) { - return Promise.resolve({}); - } - - diff(_source: any, _options?: any) { - return Promise.resolve({}); - } - - list(_source: any, _options?: any) { - return Promise.resolve([{ stackName: 'MockStack' }]); - } - - bootstrap(_environments: any) { - return Promise.resolve({}); - } -} - -export const BaseCredentials = { - awsCliCompatible: (_options?: any) => ({}), -}; -export const BootstrapEnvironments = { - fromList: (_environments: string[]) => ({}), -}; - -// Mock Handlebars -const Handlebars = { - compile: (template: string) => (context: any) => template, - parse: (template: string) => ({ type: 'Program', body: [] }), - precompile: (template: string) => 'function() { return ""; }', - registerHelper: () => {}, - registerPartial: () => {}, - SafeString: class SafeString { - constructor(public value: string) {} - toString() { - return this.value; - } - }, -}; - -export default Handlebars; -export { Handlebars }; -export const parse = Handlebars.parse; -export const compile = Handlebars.compile; - -// Mock @agentcore/cdk -export const logicalId = (name: string) => `Mock${name}`; -export const toPascalId = (name: string) => - name.replace(/[-_\s]+(.)?/g, (_, c) => (c ? c.toUpperCase() : '')).replace(/^./, s => s.toUpperCase()); -export class AgentCoreApplication { - constructor(_scope: any, _id: string, _props: any) {} -} -export class AgentCoreMcp { - constructor(_scope: any, _id: string, _props: any) {} -} diff --git a/web-harness/harness-env.ts b/web-harness/harness-env.ts deleted file mode 100644 index 41c23292..00000000 --- a/web-harness/harness-env.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Harness Environment Configuration - * - * Central configuration for the browser test harness. - * Change these settings to test different scenarios. - */ - -// ============= Mock Scenario ============= -// Available scenarios (defined in mocks/ directory): -// - 'demo-workspace': Full workspace with 2 agents, AWS targets, deployed state -// - 'empty-workspace': Fresh init state, no agents - -export type MockScenario = 'demo-workspace' | 'empty-workspace'; - -/** - * The active mock scenario. - * Change this to test different workspace states. - */ -export const MOCK_SCENARIO: MockScenario = 'demo-workspace'; - -// ============= Mock Paths ============= -// These define where the mock workspace "lives" in the virtual filesystem -// NOTE: These must match the paths in mock-fs-server.ts and mock-fs-client.ts - -export const MOCK_WORKSPACE_ROOT = '/mock/workspace'; -export const MOCK_AGENTCORE_DIR = `${MOCK_WORKSPACE_ROOT}/agentcore`; -export const MOCK_CLI_DIR = `${MOCK_AGENTCORE_DIR}/.cli`; - -// ============= Feature Flags ============= -// Enable/disable features for testing - -export const HARNESS_CONFIG = { - /** Log mock operations to console */ - logMockOperations: false, - - /** Simulate network latency for async operations (ms) */ - simulatedLatency: 0, - - /** Show debug borders around Ink components */ - debugBorders: false, -} as const; diff --git a/web-harness/index.html b/web-harness/index.html deleted file mode 100644 index 27a2a60e..00000000 --- a/web-harness/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - AgentCore CLI - Browser Test - - - -
- - - diff --git a/web-harness/ink-browser-shim.tsx b/web-harness/ink-browser-shim.tsx deleted file mode 100644 index 41706bcd..00000000 --- a/web-harness/ink-browser-shim.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import React, { createContext, useContext, useEffect } from 'react'; - -// Terminal dimensions context -export const TerminalContext = createContext({ columns: 80, rows: 24 }); - -// Box component - flexbox container -// Ink uses character units: 1 padding = 1 character width -export const Box = ({ - children, - flexDirection = 'row', - borderStyle, - borderColor, - padding, - paddingX, - paddingY, - paddingLeft, - paddingRight, - paddingTop, - paddingBottom, - margin, - marginTop, - marginBottom, - marginLeft, - marginRight, - marginX, - marginY, - width, - height, - minWidth, - minHeight, - flexGrow, - flexShrink, - flexBasis, - justifyContent, - alignItems, - alignSelf, - gap, - overflowX, - overflowY, - ...rest -}: any) => { - // Calculate padding - specific overrides general - const pl = paddingLeft ?? paddingX ?? padding ?? 0; - const pr = paddingRight ?? paddingX ?? padding ?? 0; - const pt = paddingTop ?? paddingY ?? padding ?? 0; - const pb = paddingBottom ?? paddingY ?? padding ?? 0; - - // Calculate margin - specific overrides general - const ml = marginLeft ?? marginX ?? margin ?? 0; - const mr = marginRight ?? marginX ?? margin ?? 0; - const mt = marginTop ?? marginY ?? margin ?? 0; - const mb = marginBottom ?? marginY ?? margin ?? 0; - - const style: React.CSSProperties = { - display: 'flex', - flexDirection, - justifyContent, - alignItems, - alignSelf, - gap: gap ? `${gap}ch` : undefined, - paddingLeft: pl ? `${pl}ch` : undefined, - paddingRight: pr ? `${pr}ch` : undefined, - paddingTop: pt ? `${pt * 1.2}em` : undefined, - paddingBottom: pb ? `${pb * 1.2}em` : undefined, - marginLeft: ml ? `${ml}ch` : undefined, - marginRight: mr ? `${mr}ch` : undefined, - marginTop: mt ? `${mt * 1.2}em` : undefined, - marginBottom: mb ? `${mb * 1.2}em` : undefined, - width: width === '100%' ? '100%' : typeof width === 'number' ? `${width}ch` : width, - height: typeof height === 'number' ? `${height * 1.2}em` : height, - minWidth: typeof minWidth === 'number' ? `${minWidth}ch` : minWidth, - minHeight: typeof minHeight === 'number' ? `${minHeight * 1.2}em` : minHeight, - flexGrow, - flexShrink, - flexBasis, - border: borderStyle ? `1px solid ${borderColor || '#666'}` : undefined, - borderRadius: borderStyle === 'round' ? '4px' : undefined, - boxSizing: 'border-box', - overflowX, - overflowY, - }; - return
{children}
; -}; - -// Text component -export const Text = ({ children, color, bold, dimColor, underline, wrap, ...rest }: any) => { - const style: React.CSSProperties = { - color: color || 'inherit', - fontWeight: bold ? 'bold' : 'normal', - opacity: dimColor ? 0.5 : 1, - textDecoration: underline ? 'underline' : undefined, - fontFamily: 'monospace', - whiteSpace: wrap === 'truncate' ? 'nowrap' : 'pre-wrap', - overflow: wrap === 'truncate' ? 'hidden' : undefined, - textOverflow: wrap === 'truncate' ? 'ellipsis' : undefined, - }; - return {children}; -}; - -export const Newline = () =>
; - -// Transform component - transforms children text -export const Transform = ({ - children, - transform, -}: { - children?: React.ReactNode; - transform?: (text: string) => string; -}) => { - if (typeof children === 'string' && transform) { - return <>{transform(children)}; - } - return <>{children}; -}; - -// useInput hook - keyboard handling -export const useInput = (handler: (input: string, key: any) => void, options?: { isActive?: boolean }) => { - const isActive = options?.isActive ?? true; - - useEffect(() => { - if (!isActive) return; - - const listener = (e: KeyboardEvent) => { - if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Tab', ' '].includes(e.key)) { - e.preventDefault(); - } - - const key = { - return: e.key === 'Enter', - escape: e.key === 'Escape', - upArrow: e.key === 'ArrowUp', - downArrow: e.key === 'ArrowDown', - leftArrow: e.key === 'ArrowLeft', - rightArrow: e.key === 'ArrowRight', - backspace: e.key === 'Backspace', - delete: e.key === 'Delete', - tab: e.key === 'Tab', - ctrl: e.ctrlKey, - meta: e.metaKey, - }; - - const input = e.key.length === 1 ? e.key : ''; - handler(input, key); - }; - - window.addEventListener('keydown', listener); - return () => window.removeEventListener('keydown', listener); - }, [handler, isActive]); -}; - -// useApp hook -export const useApp = () => ({ - exit: () => console.log('[Browser] App exit called'), -}); - -// useStdout hook - reads from TerminalContext -export const useStdout = () => { - const { columns, rows } = useContext(TerminalContext); - return { - stdout: { - columns, - rows, - on: () => {}, // Resize event listener (no-op in browser) - off: () => {}, - }, - write: (str: string) => console.log('[stdout]', str), - }; -}; - -// render function (no-op, we use ReactDOM) -export const render = () => ({ - clear: () => {}, - unmount: () => {}, - waitUntilExit: () => Promise.resolve(), -}); diff --git a/web-harness/ink-spinner-shim.tsx b/web-harness/ink-spinner-shim.tsx deleted file mode 100644 index 685ea314..00000000 --- a/web-harness/ink-spinner-shim.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React, { useEffect, useState } from 'react'; - -const DOTS = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']; - -export default function Spinner({ type = 'dots' }: { type?: string }) { - const [frame, setFrame] = useState(0); - - useEffect(() => { - const timer = setInterval(() => { - setFrame(f => (f + 1) % DOTS.length); - }, 80); - return () => clearInterval(timer); - }, []); - - return {DOTS[frame]}; -} diff --git a/web-harness/lib-mocks.ts b/web-harness/lib-mocks.ts deleted file mode 100644 index 22a40e18..00000000 --- a/web-harness/lib-mocks.ts +++ /dev/null @@ -1,245 +0,0 @@ -// Mock @agentcore/lib - only the parts that depend on Node.js -// The schema package is NOT mocked - it's pure TypeScript/Zod -// Configuration is centralized in harness-env.ts -import { MOCK_AGENTCORE_DIR, MOCK_SCENARIO } from './harness-env'; -import * as mockFs from './mock-fs-client'; - -// Define mock paths (must match mock-fs-server.ts and mock-fs-client.ts) -const MOCK_WORKSPACE = '/mock/workspace/agentcore'; -const MOCK_CLI_DIR = `${MOCK_WORKSPACE}/.cli`; - -// Virtual paths to schema files -const VIRTUAL_PATHS = { - agentcore: `${MOCK_WORKSPACE}/agentcore.json`, - awsTargets: `${MOCK_WORKSPACE}/aws-targets.json`, - mcp: `${MOCK_WORKSPACE}/mcp.json`, - mcpDefs: `${MOCK_WORKSPACE}/mcp-defs.json`, - deployedState: `${MOCK_CLI_DIR}/deployed-state.json`, -}; - -// Constants -export const CONFIG_DIR = 'agentcore'; -export const CLI_SYSTEM_DIR = '.cli'; -export const CLI_LOGS_DIR = '.cli/logs'; -export const CONFIG_FILES = {}; -export const UV_INSTALL_HINT = 'Install uv'; -export const DEFAULT_PYTHON_PLATFORM = 'linux'; -export const APP_DIR = 'app'; -export const MCP_APP_SUBDIR = 'mcp'; - -// Error class -export class NoProjectError extends Error { - constructor(message?: string) { - super(message || 'No project found'); - this.name = 'NoProjectError'; - } -} - -// Utility functions that use Node.js -export const isWindows = false; -export const findConfigRoot = () => MOCK_WORKSPACE; -export const findProjectRoot = () => '/mock/workspace'; -export const getWorkingDirectory = () => '/mock/workspace'; -export const requireConfigRoot = () => MOCK_WORKSPACE; -export const runSubprocess = async () => ({ stdout: '', stderr: '', code: 0 }); - -// Environment file utilities -export const readEnvFile = async (_path: string) => ({}); -export const setEnvVar = async (_path: string, _key: string, _value: string) => {}; - -// SecureCredentials class mock -export class SecureCredentials { - private creds: Record = {}; - - constructor(_agentName?: string) {} - - async get(key: string): Promise { - return this.creds[key]; - } - - async set(key: string, value: string): Promise { - this.creds[key] = value; - } - - async delete(key: string): Promise { - delete this.creds[key]; - } - - async list(): Promise { - return Object.keys(this.creds); - } -} - -// Mock subprocess capture - returns appropriate version info based on command -export const runSubprocessCapture = async (cmd: string, args?: string[]) => { - const fullCmd = args ? `${cmd} ${args.join(' ')}` : cmd; - // Node version check - if (fullCmd.includes('node') && fullCmd.includes('--version')) { - return { stdout: 'v20.0.0\n', stderr: '', code: 0 }; - } - // UV version check - if (fullCmd.includes('uv') && fullCmd.includes('--version')) { - return { stdout: 'uv 0.9.2\n', stderr: '', code: 0 }; - } - // NPM version check - if (fullCmd.includes('npm') && fullCmd.includes('--version')) { - return { stdout: '10.0.0\n', stderr: '', code: 0 }; - } - // CDK version check - if (fullCmd.includes('cdk') && fullCmd.includes('--version')) { - return { stdout: '2.150.0\n', stderr: '', code: 0 }; - } - return { stdout: '', stderr: '', code: 0 }; -}; - -export const runSubprocessCaptureSync = (cmd: string, args?: string[]) => { - const fullCmd = args ? `${cmd} ${args.join(' ')}` : cmd; - // Node version check - if (fullCmd.includes('node') && fullCmd.includes('--version')) { - return { stdout: 'v20.0.0\n', stderr: '', code: 0 }; - } - // UV version check - if (fullCmd.includes('uv') && fullCmd.includes('--version')) { - return { stdout: 'uv 0.9.2\n', stderr: '', code: 0 }; - } - // NPM version check - if (fullCmd.includes('npm') && fullCmd.includes('--version')) { - return { stdout: '10.0.0\n', stderr: '', code: 0 }; - } - // CDK version check - if (fullCmd.includes('cdk') && fullCmd.includes('--version')) { - return { stdout: '2.150.0\n', stderr: '', code: 0 }; - } - return { stdout: '', stderr: '', code: 0 }; -}; -export const checkSubprocess = async () => true; -export const packRuntime = async () => '/mock/artifact.zip'; -export const resolveCodeLocation = () => '/mock/code'; -export const validateAgentExists = () => true; -export const getArtifactZipName = () => 'artifact.zip'; -export const setSessionProjectRoot = () => {}; -export const getSessionProjectRoot = () => '/mock/workspace'; - -// Mock PathResolver class - mirrors all methods from agentcore-lib -export class PathResolver { - private baseDir = MOCK_WORKSPACE; - - getBaseDir() { - return this.baseDir; - } - getProjectRoot() { - return '/mock/workspace'; - } - getAgentConfigPath() { - return VIRTUAL_PATHS.agentcore; - } - getAWSTargetsConfigPath() { - return VIRTUAL_PATHS.awsTargets; - } - getCliSystemDir() { - return MOCK_CLI_DIR; - } - getLogsDir() { - return `${MOCK_CLI_DIR}/logs`; - } - getStatePath() { - return VIRTUAL_PATHS.deployedState; - } - getMcpConfigPath() { - return VIRTUAL_PATHS.mcp; - } - getMcpDefsPath() { - return VIRTUAL_PATHS.mcpDefs; - } - setBaseDir(baseDir: string) { - this.baseDir = baseDir; - } -} - -// Helper to read and parse JSON from mock filesystem -async function readJsonFile(virtualPath: string): Promise { - await mockFs.waitForInit(); - const content = mockFs.readFileSync(virtualPath); - return JSON.parse(content) as T; -} - -// Helper to write JSON to mock filesystem -async function writeJsonFile(virtualPath: string, data: unknown): Promise { - await mockFs.waitForInit(); - const content = JSON.stringify(data, null, 2); - await mockFs.writeFile(virtualPath, content); -} - -// Mock ConfigIO class (uses fs operations) -// Now reads/writes to the writable mock filesystem -export class ConfigIO { - private pathResolver = new PathResolver(); - - constructor(_opts?: any) {} - - configExists(configName: string): boolean { - // Return true for configs that have mock data - const existingConfigs = ['project', 'awsTargets', 'state', 'mcp', 'mcpDefs']; - return existingConfigs.includes(configName); - } - - getPathResolver(): PathResolver { - return this.pathResolver; - } - - getProjectRoot(): string { - return this.pathResolver.getProjectRoot(); - } - - getConfigRoot(): string { - return this.pathResolver.getBaseDir(); - } - - async readProjectSpec() { - return readJsonFile(VIRTUAL_PATHS.agentcore); - } - - async writeProjectSpec(data: unknown) { - await writeJsonFile(VIRTUAL_PATHS.agentcore, data); - } - - async readAWSDeploymentTargets() { - return readJsonFile(VIRTUAL_PATHS.awsTargets); - } - - async writeAWSDeploymentTargets(data: unknown) { - await writeJsonFile(VIRTUAL_PATHS.awsTargets, data); - } - - async readDeployedState() { - return readJsonFile(VIRTUAL_PATHS.deployedState); - } - - async writeDeployedState(data: unknown) { - await writeJsonFile(VIRTUAL_PATHS.deployedState, data); - } - - async readMcpSpec() { - return readJsonFile(VIRTUAL_PATHS.mcp); - } - - async writeMcpSpec(data: unknown) { - await writeJsonFile(VIRTUAL_PATHS.mcp, data); - } - - async readMcpDefs() { - return readJsonFile(VIRTUAL_PATHS.mcpDefs); - } - - async writeMcpDefs(data: unknown) { - await writeJsonFile(VIRTUAL_PATHS.mcpDefs, data); - } - - async initializeBaseDir() {} - - baseDirExists(): boolean { - return true; - } - - setBaseDir(_baseDir: string): void {} -} diff --git a/web-harness/mock-fs-client.ts b/web-harness/mock-fs-client.ts deleted file mode 100644 index c8008528..00000000 --- a/web-harness/mock-fs-client.ts +++ /dev/null @@ -1,248 +0,0 @@ -/** - * Mock Filesystem Client - * - * Browser-side mock filesystem that: - * - Loads initial state from the server on startup - * - Provides sync read/write operations (from in-memory cache) - * - Persists writes to the server (async, fire-and-forget) - * - * This allows the TUI to work with synchronous fs operations - * while changes are persisted to the dev server. - */ -import { MOCK_SCENARIO } from './harness-env'; - -// Types -export interface MockFile { - content: string; - lastModified: number; -} - -export interface MockFileStore { - [path: string]: MockFile; -} - -// In-memory file store (populated from server on init) -let fileStore: MockFileStore = {}; -let directories: Set = new Set(); -let initialized = false; -let initPromise: Promise | null = null; - -// Log flag -const LOG_OPERATIONS = false; - -function log(...args: unknown[]) { - if (LOG_OPERATIONS) { - console.log('[mock-fs-client]', ...args); - } -} - -/** - * Initialize the mock filesystem from the server. - * Call this early in the app lifecycle. - */ -export async function initializeMockFs(): Promise { - if (initialized) return; - if (initPromise) return initPromise; - - initPromise = (async () => { - try { - log('Initializing from server...'); - const response = await fetch('/__mock-fs-sync'); - if (!response.ok) { - throw new Error(`Failed to sync: ${response.status}`); - } - const data = await response.json(); - fileStore = data.files || {}; - directories = new Set(data.directories || []); - initialized = true; - log('Initialized with', Object.keys(fileStore).length, 'files'); - } catch (err) { - console.error('[mock-fs-client] Failed to initialize:', err); - // Initialize with empty state so app doesn't crash - fileStore = {}; - directories = new Set(); - initialized = true; - } - })(); - - return initPromise; -} - -/** - * Check if the mock filesystem is initialized. - */ -export function isInitialized(): boolean { - return initialized; -} - -/** - * Wait for initialization to complete. - */ -export async function waitForInit(): Promise { - if (initialized) return; - if (initPromise) return initPromise; - return initializeMockFs(); -} - -/** - * Check if a file exists (synchronous, from cache). - */ -export function existsSync(filePath: string): boolean { - if (!initialized) { - console.warn('[mock-fs-client] existsSync called before initialization'); - return false; - } - const exists = filePath in fileStore || directories.has(filePath); - log('existsSync', filePath, '->', exists); - return exists; -} - -/** - * Check if path is a directory. - */ -export function isDirectory(filePath: string): boolean { - return directories.has(filePath); -} - -/** - * Read file content (synchronous, from cache). - */ -export function readFileSync(filePath: string): string { - if (!initialized) { - console.warn('[mock-fs-client] readFileSync called before initialization'); - return '{}'; - } - const file = fileStore[filePath]; - if (!file) { - log('readFileSync', filePath, '-> NOT FOUND'); - return '{}'; - } - log('readFileSync', filePath, '->', file.content.length, 'bytes'); - return file.content; -} - -/** - * Write file content (synchronous write to cache, async persist to server). - */ -export function writeFileSync(filePath: string, content: string): void { - log('writeFileSync', filePath, content.length, 'bytes'); - - // Update local cache immediately - fileStore[filePath] = { - content, - lastModified: Date.now(), - }; - - // Persist to server asynchronously - fetch(`/__mock-fs${filePath}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content }), - }).catch(err => { - console.error('[mock-fs-client] Failed to persist write:', err); - }); -} - -/** - * Async read file (returns Promise). - */ -export async function readFile(filePath: string): Promise { - await waitForInit(); - return readFileSync(filePath); -} - -/** - * Async write file (returns Promise when persisted to server). - */ -export async function writeFile(filePath: string, content: string): Promise { - await waitForInit(); - - // Update local cache - fileStore[filePath] = { - content, - lastModified: Date.now(), - }; - - // Persist to server - const response = await fetch(`/__mock-fs${filePath}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content }), - }); - - if (!response.ok) { - throw new Error(`Failed to write file: ${response.status}`); - } -} - -/** - * Delete a file. - */ -export async function deleteFile(filePath: string): Promise { - await waitForInit(); - - delete fileStore[filePath]; - - const response = await fetch(`/__mock-fs${filePath}`, { - method: 'DELETE', - }); - - if (!response.ok && response.status !== 404) { - throw new Error(`Failed to delete file: ${response.status}`); - } -} - -/** - * List files in a directory. - */ -export function readdirSync(dirPath: string): string[] { - if (!initialized) { - console.warn('[mock-fs-client] readdirSync called before initialization'); - return []; - } - - const prefix = dirPath.endsWith('/') ? dirPath : dirPath + '/'; - const files = Object.keys(fileStore) - .filter(p => p.startsWith(prefix)) - .map(p => { - const rest = p.slice(prefix.length); - const firstSlash = rest.indexOf('/'); - return firstSlash === -1 ? rest : rest.slice(0, firstSlash); - }) - .filter((v, i, a) => a.indexOf(v) === i); // unique - - log('readdirSync', dirPath, '->', files); - return files; -} - -/** - * Reset the filesystem to initial state. - */ -export async function resetMockFs(): Promise { - const response = await fetch('/__mock-fs-reset', { method: 'POST' }); - if (!response.ok) { - throw new Error(`Failed to reset: ${response.status}`); - } - - // Re-sync from server - initialized = false; - initPromise = null; - await initializeMockFs(); -} - -/** - * Get the current file store (for debugging). - */ -export function getFileStore(): Readonly { - return fileStore; -} - -/** - * Get current scenario. - */ -export function getCurrentScenario(): string { - return MOCK_SCENARIO; -} - -// Auto-initialize when module loads (will be ready by the time React renders) -initializeMockFs(); diff --git a/web-harness/mock-fs-server.ts b/web-harness/mock-fs-server.ts deleted file mode 100644 index dd2c623b..00000000 --- a/web-harness/mock-fs-server.ts +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Mock Filesystem Server Plugin for Vite - * - * Provides a server-side file store that: - * - Initializes with mock JSON data on dev server start - * - Exposes REST API endpoints for reading/writing files - * - Persists changes in memory during the dev session - * - Resets to fresh mock data on server restart - */ -import fs from 'node:fs'; -import path from 'node:path'; -import type { Plugin, ViteDevServer } from 'vite'; - -// Types for mock filesystem -export interface MockFile { - content: string; - lastModified: number; -} - -export interface MockFileStore { - [path: string]: MockFile; -} - -// Define mock file paths -const MOCK_WORKSPACE = '/mock/workspace/agentcore'; -const MOCK_CLI_DIR = `${MOCK_WORKSPACE}/.cli`; - -// Map of virtual paths to their mock JSON source files -const MOCK_FILE_MAPPING: Record = { - [`${MOCK_WORKSPACE}/agentcore.json`]: 'agentcore.json', - [`${MOCK_WORKSPACE}/aws-targets.json`]: 'aws-targets.json', - [`${MOCK_WORKSPACE}/mcp.json`]: 'mcp.json', - [`${MOCK_WORKSPACE}/mcp-defs.json`]: 'mcp-defs.json', - [`${MOCK_CLI_DIR}/deployed-state.json`]: 'deployed-state.json', -}; - -// Known mock directories -const MOCK_DIRECTORIES = new Set([ - '/mock', - '/mock/workspace', - MOCK_WORKSPACE, - MOCK_CLI_DIR, - `${MOCK_CLI_DIR}/logs`, - `${MOCK_WORKSPACE}/cdk`, -]); - -export function createMockFsPlugin(scenario: 'demo-workspace' | 'empty-workspace' = 'demo-workspace'): Plugin { - // In-memory file store - const fileStore: MockFileStore = {}; - const mocksDir = path.resolve(__dirname, `./mocks/${scenario}`); - - // Initialize file store from mock JSON files - function initializeFileStore() { - console.log(`[mock-fs] Initializing file store from scenario: ${scenario}`); - - for (const [virtualPath, fileName] of Object.entries(MOCK_FILE_MAPPING)) { - const sourcePath = path.join(mocksDir, fileName); - try { - const content = fs.readFileSync(sourcePath, 'utf-8'); - fileStore[virtualPath] = { - content, - lastModified: Date.now(), - }; - console.log(`[mock-fs] Loaded: ${virtualPath}`); - } catch (err) { - console.warn(`[mock-fs] Failed to load ${sourcePath}:`, err); - // Initialize with empty object for missing files - fileStore[virtualPath] = { - content: '{}', - lastModified: Date.now(), - }; - } - } - } - - return { - name: 'mock-fs-server', - - configureServer(server: ViteDevServer) { - // Initialize file store on server start - initializeFileStore(); - - // Endpoint to get all files at once (for initial sync) - // MUST be registered BEFORE the generic /__mock-fs handler - server.middlewares.use((req, res, next) => { - if (req.url === '/__mock-fs-sync' && req.method === 'GET') { - res.setHeader('Content-Type', 'application/json'); - res.end( - JSON.stringify({ - files: fileStore, - directories: Array.from(MOCK_DIRECTORIES), - }) - ); - return; - } - next(); - }); - - // Endpoint to reset to initial state - // MUST be registered BEFORE the generic /__mock-fs handler - server.middlewares.use((req, res, next) => { - if (req.url === '/__mock-fs-reset' && req.method === 'POST') { - initializeFileStore(); - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ success: true, message: 'File store reset to initial state' })); - return; - } - next(); - }); - - // Add middleware for mock filesystem API (generic file operations) - server.middlewares.use((req, res, next) => { - // Only handle our mock-fs API endpoints - if (!req.url?.startsWith('/__mock-fs/')) { - return next(); - } - - const urlPath = req.url.replace('/__mock-fs', '') || '/'; - - // GET - Read file or list directory - if (req.method === 'GET') { - // Check if it's a directory - if (MOCK_DIRECTORIES.has(urlPath)) { - // List files in directory - const files = Object.keys(fileStore) - .filter(p => p.startsWith(urlPath + '/') && !p.slice(urlPath.length + 1).includes('/')) - .map(p => p.split('/').pop()); - - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ type: 'directory', files })); - return; - } - - // Read file - const file = fileStore[urlPath]; - if (file) { - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ type: 'file', content: file.content, lastModified: file.lastModified })); - } else { - res.statusCode = 404; - res.end(JSON.stringify({ error: 'File not found', path: urlPath })); - } - return; - } - - // POST - Write file - if (req.method === 'POST') { - let body = ''; - req.on('data', chunk => { - body += chunk.toString(); - }); - req.on('end', () => { - try { - const { content } = JSON.parse(body); - fileStore[urlPath] = { - content: typeof content === 'string' ? content : JSON.stringify(content, null, 2), - lastModified: Date.now(), - }; - console.log(`[mock-fs] Written: ${urlPath} (${fileStore[urlPath].content.length} bytes)`); - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({ success: true, path: urlPath })); - } catch (err) { - res.statusCode = 400; - res.end(JSON.stringify({ error: 'Invalid request body' })); - } - }); - return; - } - - // DELETE - Remove file - if (req.method === 'DELETE') { - if (fileStore[urlPath]) { - delete fileStore[urlPath]; - console.log(`[mock-fs] Deleted: ${urlPath}`); - res.end(JSON.stringify({ success: true })); - } else { - res.statusCode = 404; - res.end(JSON.stringify({ error: 'File not found' })); - } - return; - } - - // HEAD - Check if file exists - if (req.method === 'HEAD') { - if (fileStore[urlPath] || MOCK_DIRECTORIES.has(urlPath)) { - res.statusCode = 200; - } else { - res.statusCode = 404; - } - res.end(); - return; - } - - next(); - }); - }, - }; -} - -export default createMockFsPlugin; diff --git a/web-harness/mocks/demo-workspace/agentcore.json b/web-harness/mocks/demo-workspace/agentcore.json deleted file mode 100644 index ba6d1e27..00000000 --- a/web-harness/mocks/demo-workspace/agentcore.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "name": "DemoWorkspace", - "version": "0.1", - "description": "Demo AgentCore workspace for browser testing", - "agents": [ - { - "name": "ResearchAssistant", - "id": "research-assistant-001", - "sdkFramework": "Strands", - "targetLanguage": "python", - "modelProvider": "Bedrock", - "runtime": { - "artifact": "CodeZip", - "name": "ResearchAssistantRuntime", - "pythonVersion": "PYTHON_3_12", - "entrypoint": "main.py:agent", - "codeLocation": "./agents/research" - }, - "mcpProviders": [ - { - "type": "AgentCoreGateway", - "name": "MainTools", - "description": "Primary tool gateway", - "gatewayName": "main-gateway" - } - ], - "memoryProviders": [ - { - "type": "AgentCoreMemory", - "relation": "own", - "name": "SharedMemory", - "description": "Shared memory", - "config": { - "eventExpiryDuration": 30, - "memoryStrategies": [{ "type": "SEMANTIC", "name": "semantic_memory" }] - } - } - ], - "identityProviders": [], - "remoteTools": [] - }, - { - "name": "CodeReviewer", - "id": "code-reviewer-001", - "sdkFramework": "Strands", - "targetLanguage": "Typescript", - "modelProvider": "Bedrock", - "runtime": { - "artifact": "CodeZip", - "name": "CodeReviewerRuntime", - "pythonVersion": "PYTHON_3_12", - "entrypoint": "main.py:agent", - "codeLocation": "./agents/reviewer" - }, - "mcpProviders": [ - { - "type": "AgentCoreGateway", - "name": "MainTools", - "description": "Primary tool gateway", - "gatewayName": "main-gateway" - } - ], - "memoryProviders": [ - { - "type": "AgentCoreMemory", - "relation": "own", - "name": "SharedMemory", - "description": "Shared memory", - "config": { - "eventExpiryDuration": 30, - "memoryStrategies": [{ "type": "SEMANTIC", "name": "semantic_memory" }] - } - } - ], - "identityProviders": [], - "remoteTools": [] - } - ] -} diff --git a/web-harness/mocks/demo-workspace/aws-targets.json b/web-harness/mocks/demo-workspace/aws-targets.json deleted file mode 100644 index 87fa2da6..00000000 --- a/web-harness/mocks/demo-workspace/aws-targets.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "development", - "account": "123456789012", - "region": "us-west-2", - "stage": "dev" - }, - { - "name": "production", - "account": "123456789012", - "region": "us-east-1", - "stage": "prod" - } -] diff --git a/web-harness/mocks/demo-workspace/deployed-state.json b/web-harness/mocks/demo-workspace/deployed-state.json deleted file mode 100644 index 0888e097..00000000 --- a/web-harness/mocks/demo-workspace/deployed-state.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "targets": { - "development": { - "stackName": "AgentCore-DemoWorkspace-dev", - "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/AgentCore-DemoWorkspace-dev/abc123", - "lastDeployedAt": "2024-01-15T10:30:00Z", - "outputs": { - "ResearchAssistantRuntimeArn": "arn:aws:agentcore:us-west-2:123456789012:runtime/research-assistant", - "CodeReviewerRuntimeArn": "arn:aws:agentcore:us-west-2:123456789012:runtime/code-reviewer" - } - } - } -} diff --git a/web-harness/mocks/demo-workspace/mcp-defs.json b/web-harness/mocks/demo-workspace/mcp-defs.json deleted file mode 100644 index c0215003..00000000 --- a/web-harness/mocks/demo-workspace/mcp-defs.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "tools": { - "web-search": { - "name": "web-search", - "description": "Search the web for information", - "inputSchema": { - "type": "object", - "properties": { - "query": { "type": "string" } - } - } - }, - "code-analyzer": { - "name": "code-analyzer", - "description": "Analyze code for patterns and issues", - "inputSchema": { - "type": "object", - "properties": { - "code": { "type": "string" }, - "language": { "type": "string" } - } - } - } - } -} diff --git a/web-harness/mocks/demo-workspace/mcp.json b/web-harness/mocks/demo-workspace/mcp.json deleted file mode 100644 index eeca73a9..00000000 --- a/web-harness/mocks/demo-workspace/mcp.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "agentCoreGateways": [ - { - "name": "main-gateway", - "description": "Primary gateway for agent tools", - "targets": [ - { - "targetType": "lambda", - "toolDefinition": { - "name": "web-search", - "description": "Search the web for information", - "inputSchema": { "type": "object", "properties": { "query": { "type": "string" } } } - }, - "compute": { - "host": "Lambda", - "implementation": { - "path": "./tools/web-search", - "language": "python", - "handler": "handler.search" - }, - "pythonVersion": "PYTHON_3_12" - } - }, - { - "targetType": "lambda", - "toolDefinition": { - "name": "file-reader", - "description": "Read files from S3", - "inputSchema": { - "type": "object", - "properties": { "bucket": { "type": "string" }, "key": { "type": "string" } } - } - }, - "compute": { - "host": "Lambda", - "implementation": { - "path": "./tools/file-reader", - "language": "python", - "handler": "handler.read" - }, - "pythonVersion": "PYTHON_3_12" - } - } - ] - }, - { - "name": "internal-gateway", - "targets": [] - } - ], - "standaloneRuntimeTools": [ - { - "name": "code-executor", - "toolDefinition": { - "name": "execute-code", - "description": "Execute code in a sandbox", - "inputSchema": { - "type": "object", - "properties": { "code": { "type": "string" }, "language": { "type": "string" } } - } - }, - "compute": { - "host": "AgentCoreRuntime", - "implementation": { - "path": "./tools/code-executor", - "language": "python", - "handler": "handler.execute" - } - } - } - ] -} diff --git a/web-harness/mocks/empty-workspace/agentcore.json b/web-harness/mocks/empty-workspace/agentcore.json deleted file mode 100644 index af22878d..00000000 --- a/web-harness/mocks/empty-workspace/agentcore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "EmptyWorkspace", - "version": "0.1", - "description": "Empty workspace for testing initial state", - "agents": [] -} diff --git a/web-harness/mocks/empty-workspace/aws-targets.json b/web-harness/mocks/empty-workspace/aws-targets.json deleted file mode 100644 index fe51488c..00000000 --- a/web-harness/mocks/empty-workspace/aws-targets.json +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/web-harness/mocks/empty-workspace/deployed-state.json b/web-harness/mocks/empty-workspace/deployed-state.json deleted file mode 100644 index bf7bb6fa..00000000 --- a/web-harness/mocks/empty-workspace/deployed-state.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "targets": {} -} diff --git a/web-harness/mocks/empty-workspace/mcp-defs.json b/web-harness/mocks/empty-workspace/mcp-defs.json deleted file mode 100644 index 2f8e00f8..00000000 --- a/web-harness/mocks/empty-workspace/mcp-defs.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "tools": {} -} diff --git a/web-harness/mocks/empty-workspace/mcp.json b/web-harness/mocks/empty-workspace/mcp.json deleted file mode 100644 index 617139bc..00000000 --- a/web-harness/mocks/empty-workspace/mcp.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "agentCoreGateways": [] -} diff --git a/web-harness/nl-edit-mock.ts b/web-harness/nl-edit-mock.ts deleted file mode 100644 index 0c703dcf..00000000 --- a/web-harness/nl-edit-mock.ts +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Mock for the nl-edit operations module. - * The real module uses Bun-specific `import ... with { type: 'text' }` syntax - * which is not supported by Vite/esbuild. - */ - -// Re-export types without importing from the schema package -export interface SchemaState { - workspace: unknown | null; - mcp: unknown | null; - mcpDefs: unknown | null; -} - -export interface OutOfDomainResponse { - status: 'OUT_OF_DOMAIN'; - reason: string; -} - -export interface AmbiguousInputResponse { - status: 'AMBIGUOUS_INPUT'; - reason: string; -} - -export interface SuccessResponse { - status: 'SUCCESS'; - diff_message: string; - changes: { - 'agentcore.json'?: unknown; - 'mcp.json'?: unknown; - 'mcp-defs.json'?: unknown; - }; -} - -export interface ResponseValidationIssue { - path: string; - message: string; -} - -export interface ResponseValidationError { - file: string; - issues: ResponseValidationIssue[]; -} - -export type NlEditResponse = OutOfDomainResponse | AmbiguousInputResponse | SuccessResponse; - -export interface NlEditResult { - success: boolean; - response?: NlEditResponse; - previewPaths?: Record; - error?: string; - validationError?: ResponseValidationError; -} - -export interface ValidationResult { - success: boolean; - response?: NlEditResponse; - error?: string; - validationError?: ResponseValidationError; -} - -// Mock functions -export async function executeNlEdit(_userInput: string, _cwd: string): Promise { - console.log('[nl-edit-mock] executeNlEdit called'); - return { - success: false, - error: 'NL Edit is not available in browser harness', - }; -} - -export async function applyNlEditChanges(_cwd: string, _response: SuccessResponse): Promise { - console.log('[nl-edit-mock] applyNlEditChanges called'); - throw new Error('NL Edit is not available in browser harness'); -} - -export async function buildPrompt( - _userInput: string, - _currentSchemas: SchemaState, - _fileTreeContext: string -): Promise { - console.log('[nl-edit-mock] buildPrompt called'); - return 'Mock prompt - NL Edit not available in browser'; -} - -export function parseAndValidateResponse(_rawContent: string): ValidationResult { - console.log('[nl-edit-mock] parseAndValidateResponse called'); - return { - success: false, - error: 'NL Edit is not available in browser harness', - }; -} diff --git a/web-harness/node-mocks.ts b/web-harness/node-mocks.ts deleted file mode 100644 index b02ce5ad..00000000 --- a/web-harness/node-mocks.ts +++ /dev/null @@ -1,445 +0,0 @@ -// Comprehensive mock for Node.js modules in browser -// ============= Mock Filesystem Integration ============= -// Uses the mock-fs-client for writable file operations that persist during dev session -import { HARNESS_CONFIG, MOCK_SCENARIO, type MockScenario } from './harness-env'; -import * as mockFs from './mock-fs-client'; - -// Re-export types and scenario getter for convenience -export type { MockScenario }; -export function getMockScenario(): MockScenario { - return MOCK_SCENARIO; -} - -// Define mock paths -const MOCK_WORKSPACE = '/mock/workspace/agentcore'; -const MOCK_CLI_DIR = `${MOCK_WORKSPACE}/.cli`; - -// Map of file names to their virtual paths -const FILE_NAME_TO_PATH: Record = { - 'agentcore.json': `${MOCK_WORKSPACE}/agentcore.json`, - 'aws-targets.json': `${MOCK_WORKSPACE}/aws-targets.json`, - 'mcp.json': `${MOCK_WORKSPACE}/mcp.json`, - 'mcp-defs.json': `${MOCK_WORKSPACE}/mcp-defs.json`, - 'deployed-state.json': `${MOCK_CLI_DIR}/deployed-state.json`, -}; - -// Known mock directories -const MOCK_DIRS = ['agentcore', '.cli', '.cli/logs', 'cdk']; - -// ============= fs module ============= - -// Helper to resolve file path to virtual path -function resolveToVirtualPath(filePath: string): string | null { - const normalizedPath = String(filePath); - const fileName = normalizedPath.split('/').pop() || ''; - - // Check if this is a known mock file by name - if (FILE_NAME_TO_PATH[fileName]) { - return FILE_NAME_TO_PATH[fileName]; - } - - // Check if the path is already a virtual path - if (normalizedPath.startsWith('/mock/')) { - return normalizedPath; - } - - return null; -} - -// Helper to return mock content based on file path -function getMockFileContent(filePath: string): string { - const virtualPath = resolveToVirtualPath(filePath); - - if (virtualPath) { - return mockFs.readFileSync(virtualPath); - } - - // Special case for package.json - if (filePath.endsWith('package.json')) { - return JSON.stringify({ name: 'mock-package', version: '1.0.0', dependencies: {} }); - } - - // Default for unknown JSON files - if (filePath.endsWith('.json')) { - return '{}'; - } - - return ''; -} - -export const existsSync = (path: string): boolean => { - const virtualPath = resolveToVirtualPath(path); - - // Check virtual file system - if (virtualPath && mockFs.existsSync(virtualPath)) { - return true; - } - - // Check if it's a package.json (needed for CDK project validation) - const fileName = String(path).split('/').pop() || ''; - if (fileName === 'package.json') return true; - - // Check if it's a known mock directory - const normalizedPath = String(path); - for (const dir of MOCK_DIRS) { - if (normalizedPath.endsWith(dir) || normalizedPath.endsWith(`/${dir}`)) { - return true; - } - } - - return false; -}; - -export const readdirSync = (path: string): string[] => { - const virtualPath = resolveToVirtualPath(path); - if (virtualPath) { - return mockFs.readdirSync(virtualPath); - } - return []; -}; - -export const statSync = (path: string) => { - const isDir = mockFs.isDirectory(path); - return { - isDirectory: () => isDir, - isFile: () => !isDir && mockFs.existsSync(path), - }; -}; - -export const readFileSync = (filePath: string): string => getMockFileContent(String(filePath)); - -export const writeFileSync = (filePath: string, content: string | object): void => { - const virtualPath = resolveToVirtualPath(filePath); - if (virtualPath) { - const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2); - mockFs.writeFileSync(virtualPath, contentStr); - } -}; - -export const mkdirSync = () => {}; -export const unlinkSync = () => {}; -export const copyFileSync = () => {}; -export const rmSync = () => {}; -export const appendFileSync = () => {}; -export const createReadStream = () => ({ pipe: () => {}, on: () => {} }); -export const createWriteStream = () => ({ write: () => {}, end: () => {}, on: () => {} }); - -export const promises = { - readFile: async (filePath: string): Promise => { - const virtualPath = resolveToVirtualPath(filePath); - if (virtualPath) { - return mockFs.readFile(virtualPath); - } - return getMockFileContent(String(filePath)); - }, - writeFile: async (filePath: string, content: string | object): Promise => { - const virtualPath = resolveToVirtualPath(filePath); - if (virtualPath) { - const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2); - await mockFs.writeFile(virtualPath, contentStr); - } - }, - mkdir: async () => {}, - readdir: async (path: string) => readdirSync(path), - stat: async (path: string) => statSync(path), - unlink: async () => {}, - rm: async () => {}, - copyFile: async () => {}, - access: async () => {}, - rename: async () => {}, -}; - -// Also export async functions at top level for fs/promises imports -export const readFile = promises.readFile; -export const writeFile = promises.writeFile; -export const mkdir = promises.mkdir; -export const readdir = promises.readdir; -export const stat = promises.stat; -export const access = promises.access; -export const copyFile = promises.copyFile; -export const rm = promises.rm; -export const rename = promises.rename; - -// ============= path module ============= -export const join = (...parts: string[]) => parts.filter(Boolean).join('/'); -export const resolve = (...parts: string[]) => '/' + parts.filter(Boolean).join('/'); -export const dirname = (p: string) => p.split('/').slice(0, -1).join('/') || '/'; -export const basename = (p: string, ext?: string) => { - const base = p.split('/').pop() || ''; - return ext && base.endsWith(ext) ? base.slice(0, -ext.length) : base; -}; -export const extname = (p: string) => { - const base = p.split('/').pop() || ''; - const idx = base.lastIndexOf('.'); - return idx > 0 ? base.slice(idx) : ''; -}; -export const relative = (_from: string, to: string) => to; -export const isAbsolute = (p: string) => p.startsWith('/'); -export const normalize = (p: string) => p; -export const sep = '/'; -export const delimiter = ':'; -export const parse = (p: string) => ({ - root: '/', - dir: dirname(p), - base: basename(p), - ext: extname(p), - name: basename(p, extname(p)), -}); - -// ============= url module ============= -export const fileURLToPath = (url: string | URL) => { - const urlStr = typeof url === 'string' ? url : url.href; - return urlStr.replace('file://', ''); -}; -export const pathToFileURL = (p: string) => new URL(`file://${p}`); - -// ============= child_process module ============= -export const spawn = () => ({ - stdout: { on: () => {}, pipe: () => {} }, - stderr: { on: () => {}, pipe: () => {} }, - stdin: { write: () => {}, end: () => {} }, - on: (_event: string, cb: (code: number) => void) => { - if (_event === 'close') setTimeout(() => cb(0), 10); - }, - kill: () => {}, -}); -export const execSync = () => ''; -export const exec = (_cmd: string, _opts: unknown, cb?: (err: null, stdout: string, stderr: string) => void) => { - const callback = typeof _opts === 'function' ? _opts : cb; - if (callback) setTimeout(() => callback(null, '', ''), 10); -}; -export const spawnSync = () => ({ stdout: '', stderr: '', status: 0 }); -export const fork = spawn; -export const execFile = exec; -export const execFileSync = execSync; - -// ============= os module ============= -export const platform = () => 'browser'; -export const homedir = () => '/home/user'; -export const tmpdir = () => '/tmp'; -export const hostname = () => 'localhost'; -export const type = () => 'Browser'; -export const release = () => '1.0.0'; -export const cpus = () => [{ model: 'Browser', speed: 0 }]; -export const totalmem = () => 0; -export const freemem = () => 0; -export const EOL = '\n'; -export const arch = () => 'x64'; -export const userInfo = () => ({ username: 'user', homedir: '/home/user' }); - -// ============= crypto module ============= -export const randomBytes = (size: number) => new Uint8Array(size); -export const randomUUID = () => crypto.randomUUID(); -export const createHash = () => ({ - update: function () { - return this; - }, - digest: () => 'mockhash', -}); -export const createHmac = createHash; - -// ============= events module ============= -export class EventEmitter { - private listeners: Record = {}; - on(event: string, listener: Function) { - this.listeners[event] = this.listeners[event] || []; - this.listeners[event].push(listener); - return this; - } - emit(event: string, ...args: unknown[]) { - (this.listeners[event] || []).forEach(fn => fn(...args)); - return true; - } - removeListener(event: string, listener: Function) { - this.listeners[event] = (this.listeners[event] || []).filter(fn => fn !== listener); - return this; - } - off = this.removeListener; - once(event: string, listener: Function) { - const wrapped = (...args: unknown[]) => { - this.removeListener(event, wrapped); - listener(...args); - }; - return this.on(event, wrapped); - } - addListener = this.on; - removeAllListeners(event?: string) { - if (event) delete this.listeners[event]; - else this.listeners = {}; - return this; - } - listenerCount(event: string) { - return (this.listeners[event] || []).length; - } -} - -// ============= stream module ============= -export class Readable extends EventEmitter { - pipe() { - return this; - } - read() { - return null; - } -} -export class Writable extends EventEmitter { - write() { - return true; - } - end() {} -} -export class Transform extends EventEmitter { - pipe() { - return this; - } - write() { - return true; - } - end() {} -} -export class PassThrough extends Transform {} -export class Duplex extends EventEmitter { - pipe() { - return this; - } - write() { - return true; - } - end() {} - read() { - return null; - } -} - -// stream/promises exports -export const pipeline = async (..._args: unknown[]) => { - // Mock pipeline - just resolve immediately - return Promise.resolve(); -}; -export const finished = async (_stream: unknown) => { - return Promise.resolve(); -}; - -// ============= util module ============= -export const promisify = (fn: Function) => fn; -export const inspect = (obj: unknown) => JSON.stringify(obj); -export const format = (fmt: string, ...args: unknown[]) => { - let i = 0; - return fmt.replace(/%[sdjO]/g, () => String(args[i++])); -}; -export const deprecate = (fn: Function) => fn; -export const inherits = () => {}; -export const types = { - isPromise: (v: unknown) => v instanceof Promise, -}; - -// ============= net module ============= -export const createServer = () => ({ - listen: () => {}, - close: () => {}, - on: () => {}, - address: () => ({ port: 0 }), -}); -export const createConnection = () => ({ - on: () => {}, - write: () => {}, - end: () => {}, - destroy: () => {}, -}); -export const connect = createConnection; -export const Socket = class { - on() { - return this; - } - write() { - return true; - } - end() {} - destroy() {} -}; -export const Server = class { - listen() { - return this; - } - close() {} - on() { - return this; - } - address() { - return { port: 0 }; - } -}; - -// ============= http/https module ============= -export const request = () => ({ - on: () => {}, - write: () => {}, - end: () => {}, -}); -export const get = request; -export const Agent = class {}; -export const globalAgent = {}; - -// ============= tty module ============= -export const isatty = () => false; -export const ReadStream = class extends Readable {}; -export const WriteStream = class extends Writable {}; - -// ============= readline module ============= -export const createInterface = () => ({ - on: () => {}, - question: (_q: string, cb: (a: string) => void) => cb(''), - close: () => {}, - prompt: () => {}, -}); - -// ============= buffer module ============= -export const Buffer = { - from: (data: unknown) => new Uint8Array(typeof data === 'string' ? data.split('').map(c => c.charCodeAt(0)) : []), - alloc: (size: number) => new Uint8Array(size), - allocUnsafe: (size: number) => new Uint8Array(size), - isBuffer: () => false, - concat: (list: Uint8Array[]) => { - const totalLength = list.reduce((acc, arr) => acc + arr.length, 0); - const result = new Uint8Array(totalLength); - let offset = 0; - for (const arr of list) { - result.set(arr, offset); - offset += arr.length; - } - return result; - }, -}; - -// ============= assert module ============= -export const ok = () => {}; -export const strictEqual = () => {}; -export const deepStrictEqual = () => {}; -export const notStrictEqual = () => {}; -export const throws = () => {}; -export const doesNotThrow = () => {}; -export const rejects = async () => {}; -export const doesNotReject = async () => {}; - -// ============= zlib module ============= -export const gzip = (_data: unknown, cb: (err: null, result: Uint8Array) => void) => cb(null, new Uint8Array()); -export const gunzip = gzip; -export const deflate = gzip; -export const inflate = gzip; -export const createGzip = () => new Transform(); -export const createGunzip = () => new Transform(); - -// Default export for path (commonly used as `import path from 'path'`) -export default { - join, - resolve, - dirname, - basename, - extname, - relative, - isAbsolute, - normalize, - sep, - delimiter, - parse, -}; diff --git a/web-harness/package-lock.json b/web-harness/package-lock.json deleted file mode 100644 index b72c3eb4..00000000 --- a/web-harness/package-lock.json +++ /dev/null @@ -1,1768 +0,0 @@ -{ - "name": "agentcore-web-harness", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "agentcore-web-harness", - "dependencies": { - "react": "^19.2.3", - "react-dom": "^19.2.3", - "zod": "^4.2.1" - }, - "devDependencies": { - "@types/react": "^19.2.7", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^4.4.0", - "playwright": "^1.58.0", - "typescript": "^5.0.0", - "vite": "^6.0.0" - } - }, - "../packages/agentcore-schema": { - "name": "@agentcore/schema", - "version": "0.1.0", - "extraneous": true, - "dependencies": { - "zod": "^4.2.1" - }, - "devDependencies": { - "@eslint/js": "^9.39.2", - "@types/node": "^25.0.3", - "@typescript-eslint/eslint-plugin": "^8.50.0", - "@typescript-eslint/parser": "^8.50.0", - "eslint": "^9.39.2", - "eslint-config-prettier": "^10.1.8", - "typescript": "^5" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "dev": true, - "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" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "dev": true - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", - "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", - "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", - "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", - "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", - "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", - "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", - "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", - "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", - "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", - "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", - "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", - "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", - "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", - "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", - "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", - "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", - "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", - "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", - "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", - "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", - "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", - "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", - "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", - "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", - "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true - }, - "node_modules/@types/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", - "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", - "dev": true, - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.9.12", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.12.tgz", - "integrity": "sha512-Mij6Lij93pTAIsSYy5cyBQ975Qh9uLEc5rwGTpomiZeXZL9yIS6uORJakb3ScHgfs0serMMfIbXzokPMuEiRyw==", - "dev": true, - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", - "dev": true - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/playwright": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0.tgz", - "integrity": "sha512-2SVA0sbPktiIY/MCOPX8e86ehA/e+tDNq+e5Y8qjKYti2Z/JG7xnronT/TXTIkKbYGWlCbuucZ6dziEgkoEjQQ==", - "dev": true, - "dependencies": { - "playwright-core": "1.58.0" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.58.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0.tgz", - "integrity": "sha512-aaoB1RWrdNi3//rOeKuMiS65UCcgOVljU46At6eFcOFPFHWtd2weHRRow6z/n+Lec0Lvu0k9ZPKJSjPugikirw==", - "dev": true, - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.3" - } - }, - "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.55.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", - "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.55.1", - "@rollup/rollup-android-arm64": "4.55.1", - "@rollup/rollup-darwin-arm64": "4.55.1", - "@rollup/rollup-darwin-x64": "4.55.1", - "@rollup/rollup-freebsd-arm64": "4.55.1", - "@rollup/rollup-freebsd-x64": "4.55.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", - "@rollup/rollup-linux-arm-musleabihf": "4.55.1", - "@rollup/rollup-linux-arm64-gnu": "4.55.1", - "@rollup/rollup-linux-arm64-musl": "4.55.1", - "@rollup/rollup-linux-loong64-gnu": "4.55.1", - "@rollup/rollup-linux-loong64-musl": "4.55.1", - "@rollup/rollup-linux-ppc64-gnu": "4.55.1", - "@rollup/rollup-linux-ppc64-musl": "4.55.1", - "@rollup/rollup-linux-riscv64-gnu": "4.55.1", - "@rollup/rollup-linux-riscv64-musl": "4.55.1", - "@rollup/rollup-linux-s390x-gnu": "4.55.1", - "@rollup/rollup-linux-x64-gnu": "4.55.1", - "@rollup/rollup-linux-x64-musl": "4.55.1", - "@rollup/rollup-openbsd-x64": "4.55.1", - "@rollup/rollup-openharmony-arm64": "4.55.1", - "@rollup/rollup-win32-arm64-msvc": "4.55.1", - "@rollup/rollup-win32-ia32-msvc": "4.55.1", - "@rollup/rollup-win32-x64-gnu": "4.55.1", - "@rollup/rollup-win32-x64-msvc": "4.55.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/vite": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", - "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", - "dev": true, - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/zod": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", - "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/web-harness/package.json b/web-harness/package.json deleted file mode 100644 index 145a5c3b..00000000 --- a/web-harness/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "agentcore-web-harness", - "private": true, - "type": "module", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "dependencies": { - "react": "^19.2.3", - "react-dom": "^19.2.3", - "zod": "^4.2.1" - }, - "devDependencies": { - "@types/react": "^19.2.7", - "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^4.4.0", - "playwright": "^1.58.0", - "typescript": "^5.0.0", - "vite": "^6.0.0" - } -} diff --git a/web-harness/schema-assets-mock.ts b/web-harness/schema-assets-mock.ts deleted file mode 100644 index f88c0456..00000000 --- a/web-harness/schema-assets-mock.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Mock for templates/schema-assets.ts - browser mock -// These are raw text imports that don't work in the browser - -/** - * LLM-compacted schema files for AI coding context. - * Each file is self-contained and maps to a JSON config file. - */ -export const LLM_CONTEXT_FILES: Record = { - 'README.md': '# LLM Context Files\n\nMock content for browser testing.', - 'agentcore.ts': 'export const AgentCoreSchema = {};', - 'aws-targets.ts': 'export const AwsTargetsSchema = {};', -}; diff --git a/web-harness/screenshot.png b/web-harness/screenshot.png deleted file mode 100644 index 7ab22b1d..00000000 Binary files a/web-harness/screenshot.png and /dev/null differ diff --git a/web-harness/shell-mock.ts b/web-harness/shell-mock.ts deleted file mode 100644 index a82afa05..00000000 --- a/web-harness/shell-mock.ts +++ /dev/null @@ -1,65 +0,0 @@ -// Mock for shell module - no-op implementations for browser - -// Types -export type ShellMode = 'inactive' | 'input' | 'running' | 'done'; - -export interface ShellOutput { - lines: string[]; - exitCode: number | null; -} - -export interface ShellExecutorCallbacks { - onOutput: (lines: string[]) => void; - onComplete: (exitCode: number | null) => void; - onError: (error: string) => void; -} - -export interface ShellExecutor { - kill: (signal?: string) => void; -} - -// Functions -export function warmupShell(): void { - console.log('[browser mock] warmupShell called'); -} - -export function destroyShell(): void { - console.log('[browser mock] destroyShell called'); -} - -export function spawnPersistentShellCommand(command: string, callbacks: ShellExecutorCallbacks): ShellExecutor { - // Simulate command execution with mock output - setTimeout(() => { - callbacks.onOutput([`$ ${command}`, '(Commands are mocked in browser)']); - }, 50); - - setTimeout(() => { - callbacks.onComplete(0); - }, 150); - - return { - kill: (_signal?: string) => { - console.log('[browser mock] persistent shell kill called'); - callbacks.onComplete(130); - }, - }; -} - -export function spawnShellCommand(command: string, callbacks: ShellExecutorCallbacks): ShellExecutor { - // Simulate command execution with mock output - setTimeout(() => { - callbacks.onOutput([`$ ${command}`, '(Commands are mocked in browser)']); - }, 50); - - setTimeout(() => { - callbacks.onComplete(0); - }, 150); - - return { - kill: (_signal?: string) => console.log('[browser mock] shell kill called'), - }; -} - -export function truncateOutput(lines: string[], _maxLines: number = 500): string[] { - return lines; -} diff --git a/web-harness/template-root-mock.ts b/web-harness/template-root-mock.ts deleted file mode 100644 index 30518df0..00000000 --- a/web-harness/template-root-mock.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Mock for templates/templateRoot.ts - browser mock - -export const TEMPLATE_ROOT = '/mock/templates'; - -export function resolveTemplateRoot(): string { - return TEMPLATE_ROOT; -} - -export function getTemplatePath(relativePath: string): string { - return `${TEMPLATE_ROOT}/${relativePath}`; -} diff --git a/web-harness/test-harness.mjs b/web-harness/test-harness.mjs deleted file mode 100644 index 91899339..00000000 --- a/web-harness/test-harness.mjs +++ /dev/null @@ -1,73 +0,0 @@ -import { chromium } from 'playwright'; - -async function testHarness() { - const browser = await chromium.launch({ headless: true }); - const page = await browser.newPage(); - - // Collect console messages - const consoleLogs = []; - const consoleErrors = []; - - page.on('console', msg => { - if (msg.type() === 'error') { - consoleErrors.push(msg.text()); - } else { - consoleLogs.push(`[${msg.type()}] ${msg.text()}`); - } - }); - - page.on('pageerror', err => { - consoleErrors.push(`PAGE ERROR: ${err.message}`); - }); - - try { - console.log('Navigating to http://localhost:5173/...'); - await page.goto('http://localhost:5173/', { waitUntil: 'networkidle', timeout: 30000 }); - - // Wait a bit for React to render - await page.waitForTimeout(2000); - - // Get page title - const title = await page.title(); - console.log(`\nPage title: ${title}`); - - // Check if root has content - const rootContent = await page.$eval('#root', el => el.innerHTML.length); - console.log(`Root element content length: ${rootContent} chars`); - - // Look for terminal frames - const terminals = await page.$$('div[style*="background"]'); - console.log(`Found ${terminals.length} styled divs`); - - // Get visible text - const bodyText = await page.textContent('body'); - console.log(`\nVisible text preview: ${bodyText?.substring(0, 500)}...`); - - // Take a screenshot - await page.screenshot({ path: '/Users/owenkaplan/code/agentcore-cli/web-harness/screenshot.png', fullPage: true }); - console.log('\nScreenshot saved to web-harness/screenshot.png'); - - // Report errors - if (consoleErrors.length > 0) { - console.log('\n❌ CONSOLE ERRORS:'); - consoleErrors.forEach(e => console.log(` - ${e}`)); - } else { - console.log('\n✅ No console errors!'); - } - - // Report some logs - if (consoleLogs.length > 0) { - console.log(`\nConsole logs (${consoleLogs.length} total):`); - consoleLogs.slice(0, 10).forEach(l => console.log(` ${l}`)); - if (consoleLogs.length > 10) { - console.log(` ... and ${consoleLogs.length - 10} more`); - } - } - } catch (err) { - console.error('Error:', err.message); - } finally { - await browser.close(); - } -} - -testHarness(); diff --git a/web-harness/test-writable-fs.mjs b/web-harness/test-writable-fs.mjs deleted file mode 100644 index c840517d..00000000 --- a/web-harness/test-writable-fs.mjs +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env node -/** - * Test script to verify the writable mock filesystem works end-to-end. - * - * Tests: - * 1. Server API endpoints work (read/write/reset) - * 2. Changes persist until reset - * 3. Reset restores original data - */ - -const BASE_URL = 'http://localhost:5173'; - -async function testReadFile(path) { - const response = await fetch(`${BASE_URL}/__mock-fs${path}`); - if (!response.ok) { - throw new Error(`Failed to read ${path}: ${response.status}`); - } - const data = await response.json(); - return data.content; -} - -async function testWriteFile(path, content) { - const response = await fetch(`${BASE_URL}/__mock-fs${path}`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ content }), - }); - if (!response.ok) { - throw new Error(`Failed to write ${path}: ${response.status}`); - } - return await response.json(); -} - -async function testReset() { - const response = await fetch(`${BASE_URL}/__mock-fs-reset`, { method: 'POST' }); - if (!response.ok) { - throw new Error(`Failed to reset: ${response.status}`); - } - return await response.json(); -} - -async function testSync() { - const response = await fetch(`${BASE_URL}/__mock-fs-sync`); - if (!response.ok) { - throw new Error(`Failed to sync: ${response.status}`); - } - return await response.json(); -} - -async function runTests() { - console.log('🧪 Testing Writable Mock Filesystem\n'); - - const agentcorePath = '/mock/workspace/agentcore/agentcore.json'; - - // Test 1: Read original file - console.log('1️⃣ Testing: Read original file...'); - const originalContent = await testReadFile(agentcorePath); - const original = JSON.parse(originalContent); - console.log(` ✅ Original workspace name: "${original.name}"`); - console.log(` ✅ Original has ${original.agents?.length || 0} agents`); - - // Test 2: Write modified content - console.log('\n2️⃣ Testing: Write modified content...'); - const modified = { - ...original, - name: 'ModifiedWorkspace', - description: 'This was modified by the test script!', - agents: original.agents?.slice(0, 1) || [], // Keep only first agent - }; - await testWriteFile(agentcorePath, JSON.stringify(modified, null, 2)); - console.log(' ✅ Write successful'); - - // Test 3: Read back modified content - console.log('\n3️⃣ Testing: Read back modified content...'); - const readBackContent = await testReadFile(agentcorePath); - const readBack = JSON.parse(readBackContent); - if (readBack.name !== 'ModifiedWorkspace') { - throw new Error(`Expected name "ModifiedWorkspace", got "${readBack.name}"`); - } - console.log(` ✅ Modified workspace name: "${readBack.name}"`); - console.log(` ✅ Modified has ${readBack.agents?.length || 0} agents`); - - // Test 4: Verify changes persist via sync endpoint - console.log('\n4️⃣ Testing: Verify changes via sync endpoint...'); - const syncData = await testSync(); - const syncedContent = syncData.files[agentcorePath]?.content; - if (!syncedContent?.includes('ModifiedWorkspace')) { - throw new Error('Sync endpoint did not return modified content'); - } - console.log(' ✅ Changes are visible in sync endpoint'); - - // Test 5: Reset filesystem - console.log('\n5️⃣ Testing: Reset filesystem...'); - await testReset(); - console.log(' ✅ Reset successful'); - - // Test 6: Verify reset restored original - console.log('\n6️⃣ Testing: Verify reset restored original...'); - const afterResetContent = await testReadFile(agentcorePath); - const afterReset = JSON.parse(afterResetContent); - if (afterReset.name !== original.name) { - throw new Error(`Expected name "${original.name}", got "${afterReset.name}"`); - } - console.log(` ✅ Reset restored workspace name: "${afterReset.name}"`); - console.log(` ✅ Reset restored ${afterReset.agents?.length || 0} agents`); - - console.log('\n🎉 All tests passed!\n'); - console.log('The writable mock filesystem is working correctly.'); - console.log('- Changes persist in memory during the dev session'); - console.log('- Reset restores the original mock data'); - console.log('- Refreshing the page will reload data from server memory'); -} - -runTests().catch(err => { - console.error('\n❌ Test failed:', err.message); - process.exit(1); -}); diff --git a/web-harness/tsconfig.json b/web-harness/tsconfig.json deleted file mode 100644 index feeccc4f..00000000 --- a/web-harness/tsconfig.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - "strict": true, - "noUnusedLocals": false, - "noUnusedParameters": false, - "noFallthroughCasesInSwitch": true, - "paths": { - "@agentcore/lib": ["./lib-mocks.ts"], - "@agentcore/schema": ["./lib-mocks.ts"] - } - }, - "include": [ - "./**/*.ts", - "./**/*.tsx", - "../packages/agentcore-cli/src/**/*.ts", - "../packages/agentcore-cli/src/**/*.tsx" - ] -} diff --git a/web-harness/tui-process-mock.ts b/web-harness/tui-process-mock.ts deleted file mode 100644 index 8e46602b..00000000 --- a/web-harness/tui-process-mock.ts +++ /dev/null @@ -1,9 +0,0 @@ -// Mock for tui/utils/process.ts - no-op implementations for browser - -export async function isProcessRunning(_pid: number): Promise { - return false; -} - -export async function cleanupStaleLockFiles(_cdkOutDir: string): Promise { - // No-op in browser -} diff --git a/web-harness/vite.config.ts b/web-harness/vite.config.ts deleted file mode 100644 index 833ab7c3..00000000 --- a/web-harness/vite.config.ts +++ /dev/null @@ -1,247 +0,0 @@ -import { MOCK_SCENARIO } from './harness-env'; -import { createMockFsPlugin } from './mock-fs-server'; -import react from '@vitejs/plugin-react'; -import path from 'path'; -import { Plugin, defineConfig } from 'vite'; - -// Custom plugin to handle module resolution for Node.js and workspace packages -function browserMocksPlugin(): Plugin { - const mocks: Record = { - // Node.js modules - 'node:fs': path.resolve(__dirname, './node-mocks.ts'), - 'node:fs/promises': path.resolve(__dirname, './node-mocks.ts'), - fs: path.resolve(__dirname, './node-mocks.ts'), - 'fs/promises': path.resolve(__dirname, './node-mocks.ts'), - 'node:path': path.resolve(__dirname, './node-mocks.ts'), - path: path.resolve(__dirname, './node-mocks.ts'), - 'node:url': path.resolve(__dirname, './node-mocks.ts'), - url: path.resolve(__dirname, './node-mocks.ts'), - 'node:child_process': path.resolve(__dirname, './node-mocks.ts'), - child_process: path.resolve(__dirname, './node-mocks.ts'), - 'node:os': path.resolve(__dirname, './node-mocks.ts'), - os: path.resolve(__dirname, './node-mocks.ts'), - 'node:crypto': path.resolve(__dirname, './node-mocks.ts'), - crypto: path.resolve(__dirname, './node-mocks.ts'), - 'node:events': path.resolve(__dirname, './node-mocks.ts'), - events: path.resolve(__dirname, './node-mocks.ts'), - 'node:stream': path.resolve(__dirname, './node-mocks.ts'), - stream: path.resolve(__dirname, './node-mocks.ts'), - 'stream/promises': path.resolve(__dirname, './node-mocks.ts'), - 'node:stream/promises': path.resolve(__dirname, './node-mocks.ts'), - 'node:util': path.resolve(__dirname, './node-mocks.ts'), - util: path.resolve(__dirname, './node-mocks.ts'), - 'node:net': path.resolve(__dirname, './node-mocks.ts'), - net: path.resolve(__dirname, './node-mocks.ts'), - 'node:http': path.resolve(__dirname, './node-mocks.ts'), - http: path.resolve(__dirname, './node-mocks.ts'), - 'node:https': path.resolve(__dirname, './node-mocks.ts'), - https: path.resolve(__dirname, './node-mocks.ts'), - 'node:tty': path.resolve(__dirname, './node-mocks.ts'), - tty: path.resolve(__dirname, './node-mocks.ts'), - 'node:readline': path.resolve(__dirname, './node-mocks.ts'), - readline: path.resolve(__dirname, './node-mocks.ts'), - 'node:buffer': path.resolve(__dirname, './node-mocks.ts'), - buffer: path.resolve(__dirname, './node-mocks.ts'), - 'node:assert': path.resolve(__dirname, './node-mocks.ts'), - assert: path.resolve(__dirname, './node-mocks.ts'), - 'node:zlib': path.resolve(__dirname, './node-mocks.ts'), - zlib: path.resolve(__dirname, './node-mocks.ts'), - - // Ink shims - ink: path.resolve(__dirname, './ink-browser-shim.tsx'), - 'ink-spinner': path.resolve(__dirname, './ink-spinner-shim.tsx'), - // Ink's Node.js dependencies - not needed when using our shim - 'yoga-layout': path.resolve(__dirname, './external-mocks.ts'), - '@resvg/resvg-js': path.resolve(__dirname, './external-mocks.ts'), - 'yoga-wasm-web': path.resolve(__dirname, './external-mocks.ts'), - // Terminal detection packages - not needed in browser - 'supports-color': path.resolve(__dirname, './external-mocks.ts'), - 'supports-hyperlinks': path.resolve(__dirname, './external-mocks.ts'), - - // Force zod to resolve from web-harness node_modules - zod: path.resolve(__dirname, './node_modules/zod/index.js'), - - // External package mocks - '@commander-js/extra-typings': path.resolve(__dirname, './external-mocks.ts'), - commander: path.resolve(__dirname, './external-mocks.ts'), - handlebars: path.resolve(__dirname, './external-mocks.ts'), - dotenv: path.resolve(__dirname, './external-mocks.ts'), - - // AWS SDK mocks - '@aws-sdk/client-cloudformation': path.resolve(__dirname, './external-mocks.ts'), - '@aws-sdk/client-sts': path.resolve(__dirname, './external-mocks.ts'), - '@aws-sdk/client-bedrock-runtime': path.resolve(__dirname, './external-mocks.ts'), - '@aws-sdk/client-bedrock-agentcore': path.resolve(__dirname, './external-mocks.ts'), - '@aws-sdk/client-bedrock-agentcore-control': path.resolve(__dirname, './external-mocks.ts'), - '@aws-sdk/credential-providers': path.resolve(__dirname, './external-mocks.ts'), - '@smithy/shared-ini-file-loader': path.resolve(__dirname, './external-mocks.ts'), - '@aws-cdk/toolkit-lib': path.resolve(__dirname, './external-mocks.ts'), - }; - - const cliMock = path.resolve(__dirname, './cli-mock.ts'); - const shellMock = path.resolve(__dirname, './shell-mock.ts'); - const cliConstantsMock = path.resolve(__dirname, './cli-constants-mock.ts'); - const tuiProcessMock = path.resolve(__dirname, './tui-process-mock.ts'); - const templateRootMock = path.resolve(__dirname, './template-root-mock.ts'); - const nlEditMock = path.resolve(__dirname, './nl-edit-mock.ts'); - - // Path to the main CLI constants (NOT the TUI constants) - const mainConstantsPath = path.resolve(__dirname, '../src/cli/constants.ts'); - - return { - name: 'browser-mocks', - enforce: 'pre', - resolveId(source, importer) { - // Handle exact matches - if (mocks[source]) { - return mocks[source]; - } - - // Mock the CLI module (has many Node.js dependencies including 'module' builtin) - if (source === '../cli' || source === './cli' || source.endsWith('/cli')) { - if (importer?.includes('src/cli')) { - return cliMock; - } - } - - // Mock the shell module - if (source === '../shell' || source === './shell' || source.endsWith('/shell')) { - if (importer?.includes('src/cli')) { - return shellMock; - } - } - - // Mock the lib module (uses Node.js APIs) - if ( - source === '../../lib' || - source === '../../../lib' || - source === '../../../../lib' || - source.match(/^\.\.\/.*\/lib$/) - ) { - if (importer?.includes('src/cli')) { - return path.resolve(__dirname, './lib-mocks.ts'); - } - } - - // Mock the CLI's internal schema module (uses fs/promises) - // Only mock imports that resolve to src/cli/schema (not src/schema) - // From screens/schema/*.tsx, '../../../schema' resolves to cli/schema - // From hooks/*.ts, '../../schema' resolves to cli/schema - if (source === '../../../schema') { - if (importer?.includes('src/cli/tui/screens')) { - return path.resolve(__dirname, './cli-schema-mock.ts'); - } - } - if (source === '../../schema') { - if (importer?.includes('src/cli/tui/hooks')) { - return path.resolve(__dirname, './cli-schema-mock.ts'); - } - } - - // Mock the TUI process utility (uses child_process) - if (source === './process' || source === '../process' || source.endsWith('/process')) { - if (importer?.includes('src/cli/tui')) { - return tuiProcessMock; - } - } - - // Mock templateRoot (uses node:url) - if (source === './templateRoot' || source.endsWith('/templateRoot')) { - if (importer?.includes('src/cli')) { - return templateRootMock; - } - } - - // Mock schema-assets (imports raw text files which need special handling) - if (source === './schema-assets' || source.endsWith('/schema-assets')) { - if (importer?.includes('src/cli')) { - return path.resolve(__dirname, './schema-assets-mock.ts'); - } - } - - // Mock the nl-edit operations module (uses Bun-specific import ... with { type: 'text' }) - if ( - source.includes('operations/nl-edit') || - source === '../../../operations/nl-edit' || - source === '../../operations/nl-edit' || - source === '../operations/nl-edit' || - source === './nl-edit' - ) { - if (importer?.includes('src/cli')) { - console.log(`[browser-mocks] INTERCEPTING nl-edit import -> ${nlEditMock}`); - return nlEditMock; - } - } - - // Mock the MAIN CLI constants.ts (uses Node.js 'module' builtin) - // Intercept imports that resolve to src/cli/constants.ts (not tui/constants.ts) - if (source.endsWith('/constants') || source.endsWith('/constants.ts')) { - // Check if this resolves to the MAIN cli constants (not tui constants) - // ../../../constants from tui/screens/update -> cli/constants (main - needs mock) - // ../../constants from tui/screens -> tui/constants (tui - don't mock) - // ../constants from tui/components -> tui/constants (tui - don't mock) - const isFromTui = importer?.includes('/tui/'); - const goesToMainConstants = - source === '../../../constants' || // from tui/screens/*/ - source === '../../../../constants'; // from tui/screens/*/*/ - - if (isFromTui && goesToMainConstants) { - console.log(`[browser-mocks] INTERCEPTING main constants import from TUI -> ${cliConstantsMock}`); - return cliConstantsMock; - } - - // Also mock non-TUI imports to main constants - const isCliSrc = importer?.includes('src/cli'); - const isNotTui = !isFromTui; - if (isCliSrc && isNotTui) { - console.log(`[browser-mocks] INTERCEPTING constants import -> ${cliConstantsMock}`); - return cliConstantsMock; - } - } - - return null; - }, - }; -} - -export default defineConfig({ - plugins: [createMockFsPlugin(MOCK_SCENARIO), browserMocksPlugin(), react()], - server: { - fs: { - // Allow serving files from parent directory (src/) - allow: ['..'], - }, - }, - define: { - 'process.env': JSON.stringify({}), - 'process.cwd': '() => "/mock/workspace"', - 'process.chdir': '() => {}', - 'process.platform': JSON.stringify('browser'), - // Signal handling no-ops for browser - 'process.on': '(() => {})', - 'process.off': '(() => {})', - 'process.once': '(() => {})', - 'process.removeListener': '(() => {})', - }, - assetsInclude: ['**/*.txt'], - optimizeDeps: { - include: ['zod'], - // Exclude packages that should be aliased to shims - don't let Vite try to pre-bundle them - exclude: ['ink', 'ink-spinner', 'yoga-layout', '@resvg/resvg-js', 'supports-color', 'supports-hyperlinks'], - esbuildOptions: { - platform: 'browser', - }, - }, - resolve: { - // Ensure we use the browser-compatible version - conditions: ['browser', 'module', 'import', 'default'], - // Force single copy of zod - dedupe: ['zod'], - }, - // Handle CommonJS modules from the schema package - build: { - commonjsOptions: { - transformMixedEsModules: true, - }, - }, -});