diff --git a/.jules/bolt.md b/.jules/bolt.md index 57daf471..7b1ef992 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -3,3 +3,8 @@ **Learning:** `Date.parse(value)` returns the timestamp primitive directly, while `new Date(value).getTime()` also constructs a `Date` object. Both use the same ECMAScript string-parsing semantics for these call sites. **Action:** In frequently executed paths that only need a timestamp primitive, prefer `Date.parse(value)`. Treat the allocation reduction as a bounded micro-optimization unless a committed benchmark establishes a larger runtime effect. +## 2026-08-11 - Use for...in for N-sized object iterations in hot paths + +**Learning:** `Object.keys()` allocates a new N-sized string array upon every call. In large aggregations processing thousands of nested keys, this creates significant garbage collection overhead and heap thrashing. + +**Action:** When iterating over objects with unknown lengths (like dynamic id/name dictionaries) in high-frequency hot paths, prefer `for...in` guarded by `Object.hasOwn()`. This completely bypasses the temporary array allocation. diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 7902c442..24040c9a 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -30,3 +30,7 @@ **Vulnerability:** Known high-severity vulnerabilities discovered by the audit in `js-yaml` and `nanoid` packages. **Learning:** Deeply nested dependencies (`js-yaml` via `eslint`, `nanoid` via `vitest/vite`) may expose the application to DoS or logic loops. **Prevention:** Use `pnpm.overrides` in the root `package.json` to enforce patched versions across all transitive paths in a pnpm workspace. +## 2026-09-04 - Fix nested dependency vulnerabilities via pnpm.overrides +**Vulnerability:** Multiple critical/high vulnerabilities flagged by OSV-scanner in deeply nested dependencies (like `fast-uri`, `qs`, `@humanfs/node`, etc.). +**Learning:** These dependencies are buried deeply in the dependency tree (e.g., inside `@modelcontextprotocol/sdk` -> `ajv`), meaning normal `pnpm update` cannot resolve them if the parent package pins the older version. +**Prevention:** Use `pnpm.overrides` in the root `package.json` to enforce the patched versions globally across the workspace, and run `pnpm install` to apply the lockfile changes. diff --git a/package.json b/package.json index d085ba62..1553ed3d 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,17 @@ "brace-expansion@1": "1.1.15", "brace-expansion@2": "2.1.2", "brace-expansion@>=3": "5.0.9", - "fast-uri": "^3.1.5", + "fast-uri": "3.1.6", "ip-address": "^10.3.1", "undici": "^7.29.0", "minimatch": "^10.0.0", "@hono/node-server": "^2.0.5", - "body-parser": "^2.3.0" + "body-parser": "^2.3.0", + "@humanfs/node": "0.16.8", + "browserslist": "4.28.7", + "deepmerge-ts": "8.0.0", + "postcss-selector-parser": "7.1.3", + "qs": "6.16.0" } } } diff --git a/packages/web/src/lib/server/daily-rollup.ts b/packages/web/src/lib/server/daily-rollup.ts index 44fb4e5c..405e2206 100644 --- a/packages/web/src/lib/server/daily-rollup.ts +++ b/packages/web/src/lib/server/daily-rollup.ts @@ -438,16 +438,22 @@ export async function getDailyRollupsForProjects( const userSet = userSetsByDate.get(r.date)! for (const u of r.activeUserIds) userSet.add(u) - // [Bolt: Performance Optimization] Use Object.keys() instead of Object.entries() in hot paths. + // [Bolt: Performance Optimization] Use for...in instead of Object.keys() in hot paths. // Impact: Avoids array allocation for each key-value pair, significantly reducing GC overhead when aggregating large daily rollups. - for (const k of Object.keys(r.skillCounts)) { - prev.skillCounts[k] = (prev.skillCounts[k] ?? 0) + r.skillCounts[k]! + for (const k in r.skillCounts) { + if (Object.hasOwn(r.skillCounts, k)) { + prev.skillCounts[k] = (prev.skillCounts[k] ?? 0) + r.skillCounts[k]! + } } - for (const k of Object.keys(r.agentCounts)) { - prev.agentCounts[k] = (prev.agentCounts[k] ?? 0) + r.agentCounts[k]! + for (const k in r.agentCounts) { + if (Object.hasOwn(r.agentCounts, k)) { + prev.agentCounts[k] = (prev.agentCounts[k] ?? 0) + r.agentCounts[k]! + } } - for (const k of Object.keys(r.modelTokens)) { - prev.modelTokens[k] = (prev.modelTokens[k] ?? 0) + r.modelTokens[k]! + for (const k in r.modelTokens) { + if (Object.hasOwn(r.modelTokens, k)) { + prev.modelTokens[k] = (prev.modelTokens[k] ?? 0) + r.modelTokens[k]! + } } // userStats: userId 기준 sum (지연된 Map 변환) @@ -622,10 +628,16 @@ export function aggregateSummary( totals.cacheCreationTokens += r.cacheCreationTokens totals.estimatedCostUsd += r.estimatedCostUsd for (const u of r.activeUserIds) activeUsers.add(u) - // [Bolt: Performance Optimization] Object.keys() iterations avoid internal array tuples, reducing heap thrashing - for (const k of Object.keys(r.skillCounts)) skillCounts[k] = (skillCounts[k] ?? 0) + r.skillCounts[k]! - for (const k of Object.keys(r.agentCounts)) agentCounts[k] = (agentCounts[k] ?? 0) + r.agentCounts[k]! - for (const k of Object.keys(r.modelTokens)) modelTokens[k] = (modelTokens[k] ?? 0) + r.modelTokens[k]! + // [Bolt: Performance Optimization] for...in iterations avoid array allocations, reducing heap thrashing + for (const k in r.skillCounts) { + if (Object.hasOwn(r.skillCounts, k)) skillCounts[k] = (skillCounts[k] ?? 0) + r.skillCounts[k]! + } + for (const k in r.agentCounts) { + if (Object.hasOwn(r.agentCounts, k)) agentCounts[k] = (agentCounts[k] ?? 0) + r.agentCounts[k]! + } + for (const k in r.modelTokens) { + if (Object.hasOwn(r.modelTokens, k)) modelTokens[k] = (modelTokens[k] ?? 0) + r.modelTokens[k]! + } } // Deterministic tie-break: callCount DESC, skillName ASC (codepoint binary — diff --git a/packages/web/src/lib/server/weekly-report.ts b/packages/web/src/lib/server/weekly-report.ts index eb95d36f..419a12b4 100644 --- a/packages/web/src/lib/server/weekly-report.ts +++ b/packages/web/src/lib/server/weekly-report.ts @@ -394,19 +394,23 @@ export async function getWeeklyReport( // Insights — delegation // ⚡ Bolt Optimization: // 병목 지점: 기존 코드는 `thisWeekRollups`를 3번 순회하고, 매 순회마다 Object.values()로 중간 배열을 생성하여 메모리 할당 비용이 발생했습니다. - // 최적화 방법: 단일 for...of 루프와 Object.keys() 순회를 결합하여 N+1 순회를 1회 순회로 통합하고 중간 배열 할당을 제거했습니다. - // 기대 효과: `thisWeekRollups`의 크기가 클 경우, 불필요한 배열 생성 오버헤드와 O(N) 순회를 1/3로 줄여 리포트 생성 성능이 향상됩니다. + // 최적화 방법: 단일 for...of 루프와 for...in 순회를 결합하여 N+1 순회를 1회 순회로 통합하고 배열 할당을 완전히 제거했습니다. + // 기대 효과: `thisWeekRollups`의 크기가 클 경우, 불필요한 배열 생성 오버헤드와 O(N) 순회를 줄여 리포트 생성 성능이 극대화됩니다. let totalAgentCalls = 0 let totalSkillCalls = 0 const distinctSkillsThisWeek = new Set() for (const r of thisWeekRollups) { - for (const k of Object.keys(r.agentCounts)) { - totalAgentCalls += r.agentCounts[k] + for (const k in r.agentCounts) { + if (Object.hasOwn(r.agentCounts, k)) { + totalAgentCalls += r.agentCounts[k] + } } - for (const k of Object.keys(r.skillCounts)) { - totalSkillCalls += r.skillCounts[k] - distinctSkillsThisWeek.add(k) + for (const k in r.skillCounts) { + if (Object.hasOwn(r.skillCounts, k)) { + totalSkillCalls += r.skillCounts[k] + distinctSkillsThisWeek.add(k) + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dfd315f..5b0f1315 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,12 +16,17 @@ overrides: brace-expansion@1: 1.1.15 brace-expansion@2: 2.1.2 brace-expansion@>=3: 5.0.9 - fast-uri: ^3.1.5 + fast-uri: 3.1.6 ip-address: ^10.3.1 undici: ^7.29.0 minimatch: ^10.0.0 '@hono/node-server': ^2.0.5 body-parser: ^2.3.0 + '@humanfs/node': 0.16.8 + browserslist: 4.28.7 + deepmerge-ts: 8.0.0 + postcss-selector-parser: 7.1.3 + qs: 6.16.0 pnpmfileChecksum: qsp27c6veblwg3gxusbbzrumtm @@ -711,12 +716,16 @@ packages: peerDependencies: hono: ^4.12.34 - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': @@ -1939,8 +1948,8 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - baseline-browser-mapping@2.10.33: - resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} + baseline-browser-mapping@2.11.21: + resolution: {integrity: sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -1962,8 +1971,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.2: - resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + browserslist@4.28.7: + resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -2006,6 +2015,9 @@ packages: caniuse-lite@1.0.30001793: resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -2278,8 +2290,8 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge-ts@7.1.5: - resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + deepmerge-ts@8.0.0: + resolution: {integrity: sha512-ICNjaP0ML+eSdEpJYQC46XiAn/UjAdwbEl0dE8p85ZTeNDinN4Kd4+9jS4OSAuH7st6eC7rQhsqTF5zIDaUm2g==} engines: {node: '>=16.0.0'} deepmerge@4.3.1: @@ -2369,8 +2381,8 @@ packages: effect@3.21.0: resolution: {integrity: sha512-PPN80qRokCd1f015IANNhrwOnLO7GrrMQfk4/lnZRE/8j7UPWrNNjPV0uBrZutI/nHzernbW+J0hdqQysHiSnQ==} - electron-to-chromium@1.5.364: - resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==} + electron-to-chromium@1.5.422: + resolution: {integrity: sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -2668,8 +2680,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.5: - resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + fast-uri@3.1.6: + resolution: {integrity: sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -3673,8 +3685,8 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - node-releases@2.0.46: - resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + node-releases@2.0.54: + resolution: {integrity: sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==} engines: {node: '>=18'} npm-run-path@4.0.1: @@ -3859,8 +3871,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss-selector-parser@7.1.1: - resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + postcss-selector-parser@7.1.3: + resolution: {integrity: sha512-ajnd7iZnqjJDkyHNfznl/ZVO0lWqvBmQXfKKENx9/p/bEiF/L3eHwdydNUg9RXZx6xfZWOCmXmBa5oeB+YrAPQ==} engines: {node: '>=4'} postcss@8.5.25: @@ -3922,8 +3934,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.15.2: - resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + qs@6.16.0: + resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -4182,6 +4194,10 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -4530,7 +4546,7 @@ packages: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true peerDependencies: - browserslist: '>= 4.21.0' + browserslist: 4.28.7 uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -4845,7 +4861,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.2 + browserslist: 4.28.7 lru-cache: 5.1.1 semver: 6.3.1 @@ -5245,13 +5261,18 @@ snapshots: dependencies: hono: 4.13.0 - '@humanfs/core@0.19.1': {} + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 - '@humanfs/node@0.16.7': + '@humanfs/node@0.16.8': dependencies: - '@humanfs/core': 0.19.1 + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 '@humanwhocodes/retry': 0.4.3 + '@humanfs/types@0.15.0': {} + '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/retry@0.4.3': {} @@ -5659,7 +5680,7 @@ snapshots: '@prisma/config@6.19.3(magicast@0.3.5)': dependencies: c12: 3.1.0(magicast@0.3.5) - deepmerge-ts: 7.1.5 + deepmerge-ts: 8.0.0 effect: 3.21.0 empathic: 2.0.0 transitivePeerDependencies: @@ -6238,7 +6259,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.5 + fast-uri: 3.1.6 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -6359,7 +6380,7 @@ snapshots: balanced-match@4.0.4: {} - baseline-browser-mapping@2.10.33: {} + baseline-browser-mapping@2.11.21: {} bcryptjs@2.4.3: {} @@ -6375,7 +6396,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.15.2 + qs: 6.16.0 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -6389,13 +6410,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.28.2: + browserslist@4.28.7: dependencies: - baseline-browser-mapping: 2.10.33 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.364 - node-releases: 2.0.46 - update-browserslist-db: 1.2.3(browserslist@4.28.2) + baseline-browser-mapping: 2.11.21 + caniuse-lite: 1.0.30001810 + electron-to-chromium: 1.5.422 + node-releases: 2.0.54 + update-browserslist-db: 1.2.3(browserslist@4.28.7) bundle-name@4.1.0: dependencies: @@ -6443,6 +6464,8 @@ snapshots: caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001810: {} + ccount@2.0.1: {} chai@5.3.3: @@ -6660,7 +6683,7 @@ snapshots: deep-is@0.1.4: {} - deepmerge-ts@7.1.5: {} + deepmerge-ts@8.0.0: {} deepmerge@4.3.1: {} @@ -6740,7 +6763,7 @@ snapshots: '@standard-schema/spec': 1.1.0 fast-check: 3.23.2 - electron-to-chromium@1.5.364: {} + electron-to-chromium@1.5.422: {} emoji-regex@10.6.0: {} @@ -7066,7 +7089,7 @@ snapshots: '@eslint/eslintrc': 3.3.5 '@eslint/js': 9.39.4 '@eslint/plugin-kit': 0.4.1 - '@humanfs/node': 0.16.7 + '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -7189,7 +7212,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.2 + qs: 6.16.0 range-parser: 1.2.1 router: 2.2.0 send: 1.2.1 @@ -7238,7 +7261,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.5: {} + fast-uri@3.1.6: {} fast-wrap-ansi@0.2.2: dependencies: @@ -8406,7 +8429,7 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 - node-releases@2.0.46: {} + node-releases@2.0.54: {} npm-run-path@4.0.1: dependencies: @@ -8605,7 +8628,7 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-selector-parser@7.1.1: + postcss-selector-parser@7.1.3: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 @@ -8667,9 +8690,10 @@ snapshots: pure-rand@6.1.0: {} - qs@6.15.2: + qs@6.16.0: dependencies: - side-channel: 1.1.0 + es-define-property: 1.0.1 + side-channel: 1.1.1 queue-microtask@1.2.3: {} @@ -8999,7 +9023,7 @@ snapshots: '@dotenvx/dotenvx': 1.70.0 '@modelcontextprotocol/sdk': 1.29.0(zod@3.25.76) '@types/validate-npm-package-name': 4.0.2 - browserslist: 4.28.2 + browserslist: 4.28.7 commander: 14.0.3 cosmiconfig: 9.0.1(typescript@5.9.3) dedent: 1.7.2 @@ -9016,7 +9040,7 @@ snapshots: open: 11.0.0 ora: 8.2.0 postcss: 8.5.25 - postcss-selector-parser: 7.1.1 + postcss-selector-parser: 7.1.3 prompts: 2.4.2 recast: 0.23.11 stringify-object: 5.0.0 @@ -9101,6 +9125,14 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@3.0.7: {} @@ -9491,9 +9523,9 @@ snapshots: until-async@3.0.2: {} - update-browserslist-db@1.2.3(browserslist@4.28.2): + update-browserslist-db@1.2.3(browserslist@4.28.7): dependencies: - browserslist: 4.28.2 + browserslist: 4.28.7 escalade: 3.2.0 picocolors: 1.1.1