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,
- },
- },
-});