From 21b2a1191b71a0a0031d5541e98f018864000f95 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 22 Feb 2026 11:41:44 +0100 Subject: [PATCH] feat: integrate xterm-zerolag-input library into Claudeman app.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the embedded 348-line LocalEchoOverlay class with the standalone xterm-zerolag-input library (inlined as ZerolagInputAddon). A bridge class `LocalEchoOverlay extends ZerolagInputAddon` preserves the constructor API so existing `new LocalEchoOverlay(terminal)` call works. All 43+ private property accesses (_flushedOffset, _bufferDetectDone, _lastRenderKey, _render(), _detectBufferText(), etc.) replaced with public library methods: - Backspace: 60-line 3-branch handler → removeChar() returning 'pending'|'flushed'|false + Map sync - Tab completion: _bufferDetectDone/_detectBufferText/_flushedOffset → resetBufferDetection()/detectBufferText()/undoDetection()/rerender() - Tab switch save: _flushedOffset/_flushedText reads → getFlushed() - Tab switch restore: direct assignments → setFlushed(n, t, false) - Buffer detection guard: _bufferDetectDone=true → suppressBufferDetection() - Resize re-render: _lastRenderKey='';rerender() → rerender() - Post-load render: _lastRenderKey='';_render() → rerender() Verified with 9 Playwright integration tests + manual testing. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 2 +- package-lock.json | 1062 ++++++++++++++++------------------------- package.json | 4 +- src/web/public/app.js | 812 +++++++++++++++---------------- 4 files changed, 791 insertions(+), 1089 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 48989e83..52993864 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -35,7 +35,7 @@ When user says "COM": 1. Increment version in BOTH `package.json` AND `CLAUDE.md` (verify they match with `grep version package.json && grep Version CLAUDE.md`) 2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web` -**Version**: 0.1600 (must match `package.json` for npm publish) +**Version**: 0.1601 (must match `package.json` for npm publish) ## Project Overview diff --git a/package-lock.json b/package-lock.json index a15b0dcc..9493ab33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "claudeman", - "version": "0.1580", + "version": "0.1600", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "claudeman", - "version": "0.1580", + "version": "0.1600", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -27,7 +27,7 @@ "claudeman": "dist/index.js" }, "devDependencies": { - "@types/node": "^20.14.0", + "@types/node": "^20.19.33", "@types/pngjs": "^6.0.5", "@types/uuid": "^10.0.0", "@vitest/coverage-v8": "^4.0.18", @@ -46,9 +46,9 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", - "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -88,13 +88,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", - "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.6" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -104,9 +104,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", - "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -769,82 +769,13 @@ "glob": "^11.0.0" } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=18" } }, "node_modules/@jridgewell/resolve-uri": { @@ -891,9 +822,9 @@ "license": "MIT" }, "node_modules/@puppeteer/browsers": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.11.1.tgz", - "integrity": "sha512-YmhAxs7XPuxN0j7LJloHpfD1ylhDuFmmwMvfy/+6nBSrETT2ycL53LrhgPtR+f+GcPSybQVuQ5inWWu5MrWCpA==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz", + "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -901,7 +832,7 @@ "extract-zip": "^2.0.1", "progress": "^2.0.3", "proxy-agent": "^6.5.0", - "semver": "^7.7.3", + "semver": "^7.7.4", "tar-fs": "^3.1.1", "yargs": "^17.7.2" }, @@ -913,9 +844,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", - "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", + "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" ], @@ -927,9 +858,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", - "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", + "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" ], @@ -941,9 +872,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", - "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", + "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" ], @@ -955,9 +886,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", - "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", + "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" ], @@ -969,9 +900,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", - "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", + "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" ], @@ -983,9 +914,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", - "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", + "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" ], @@ -997,9 +928,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", - "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", + "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" ], @@ -1011,9 +942,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", - "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", + "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" ], @@ -1025,9 +956,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", - "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", + "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" ], @@ -1039,9 +970,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", - "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", + "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" ], @@ -1053,9 +984,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", - "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", + "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" ], @@ -1067,9 +998,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", - "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", + "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" ], @@ -1081,9 +1012,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", - "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", + "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" ], @@ -1095,9 +1026,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", - "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", + "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" ], @@ -1109,9 +1040,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", - "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", + "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" ], @@ -1123,9 +1054,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", - "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", + "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" ], @@ -1137,9 +1068,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", - "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", + "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" ], @@ -1151,9 +1082,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", - "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", + "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" ], @@ -1165,9 +1096,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", - "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", + "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" ], @@ -1179,9 +1110,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", - "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", + "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" ], @@ -1193,9 +1124,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", - "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", + "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" ], @@ -1207,9 +1138,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", - "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", + "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" ], @@ -1221,9 +1152,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", - "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", + "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" ], @@ -1235,9 +1166,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", - "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", + "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" ], @@ -1249,9 +1180,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", - "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", + "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" ], @@ -1302,9 +1233,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", - "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "version": "20.19.33", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", + "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", "dev": true, "license": "MIT", "dependencies": { @@ -1536,9 +1467,9 @@ } }, "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -1569,24 +1500,26 @@ } }, "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" @@ -1605,18 +1538,6 @@ "node": ">= 8" } }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1648,15 +1569,15 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", - "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.11.tgz", + "integrity": "sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", - "js-tokens": "^9.0.1" + "js-tokens": "^10.0.0" } }, "node_modules/atomic-sleep": { @@ -1669,9 +1590,19 @@ } }, "node_modules/avvio": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.1.0.tgz", - "integrity": "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw==", + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/avvio/-/avvio-9.2.0.tgz", + "integrity": "sha512-2t/sy01ArdHHE0vRH5Hsay+RtCZt3dLPji7W7/MMOCEgze5b7SNDC4j5H6FnVgPkI1MTNFGzHdHrVXDDl7QSSQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT", "dependencies": { "@fastify/error": "^4.0.0", @@ -1679,9 +1610,9 @@ } }, "node_modules/b4a": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", - "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.0.tgz", + "integrity": "sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -1693,6 +1624,15 @@ } } }, + "node_modules/balanced-match": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.3.tgz", + "integrity": "sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==", + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/bare-events": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", @@ -1709,9 +1649,9 @@ } }, "node_modules/bare-fs": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.3.tgz", - "integrity": "sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.4.tgz", + "integrity": "sha512-POK4oplfA7P7gqvetNmCs4CNtm9fNsx+IAh7jH7GgU0OJdge2rso0R20TNWVq6VoWcCvsTdlNDaleLHGaKx8CA==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -1757,14 +1697,15 @@ } }, "node_modules/bare-stream": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", - "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz", + "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { - "streamx": "^2.21.0" + "streamx": "^2.21.0", + "teex": "^1.0.1" }, "peerDependencies": { "bare-buffer": "*", @@ -1832,6 +1773,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/braces": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", @@ -1941,9 +1894,9 @@ } }, "node_modules/chromium-bidi": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-13.0.1.tgz", - "integrity": "sha512-c+RLxH0Vg2x2syS9wPw378oJgiJNXtYXUvnVAldUlt5uaHekn0CCU7gPksNgHjrH1qFhmjVXQj4esvuthuC7OQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-14.0.0.tgz", + "integrity": "sha512-9gYlLtS6tStdRWzrtXaTMnqcM4dudNegMXJxkR0I/CXObHalYeYcAMPrL19eroNZHtJ8DQmu1E+ZNOYu/IXMXw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1979,92 +1932,11 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -2077,6 +1949,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, "license": "MIT" }, "node_modules/commander": { @@ -2100,6 +1973,19 @@ "node": ">= 0.6" } }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -2209,9 +2095,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1551306", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1551306.tgz", - "integrity": "sha512-CFx8QdSim8iIv+2ZcEOclBKTQY6BI1IEDa7Tm9YkwAXzEWFndTEzpTo5jAUhSnq24IC7xaDw0wvGcm96+Y3PEg==", + "version": "0.0.1566079", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1566079.tgz", + "integrity": "sha512-MJfAEA1UfVhSs7fbSQOG4czavUp1ajfg6prlAN0+cmfa2zNjaIbvq8VneP7do1WAQQIvgNJWSMeP6UyI90gIlQ==", "dev": true, "license": "BSD-3-Clause" }, @@ -2257,16 +2143,11 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/end-of-stream": { @@ -2508,9 +2389,9 @@ "license": "MIT" }, "node_modules/fast-json-stringify": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.2.0.tgz", - "integrity": "sha512-Eaf/KNIDwHkzfyeQFNfLXJnQ7cl1XQI3+zRqmPlvtkMigbXnAcasTrvJQmquBSxKfFGeRA6PFog8t+hFmpDoWw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.3.0.tgz", + "integrity": "sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==", "funding": [ { "type": "github", @@ -2557,9 +2438,9 @@ "license": "BSD-3-Clause" }, "node_modules/fastify": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.7.2.tgz", - "integrity": "sha512-dBJolW+hm6N/yJVf6J5E1BxOBNkuXNl405nrfeR8SpvGWG3aCC2XDHyiFBdow8Win1kj7sjawQc257JlYY6M/A==", + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.7.4.tgz", + "integrity": "sha512-e6l5NsRdaEP8rdD8VR0ErJASeyaRbzXYpmkrpr2SuvuMq6Si3lvsaVy5C+7gLanEkvjpMDzBXWE5HPeb/hgTxA==", "funding": [ { "type": "github", @@ -2624,24 +2505,6 @@ "pend": "~1.2.0" } }, - "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, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2655,9 +2518,9 @@ } }, "node_modules/find-my-way": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.4.0.tgz", - "integrity": "sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.5.0.tgz", + "integrity": "sha512-VW2RfnmscZO5KgBY5XVyKREMW5nMZcxDy+buTOsL+zIPnBlbKm+00sgzoQzq1EVh4aALZLfKdwv6atBGcjvjrQ==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -2685,9 +2548,9 @@ } }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -2725,9 +2588,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", "dev": true, "license": "MIT", "dependencies": { @@ -2756,6 +2619,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "BlueOak-1.0.0", "dependencies": { "foreground-child": "^3.3.1", @@ -2942,6 +2806,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3015,12 +2889,12 @@ } }, "node_modules/jackspeak": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/cliui": "^8.0.2" + "@isaacs/cliui": "^9.0.0" }, "engines": { "node": "20 || >=22" @@ -3030,9 +2904,9 @@ } }, "node_modules/js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", "dev": true, "license": "MIT" }, @@ -3102,19 +2976,6 @@ "set-cookie-parser": "^2.6.0" } }, - "node_modules/light-my-request/node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/light-my-request/node_modules/process-warning": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.1.tgz", @@ -3139,9 +3000,9 @@ "license": "MIT" }, "node_modules/lru-cache": { - "version": "11.2.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.5.tgz", - "integrity": "sha512-vFrFJkWtJvJnD5hg+hJvVE8Lh/TcMzKnTgCWmtBipwI5yLX/iX+5UB2tfuyODF5E7k9xEzMdYgGqaSb1c0c5Yw==", + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -3158,14 +3019,14 @@ } }, "node_modules/magicast": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", - "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.2.tgz", + "integrity": "sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "source-map-js": "^1.2.1" } }, @@ -3207,25 +3068,25 @@ } }, "node_modules/minimatch": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", - "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.2.tgz", + "integrity": "sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==", "license": "BlueOak-1.0.0", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -3409,16 +3270,16 @@ } }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3457,22 +3318,21 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pino": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-10.3.0.tgz", - "integrity": "sha512-0GNPNzHXBKw6U/InGe79A3Crzyk9bcSyObF9/Gfo9DLEf5qj5RF50RSjsu0W1rZ6ZqRGdzDFCRBQvi9/rSGPtA==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-10.3.1.tgz", + "integrity": "sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==", "license": "MIT", "dependencies": { "@pinojs/redact": "^0.4.0", @@ -3520,13 +3380,13 @@ } }, "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==", + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", + "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.58.0" + "playwright-core": "1.58.2" }, "bin": { "playwright": "cli.js" @@ -3539,9 +3399,9 @@ } }, "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==", + "version": "1.58.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", + "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3551,6 +3411,21 @@ "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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/pngjs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", @@ -3716,18 +3591,18 @@ } }, "node_modules/puppeteer": { - "version": "24.36.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.36.0.tgz", - "integrity": "sha512-BD/VCyV/Uezvd6o7Fd1DmEJSxTzofAKplzDy6T9d4WbLTQ5A+06zY7VwO91ZlNU22vYE8sidVEsTpTrKc+EEnQ==", + "version": "24.37.5", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.37.5.tgz", + "integrity": "sha512-3PAOIQLceyEmn1Fi76GkGO2EVxztv5OtdlB1m8hMUZL3f8KDHnlvXbvCXv+Ls7KzF1R0KdKBqLuT/Hhrok12hQ==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.11.1", - "chromium-bidi": "13.0.1", + "@puppeteer/browsers": "2.13.0", + "chromium-bidi": "14.0.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1551306", - "puppeteer-core": "24.36.0", + "devtools-protocol": "0.0.1566079", + "puppeteer-core": "24.37.5", "typed-query-selector": "^2.12.0" }, "bin": { @@ -3738,18 +3613,18 @@ } }, "node_modules/puppeteer-core": { - "version": "24.36.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.36.0.tgz", - "integrity": "sha512-P3Ou0MAFDCQ0dK1d9F9+8jTrg6JvXjUacgG0YkJQP4kbEnUOGokSDEMmMId5ZhXD5HwsHM202E9VwEpEjWfwxg==", + "version": "24.37.5", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.37.5.tgz", + "integrity": "sha512-ybL7iE78YPN4T6J+sPLO7r0lSByp/0NN6PvfBEql219cOnttoTFzCWKiBOjstXSqi/OKpwae623DWAsL7cn2MQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.11.1", - "chromium-bidi": "13.0.1", + "@puppeteer/browsers": "2.13.0", + "chromium-bidi": "14.0.0", "debug": "^4.4.3", - "devtools-protocol": "0.0.1551306", + "devtools-protocol": "0.0.1566079", "typed-query-selector": "^2.12.0", - "webdriver-bidi-protocol": "0.4.0", + "webdriver-bidi-protocol": "0.4.1", "ws": "^8.19.0" }, "engines": { @@ -3790,18 +3665,6 @@ "node": ">=8.10.0" } }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", @@ -3876,9 +3739,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.56.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", - "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", + "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": { @@ -3892,31 +3755,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.56.0", - "@rollup/rollup-android-arm64": "4.56.0", - "@rollup/rollup-darwin-arm64": "4.56.0", - "@rollup/rollup-darwin-x64": "4.56.0", - "@rollup/rollup-freebsd-arm64": "4.56.0", - "@rollup/rollup-freebsd-x64": "4.56.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", - "@rollup/rollup-linux-arm-musleabihf": "4.56.0", - "@rollup/rollup-linux-arm64-gnu": "4.56.0", - "@rollup/rollup-linux-arm64-musl": "4.56.0", - "@rollup/rollup-linux-loong64-gnu": "4.56.0", - "@rollup/rollup-linux-loong64-musl": "4.56.0", - "@rollup/rollup-linux-ppc64-gnu": "4.56.0", - "@rollup/rollup-linux-ppc64-musl": "4.56.0", - "@rollup/rollup-linux-riscv64-gnu": "4.56.0", - "@rollup/rollup-linux-riscv64-musl": "4.56.0", - "@rollup/rollup-linux-s390x-gnu": "4.56.0", - "@rollup/rollup-linux-x64-gnu": "4.56.0", - "@rollup/rollup-linux-x64-musl": "4.56.0", - "@rollup/rollup-openbsd-x64": "4.56.0", - "@rollup/rollup-openharmony-arm64": "4.56.0", - "@rollup/rollup-win32-arm64-msvc": "4.56.0", - "@rollup/rollup-win32-ia32-msvc": "4.56.0", - "@rollup/rollup-win32-x64-gnu": "4.56.0", - "@rollup/rollup-win32-x64-msvc": "4.56.0", + "@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" } }, @@ -3985,9 +3848,9 @@ "license": "BSD-3-Clause" }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -4090,9 +3953,9 @@ } }, "node_modules/sonic-boom": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", - "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0" @@ -4178,11 +4041,11 @@ "safe-buffer": "~5.2.0" } }, - "node_modules/string-width-cjs": { - "name": "string-width", + "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -4193,56 +4056,11 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -4251,15 +4069,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4300,10 +4109,21 @@ "streamx": "^2.15.0" } }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", + "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4396,6 +4216,37 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyglobby/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, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinyrainbow": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", @@ -4463,21 +4314,6 @@ "fsevents": "~2.3.3" } }, - "node_modules/tsx/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, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/typed-query-selector": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", @@ -4600,19 +4436,35 @@ } } }, - "node_modules/vite/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/vite/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, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/vitest": { @@ -4693,10 +4545,23 @@ } } }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/webdriver-bidi-protocol": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.0.tgz", - "integrity": "sha512-U9VIlNRrq94d1xxR9JrCEAx5Gv/2W7ERSv8oWRoNe/QYbfccS0V3h/H6qeNeCRJxXGMhhnkqvwNrvPAYeuP9VA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.4.1.tgz", + "integrity": "sha512-ARrjNjtWRRs2w4Tk7nqrf2gBI0QXWuOmMCx2hU+1jUt6d00MjMxURrhxhGbrsoiZKJrhTSTzbIrc554iKI10qw==", "dev": true, "license": "Apache-2.0" }, @@ -4732,11 +4597,11 @@ "node": ">=8" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", + "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -4750,65 +4615,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4912,54 +4718,6 @@ "node": ">=12" } }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/package.json b/package.json index 20034872..9eb29ae2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claudeman", - "version": "0.1600", + "version": "0.1601", "description": "The missing control plane for Claude Code - run 20 autonomous agents with real-time monitoring and session persistence", "type": "module", "main": "dist/index.js", @@ -51,7 +51,7 @@ "zod": "^4.3.6" }, "devDependencies": { - "@types/node": "^20.14.0", + "@types/node": "^20.19.33", "@types/pngjs": "^6.0.5", "@types/uuid": "^10.0.0", "@vitest/coverage-v8": "^4.0.18", diff --git a/src/web/public/app.js b/src/web/public/app.js index 47578bd3..66ef485e 100644 --- a/src/web/public/app.js +++ b/src/web/public/app.js @@ -867,360 +867,353 @@ class FocusTrap { } /** - * Local echo DOM overlay — shows typed characters instantly at the visible prompt - * position for high-latency connections. Positioned by scanning the terminal buffer - * for the ❯ prompt character, not by trusting buffer.cursorY (which reflects Ink's - * internal cursor near the status bar). + * xterm-zerolag-input — Instant keystroke feedback overlay for xterm.js. + * Inlined from packages/xterm-zerolag-input (built output). + * See packages/xterm-zerolag-input/README.md for full API documentation. */ -class LocalEchoOverlay { - constructor(terminal) { - this.terminal = terminal; - // Container: positioned at prompt row, holds per-line child divs - this.overlay = document.createElement('div'); - this.overlay.style.cssText = 'position:absolute;z-index:7;pointer-events:none;display:none'; - const screen = terminal.element.querySelector('.xterm-screen'); - // Cache font/color styles for line divs - this._fontFamily = terminal.options.fontFamily; - this._fontSize = terminal.options.fontSize + 'px'; - this._fontWeight = terminal.options.fontWeight || 'normal'; - this._bg = terminal.options?.theme?.background || '#0d0d0d'; - this._color = terminal.options?.theme?.foreground || '#eeeeee'; - this._letterSpacing = ''; - const rows = terminal.element.querySelector('.xterm-rows'); - if (rows) { - const cs = getComputedStyle(rows); - this._letterSpacing = cs.letterSpacing; - // Prefer computed color from rendered rows (matches actual rendering), - // fall back to theme foreground if the computed value is empty/default. - if (cs.color) this._color = cs.color; - } - screen.appendChild(this.overlay); - this.pendingText = ''; - this._flushedOffset = 0; // chars flushed to PTY during tab switch (echo may not have arrived yet) - this._flushedText = ''; // stored flushed text string (avoids reading stale terminal buffer) - this._storageKey = 'claudeman_local_echo_pending'; - // Clear stale text from previous page load. Persisted text can't be - // backspaced (flushedOffset is lost on reload) and ghost-merges with - // new input, breaking editing. Tab-switch text is already flushed to - // PTY directly — localStorage persistence is not needed. - try { localStorage.removeItem(this._storageKey); } catch {} - // Hide overlay when user scrolls away from bottom (prompt not in viewport). - // _render() checks viewportY !== baseY, but only on render triggers — scrolling - // alone doesn't trigger a render, so the overlay stays visible over wrong content. - // Listen on .xterm-viewport DOM element (terminal.onScroll fires on buffer changes). - // Debounce the re-render on scroll-to-bottom to avoid loadCell errors when the - // buffer is mid-update during rapid scroll events. - this._scrollTimer = null; - this._scrollHandler = () => { - try { - const buf = this.terminal.buffer.active; - if (buf.viewportY !== buf.baseY) { - this.overlay.style.display = 'none'; - if (this._scrollTimer) { clearTimeout(this._scrollTimer); this._scrollTimer = null; } - } else if (this.pendingText || this._flushedOffset > 0) { - // Debounce re-render — buffer lines may still be settling - if (this._scrollTimer) clearTimeout(this._scrollTimer); - this._scrollTimer = setTimeout(() => { - this._scrollTimer = null; - this._lastRenderKey = ''; - this._render(); - }, 50); - } - } catch {} - }; - const viewport = terminal.element.querySelector('.xterm-viewport'); - if (viewport) viewport.addEventListener('scroll', this._scrollHandler, { passive: true }); - this._scrollViewport = viewport; + +// --- xterm-zerolag-input library (inlined) --- + +function _zl_getCellDimensions(terminal) { + const t = terminal; + if (t.dimensions?.css?.cell) { + return { width: t.dimensions.css.cell.width, height: t.dimensions.css.cell.height }; + } + try { + const dims = t._core?._renderService?.dimensions; + if (dims?.css?.cell) { + return { width: dims.css.cell.width, height: dims.css.cell.height }; } + } catch {} + return null; +} - // No-op: localStorage persistence removed — stale text from previous page - // loads can't be edited (flushedOffset lost) and ghost-merges with new input. - _persist() {} - - // Scan terminal buffer to find the visible ❯ prompt position (bottom-up) - _findPrompt() { - try { - const buffer = this.terminal.buffer.active; - const viewportTop = buffer.viewportY; - for (let row = this.terminal.rows - 1; row >= 0; row--) { - const line = buffer.getLine(viewportTop + row); - if (!line) continue; - const text = line.translateToString(true); - const idx = text.lastIndexOf('\u276f'); - if (idx >= 0) { - return { row, col: idx }; - } - } - } catch {} +function _zl_findPrompt(terminal, finder) { + try { + const buffer = terminal.buffer.active; + const viewportTop = buffer.viewportY; + switch (finder.type) { + case 'character': { + for (let row = terminal.rows - 1; row >= 0; row--) { + const line = buffer.getLine(viewportTop + row); + if (!line) continue; + const text = line.translateToString(true); + const idx = text.lastIndexOf(finder.char); + if (idx >= 0) return { row, col: idx }; + } + return null; + } + case 'regex': { + const pattern = finder.pattern; + const safePattern = pattern.global ? new RegExp(pattern.source, pattern.flags.replace('g', '')) : pattern; + for (let row = terminal.rows - 1; row >= 0; row--) { + const line = buffer.getLine(viewportTop + row); + if (!line) continue; + const text = line.translateToString(true); + const match = text.match(safePattern); + if (match) return { row, col: match.index ?? 0 }; + } + return null; + } + case 'custom': + return finder.find(terminal); + default: return null; } - - // Auto-detect text already on the prompt line in the terminal buffer. - // Called on first keystroke when overlay is empty (pendingText='' and - // flushedOffset=0). Handles Tab completion, arrow-key edits, and any - // other case where the PTY has prompt text the overlay doesn't know about. - // Without this, the overlay's opaque background covers the canvas text. - _detectBufferText() { - // Skip if we already detected and the user backspaced through it — - // the PTY backspace echo is async, so the buffer still has stale text. - // Reset on clear() (Enter, Ctrl+C, tab switch). - if (this._bufferDetectDone) return; - try { - const prompt = this._findPrompt(); - if (!prompt) return; - const buf = this.terminal.buffer.active; - const absRow = buf.viewportY + prompt.row; - const line = buf.getLine(absRow); - if (!line) return; - const lineText = line.translateToString(true); - const textStart = prompt.col + 2; // after "❯ " - const afterPrompt = lineText.slice(textStart).trimEnd(); - if (afterPrompt.length > 0) { - this._flushedOffset = afterPrompt.length; - this._flushedText = afterPrompt; - this._lastPromptPos = prompt; - this._bufferDetectDone = true; - } - } catch {} - } - - addChar(char) { - // On first keystroke after overlay was empty, detect existing buffer text - if (!this.pendingText && !this._flushedOffset) this._detectBufferText(); - this.pendingText += char; - this._persist(); - this._render(); - } - - removeChar() { - if (this.pendingText.length > 0) { - this.pendingText = this.pendingText.slice(0, -1); - this._persist(); - if (this.pendingText.length > 0 || this._flushedOffset > 0) { - // Re-render: either pending text remains, or flushed text exists - // and should stay visible so the user can continue backspacing. - this._render(); - } else { - // Both pending and flushed are empty — hide overlay completely. - this._lastRenderKey = ''; - this._lastPromptPos = null; - this.overlay.innerHTML = ''; - this.overlay.style.display = 'none'; - } - } - } - - appendText(text) { - if (!text) return; - if (!this.pendingText && !this._flushedOffset) this._detectBufferText(); - this.pendingText += text; - this._persist(); - this._render(); - } - - clear() { - this.pendingText = ''; - this._flushedOffset = 0; - this._flushedText = ''; - this._bufferDetectDone = false; // allow re-detection after next clear - this._persist(); - this._lastRenderKey = ''; - this._lastPromptPos = null; - this.overlay.innerHTML = ''; - this.overlay.style.display = 'none'; - } - - // Create a styled line div with per-character grid positioning. - // Each char is placed at exact col*cellW to match xterm's canvas renderer - // (DOM text flow drifts vs canvas due to sub-pixel glyph width differences). - _makeLine(text, leftPx, topPx, widthPx, cellH, cellW) { - const el = document.createElement('div'); - el.style.cssText = `position:absolute;pointer-events:none`; - el.style.backgroundColor = this._bg; - el.style.left = leftPx + 'px'; - el.style.top = topPx + 'px'; - el.style.width = widthPx + 'px'; - el.style.height = (cellH + 1) + 'px'; - el.style.lineHeight = cellH + 'px'; - // Place each character at its exact grid position - for (let i = 0; i < text.length; i++) { - const span = document.createElement('span'); - // Match xterm.js WebGL canvas text rendering as closely as possible: - // - antialiased font smoothing (canvas uses grayscale, not LCD subpixel) - // - geometricPrecision for consistent glyph sizing - // - no ligatures (canvas renders each glyph independently) - span.style.cssText = `position:absolute;display:inline-block;text-align:center;pointer-events:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:geometricPrecision;font-feature-settings:'liga' 0,'calt' 0`; - span.style.left = (i * cellW) + 'px'; - span.style.width = cellW + 'px'; - span.style.fontFamily = this._fontFamily; - span.style.fontSize = this._fontSize; - span.style.fontWeight = this._fontWeight; - span.style.color = this._color; - if (this._letterSpacing) span.style.letterSpacing = this._letterSpacing; - span.textContent = text[i]; - el.appendChild(span); - } - return el; - } - - _render() { - if (!this.pendingText && !(this._flushedOffset > 0)) { - this.overlay.style.display = 'none'; - return; - } - try { - // Hide overlay when scrolled up — the current prompt is at the bottom - // of the buffer, not in the visible viewport. Rendering at a stale - // prompt position would overlap unrelated content. - const buf = this.terminal.buffer.active; - if (buf.viewportY !== buf.baseY) { - this.overlay.style.display = 'none'; - return; - } - - // Re-scan for prompt on EVERY render — Ink can move it between redraws. - // Cache last known position as fallback during Ink redraw flicker. - const prompt = this._findPrompt(); - if (prompt) { - // When flushed text exists, lock the column to prevent jitter from - // Ink redraws that temporarily shift the ❯ prompt. Only allow the - // ROW to change (terminal output may scroll the prompt down). - if (this._lastPromptPos && (this._flushedOffset || 0) > 0) { - this._lastPromptPos = { row: prompt.row, col: this._lastPromptPos.col }; - } else { - this._lastPromptPos = prompt; - } - } else if (!this._lastPromptPos) { - this.overlay.style.display = 'none'; return; - } - const activePrompt = this._lastPromptPos; - - const dims = this.terminal._core._renderService.dimensions; - const cellW = dims.css.cell.width; - const cellH = dims.css.cell.height; - const totalCols = this.terminal.cols; - - // When flushed text exists alongside pending text, both render on the - // same prompt line but via different engines (canvas vs DOM), creating a - // visible font mismatch. Fix: read the flushed portion from the terminal - // buffer and re-render the ENTIRE line as DOM, covering the canvas text. - let displayText = this.pendingText; - const flushed = this._flushedOffset || 0; - const textStart = activePrompt.col + 2; // right after "❯ " - if (flushed > 0) { - // Use stored flushed text (reliable) instead of reading from terminal - // buffer (which may be stale/wrong after async buffer reload on tab switch). - if (this._flushedText && this._flushedText.length === flushed) { - displayText = this._flushedText + this.pendingText; - } else { - // Fallback: read flushed chars from terminal buffer - const promptAbsRow = buf.viewportY + activePrompt.row; - const line = buf.getLine(promptAbsRow); - if (line) { - const lineText = line.translateToString(true); - const flushedChars = lineText.slice(textStart, textStart + flushed); - displayText = flushedChars + this.pendingText; - } - } - } - - const startCol = textStart; - const firstLineCols = Math.max(1, totalCols - startCol); - - // Skip redundant re-renders (e.g. from flushPendingWrites at 60fps) - const renderKey = `${displayText.length}:${startCol}:${activePrompt.row}:${activePrompt.col}:${totalCols}:${flushed}`; - if (renderKey === this._lastRenderKey && this.overlay.style.display !== 'none') return; - this._lastRenderKey = renderKey; - - // Split text into visual lines matching terminal character-wrap behavior - // Line 0: starts after prompt, fits (totalCols - startCol) chars - // Line 1+: starts at col 0, fits totalCols chars each - const lines = []; - let remaining = displayText; - lines.push(remaining.slice(0, firstLineCols)); - remaining = remaining.slice(firstLineCols); - while (remaining.length > 0) { - lines.push(remaining.slice(0, totalCols)); - remaining = remaining.slice(totalCols); - } - - // Position overlay container at prompt row - this.overlay.style.left = '0px'; - this.overlay.style.top = (activePrompt.row * cellH) + 'px'; - - // Build line elements — recreate on each render (typically 1-3 divs, negligible cost) - this.overlay.innerHTML = ''; - const fullWidthPx = totalCols * cellW; - for (let i = 0; i < lines.length; i++) { - const leftPx = i === 0 ? startCol * cellW : 0; - const widthPx = i === 0 ? (fullWidthPx - leftPx) : fullWidthPx; - const topPx = i * cellH; - const lineEl = this._makeLine(lines[i], leftPx, topPx, widthPx, cellH, cellW); - this.overlay.appendChild(lineEl); - } - - // Block cursor at end of last line - const lastLine = lines[lines.length - 1]; - const lastLineLeft = lines.length === 1 ? startCol : 0; - const cursorCol = lastLineLeft + lastLine.length; - if (cursorCol < totalCols) { - const cursor = document.createElement('span'); - cursor.style.cssText = 'position:absolute;display:inline-block'; - cursor.style.left = (cursorCol * cellW) + 'px'; - cursor.style.top = ((lines.length - 1) * cellH) + 'px'; - cursor.style.width = cellW + 'px'; - cursor.style.height = cellH + 'px'; - cursor.style.backgroundColor = this.terminal.options?.theme?.cursor || '#e0e0e0'; - this.overlay.appendChild(cursor); - } - - this.overlay.style.display = ''; - } catch { - // Hide overlay on render error but preserve pendingText — - // next rerender() (from flushPendingWrites) will retry when terminal is ready. - this.overlay.innerHTML = ''; - this.overlay.style.display = 'none'; - } - } - - // Refresh cached font properties from terminal options. - // Call after font size changes, theme changes, etc. - refreshFont() { - this._fontFamily = this.terminal.options.fontFamily; - this._fontSize = this.terminal.options.fontSize + 'px'; - this._fontWeight = this.terminal.options.fontWeight || 'normal'; - this._bg = this.terminal.options?.theme?.background || '#0d0d0d'; - const fg = this.terminal.options?.theme?.foreground || '#eeeeee'; - this._color = fg; - const rows = this.terminal.element?.querySelector('.xterm-rows'); - if (rows) { - const cs = getComputedStyle(rows); - this._letterSpacing = cs.letterSpacing; - if (cs.color) this._color = cs.color; - } - // Force full re-render with updated font (clear render cache) - this._lastRenderKey = ''; - if (this.pendingText) this._render(); - } - - // Re-render overlay at current prompt position without clearing pending text. - // Used after terminal resets/redraws that move the prompt. - rerender() { - if (this.pendingText || this._flushedOffset > 0) this._render(); - } - - get hasPending() { return this.pendingText.length > 0 || this._flushedOffset > 0; } - - dispose() { - this.clear(); - if (this._scrollTimer) { clearTimeout(this._scrollTimer); this._scrollTimer = null; } - if (this._scrollViewport && this._scrollHandler) { - this._scrollViewport.removeEventListener('scroll', this._scrollHandler); - } - this.overlay.remove(); - } + } catch { return null; } } +function _zl_readTextAfterPrompt(terminal, prompt, offset) { + try { + const buffer = terminal.buffer.active; + const absRow = buffer.viewportY + prompt.row; + const line = buffer.getLine(absRow); + if (!line) return ''; + return line.translateToString(true).slice(prompt.col + offset).trimEnd(); + } catch { return ''; } +} + +function _zl_renderOverlay(container, params) { + const { lines, startCol, totalCols, cellW, cellH, promptRow, font, showCursor, cursorColor } = params; + container.style.left = '0px'; + container.style.top = (promptRow * cellH) + 'px'; + container.innerHTML = ''; + const fullWidthPx = totalCols * cellW; + for (let i = 0; i < lines.length; i++) { + const leftPx = i === 0 ? startCol * cellW : 0; + const widthPx = i === 0 ? (fullWidthPx - leftPx) : fullWidthPx; + const topPx = i * cellH; + const lineEl = _zl_makeLine(lines[i], leftPx, topPx, widthPx, cellH, cellW, font); + container.appendChild(lineEl); + } + if (showCursor) { + const lastLine = lines[lines.length - 1]; + const lastLineLeft = lines.length === 1 ? startCol : 0; + const cursorCol = lastLineLeft + lastLine.length; + if (cursorCol < totalCols) { + const cursor = document.createElement('span'); + cursor.style.cssText = 'position:absolute;display:inline-block'; + cursor.style.left = (cursorCol * cellW) + 'px'; + cursor.style.top = ((lines.length - 1) * cellH) + 'px'; + cursor.style.width = cellW + 'px'; + cursor.style.height = cellH + 'px'; + cursor.style.backgroundColor = cursorColor; + container.appendChild(cursor); + } + } + container.style.display = ''; +} + +function _zl_makeLine(text, leftPx, topPx, widthPx, cellH, cellW, font) { + const el = document.createElement('div'); + el.style.cssText = 'position:absolute;pointer-events:none'; + el.style.backgroundColor = font.backgroundColor; + el.style.left = leftPx + 'px'; + el.style.top = topPx + 'px'; + el.style.width = widthPx + 'px'; + el.style.height = (cellH + 1) + 'px'; + el.style.lineHeight = cellH + 'px'; + for (let i = 0; i < text.length; i++) { + const span = document.createElement('span'); + span.style.cssText = "position:absolute;display:inline-block;text-align:center;pointer-events:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:geometricPrecision;font-feature-settings:'liga' 0,'calt' 0"; + span.style.left = (i * cellW) + 'px'; + span.style.width = cellW + 'px'; + span.style.fontFamily = font.fontFamily; + span.style.fontSize = font.fontSize; + span.style.fontWeight = font.fontWeight; + span.style.color = font.color; + if (font.letterSpacing) span.style.letterSpacing = font.letterSpacing; + span.textContent = text[i]; + el.appendChild(span); + } + return el; +} + +const _ZL_DEFAULT_PROMPT = { type: 'character', char: '>', offset: 2 }; +const _ZL_DEFAULT_BG = '#0d0d0d'; +const _ZL_DEFAULT_FG = '#eeeeee'; +const _ZL_DEFAULT_CURSOR = '#e0e0e0'; + +class ZerolagInputAddon { + constructor(options) { + this._terminal = null; + this._overlay = null; + this._pendingText = ''; + this._flushedOffset = 0; + this._flushedText = ''; + this._bufferDetectDone = false; + this._lastRenderKey = ''; + this._lastPromptPos = null; + this._font = { fontFamily: 'monospace', fontSize: '14px', fontWeight: 'normal', color: _ZL_DEFAULT_FG, backgroundColor: _ZL_DEFAULT_BG, letterSpacing: '' }; + this._scrollTimer = null; + this._scrollHandler = null; + this._scrollViewport = null; + this._options = { + prompt: options?.prompt ?? _ZL_DEFAULT_PROMPT, + zIndex: options?.zIndex ?? 7, + showCursor: options?.showCursor ?? true, + scrollDebounceMs: options?.scrollDebounceMs ?? 50, + backgroundColor: options?.backgroundColor, + foregroundColor: options?.foregroundColor, + cursorColor: options?.cursorColor + }; + } + activate(terminal) { + this._terminal = terminal; + this._overlay = document.createElement('div'); + this._overlay.style.cssText = `position:absolute;z-index:${this._options.zIndex};pointer-events:none;display:none`; + const screen = terminal.element?.querySelector('.xterm-screen'); + if (screen) screen.appendChild(this._overlay); + this._cacheFont(); + this._scrollHandler = () => { + try { + const buf = this._terminal.buffer.active; + if (buf.viewportY !== buf.baseY) { + this._overlay.style.display = 'none'; + if (this._scrollTimer) { clearTimeout(this._scrollTimer); this._scrollTimer = null; } + } else if (this._pendingText || this._flushedOffset > 0) { + if (this._scrollTimer) clearTimeout(this._scrollTimer); + this._scrollTimer = setTimeout(() => { this._scrollTimer = null; this._lastRenderKey = ''; this._render(); }, this._options.scrollDebounceMs); + } + } catch {} + }; + const viewport = terminal.element?.querySelector('.xterm-viewport'); + if (viewport) { viewport.addEventListener('scroll', this._scrollHandler, { passive: true }); this._scrollViewport = viewport; } + } + dispose() { + this.clear(); + if (this._scrollTimer) { clearTimeout(this._scrollTimer); this._scrollTimer = null; } + if (this._scrollViewport && this._scrollHandler) this._scrollViewport.removeEventListener('scroll', this._scrollHandler); + this._overlay?.remove(); + this._overlay = null; this._scrollViewport = null; this._scrollHandler = null; this._terminal = null; + } + addChar(char) { + if (!this._pendingText && !this._flushedOffset) this._detectBufferText(); + this._pendingText += char; + this._render(); + } + appendText(text) { + if (!text) return; + if (!this._pendingText && !this._flushedOffset) this._detectBufferText(); + this._pendingText += text; + this._render(); + } + removeChar() { + if (this._pendingText.length > 0) { + this._pendingText = this._pendingText.slice(0, -1); + if (this._pendingText.length > 0 || this._flushedOffset > 0) this._render(); else this._hide(); + return 'pending'; + } + if (this._flushedOffset > 0) { + this._flushedOffset--; this._flushedText = this._flushedText.slice(0, -1); + if (this._flushedOffset > 0) this._render(); else this._hide(); + return 'flushed'; + } + this._detectBufferText(); + if (this._flushedOffset > 0) { + this._flushedOffset--; this._flushedText = this._flushedText.slice(0, -1); + if (this._flushedOffset > 0) this._render(); else this._hide(); + return 'flushed'; + } + return false; + } + clear() { + this._pendingText = ''; this._flushedOffset = 0; this._flushedText = ''; + this._bufferDetectDone = false; this._lastRenderKey = ''; this._lastPromptPos = null; + this._hide(); + } + setFlushed(count, text, render = true) { + this._flushedOffset = count; this._flushedText = text; + if (render) this._render(); + } + getFlushed() { return { count: this._flushedOffset, text: this._flushedText }; } + clearFlushed() { + this._flushedOffset = 0; this._flushedText = ''; + if (this._pendingText) this._render(); else this._hide(); + } + rerender() { + if (this._pendingText || this._flushedOffset > 0) { this._lastRenderKey = ''; this._render(); } + } + refreshFont() { + this._cacheFont(); this._lastRenderKey = ''; + if (this._pendingText || this._flushedOffset > 0) this._render(); + } + detectBufferText() { return this._detectBufferText(); } + resetBufferDetection() { this._bufferDetectDone = false; } + undoDetection() { this._flushedOffset = 0; this._flushedText = ''; this._bufferDetectDone = false; } + suppressBufferDetection() { this._bufferDetectDone = true; } + findPrompt() { + if (!this._terminal) return null; + return _zl_findPrompt(this._terminal, this._options.prompt ?? _ZL_DEFAULT_PROMPT); + } + readPromptText() { + if (!this._terminal) return null; + const prompt = this.findPrompt(); + if (!prompt) return null; + const offset = (this._options.prompt ?? _ZL_DEFAULT_PROMPT).offset ?? 2; + const text = _zl_readTextAfterPrompt(this._terminal, prompt, offset); + return text || null; + } + get pendingText() { return this._pendingText; } + get hasPending() { return this._pendingText.length > 0 || this._flushedOffset > 0; } + get state() { + return { + pendingText: this._pendingText, flushedLength: this._flushedOffset, flushedText: this._flushedText, + visible: this._overlay !== null && this._overlay.style.display !== 'none', + promptPosition: this._lastPromptPos ? { ...this._lastPromptPos } : null + }; + } + _detectBufferText() { + if (this._bufferDetectDone || !this._terminal) return null; + try { + const prompt = this.findPrompt(); + if (!prompt) return null; + const offset = (this._options.prompt ?? _ZL_DEFAULT_PROMPT).offset ?? 2; + const afterPrompt = _zl_readTextAfterPrompt(this._terminal, prompt, offset); + if (afterPrompt.length > 0) { + this._flushedOffset = afterPrompt.length; this._flushedText = afterPrompt; + this._lastPromptPos = prompt; this._bufferDetectDone = true; + return afterPrompt; + } + } catch {} + return null; + } + _cacheFont() { + if (!this._terminal) return; + const t = this._terminal; + this._font.fontFamily = t.options.fontFamily || 'monospace'; + this._font.fontSize = (t.options.fontSize || 14) + 'px'; + this._font.fontWeight = String(t.options.fontWeight || 'normal'); + this._font.backgroundColor = this._options.backgroundColor ?? t.options.theme?.background ?? _ZL_DEFAULT_BG; + this._font.color = this._options.foregroundColor ?? t.options.theme?.foreground ?? _ZL_DEFAULT_FG; + this._font.letterSpacing = ''; + const rows = t.element?.querySelector('.xterm-rows'); + if (rows) { + const cs = getComputedStyle(rows); + this._font.letterSpacing = cs.letterSpacing; + if (!this._options.foregroundColor && cs.color) this._font.color = cs.color; + } + } + _hide() { + if (!this._overlay) return; + this._lastRenderKey = ''; this._lastPromptPos = null; + this._overlay.innerHTML = ''; this._overlay.style.display = 'none'; + } + _render() { + if (!this._terminal || !this._overlay) return; + if (!this._pendingText && !(this._flushedOffset > 0)) { this._overlay.style.display = 'none'; return; } + try { + const buf = this._terminal.buffer.active; + if (buf.viewportY !== buf.baseY) { this._overlay.style.display = 'none'; return; } + const prompt = this.findPrompt(); + if (prompt) { + if (this._lastPromptPos && this._flushedOffset > 0) { + this._lastPromptPos = { row: prompt.row, col: this._lastPromptPos.col }; + } else { this._lastPromptPos = prompt; } + } else if (!this._lastPromptPos) { this._overlay.style.display = 'none'; return; } + const activePrompt = this._lastPromptPos; + const dims = _zl_getCellDimensions(this._terminal); + if (!dims) { this._overlay.style.display = 'none'; return; } + const { width: cellW, height: cellH } = dims; + const totalCols = this._terminal.cols; + const offset = (this._options.prompt ?? _ZL_DEFAULT_PROMPT).offset ?? 2; + const startCol = activePrompt.col + offset; + let displayText = this._pendingText; + if (this._flushedOffset > 0) { + if (this._flushedText && this._flushedText.length === this._flushedOffset) { + displayText = this._flushedText + this._pendingText; + } else { + const absRow = buf.viewportY + activePrompt.row; + const line = buf.getLine(absRow); + if (line) { displayText = line.translateToString(true).slice(startCol, startCol + this._flushedOffset) + this._pendingText; } + } + } + const renderKey = `${displayText}:${startCol}:${activePrompt.row}:${activePrompt.col}:${totalCols}:${this._flushedOffset}`; + if (renderKey === this._lastRenderKey && this._overlay.style.display !== 'none') return; + this._lastRenderKey = renderKey; + const firstLineCols = Math.max(1, totalCols - startCol); + const lines = []; let remaining = displayText; + lines.push(remaining.slice(0, firstLineCols)); remaining = remaining.slice(firstLineCols); + while (remaining.length > 0) { lines.push(remaining.slice(0, totalCols)); remaining = remaining.slice(totalCols); } + const cursorColor = this._options.cursorColor ?? this._terminal.options.theme?.cursor ?? _ZL_DEFAULT_CURSOR; + _zl_renderOverlay(this._overlay, { lines, startCol, totalCols, cellW, cellH, promptRow: activePrompt.row, font: this._font, showCursor: this._options.showCursor, cursorColor }); + } catch { + if (this._overlay) { this._overlay.innerHTML = ''; this._overlay.style.display = 'none'; } + } + } +} + +// --- end xterm-zerolag-input library --- + +// Legacy alias — kept so the rest of app.js references work without renaming +const LocalEchoOverlay = class extends ZerolagInputAddon { + constructor(terminal) { + super({ prompt: { type: 'character', char: '\u276f', offset: 2 } }); + this.activate(terminal); + } +}; + + /** * Process data containing DEC 2026 sync markers. * Strips markers and returns segments that should be written atomically. @@ -2175,7 +2168,6 @@ class ClaudemanApp { this.updateConnectionLines(); // Re-render local echo overlay at new cell dimensions/positions if (this._localEchoOverlay?.hasPending) { - this._localEchoOverlay._lastRenderKey = ''; // force re-render (cols changed) this._localEchoOverlay.rerender(); } }, 100); // Throttle to 100ms @@ -2224,65 +2216,24 @@ class ClaudemanApp { // (or a control char) is pressed — avoids out-of-order char delivery. if (this._localEchoEnabled) { if (data === '\x7f') { - if (this._localEchoOverlay?.pendingText) { - // Backspace with pending overlay text: remove from overlay only - this._localEchoOverlay.removeChar(); - } else if (this._localEchoOverlay?._flushedOffset > 0) { - // No pending text but flushed text in PTY — send backspace to PTY - // so the user can delete chars that were auto-flushed during tab switch. - this._localEchoOverlay._flushedOffset--; - // Trim stored flushed text to match - if (this._localEchoOverlay._flushedText) { - this._localEchoOverlay._flushedText = this._localEchoOverlay._flushedText.slice(0, -1); - } + const source = this._localEchoOverlay?.removeChar(); + if (source === 'flushed') { + // Sync app-level flushed Maps (per-session state for tab switching) + const { count, text } = this._localEchoOverlay.getFlushed(); if (this._flushedOffsets?.has(this.activeSessionId)) { - const prev = this._flushedOffsets.get(this.activeSessionId); - if (prev <= 1) { + if (count === 0) { this._flushedOffsets.delete(this.activeSessionId); this._flushedTexts?.delete(this.activeSessionId); } else { - this._flushedOffsets.set(this.activeSessionId, prev - 1); - if (this._flushedTexts?.has(this.activeSessionId)) { - this._flushedTexts.set(this.activeSessionId, - this._flushedTexts.get(this.activeSessionId).slice(0, -1)); - } + this._flushedOffsets.set(this.activeSessionId, count); + this._flushedTexts?.set(this.activeSessionId, text); } } - // Immediate visual feedback — re-render overlay with shortened flushed text - this._localEchoOverlay._lastRenderKey = ''; - if (this._localEchoOverlay._flushedOffset > 0) { - this._localEchoOverlay._render(); - } else { - // Fully backspaced through flushed text — hide overlay - this._localEchoOverlay._lastPromptPos = null; - this._localEchoOverlay.overlay.innerHTML = ''; - this._localEchoOverlay.overlay.style.display = 'none'; - } this._pendingInput += data; flushInput(); - } else if (this._localEchoOverlay) { - // No pending or flushed text — try detecting buffer text first - // (handles Tab completion, arrow edits, etc.) - this._localEchoOverlay._detectBufferText(); - if (this._localEchoOverlay._flushedOffset > 0) { - // Found buffer text — delete last char - this._localEchoOverlay._flushedOffset--; - if (this._localEchoOverlay._flushedText) { - this._localEchoOverlay._flushedText = this._localEchoOverlay._flushedText.slice(0, -1); - } - this._localEchoOverlay._lastRenderKey = ''; - if (this._localEchoOverlay._flushedOffset > 0) { - this._localEchoOverlay._render(); - } else { - this._localEchoOverlay._lastPromptPos = null; - this._localEchoOverlay.overlay.innerHTML = ''; - this._localEchoOverlay.overlay.style.display = 'none'; - } - this._pendingInput += data; - flushInput(); - } - // else: truly nothing to delete — swallow the backspace } + // 'pending' = removed unsent text (no PTY backspace needed) + // false = nothing to remove (swallow the backspace) return; } if (/^[\r\n]+$/.test(data)) { @@ -2356,7 +2307,7 @@ class ClaudemanApp { // real Tab completions from pre-existing Claude UI text. let baseText = ''; try { - const p = this._localEchoOverlay?._findPrompt?.(); + const p = this._localEchoOverlay?.findPrompt?.(); if (p) { const buf = this.terminal.buffer.active; const line = buf.getLine(buf.viewportY + p.row); @@ -2380,17 +2331,13 @@ class ClaudemanApp { if (!ov || ov.pendingText) return; selfTab.terminal.write('', () => { if (!selfTab._tabCompletionSessionId) return; - ov._bufferDetectDone = false; - ov._detectBufferText(); - if (ov._flushedOffset > 0) { - const detected = ov._flushedText; - if (detected !== selfTab._tabCompletionBaseText) { - selfTab._tabCompletionSessionId = null; - selfTab._tabCompletionRetries = 0; - selfTab._tabCompletionBaseText = null; - ov._lastRenderKey = ''; - ov._render(); - } + ov.resetBufferDetection(); + const detected = ov.detectBufferText(); + if (detected && detected !== selfTab._tabCompletionBaseText) { + selfTab._tabCompletionSessionId = null; + selfTab._tabCompletionRetries = 0; + selfTab._tabCompletionBaseText = null; + ov.rerender(); } }); }, 300); @@ -2771,17 +2718,12 @@ class ClaudemanApp { const self = this; this.terminal.write('', () => { if (!self._tabCompletionSessionId) return; // already resolved - overlay._bufferDetectDone = false; - overlay._detectBufferText(); - if (overlay._flushedOffset > 0) { - // Compare with pre-Tab snapshot to avoid false positives from - // Claude's pre-existing UI text (placeholder hints, etc.). - const detected = overlay._flushedText; + overlay.resetBufferDetection(); + const detected = overlay.detectBufferText(); + if (detected) { if (detected === self._tabCompletionBaseText) { // Same text as before Tab — no completion yet. Undo and retry. - overlay._flushedOffset = 0; - overlay._flushedText = ''; - overlay._bufferDetectDone = false; + overlay.undoDetection(); self._tabCompletionRetries = (self._tabCompletionRetries || 0) + 1; if (self._tabCompletionRetries > 60) { self._tabCompletionSessionId = null; @@ -2793,8 +2735,7 @@ class ClaudemanApp { self._tabCompletionRetries = 0; self._tabCompletionBaseText = null; if (self._tabCompletionFallback) { clearTimeout(self._tabCompletionFallback); self._tabCompletionFallback = null; } - overlay._lastRenderKey = ''; - overlay._render(); + overlay.rerender(); } } else { // No text found yet — retry on next flush. @@ -4957,8 +4898,8 @@ class ClaudemanApp { const echoText = this._localEchoOverlay?.pendingText || ''; // Include buffer-detected flushed text (from Tab completion, etc.) // so it's preserved across tab switches. - const existingFlushed = this._localEchoOverlay?._flushedOffset || 0; - const existingFlushedText = this._localEchoOverlay?._flushedText || ''; + const existingFlushed = this._localEchoOverlay?.getFlushed()?.count || 0; + const existingFlushedText = this._localEchoOverlay?.getFlushed()?.text || ''; if (echoText) { this._sendInputAsync(this.activeSessionId, echoText); } @@ -4977,7 +4918,7 @@ class ClaudemanApp { // After the user's first Enter, clear() resets _bufferDetectDone = false, // re-enabling detection for tab completion and other legitimate cases. if (this._localEchoOverlay && !this._flushedOffsets?.has(sessionId)) { - this._localEchoOverlay._bufferDetectDone = true; + this._localEchoOverlay.suppressBufferDetection(); } this.activeSessionId = sessionId; try { localStorage.setItem('claudeman-active-session', sessionId); } catch {} @@ -4994,8 +4935,11 @@ class ClaudemanApp { // fetch() gap: backspace is swallowed, and typing a space covers the // canvas text with an opaque overlay showing only the new char. if (this._flushedOffsets?.has(sessionId) && this._localEchoOverlay) { - this._localEchoOverlay._flushedOffset = this._flushedOffsets.get(sessionId); - this._localEchoOverlay._flushedText = this._flushedTexts?.get(sessionId) || ''; + this._localEchoOverlay.setFlushed( + this._flushedOffsets.get(sessionId), + this._flushedTexts?.get(sessionId) || '', + false // render=false: buffer not loaded yet + ); } // Glow the newly-active tab @@ -5084,17 +5028,17 @@ class ClaudemanApp { // Restore flushed offset and text for this session so the overlay positions // correctly even before the PTY echo arrives in the terminal buffer. if (this._flushedOffsets?.has(sessionId) && this._localEchoOverlay) { - this._localEchoOverlay._flushedOffset = this._flushedOffsets.get(sessionId); - this._localEchoOverlay._flushedText = this._flushedTexts?.get(sessionId) || ''; + this._localEchoOverlay.setFlushed( + this._flushedOffsets.get(sessionId), + this._flushedTexts?.get(sessionId) || '', + false // render=false: buffer just loaded, defer to rerender + ); // Trigger render after xterm.js finishes processing the buffer data. // terminal.write('', callback) fires the callback after ALL previously - // queued writes have been parsed — so _findPrompt() can find ❯ in the buffer. - const overlay = this._localEchoOverlay; + // queued writes have been parsed — so findPrompt() can find ❯ in the buffer. + const zl = this._localEchoOverlay; this.terminal.write('', () => { - if (overlay._flushedOffset > 0) { - overlay._lastRenderKey = ''; - overlay._render(); - } + if (zl.hasPending) zl.rerender(); }); }