From 30812b49d74ba3e31d7ed6fd1b7ddf6918d1c64c Mon Sep 17 00:00:00 2001 From: kishindra26mei10033-boop Date: Sat, 12 Sep 2026 14:32:02 +0530 Subject: [PATCH 1/2] feat: add automated finance and invoice tracking plugin --- bun.lock | 152 ++++++++++++++++++----- mcp-skills/financeagent/finance-agent.ts | 60 +++++++++ package-lock.json | 7 -- src/main.ts | 2 +- 4 files changed, 179 insertions(+), 42 deletions(-) create mode 100644 mcp-skills/financeagent/finance-agent.ts diff --git a/bun.lock b/bun.lock index 713ba2238..4ff74d12a 100644 --- a/bun.lock +++ b/bun.lock @@ -9,15 +9,19 @@ "cli-table3": "^0.6.5", "cloakbrowser": "0.4.5", "commander": "^14.0.3", - "js-yaml": "^4.3.0", + "impit": "0.14.3", + "js-yaml": "^4.3.2", + "jsdom": "^29.0.2", "playwright-core": "1.61.1", "quickjs-emscripten": "0.32.0", + "tldts": "^7.4.11", "turndown": "^7.2.2", "turndown-plugin-gfm": "^1.0.2", "undici": "^6.27.0", "ws": "^8.18.0", }, "devDependencies": { + "@emnapi/core": "^1.11.2", "@emnapi/runtime": "^1.11.2", "@google/genai": "^2.10.0", "@types/js-yaml": "^4.0.9", @@ -25,7 +29,7 @@ "@types/node": "^25.5.2", "@types/turndown": "^5.0.6", "@types/ws": "^8.5.13", - "jsdom": "^29.0.2", + "esbuild": "^0.28.1", "tsx": "^4.19.3", "typescript": "^6.0.2", "vitest": "^4.1.0", @@ -60,63 +64,63 @@ "@csstools/css-tokenizer": ["@csstools/css-tokenizer@4.0.0", "", {}, "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA=="], - "@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], + "@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" } }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="], "@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="], - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], + "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.2", "", { "os": "android", "cpu": "arm" }, "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.4", "", { "os": "android", "cpu": "arm64" }, "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.27.4", "", { "os": "android", "cpu": "x64" }, "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.2", "", { "os": "android", "cpu": "x64" }, "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.4", "", { "os": "linux", "cpu": "arm" }, "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.2", "", { "os": "linux", "cpu": "arm" }, "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.4", "", { "os": "linux", "cpu": "x64" }, "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.2", "", { "os": "linux", "cpu": "x64" }, "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.4", "", { "os": "none", "cpu": "arm64" }, "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.4", "", { "os": "none", "cpu": "x64" }, "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.2", "", { "os": "none", "cpu": "x64" }, "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.4", "", { "os": "none", "cpu": "arm64" }, "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="], "@exodus/bytes": ["@exodus/bytes@1.15.1", "", { "peerDependencies": { "@noble/hashes": "^1.8.0 || ^2.0.0" }, "optionalPeers": ["@noble/hashes"] }, "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q=="], @@ -280,7 +284,7 @@ "es-module-lexer": ["es-module-lexer@2.0.0", "", {}, "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw=="], - "esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": "bin/esbuild" }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], + "esbuild": ["esbuild@0.28.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.2", "@esbuild/android-arm": "0.28.2", "@esbuild/android-arm64": "0.28.2", "@esbuild/android-x64": "0.28.2", "@esbuild/darwin-arm64": "0.28.2", "@esbuild/darwin-x64": "0.28.2", "@esbuild/freebsd-arm64": "0.28.2", "@esbuild/freebsd-x64": "0.28.2", "@esbuild/linux-arm": "0.28.2", "@esbuild/linux-arm64": "0.28.2", "@esbuild/linux-ia32": "0.28.2", "@esbuild/linux-loong64": "0.28.2", "@esbuild/linux-mips64el": "0.28.2", "@esbuild/linux-ppc64": "0.28.2", "@esbuild/linux-riscv64": "0.28.2", "@esbuild/linux-s390x": "0.28.2", "@esbuild/linux-x64": "0.28.2", "@esbuild/netbsd-arm64": "0.28.2", "@esbuild/netbsd-x64": "0.28.2", "@esbuild/openbsd-arm64": "0.28.2", "@esbuild/openbsd-x64": "0.28.2", "@esbuild/openharmony-arm64": "0.28.2", "@esbuild/sunos-x64": "0.28.2", "@esbuild/win32-arm64": "0.28.2", "@esbuild/win32-ia32": "0.28.2", "@esbuild/win32-x64": "0.28.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA=="], "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], @@ -310,11 +314,29 @@ "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + "impit": ["impit@0.14.3", "", { "optionalDependencies": { "impit-darwin-arm64": "0.14.3", "impit-darwin-x64": "0.14.3", "impit-linux-arm64-gnu": "0.14.3", "impit-linux-arm64-musl": "0.14.3", "impit-linux-x64-gnu": "0.14.3", "impit-linux-x64-musl": "0.14.3", "impit-win32-arm64-msvc": "0.14.3", "impit-win32-x64-msvc": "0.14.3" } }, "sha512-SbCLoeW0YDRox5kQoy71jtpjZE+BwjWO411OdgfbLMbNmSX79s5Y0Y2vCE7AO6zQSq9F4Fu8SJTCKnp8rXQzpg=="], + + "impit-darwin-arm64": ["impit-darwin-arm64@0.14.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kMoQB+CR+a954pnhe4kf1O2RyJCsqGRE95jIXfgqNOiIMS5O1z0cOMzG/sohJk/nodZVSJ5VdWEV4BKhRWPFSA=="], + + "impit-darwin-x64": ["impit-darwin-x64@0.14.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-ft9+kjz1pR8H5xbbf5U1EgwaaIea5iXHxBf2Q3NoinPpiV7KgyzYSr83pCSrAY6evWk+smG9shHgzhQtgbj1Rg=="], + + "impit-linux-arm64-gnu": ["impit-linux-arm64-gnu@0.14.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-+mwta93S6Ndfpca3DDblvrqV1g8Bg6gZFOlEiJHfGJZpiUIQE+A/Pjg2e+inV+WrTtlnLsvff8lgwFvkIGnRug=="], + + "impit-linux-arm64-musl": ["impit-linux-arm64-musl@0.14.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-wYhfH1J8laWkpSN2SAFCKx9npY4vXrk23ex+tOzTGf2xBBqIhpMUff2wa6dOFb0or6EhZHBssoRf0HK3h/htXQ=="], + + "impit-linux-x64-gnu": ["impit-linux-x64-gnu@0.14.3", "", { "os": "linux", "cpu": "x64" }, "sha512-hAYnutJDGQO5bPvTPKBBFkHgbB7QL7QLDse8c4s21VSzC/EqGliSS3UqR5ZUUwaFdm3t8DJsXOr+gboAUwDR7w=="], + + "impit-linux-x64-musl": ["impit-linux-x64-musl@0.14.3", "", { "os": "linux", "cpu": "x64" }, "sha512-wXBeHiqCjuyqxg4u5eY4OBNVzsS4Karz/ms/0mjB8aqVZLNER1NaUTeE4J3eZCdytFaJRaAeQvKTH8HfjpPsQg=="], + + "impit-win32-arm64-msvc": ["impit-win32-arm64-msvc@0.14.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-XiF8MYpm4tF8TMbtsWrcEDDs6NxRNeirfiHM/AyKcr2jiN34hZwbZDM0EseD30PDwb2Pny2JWB+zTxpE1P5CZg=="], + + "impit-win32-x64-msvc": ["impit-win32-x64-msvc@0.14.3", "", { "os": "win32", "cpu": "x64" }, "sha512-HIaLSpU5SGVx3UDH/R3ZaGMURVgyRVjmalqXj65ABxVUqfXiBo1t5ZObDPPjqvLT3klPnrya1+xF1DQ4dfT+og=="], + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], - "js-yaml": ["js-yaml@4.3.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q=="], + "js-yaml": ["js-yaml@4.3.2", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA=="], "jsdom": ["jsdom@29.1.1", "", { "dependencies": { "@asamuzakjp/css-color": "^5.1.11", "@asamuzakjp/dom-selector": "^7.1.1", "@bramus/specificity": "^2.4.2", "@csstools/css-syntax-patches-for-csstree": "^1.1.3", "@exodus/bytes": "^1.15.0", "css-tree": "^3.2.1", "data-urls": "^7.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.3.5", "parse5": "^8.0.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.1", "undici": "^7.25.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.1", "whatwg-mimetype": "^5.0.0", "whatwg-url": "^16.0.1", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q=="], @@ -428,9 +450,9 @@ "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], - "tldts": ["tldts@7.4.5", "", { "dependencies": { "tldts-core": "^7.4.5" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-RfEzKWcq5fHUOFq7J3rl3Oz6ylKGtcHqUznzj4EcXsxLSIjJcvpbXAQtWGeJQ0xKnimR5e0Cn+cn9TssfMzm+g=="], + "tldts": ["tldts@7.4.12", "", { "dependencies": { "tldts-core": "^7.4.12" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-WylhSDKVeYnWXL3a+vKTaOxjnOeEGw938hImY8zoRWJjRRK/Jp1K+IihBzIONpUmW4e3WmXT6q5FW6vlESVZCA=="], - "tldts-core": ["tldts-core@7.4.5", "", {}, "sha512-pGrwzZDvPwKe+7NNUqAunb6rqTfynr0VOUhCMdqbu5xlvNiszsAJygRzwvpVycdzejlbpY+SWJOn+s75Og7FEA=="], + "tldts-core": ["tldts-core@7.4.12", "", {}, "sha512-nYNzS2WRf4QJmjzFFgAxLOBjyBxAGRbCy9PVBPaglcYyYajh40VBn+v5Ngr96ZMc7oM0+aCJdtQnNejvdBnXMQ=="], "tough-cookie": ["tough-cookie@6.0.1", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw=="], @@ -474,6 +496,8 @@ "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + "@napi-rs/wasm-runtime/@emnapi/core": ["@emnapi/core@1.9.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA=="], + "@napi-rs/wasm-runtime/@emnapi/runtime": ["@emnapi/runtime@1.9.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA=="], "@types/ws/@types/node": ["@types/node@22.19.15", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg=="], @@ -482,8 +506,68 @@ "jsdom/undici": ["undici@7.28.0", "", {}, "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA=="], + "tough-cookie/tldts": ["tldts@7.4.5", "", { "dependencies": { "tldts-core": "^7.4.5" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-RfEzKWcq5fHUOFq7J3rl3Oz6ylKGtcHqUznzj4EcXsxLSIjJcvpbXAQtWGeJQ0xKnimR5e0Cn+cn9TssfMzm+g=="], + + "tsx/esbuild": ["esbuild@0.27.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.4", "@esbuild/android-arm": "0.27.4", "@esbuild/android-arm64": "0.27.4", "@esbuild/android-x64": "0.27.4", "@esbuild/darwin-arm64": "0.27.4", "@esbuild/darwin-x64": "0.27.4", "@esbuild/freebsd-arm64": "0.27.4", "@esbuild/freebsd-x64": "0.27.4", "@esbuild/linux-arm": "0.27.4", "@esbuild/linux-arm64": "0.27.4", "@esbuild/linux-ia32": "0.27.4", "@esbuild/linux-loong64": "0.27.4", "@esbuild/linux-mips64el": "0.27.4", "@esbuild/linux-ppc64": "0.27.4", "@esbuild/linux-riscv64": "0.27.4", "@esbuild/linux-s390x": "0.27.4", "@esbuild/linux-x64": "0.27.4", "@esbuild/netbsd-arm64": "0.27.4", "@esbuild/netbsd-x64": "0.27.4", "@esbuild/openbsd-arm64": "0.27.4", "@esbuild/openbsd-x64": "0.27.4", "@esbuild/openharmony-arm64": "0.27.4", "@esbuild/sunos-x64": "0.27.4", "@esbuild/win32-arm64": "0.27.4", "@esbuild/win32-ia32": "0.27.4", "@esbuild/win32-x64": "0.27.4" }, "bin": "bin/esbuild" }, "sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ=="], + + "@napi-rs/wasm-runtime/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="], + "@types/ws/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], "jsdom/parse5/entities": ["entities@8.0.0", "", {}, "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA=="], + + "tough-cookie/tldts/tldts-core": ["tldts-core@7.4.5", "", {}, "sha512-pGrwzZDvPwKe+7NNUqAunb6rqTfynr0VOUhCMdqbu5xlvNiszsAJygRzwvpVycdzejlbpY+SWJOn+s75Og7FEA=="], + + "tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="], + + "tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.4", "", { "os": "android", "cpu": "arm" }, "sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ=="], + + "tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.4", "", { "os": "android", "cpu": "arm64" }, "sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw=="], + + "tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.4", "", { "os": "android", "cpu": "x64" }, "sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw=="], + + "tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ=="], + + "tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw=="], + + "tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.4", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw=="], + + "tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.4", "", { "os": "freebsd", "cpu": "x64" }, "sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ=="], + + "tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.4", "", { "os": "linux", "cpu": "arm" }, "sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg=="], + + "tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA=="], + + "tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.4", "", { "os": "linux", "cpu": "ia32" }, "sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA=="], + + "tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA=="], + + "tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw=="], + + "tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA=="], + + "tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.4", "", { "os": "linux", "cpu": "none" }, "sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw=="], + + "tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA=="], + + "tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.4", "", { "os": "linux", "cpu": "x64" }, "sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA=="], + + "tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.4", "", { "os": "none", "cpu": "arm64" }, "sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q=="], + + "tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.4", "", { "os": "none", "cpu": "x64" }, "sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg=="], + + "tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.4", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow=="], + + "tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.4", "", { "os": "openbsd", "cpu": "x64" }, "sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ=="], + + "tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.4", "", { "os": "none", "cpu": "arm64" }, "sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg=="], + + "tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.4", "", { "os": "sunos", "cpu": "x64" }, "sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g=="], + + "tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg=="], + + "tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.4", "", { "os": "win32", "cpu": "ia32" }, "sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw=="], + + "tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.4", "", { "os": "win32", "cpu": "x64" }, "sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg=="], } } diff --git a/mcp-skills/financeagent/finance-agent.ts b/mcp-skills/financeagent/finance-agent.ts new file mode 100644 index 000000000..5b83e978b --- /dev/null +++ b/mcp-skills/financeagent/finance-agent.ts @@ -0,0 +1,60 @@ +// mcp-skills/financeAgent.ts + +interface FinanceAgentArgs { + portalUrl: string; +} + +interface InvoiceRow { + invoiceId: string; + vendor: string; + amountDue: string; +} + +interface ExecutionResult { + status: "success" | "failure"; + timestamp: string; + foundInvoices: number; + data: InvoiceRow[]; +} + +export const financePlugin = { + name: "finance-agent", + description: "Automates checking pending invoices and verifying corporate balances.", + + inputs: { + portalUrl: { type: "string", default: "https://mock-finance-portal.test" } + }, + + async execute(browser: any, args: FinanceAgentArgs): Promise { + console.log(`🚀 Starting Agentic Payment sequence on: ${args.portalUrl}`); + + // 1. Navigate to the dashboard target page + await browser.goto(args.portalUrl); + + // 2. Click the 'Invoices' tab visually + await browser.click("text=Invoices"); + + // 3. Extract table data fields safely with correct array indexing + const invoiceData: InvoiceRow[] = await browser.evaluate(() => { + const rows = Array.from(document.querySelectorAll("table.invoice-list tr")); + + // Skip the table header row if it exists + return rows.slice(1).map((row) => { + const columns = row.querySelectorAll("td"); + return { + invoiceId: columns[0]?.textContent?.trim() || "N/A", + vendor: columns[1]?.textContent?.trim() || "Unknown", + amountDue: columns[2]?.textContent?.trim() || "$0.00" + }; + }); + }); + + // 4. Return structured types back to webcmd handler + return { + status: "success", + timestamp: new Date().toISOString(), + foundInvoices: invoiceData.length, + data: invoiceData + }; + } +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6263deb9c..92e711830 100644 --- a/package-lock.json +++ b/package-lock.json @@ -199,7 +199,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" }, @@ -246,7 +245,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=20.19.0" } @@ -278,7 +276,6 @@ "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -2679,7 +2676,6 @@ "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -2692,7 +2688,6 @@ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz", "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", "license": "Apache-2.0", - "peer": true, "bin": { "playwright-core": "cli.js" }, @@ -3050,7 +3045,6 @@ "integrity": "sha512-6w9FwtT8WQqRAyTNR+Z+86kghRqpmOLjXUrBlBT6T+CQGDuIMm0VmAqaFUFBIeKDTGobE6/YSigZYLeomzBaRg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "~0.28.0" }, @@ -3115,7 +3109,6 @@ "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", diff --git a/src/main.ts b/src/main.ts index 3d9f319c6..cf57f2ee3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,7 +23,7 @@ import { PKG_VERSION } from './version.js'; import { EXIT_CODES } from './errors.js'; import { isSupportedNodeVersion, MIN_SUPPORTED_NODE_MAJOR } from './runtime-detect.js'; import { CONFIG_DIR_NAME } from './brand.js'; -import { configureHostedWorkspaceOption, parseHostedRootCommandSurface, rootCompletionSentinelIndex } from './root-command-surface.js'; +import {financeagentPlugin} from './mcp-skills/financeagent/finance-agent.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); From d6ac64e87ec82e9200fd739143aff76ed27e43b2 Mon Sep 17 00:00:00 2001 From: kishindra26mei10033-boop Date: Sat, 12 Sep 2026 14:35:33 +0530 Subject: [PATCH 2/2] feat: add automated finance and invoice tracking plugin --- mcp-skills/financeagent/finance-agent.ts | 70 +++++++++++++---------- src/main.ts | 3 +- src/root-command-surface.ts | 4 +- src/site-memory/local-store.ts | 20 ++++++- verify.txt | Bin 0 -> 144796 bytes vitest-targeted.txt | 39 +++++++++++++ 6 files changed, 104 insertions(+), 32 deletions(-) create mode 100644 verify.txt create mode 100644 vitest-targeted.txt diff --git a/mcp-skills/financeagent/finance-agent.ts b/mcp-skills/financeagent/finance-agent.ts index 5b83e978b..5b2b6f2d4 100644 --- a/mcp-skills/financeagent/finance-agent.ts +++ b/mcp-skills/financeagent/finance-agent.ts @@ -8,53 +8,65 @@ interface InvoiceRow { invoiceId: string; vendor: string; amountDue: string; + status?: string; } interface ExecutionResult { - status: "success" | "failure"; + status: 'success' | 'failure'; timestamp: string; foundInvoices: number; + totalDue: string; data: InvoiceRow[]; } +interface FinanceBrowser { + goto: (url: string) => Promise; + click: (selector: string) => Promise; + evaluate: (fn: () => T | Promise) => Promise; +} + export const financePlugin = { - name: "finance-agent", - description: "Automates checking pending invoices and verifying corporate balances.", - + name: 'finance-agent', + description: 'Automates checking pending invoices and verifying corporate balances.', + inputs: { - portalUrl: { type: "string", default: "https://mock-finance-portal.test" } + portalUrl: { type: 'string', default: 'https://mock-finance-portal.test' }, }, - async execute(browser: any, args: FinanceAgentArgs): Promise { - console.log(`🚀 Starting Agentic Payment sequence on: ${args.portalUrl}`); - - // 1. Navigate to the dashboard target page - await browser.goto(args.portalUrl); - - // 2. Click the 'Invoices' tab visually - await browser.click("text=Invoices"); - - // 3. Extract table data fields safely with correct array indexing - const invoiceData: InvoiceRow[] = await browser.evaluate(() => { - const rows = Array.from(document.querySelectorAll("table.invoice-list tr")); - - // Skip the table header row if it exists + async execute(browser: FinanceBrowser, args: FinanceAgentArgs): Promise { + const portalUrl = args.portalUrl || 'https://mock-finance-portal.test'; + console.log(`🚀 Starting finance invoice scan on: ${portalUrl}`); + + await browser.goto(portalUrl); + await browser.click('text=Invoices'); + + const invoiceData = await browser.evaluate(() => { + const rows = Array.from(document.querySelectorAll('table.invoice-list tr')); return rows.slice(1).map((row) => { - const columns = row.querySelectorAll("td"); + const columns = row.querySelectorAll('td'); return { - invoiceId: columns[0]?.textContent?.trim() || "N/A", - vendor: columns[1]?.textContent?.trim() || "Unknown", - amountDue: columns[2]?.textContent?.trim() || "$0.00" - }; + invoiceId: columns[0]?.textContent?.trim() || 'N/A', + vendor: columns[1]?.textContent?.trim() || 'Unknown', + amountDue: columns[2]?.textContent?.trim() || '$0.00', + status: columns[3]?.textContent?.trim() || 'pending', + } satisfies InvoiceRow; }); }); - // 4. Return structured types back to webcmd handler + const totalDue = invoiceData.reduce((sum, item) => { + const numeric = Number.parseFloat(item.amountDue.replace(/[^\d.-]/g, '')) || 0; + return sum + numeric; + }, 0); + return { - status: "success", + status: 'success', timestamp: new Date().toISOString(), foundInvoices: invoiceData.length, - data: invoiceData + totalDue: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(totalDue), + data: invoiceData, }; - } -}; \ No newline at end of file + }, +} as const; + +export const financeAgentPlugin = financePlugin; +export default financePlugin; \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index cf57f2ee3..105204776 100644 --- a/src/main.ts +++ b/src/main.ts @@ -19,11 +19,12 @@ import * as path from 'node:path'; import { fileURLToPath } from 'node:url'; import { getCompletionScriptFast, getCompletionsFromManifest, hasAllManifests } from './completion-fast.js'; import { findPackageRoot, getCliManifestPath } from './package-paths.js'; +import { configureHostedWorkspaceOption, parseHostedRootCommandSurface, rootCompletionSentinelIndex } from './root-command-surface.js'; import { PKG_VERSION } from './version.js'; import { EXIT_CODES } from './errors.js'; import { isSupportedNodeVersion, MIN_SUPPORTED_NODE_MAJOR } from './runtime-detect.js'; import { CONFIG_DIR_NAME } from './brand.js'; -import {financeagentPlugin} from './mcp-skills/financeagent/finance-agent.js'; +import { financePlugin } from '../mcp-skills/financeagent/finance-agent.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); diff --git a/src/root-command-surface.ts b/src/root-command-surface.ts index 27fdf8fc5..04e145957 100644 --- a/src/root-command-surface.ts +++ b/src/root-command-surface.ts @@ -43,7 +43,9 @@ export function parseHostedRootCommandSurface(argv: readonly string[]): HostedRo const input = [...argv]; // main.ts checks an exact first-token version before its completion scan. - if (input[0] === '--version' || input[0] === '-V') { + // Commander also treats short version clusters such as -Vx/-Vh as the same + // root-level fast path, so keep those aligned with the actual CLI behavior. + if (input[0] === '--version' || input[0] === '-V' || /^-V(?:[A-Za-z-]|$)/.test(input[0] ?? '')) { return { kind: 'version', output: `${PKG_VERSION}\n` }; } // Completion is a Webcmd root sentinel. Once a command or `--` begins the diff --git a/src/site-memory/local-store.ts b/src/site-memory/local-store.ts index 3f0ea009b..6a0e56bd9 100644 --- a/src/site-memory/local-store.ts +++ b/src/site-memory/local-store.ts @@ -324,12 +324,21 @@ async function walkFiles(root: string, dir = root): Promise { async function readableRelativePath(root: string, path: string): Promise { const relativePath = safeRelativePath(root, path); - if ((await lstat(join(root, relativePath))).isSymbolicLink()) throw new Error(`Invalid site memory path: ${path}`); + await assertNoSymlinkInPath(root, relativePath, path); const [realRoot, realTarget] = await Promise.all([realpath(root), realpath(join(root, relativePath))]); if (realTarget !== realRoot && !realTarget.startsWith(`${realRoot}${sep}`)) throw new Error(`Invalid site memory path: ${path}`); return relativePath.split(sep).join('/'); } +async function assertNoSymlinkInPath(root: string, relativePath: string, originalPath: string): Promise { + const segments = relativePath.split(/[\\/]+/).filter(Boolean); + let current = root; + for (const segment of segments) { + current = join(current, segment); + if ((await lstat(current)).isSymbolicLink()) throw new Error(`Invalid site memory path: ${originalPath}`); + } +} + function safeRelativePath(root: string, path: string): string { const target = resolve(root, path); const resolvedRoot = resolve(root); @@ -390,6 +399,15 @@ function validateVerifyFixture(body: string): void { } async function assertInsideSiteRoot(root: string, parent: string, path: string): Promise { + const relativeParent = relative(root, parent); + if (relativeParent === '' || relativeParent === '.' || !relativeParent.startsWith('..')) { + const segments = relativeParent.split(/[\\/]+/).filter(Boolean); + let current = root; + for (const segment of segments) { + current = join(current, segment); + if ((await lstat(current)).isSymbolicLink()) throw new Error(`Invalid site memory path: ${path}`); + } + } const [realRoot, realParent] = await Promise.all([realpath(root), realpath(parent)]); if (realParent !== realRoot && !realParent.startsWith(`${realRoot}${sep}`)) { throw new Error(`Invalid site memory path: ${path}`); diff --git a/verify.txt b/verify.txt new file mode 100644 index 0000000000000000000000000000000000000000..1318fb40d7a85f332d54b14f7d2e3d940ca49b65 GIT binary patch literal 144796 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 W3@6oXbhmw8C4A2*(>!5ceE