diff --git a/.archgate/adrs/ARCH-001-command-structure.rules.ts b/.archgate/adrs/ARCH-001-command-structure.rules.ts
index aa753071..4fc8e2e1 100644
--- a/.archgate/adrs/ARCH-001-command-structure.rules.ts
+++ b/.archgate/adrs/ARCH-001-command-structure.rules.ts
@@ -8,7 +8,7 @@ export default {
const files = ctx.scopedFiles.filter((f) => !f.endsWith("index.ts"));
const checks = files.map(async (file) => {
const content = await ctx.readFile(file);
- if (!/export\s+function\s+register\w+Command/.test(content)) {
+ if (!/export\s+function\s+register\w+Command/u.test(content)) {
ctx.report.violation({
message: "Command file must export a register*Command function",
file,
@@ -27,7 +27,7 @@ export default {
files.map((file) =>
ctx.grep(
file,
- /\.(parse|match|replace|split)\(.*\).*\.(parse|match|replace|split)\(/
+ /\.(parse|match|replace|split)\(.*\).*\.(parse|match|replace|split)\(/u
)
)
);
diff --git a/.archgate/adrs/ARCH-002-error-handling.rules.ts b/.archgate/adrs/ARCH-002-error-handling.rules.ts
index 92b5a649..87b7e8b9 100644
--- a/.archgate/adrs/ARCH-002-error-handling.rules.ts
+++ b/.archgate/adrs/ARCH-002-error-handling.rules.ts
@@ -10,7 +10,7 @@ export default {
(f) => !f.endsWith("helpers/log.ts") && !f.includes("tests/")
);
const matches = await Promise.all(
- files.map((file) => ctx.grep(file, /console\.error\(/))
+ files.map((file) => ctx.grep(file, /console\.error\(/u))
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
@@ -38,7 +38,7 @@ export default {
!f.includes("tests/")
);
const matches = await Promise.all(
- files.map((file) => ctx.grep(file, /console\.(log|warn|info)\s*\(/))
+ files.map((file) => ctx.grep(file, /console\.(log|warn|info)\s*\(/u))
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
@@ -59,12 +59,12 @@ export default {
const allowedCodes = new Set([0, 1, 2, 130]);
const matches = await Promise.all(
ctx.scopedFiles.map((file) =>
- ctx.grep(file, /process\.exit\((\d+)\)/)
+ ctx.grep(file, /process\.exit\((\d+)\)/u)
)
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
- const codeMatch = m.content.match(/process\.exit\((\d+)\)/);
+ const codeMatch = m.content.match(/process\.exit\((\d+)\)/u);
if (codeMatch) {
const code = Number(codeMatch[1]);
if (!allowedCodes.has(code)) {
diff --git a/.archgate/adrs/ARCH-003-output-formatting.rules.ts b/.archgate/adrs/ARCH-003-output-formatting.rules.ts
index caf60450..de15f4a6 100644
--- a/.archgate/adrs/ARCH-003-output-formatting.rules.ts
+++ b/.archgate/adrs/ARCH-003-output-formatting.rules.ts
@@ -37,7 +37,7 @@ export default {
(f) => !f.includes("tests/") && !f.includes(".archgate/")
);
const matches = await Promise.all(
- files.map((file) => ctx.grep(file, /\\u001b\[|\\x1b\[|\\033\[/))
+ files.map((file) => ctx.grep(file, /\\u001b\[|\\x1b\[|\\033\[/u))
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
diff --git a/.archgate/adrs/ARCH-004-no-barrel-files.rules.ts b/.archgate/adrs/ARCH-004-no-barrel-files.rules.ts
index 28f0d0e4..a5bfe85b 100644
--- a/.archgate/adrs/ARCH-004-no-barrel-files.rules.ts
+++ b/.archgate/adrs/ARCH-004-no-barrel-files.rules.ts
@@ -31,7 +31,7 @@ function isBarrelFile(content: string): boolean {
// Continuation of multi-line export blocks
line.startsWith("} from") ||
line.startsWith("type ") ||
- /^[A-Za-z_$,\s]+$/.test(line) ||
+ /^[A-Za-z_$,\s]+$/u.test(line) ||
line === "}" ||
line === "};"
);
diff --git a/.archgate/adrs/ARCH-007-cross-platform-subprocess-execution.rules.ts b/.archgate/adrs/ARCH-007-cross-platform-subprocess-execution.rules.ts
index 236d7e3a..2fbb2038 100644
--- a/.archgate/adrs/ARCH-007-cross-platform-subprocess-execution.rules.ts
+++ b/.archgate/adrs/ARCH-007-cross-platform-subprocess-execution.rules.ts
@@ -12,7 +12,7 @@ export default {
// Check for Bun.$ template literal usage
const bunShellMatches = await Promise.all(
- files.map((file) => ctx.grep(file, /Bun\.\$`/))
+ files.map((file) => ctx.grep(file, /Bun\.\$`/u))
);
for (const fileMatches of bunShellMatches) {
for (const m of fileMatches) {
@@ -29,7 +29,7 @@ export default {
// Check for $ import from "bun" (the shell API)
const dollarImportMatches = await Promise.all(
files.map((file) =>
- ctx.grep(file, /import\s*\{[^}]*\$[^}]*\}\s*from\s*["']bun["']/)
+ ctx.grep(file, /import\s*\{[^}]*\$[^}]*\}\s*from\s*["']bun["']/u)
)
);
for (const fileMatches of dollarImportMatches) {
@@ -46,7 +46,7 @@ export default {
// Check for await $` pattern (destructured $ usage)
const destructuredMatches = await Promise.all(
- files.map((file) => ctx.grep(file, /await\s+\$`/))
+ files.map((file) => ctx.grep(file, /await\s+\$`/u))
);
for (const fileMatches of destructuredMatches) {
for (const m of fileMatches) {
diff --git a/.archgate/adrs/ARCH-008-typed-command-options.rules.ts b/.archgate/adrs/ARCH-008-typed-command-options.rules.ts
index 67ddd352..62aa6f2d 100644
--- a/.archgate/adrs/ARCH-008-typed-command-options.rules.ts
+++ b/.archgate/adrs/ARCH-008-typed-command-options.rules.ts
@@ -15,7 +15,7 @@ export default {
files.map((file) =>
ctx.grep(
file,
- /\.option\(\s*["']--\w+\s+<\w+>["'],\s*["'][^"']*(?:claude.*cursor|backend.*frontend)[^"']*["']/
+ /\.option\(\s*["']--\w+\s+<\w+>["'],\s*["'][^"']*(?:claude.*cursor|backend.*frontend)[^"']*["']/u
)
)
);
@@ -44,7 +44,7 @@ export default {
files.map((file) =>
ctx.grep(
file,
- /\.option\(\s*["']--\w+\s+<\w+>["'],\s*["'][^"']*["'],\s*(?:parseInt|parseFloat|\()/
+ /\.option\(\s*["']--\w+\s+<\w+>["'],\s*["'][^"']*["'],\s*(?:parseInt|parseFloat|\()/u
)
)
);
diff --git a/.archgate/adrs/ARCH-009-platform-detection-helper.rules.ts b/.archgate/adrs/ARCH-009-platform-detection-helper.rules.ts
index bab7ae05..3c070a3b 100644
--- a/.archgate/adrs/ARCH-009-platform-detection-helper.rules.ts
+++ b/.archgate/adrs/ARCH-009-platform-detection-helper.rules.ts
@@ -14,7 +14,7 @@ export default {
);
const matches = await Promise.all(
- files.map((file) => ctx.grep(file, /process\.platform/))
+ files.map((file) => ctx.grep(file, /process\.platform/u))
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
diff --git a/.archgate/adrs/ARCH-010-prefer-bun-built-in-json-parsing.rules.ts b/.archgate/adrs/ARCH-010-prefer-bun-built-in-json-parsing.rules.ts
index 30b4fb93..62639cb2 100644
--- a/.archgate/adrs/ARCH-010-prefer-bun-built-in-json-parsing.rules.ts
+++ b/.archgate/adrs/ARCH-010-prefer-bun-built-in-json-parsing.rules.ts
@@ -14,7 +14,7 @@ export default {
// Pattern 1: single-expression JSON.parse(await Bun.file(...).text())
const inlineMatches = await Promise.all(
files.map((file) =>
- ctx.grep(file, /JSON\.parse\(\s*await\s+Bun\.file/)
+ ctx.grep(file, /JSON\.parse\(\s*await\s+Bun\.file/u)
)
);
for (const fileMatches of inlineMatches) {
@@ -39,7 +39,7 @@ export default {
const textCalls = await ctx.grep(
file,
- /Bun\.file\([^)]+\)\.text\(\)/
+ /Bun\.file\([^)]+\)\.text\(\)/u
);
if (textCalls.length === 0) return;
diff --git a/.archgate/adrs/ARCH-011-consistent-project-root-resolution.rules.ts b/.archgate/adrs/ARCH-011-consistent-project-root-resolution.rules.ts
index af209b7f..2c52fdd6 100644
--- a/.archgate/adrs/ARCH-011-consistent-project-root-resolution.rules.ts
+++ b/.archgate/adrs/ARCH-011-consistent-project-root-resolution.rules.ts
@@ -16,7 +16,7 @@ export default {
);
const checks = files.map(async (file) => {
- const matches = await ctx.grep(file, /process\.cwd\(\)/);
+ const matches = await ctx.grep(file, /process\.cwd\(\)/u);
for (const m of matches) {
// Allow process.cwd() as a fallback after findProjectRoot()
// e.g. findProjectRoot() ?? process.cwd()
diff --git a/.archgate/adrs/ARCH-012-command-error-boundaries.rules.ts b/.archgate/adrs/ARCH-012-command-error-boundaries.rules.ts
index 0d7d6833..6b8ef49c 100644
--- a/.archgate/adrs/ARCH-012-command-error-boundaries.rules.ts
+++ b/.archgate/adrs/ARCH-012-command-error-boundaries.rules.ts
@@ -16,12 +16,12 @@ export default {
const content = await ctx.readFile(file);
// Find async action callbacks
- const hasAsyncAction = /\.action\(\s*async\s/.test(content);
+ const hasAsyncAction = /\.action\(\s*async\s/u.test(content);
if (!hasAsyncAction) return;
// Check if the async action body contains a try block
// Match: .action(async (...) => { ... try { ... } ... })
- const hasTryCatch = /\.action\(\s*async\s[\s\S]*?\btry\s*\{/.test(
+ const hasTryCatch = /\.action\(\s*async\s[\s\S]*?\btry\s*\{/u.test(
content
);
@@ -51,13 +51,13 @@ export default {
// Only check files with async actions that have try-catch
const hasAsyncActionWithTryCatch =
- /\.action\(\s*async\s[\s\S]*?\btry\s*\{/.test(content);
+ /\.action\(\s*async\s[\s\S]*?\btry\s*\{/u.test(content);
if (!hasAsyncActionWithTryCatch) return;
// Check for the ExitPromptError re-throw pattern anywhere in the file.
// The canonical pattern is:
// if (err instanceof Error && err.name === "ExitPromptError") throw err;
- const hasExitPromptRethrow = /ExitPromptError/.test(content);
+ const hasExitPromptRethrow = /ExitPromptError/u.test(content);
if (!hasExitPromptRethrow) {
ctx.report.violation({
diff --git a/.archgate/adrs/ARCH-013-version-synchronization.rules.ts b/.archgate/adrs/ARCH-013-version-synchronization.rules.ts
index d734ea3b..7edd8239 100644
--- a/.archgate/adrs/ARCH-013-version-synchronization.rules.ts
+++ b/.archgate/adrs/ARCH-013-version-synchronization.rules.ts
@@ -18,7 +18,7 @@ export default {
return;
}
- const match = astroConfig.match(/softwareVersion:\s*"([^"]+)"/);
+ const match = astroConfig.match(/softwareVersion:\s*"([^"]+)"/u);
if (!match) return;
const docsVersion = match[1];
diff --git a/.archgate/adrs/ARCH-014-prefer-bun-env.rules.ts b/.archgate/adrs/ARCH-014-prefer-bun-env.rules.ts
index 215b1ca3..be9225ed 100644
--- a/.archgate/adrs/ARCH-014-prefer-bun-env.rules.ts
+++ b/.archgate/adrs/ARCH-014-prefer-bun-env.rules.ts
@@ -11,7 +11,7 @@ export default {
);
const matches = await Promise.all(
- files.map((file) => ctx.grep(file, /process\.env\b/))
+ files.map((file) => ctx.grep(file, /process\.env\b/u))
);
for (const fileMatches of matches) {
for (const m of fileMatches) {
diff --git a/.archgate/adrs/CI-001-pin-github-actions-by-hash.rules.ts b/.archgate/adrs/CI-001-pin-github-actions-by-hash.rules.ts
index 85630a1e..2f75231f 100644
--- a/.archgate/adrs/CI-001-pin-github-actions-by-hash.rules.ts
+++ b/.archgate/adrs/CI-001-pin-github-actions-by-hash.rules.ts
@@ -5,13 +5,13 @@
* Captures: owner/action@ref (ignoring local refs like `./.github/...` and
* docker refs like `docker://...`).
*/
-const USES_PATTERN = /uses:\s+(?!\.\/|docker:\/\/)(\S+@\S+)/g;
+const USES_PATTERN = /uses:\s+(?!\.\/|docker:\/\/)(\S+@\S+)/gu;
/**
* A valid pinned reference: 40 hex characters (full SHA), optionally followed
* by a version comment.
*/
-const PINNED_SHA_PATTERN = /^.+@[0-9a-f]{40}\b/;
+const PINNED_SHA_PATTERN = /^.+@[0-9a-f]{40}\b/u;
/**
* Carved-out exceptions where the upstream provider does not support SHA pinning.
@@ -44,7 +44,7 @@ export default {
for (const m of matches) {
// Extract the full `uses:` value from the matched line
const usesMatch = m.content.match(
- /uses:\s+(?!\.\/|docker:\/\/)(\S+@\S+)/
+ /uses:\s+(?!\.\/|docker:\/\/)(\S+@\S+)/u
);
if (!usesMatch) continue;
diff --git a/.archgate/adrs/GEN-002-docs-i18n.rules.ts b/.archgate/adrs/GEN-002-docs-i18n.rules.ts
index 0489993b..97b0ddc6 100644
--- a/.archgate/adrs/GEN-002-docs-i18n.rules.ts
+++ b/.archgate/adrs/GEN-002-docs-i18n.rules.ts
@@ -11,7 +11,7 @@ const CONTENT_ROOT = "docs/src/content/docs";
/** Patterns that match locale-prefixed internal links in MDX files. */
const LOCALE_LINK_PATTERNS = LOCALES.map(
- (locale) => new RegExp(`(?:href="|\\]\\()/${locale}/`, "g")
+ (locale) => new RegExp(`(?:href="|\\]\\()/${locale}/`, "gu")
);
export default {
diff --git a/.simple-release.js b/.simple-release.js
index 231fd1de..59323447 100644
--- a/.simple-release.js
+++ b/.simple-release.js
@@ -16,7 +16,7 @@ class ArchgateProject extends NpmProject {
if (existsSync(astroConfigPath)) {
const astroConfig = readFileSync(astroConfigPath, "utf8");
const updated = astroConfig.replace(
- /softwareVersion:\s*"[^"]+"/,
+ /softwareVersion:\s*"[^"]+"/u,
`softwareVersion: "${version}"`
);
if (updated !== astroConfig) {
diff --git a/bun.lock b/bun.lock
index 2f67d904..37e6fcb6 100644
--- a/bun.lock
+++ b/bun.lock
@@ -18,9 +18,9 @@
"inquirer": "13.4.2",
"knip": "6.12.1",
"meriyah": "7.1.0",
- "oxfmt": "0.47.0",
- "oxlint": "1.62.0",
- "posthog-node": "5.33.2",
+ "oxfmt": "0.48.0",
+ "oxlint": "1.63.0",
+ "posthog-node": "5.33.3",
"zod": "4.4.3",
},
"peerDependencies": {
@@ -203,85 +203,85 @@
"@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.19.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw=="],
- "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.47.0", "", { "os": "android", "cpu": "arm" }, "sha512-KrMQRdMi/upr81qT4ijK6X6BNp6jqpMY7FwILQnwIy9QLc3qpnhUx5rsCLGzn4ewsCQ0CNAspN2ogmP1GXLyLw=="],
+ "@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.48.0", "", { "os": "android", "cpu": "arm" }, "sha512-uwqk+/KhQvBIpULD8SMM/zAafMRC/+DV/xsEQjkkIsJ/kLmEI/2bxonVowcYTiXqqZ/a0FEW8DPkZY3VvwELDA=="],
- "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.47.0", "", { "os": "android", "cpu": "arm64" }, "sha512-r4ixS/PeUpAFKgrpDoZ5pSkthjZzVzKd95525Aazj+aOv9H4ulK5zYHGb7wFY5n5kZxHK8TbOJUZgoEb1ohddQ=="],
+ "@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.48.0", "", { "os": "android", "cpu": "arm64" }, "sha512-VUCiKuXK5+McVssgHEJdrcGK7hRJzrRb36zm9/jwzMholyYt4BgXhw5Nm1V1DX6Ce717Zi/1jk432b/tgmQgtQ=="],
- "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.47.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-CLWxiKpMl+195cm09CuaWEhJK0CirRkoMa07aR9+9AFPat2LfIKtwx1JqxZM0MTvcMe6+adlJNdVL6jdInvq3g=="],
+ "@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.48.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-IkKp8rnIyQLW6Jt+6jragCbUVYSayk55lapiprLjIVvt4NczLyO/nwX2GgefLQ5iaBdfS8UEAFgCs/pLO6Cl0w=="],
- "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.47.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Xq5fjTYDC50faUeLSm0rZdBqoTgleXEdD7NpJdARtQIczkCJn3xNjMUSQQkUmh4CtxkKTNL68lytcOK3e/osgg=="],
+ "@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.48.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-+aFuhsGIuvnoOjXyKVHMhPKJZR1kQkAl8QyrKoMlA7yJsSTC3N0Asl53La8TChSHhW8epToQ/Q0nvLmEmfNmLg=="],
- "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.47.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-QOU9ZIJ52p5askcEC0QJvvr8trHAWoonul8bgISo6gYUL3s50zkqafBYcNAr9LJZQbsZtPfIWHk9+5+nUp1qJQ=="],
+ "@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.48.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-fbqzQL8FjI9gGnktI7RIo0dksDziTAYBy7xlI7jU7eID5fxLF/25fS4Xj6GydD8Y5oWHL83U4NK160QaOAxtyg=="],
- "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.47.0", "", { "os": "linux", "cpu": "arm" }, "sha512-oJxDM1aBhPvz9gmElBv8UpxyiqhwfjcbrSxT5F0xtuUzY6dQI27/AQPIt3eu3Z5Yvn0kQl5R7MA3Z+MbnRvCBw=="],
+ "@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.48.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hn4i0zhAyTiB3ZHjQfYUZkDvrbVkohw1S7pySWxWUoZ87HnkDoTFThj7QTxk40hNPOTUP0vHbPRNamFIv1HBJQ=="],
- "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.47.0", "", { "os": "linux", "cpu": "arm" }, "sha512-g8Lh50VS4ibGz2q6v7r9UZY4D0dM16SdrFYOMzhqIoCwGcai8VMIRUAcqn1/jlCsOOzUXJ741+kCeJt0cofakQ=="],
+ "@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.48.0", "", { "os": "linux", "cpu": "arm" }, "sha512-R4WBD9qF3QM9hqgdAa+fBGXmquTvDUujrPQ36t2Sjk8RPOSKGHDeN7l/khr10hqbQaOq9KCgPHG9ubNET/X/RQ=="],
- "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.47.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-YrNT1vQ0asaXoRbrvYENPqmBfOQ9Xr8enPNOULeYfg44VjCcrUowFy5QZr+WawE0zyP8cH9e9Gxxg0fDEFzhcg=="],
+ "@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.48.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-5bVdwSwlm1M8wbYCorLOxWxUBw/8tBvHYyQNIfwWVPwOJaj5vg1APSGJQVpwJfV5VNE9PSrR91UKEpoNwHhqUA=="],
- "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.47.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-IxtQC/sbBi4ubbY+MdwdanRWrG9InQJVZqyMsBa5IUaQcnSg86gQme574HxXMC1p4bo4YhV99zQ+wNnGCvEgzw=="],
+ "@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.48.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-vCS3Fk7gFslTqE1lUE2IlroyVV7u/9SmMA/uBqDoshuck2psGWcjW0ePyPZI3rM3+qtf2pDaMVIKMHozraifuw=="],
- "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.47.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-EWXEhOMbWO0q6eJSbu0QLkU8cKi0ljlYLngeDs2Ocu/pm1rrLwyQiYzlFbdnMRURI4w9ndr1sI9rSbhlJ5o23Q=="],
+ "@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.48.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gKtfFfueUClXDumyoHUbymqRf7prHejOOyzJK0eIJn93GF9JBdFHdo60TM1ZBHxkEwZvjuOgHmKtneKbEOc/Eg=="],
- "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.47.0", "", { "os": "linux", "cpu": "none" }, "sha512-tZrjS11TUiDuEpRaqdk8K9F9xETRyKXfuZKmdeW+Gj7coBnm7+8sBEfyt033EAFEQSlkniAXvBLh+Qja2ioGBQ=="],
+ "@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.48.0", "", { "os": "linux", "cpu": "none" }, "sha512-SYt0UhOvZD/UwZz9sXq6J2uAw8o24f5VZpLB2DH01f6MevshmlgakQlZe2lwek2sZJkd07eLu7mZa0g7yeiw7Q=="],
- "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.47.0", "", { "os": "linux", "cpu": "none" }, "sha512-KBFy+2CFKUCZzYwX2ZOPQKck1vjQbz+hextuc19G4r0WRJwadfAeuQMQRQvB+Ivc8brlbOVg7et8K7E467440g=="],
+ "@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.48.0", "", { "os": "linux", "cpu": "none" }, "sha512-JLbrwck2AopG4ud/XklZO5N+qxGC7cS7ROvXZVNfx0MCLDDL2kGOLvzuWORkVjnjAM0CMAfIMU2zNBtQbM+4dw=="],
- "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.47.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-REUPFKVGSiK99B+9eaPhluEVglzaoj/SMykNC5SUiV2RSsBfV5lWN7Y0iCIc251Wz3GaeAGZsJ/zj3gjarxdFg=="],
+ "@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.48.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-mdxt5L8OQLxkQH+JVpdC/lknZNe0lX4hlO3d8+xvw2wToo+iDrid9tiGOd5bmHfUVd5wVhrUry0qlu5vq66NkQ=="],
- "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.47.0", "", { "os": "linux", "cpu": "x64" }, "sha512-KVftVSVEDeIfRW3TIeLe3aNI/iY4m1fu5mDwHcisKMZSCMKLkrhFsjowC7o9RoqNPxbbglm2+/6KAKBIts2t0Q=="],
+ "@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.48.0", "", { "os": "linux", "cpu": "x64" }, "sha512-oEz1BQwMrV7OMEFx/3VPDU3n9TM0AnxpktDYXjEg5i6nTX87wo18wSfBvkl4tzAICdKtoAQAdBIl7Y7hsPlx5w=="],
- "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.47.0", "", { "os": "linux", "cpu": "x64" }, "sha512-DTsmGEaA2860Aq5VUyDO8/MT9NFxwVL93RnRYmpMwK6DsSkThmvEpqoUDDljziEpAedMRG19SCogrNbINSbLUQ=="],
+ "@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.48.0", "", { "os": "linux", "cpu": "x64" }, "sha512-g2SKTTurP5mWjd8Ecait0erYqmltL4IqW1EwttM25BxM6NiTt4ubobJYMR1uox1V2QgG4UfHH10CGRvWlUixjw=="],
- "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.47.0", "", { "os": "none", "cpu": "arm64" }, "sha512-8r5BDro7fLOBoq1JXHLVSs55OlrxQhEso4HVo0TcY7OXJUPYfjPoOaYL5us+yIwqyP9rQwN+rxuiNFSmaxSuOQ=="],
+ "@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.48.0", "", { "os": "none", "cpu": "arm64" }, "sha512-CIg24VgheEpvolHL2gQuax5qcQ602bRMHrJ9g8XsQr3iVj9aSPgopigBKuMqrXsupwkrU+RQCn5cG8PgFntR6w=="],
- "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.47.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-qtz/gzm8IjSPUlseZ0ofW8zyHLoZsuP5HTfcGGkWkUblB89JT8GNYH3ICqjbDsqsGqXum0/ZndXTFplSdXFIcg=="],
+ "@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.48.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-zeaWkcxcEULwkGF3I/HgEvcDPN8buYDrxibBUa/IFh5Vmwyge+KpLO+hEwSovW349H0O/C0Z2kaFmEzEDm00/Q=="],
- "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.47.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-5vIcdcIDE7nCx+MXN6sm8kbC4zajDB31E86rez4i45iHNH/2NjdKlJ720xcHTr3eeiMcttCGPHPhE1TjtBDGZw=="],
+ "@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.48.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-yiEKnIAGvx5CyZQOlMaNlZkAbwT7/Quk0j3WLt+PR5hK+qYjPTRRJYDfD77wCBPLvEYAG41v4KG3iL0H+uxoxg=="],
- "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.47.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Sr59Y5ms54ONBjxFeWhVlGyQcHXxcl9DxC23f6yXlRkcos7LXBLoO+KDfxexjHIOZh7cWqrWduzvUjJ+pHp8cQ=="],
+ "@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.48.0", "", { "os": "win32", "cpu": "x64" }, "sha512-GSD2+7t2UoVMV2NgxXypa4bKewflPMAjYnF0Xw9/ht82ZfafAHhb8STwrEd7wlH2PFogt5zw3WVCxYJaHUdbeQ=="],
- "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.62.0", "", { "os": "android", "cpu": "arm" }, "sha512-pKsthNECyvJh8lPTICz6VcwVy2jOqdhhsp1rlxCkhgZR47aKvXPmaRWQDv+zlXpRae4qm1MaaTnutkaOk5aofg=="],
+ "@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.63.0", "", { "os": "android", "cpu": "arm" }, "sha512-A9xLtQt7i0OA1PoB/meog6kikXI9CdwEp7ZwQqmgnpKn3G3b1orvTDy8CQ6T7w1HvDrgWGB78PkFKcWgibcTCg=="],
- "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.62.0", "", { "os": "android", "cpu": "arm64" }, "sha512-b1AUNViByvgmR2xJDubvLIr+dSuu3uraG7bsAoKo+xrpspPvu6RIn6Fhr2JUhobfep3jwUTy18Huco6GkwdvGQ=="],
+ "@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.63.0", "", { "os": "android", "cpu": "arm64" }, "sha512-SQo+ZMvdR9l3CxZp5W5gFNxSiDxclY6lOzzNpKYLF8asESpm3Pwumx0gER5T7aHLF1/2BAAtLD3DiDkdgy4V1A=="],
- "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.62.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iG+Tvf70UJ6otfwFYIHk36Sjq9cpPP5YLxkoggANNRtzgi3Tj3g8q6Ybqi6AtkU3+yg9QwF7bDCkCS6bbL4PCg=="],
+ "@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.63.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-6W82XjJDTmMnjg30427l0dufpnyLoq7wEukKdM6/g2VIybRVuQiBVh43EA4b+UxZ3+tLcKm+Or/pXGNgLCEU8g=="],
- "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.62.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-oOWI6YPPr5AJUx+yIDlxmuUbQjS5gZX3OH3QisawYvsZgLiQVvZtR0rPBcJTxLWqt2ClrWg0DlSrlUiG5SQNHg=="],
+ "@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.63.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-CnWd/YCuVG5W1BYkjJEVbJG11o526O9qAwBEQM+nh8K19CRFUkFdROXCyYkGmroHEYQe4vgQ6+lh3550Lp35Xw=="],
- "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.62.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dLP33T7VLCmLVv4cvjkVX+rmkcwNk2UfxmsZPNur/7BQHoQR60zJ7XLiRvNUawlzn0u8ngCa3itjEG73MAMa/w=="],
+ "@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.63.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-a4eZAqrmtajqcxfdAzC+l7g3PaE3V8hpAYqqeD3fTxLXOMFdK3eNTZrU80n4dDEVm0JXy1aL5PqvqWldBl6zYA=="],
- "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.62.0", "", { "os": "linux", "cpu": "arm" }, "sha512-fl//LWNks6qo9chNY60UDYyIwtp7a5cEx4Y/rHPjaarhuwqx6jtbzEpD5V5AqmdL4a6Y5D8zeXg5HF2Cr0QmSQ=="],
+ "@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.63.0", "", { "os": "linux", "cpu": "arm" }, "sha512-tYUtU9TdbU3uXF5D62g5zXJ13iniFGhXQx5vp9cyEjGdbSAY3VdFBSaldYvyoDmgMZ0ZYuwQP1Y4t2Fhejwa0w=="],
- "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.62.0", "", { "os": "linux", "cpu": "arm" }, "sha512-i5vkAuxvueTODV3J2dL61/TXewDHhMFKvtD156cIsk7GsdfiAu7zW7kY0NJXhKeFHeiMZIh7eFNjkPYH6J47HQ=="],
+ "@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.63.0", "", { "os": "linux", "cpu": "arm" }, "sha512-I5r3twFf776UZg9dmRo2xbrKt00tTkORXEVe0ctg4vdTkQvJAjiCHxnbAU2HL1AiJ9cqADA76MAliuilsAWnvg=="],
- "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.62.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-QwN19LLuIGuOjEflSeJkZmOTfBdBMlTmW8xbMf8TZhjd//cxVNYQPq75q7oKZBJc6hRx3gY7sX0Egc8cEIFZYg=="],
+ "@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.63.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-t7ltUkg6FFh4b564QyGir8xIj/QZbXu8FlcRkcyW9+ztr/mfRHlvUOFd95pJCXi9s/L5DrUeWWgpXRS+V+6igQ=="],
- "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.62.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-8eCy3FCDuWUM5hWujAv6heMvfZPbcCOU3SdQUAkixZLu5bSzOkNfirJiLGoQFO943xceOKkiQRMQNzH++jM3WA=="],
+ "@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.63.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Q5mmZy/XWjuYFUuQyYjOvZ5U/JkKEwnpir6hGxhh6HcdP0V/BKxLo8dqkfF/t7r7AguB17dfS/8+go5AQDRR6g=="],
- "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.62.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NjQ7K7tpTPDe9J+yq8p/s/J0E7lRCkK2uDBDqvT4XIT6f4Z0tlnr59OBg/WcrmVHER1AbrcfyxhGTXgcG8ytWg=="],
+ "@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.63.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-uBGtuZ0TzLB4x5wVa82HGNvYqY8buwDhyCnCP0R0gkk9szqVsP0MeTtD5HX7EsEuFIt+aYmYxuxeVxs3nTSwtQ=="],
- "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-oKZed9gmSwze29dEt3/Wnsv6l/Ygw/FUst+8Kfpv2SGeS/glEoTGZAMQw37SVyzFV76UTHJN2snGgxK2t2+8ow=="],
+ "@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.63.0", "", { "os": "linux", "cpu": "none" }, "sha512-h4s6FwxE+9MeA181o0dnDwHP32Y/bG8EiB/vrD6Ib+AMt6haigDc/0bUtI/sLmQDBMJnUfaCmtSSrEAqjtEVrA=="],
- "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.62.0", "", { "os": "linux", "cpu": "none" }, "sha512-gBjBxQ+9lGpAYq+ELqw0w8QXsBnkZclFc7GRX2r0LnEVn3ZTEqeIKpKcGjucmp76Q53bvJD0i4qBWBhcfhSfGA=="],
+ "@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.63.0", "", { "os": "linux", "cpu": "none" }, "sha512-2EaNcCBR8Mcjl5ARtuN3BdEpVkX7KpjSjMGZ/mJMIeaXgTtdz5ytg2VwygMSStA/k0ixfvZFoZOfjDEcouV5vQ=="],
- "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.62.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Ew2Kxs9EQ9/mbAIJ2hvocMC0wsOu6YKzStI2eFBDt+Td5O8seVC/oxgRIHqCcl5sf5ratA1nozQBAuv7tphkHg=="],
+ "@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.63.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-p4hlf/fd7TrYYl3QrWWD0GocqJefwMu3cHQhmi2FvEB/YOvFb5DZN3SMBaPi7B1TM5DeypkEtrVib674q1KKPg=="],
- "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.62.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5z25jcAA0gfKyVwz71A0VXgaPlocPoTAxhlv/hgoK6tlCrfoNuw7haWbDHvGMfjXhdic4EqVXGRv5XsTqFnbRQ=="],
+ "@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.63.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Vgq9rkRVcPcjbcH+ihYTfpeR7vCXfqpd+z5ItTGc0yYUV59L5ceHYN1iV4H9bKGV7Rn5hkVc7x3mSvHegduENA=="],
- "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.62.0", "", { "os": "linux", "cpu": "x64" }, "sha512-IWpHmMB6ZDllPvqWDkG6AmXrN7JF5e/c4g/0PuURsmlK+vHoYZPB70rr4u1bn3I4LsKCSpqqfveyx6UCOC8wdg=="],
+ "@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.63.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3/Lkq/ncooA61rorrC+ZQed1Bc4VpGj+WnGsp58zmxKgvZ2vhreu+dcVyr3mX8NUpq7mfZ4gDDTou/yrF1Pd7A=="],
- "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.62.0", "", { "os": "none", "cpu": "arm64" }, "sha512-fjlSxxrD5pA594vkyikCS9MnPRjQawW6/BLgyTYkO+73wwPlYjkcZ7LSd974l0Q2zkHQmu4DPvJFLYA7o8xrxQ=="],
+ "@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.63.0", "", { "os": "none", "cpu": "arm64" }, "sha512-0/EdD/6hDkx5Mfd769PTjvEM8mZ/6Dfukp1dBCL/2PjlIVGEtYdNZyok6ChqYPsT9JcFnlQnUeQzO0/1L/oC9w=="],
- "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.62.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-EiFXr8loNS0Ul3Gu80+9nr1T8jRmnKocqmHHg16tj5ZqTgUXyb97l2rrspVHdDluyFn9JfR4PoJFdNzw4paHww=="],
+ "@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.63.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-wb0CUkN8ngwPiRQBjD1Cj0LsHeNvm+Xt6YBHDMtj2DVQVD6Oj8Ri7g6BD+KICf6LaBqZlmzOvy6nF9E/8yyGOg=="],
- "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.62.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-IgOFvL73li1bFgab+hThXYA0N2Xms2kV2MvZN95cebV+fmrZ9AVui1JSxfeeqRLo3CpPxKZlzhyq4G0cnaAvIw=="],
+ "@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.63.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-BX5iq+ovdNlVYhSn5qPMUIT0uwAwt2lmEnCnzK+Gkhw4DovIvhGb96OFhV8yzQNUnQxn/xGkOR+X+BLrLDNm8w=="],
- "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.62.0", "", { "os": "win32", "cpu": "x64" }, "sha512-6hMpyDWQ2zGA1OXFKBrdYMUveUCO8UJhkO6JdwZPd78xIdHZNhjx+pib+4fC2Cljuhjyl0QwA2F3df/bs4Bp6A=="],
+ "@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.63.0", "", { "os": "win32", "cpu": "x64" }, "sha512-QeN/WELOfsXMeYwxvfgQrl6CbVftYUCZsGXHjXQd5Trccm8+i4gmtxaOui4xbJQaiDlviF8F3yLSBloQUeFsfA=="],
- "@posthog/core": ["@posthog/core@1.28.2", "", { "dependencies": { "@posthog/types": "1.372.8" } }, "sha512-Dii3pxDheG1WioztvV/MqHQMnb16jSFrl2HkDR1T5yf5/R7lPqJCFYt+eXkEdp/oAv/PD+1joyG6Ap/2quFmtQ=="],
+ "@posthog/core": ["@posthog/core@1.28.3", "", { "dependencies": { "@posthog/types": "1.372.9" } }, "sha512-SOy0aphKawZzp8jxfeOpTcXPwi6ii0I2V6tX8YXnM+WbxKKR/R+BXLK0jS6LV8kZtW3H5YxmPAfuIbUP1UnGTw=="],
- "@posthog/types": ["@posthog/types@1.372.8", "", {}, "sha512-ALpfCnWsMSM9Cw/6kyLPVpd81ZReEdZwmDxOi+DTJuIo7wDxBiu2cAsjOuA6D/AL22v7HOJrHsmBAPAWqS5X7Q=="],
+ "@posthog/types": ["@posthog/types@1.372.9", "", {}, "sha512-B7k9S+H9WUKHXxe1HOkQWbpWtMcrBvsodm5stZaLQ3pYxf9TowtwssdzTtX4hHjzSYqgrS1IpNnJX4vs1KgBzA=="],
"@sentry/core": ["@sentry/core@10.51.0", "", {}, "sha512-Y45V/YXvVLEXmOdkbD1oG1gkRWFi9guCEGg3PlIlIpRjAbZUrvLGgjRJIc1E7XpSzmOnWbs5BbUxMv4PDaPj2w=="],
@@ -459,9 +459,9 @@
"oxc-resolver": ["oxc-resolver@11.19.1", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="],
- "oxfmt": ["oxfmt@0.47.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.47.0", "@oxfmt/binding-android-arm64": "0.47.0", "@oxfmt/binding-darwin-arm64": "0.47.0", "@oxfmt/binding-darwin-x64": "0.47.0", "@oxfmt/binding-freebsd-x64": "0.47.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.47.0", "@oxfmt/binding-linux-arm-musleabihf": "0.47.0", "@oxfmt/binding-linux-arm64-gnu": "0.47.0", "@oxfmt/binding-linux-arm64-musl": "0.47.0", "@oxfmt/binding-linux-ppc64-gnu": "0.47.0", "@oxfmt/binding-linux-riscv64-gnu": "0.47.0", "@oxfmt/binding-linux-riscv64-musl": "0.47.0", "@oxfmt/binding-linux-s390x-gnu": "0.47.0", "@oxfmt/binding-linux-x64-gnu": "0.47.0", "@oxfmt/binding-linux-x64-musl": "0.47.0", "@oxfmt/binding-openharmony-arm64": "0.47.0", "@oxfmt/binding-win32-arm64-msvc": "0.47.0", "@oxfmt/binding-win32-ia32-msvc": "0.47.0", "@oxfmt/binding-win32-x64-msvc": "0.47.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-OFbkbzxKCpooQEnRmpTDnuwTX8KHXzZTQ4Df/hz85fpS67Pl+lxPEFvUtin56HIIS0B1k4X8oIzTXRZPufA2CA=="],
+ "oxfmt": ["oxfmt@0.48.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.48.0", "@oxfmt/binding-android-arm64": "0.48.0", "@oxfmt/binding-darwin-arm64": "0.48.0", "@oxfmt/binding-darwin-x64": "0.48.0", "@oxfmt/binding-freebsd-x64": "0.48.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.48.0", "@oxfmt/binding-linux-arm-musleabihf": "0.48.0", "@oxfmt/binding-linux-arm64-gnu": "0.48.0", "@oxfmt/binding-linux-arm64-musl": "0.48.0", "@oxfmt/binding-linux-ppc64-gnu": "0.48.0", "@oxfmt/binding-linux-riscv64-gnu": "0.48.0", "@oxfmt/binding-linux-riscv64-musl": "0.48.0", "@oxfmt/binding-linux-s390x-gnu": "0.48.0", "@oxfmt/binding-linux-x64-gnu": "0.48.0", "@oxfmt/binding-linux-x64-musl": "0.48.0", "@oxfmt/binding-openharmony-arm64": "0.48.0", "@oxfmt/binding-win32-arm64-msvc": "0.48.0", "@oxfmt/binding-win32-ia32-msvc": "0.48.0", "@oxfmt/binding-win32-x64-msvc": "0.48.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-AVaLh+7XeGx+R1zfFV+f6VV61nT2MWVJXVUDhbTm5LBWGyNt64xAyh3NYYyjeY2WykNt9AvqSQLPHcbWquYF9g=="],
- "oxlint": ["oxlint@1.62.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.62.0", "@oxlint/binding-android-arm64": "1.62.0", "@oxlint/binding-darwin-arm64": "1.62.0", "@oxlint/binding-darwin-x64": "1.62.0", "@oxlint/binding-freebsd-x64": "1.62.0", "@oxlint/binding-linux-arm-gnueabihf": "1.62.0", "@oxlint/binding-linux-arm-musleabihf": "1.62.0", "@oxlint/binding-linux-arm64-gnu": "1.62.0", "@oxlint/binding-linux-arm64-musl": "1.62.0", "@oxlint/binding-linux-ppc64-gnu": "1.62.0", "@oxlint/binding-linux-riscv64-gnu": "1.62.0", "@oxlint/binding-linux-riscv64-musl": "1.62.0", "@oxlint/binding-linux-s390x-gnu": "1.62.0", "@oxlint/binding-linux-x64-gnu": "1.62.0", "@oxlint/binding-linux-x64-musl": "1.62.0", "@oxlint/binding-openharmony-arm64": "1.62.0", "@oxlint/binding-win32-arm64-msvc": "1.62.0", "@oxlint/binding-win32-ia32-msvc": "1.62.0", "@oxlint/binding-win32-x64-msvc": "1.62.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.18.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-1uFkg6HakjsGIpW9wNdeW4/2LOHW9MEkoWjZUTUfQtIHyLIZPYt00w3Sg+H3lH+206FgBPHBbW5dVE5l2ExECQ=="],
+ "oxlint": ["oxlint@1.63.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.63.0", "@oxlint/binding-android-arm64": "1.63.0", "@oxlint/binding-darwin-arm64": "1.63.0", "@oxlint/binding-darwin-x64": "1.63.0", "@oxlint/binding-freebsd-x64": "1.63.0", "@oxlint/binding-linux-arm-gnueabihf": "1.63.0", "@oxlint/binding-linux-arm-musleabihf": "1.63.0", "@oxlint/binding-linux-arm64-gnu": "1.63.0", "@oxlint/binding-linux-arm64-musl": "1.63.0", "@oxlint/binding-linux-ppc64-gnu": "1.63.0", "@oxlint/binding-linux-riscv64-gnu": "1.63.0", "@oxlint/binding-linux-riscv64-musl": "1.63.0", "@oxlint/binding-linux-s390x-gnu": "1.63.0", "@oxlint/binding-linux-x64-gnu": "1.63.0", "@oxlint/binding-linux-x64-musl": "1.63.0", "@oxlint/binding-openharmony-arm64": "1.63.0", "@oxlint/binding-win32-arm64-msvc": "1.63.0", "@oxlint/binding-win32-ia32-msvc": "1.63.0", "@oxlint/binding-win32-x64-msvc": "1.63.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.22.1" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-9TGXetdjgIHOJ9OiReomP7nnrMkV9HxC1xM2ramJSLQpzxjsAJtQwa4wqkJN2f/uCrqZuJseFuSlWDdvcruveg=="],
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
@@ -471,7 +471,7 @@
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
- "posthog-node": ["posthog-node@5.33.2", "", { "dependencies": { "@posthog/core": "1.28.2" }, "peerDependencies": { "rxjs": "^7.0.0" }, "optionalPeers": ["rxjs"] }, "sha512-QZOT2uoEue4BGh/mrBUc7zfddtuLgCU7tTmW0MH8sTr8iK6argv82M7pQbJP/ENsiRYZa/ojpOIjTM9vO1xa6Q=="],
+ "posthog-node": ["posthog-node@5.33.3", "", { "dependencies": { "@posthog/core": "1.28.3" }, "peerDependencies": { "rxjs": "^7.0.0" }, "optionalPeers": ["rxjs"] }, "sha512-6BkdRtRKf/y/j6JGXLUDWpruL9Rebpe2EtbSU3EB+yaI9ukTwEGT8XJQDyM8wcsxu1HdOnvAwN7gnOOu5OgY2A=="],
"pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="],
diff --git a/docs/scripts/generate-llms-full.ts b/docs/scripts/generate-llms-full.ts
index fd84b75e..82f36ea1 100644
--- a/docs/scripts/generate-llms-full.ts
+++ b/docs/scripts/generate-llms-full.ts
@@ -39,35 +39,35 @@ function collectFiles(dir: string): string[] {
/** Strip YAML frontmatter (--- ... ---) from markdown content. */
function stripFrontmatter(content: string): string {
- const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/);
+ const match = content.match(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/u);
return match ? content.slice(match[0].length) : content;
}
/** Extract title from YAML frontmatter. */
function extractTitle(content: string): string | null {
- const match = content.match(/^---\r?\n[\s\S]*?\r?\n---/);
+ const match = content.match(/^---\r?\n[\s\S]*?\r?\n---/u);
if (!match) return null;
- const titleMatch = match[0].match(/^title:\s*["']?(.+?)["']?\s*$/m);
+ const titleMatch = match[0].match(/^title:\s*["']?(.+?)["']?\s*$/mu);
return titleMatch ? titleMatch[1] : null;
}
/** Strip JSX imports and component tags (keep content inside simple tags). */
function stripJsx(content: string): string {
return content
- .replaceAll(/^import\s+.*$/gm, "") // import lines
- .replaceAll(/<[A-Z]\w+[^>]*\/>/g, "") // self-closing components
- .replaceAll(/<[A-Z]\w+[^>]*>|<\/[A-Z]\w+>/g, "") // opening/closing components
- .replaceAll(/:::.*\[.*\]\n?/g, "") // Starlight admonition openers (:::tip[...])
- .replaceAll(/^:::\s*$/gm, "") // Starlight admonition closers
- .replaceAll(/\n{3,}/g, "\n\n"); // collapse excess blank lines
+ .replaceAll(/^import\s+.*$/gmu, "") // import lines
+ .replaceAll(/<[A-Z]\w+[^>]*\/>/gu, "") // self-closing components
+ .replaceAll(/<[A-Z]\w+[^>]*>|<\/[A-Z]\w+>/gu, "") // opening/closing components
+ .replaceAll(/:::.*\[.*\]\n?/gu, "") // Starlight admonition openers (:::tip[...])
+ .replaceAll(/^:::\s*$/gmu, "") // Starlight admonition closers
+ .replaceAll(/\n{3,}/gu, "\n\n"); // collapse excess blank lines
}
/** Convert a file path to its URL path on the site. */
function fileToUrl(filePath: string): string {
const rel = relative(docsDir, filePath)
.replaceAll("\\", "/")
- .replace(/(?:\/)?index\.mdx?$/, "/")
- .replace(/\.mdx?$/, "/");
+ .replace(/(?:\/)?index\.mdx?$/u, "/")
+ .replace(/\.mdx?$/u, "/");
const path = rel === "/" ? "/" : `/${rel}`;
return `${siteUrl}${path}`;
}
diff --git a/docs/src/components/HeadSEO.astro b/docs/src/components/HeadSEO.astro
index 67195172..860a32d0 100644
--- a/docs/src/components/HeadSEO.astro
+++ b/docs/src/components/HeadSEO.astro
@@ -13,7 +13,7 @@ import Analytics from "./Analytics.astro";
const route = Astro.locals.starlightRoute;
const siteUrl =
- Astro.site?.href?.replace(/\/$/, "") ?? "https://cli.archgate.dev";
+ Astro.site?.href?.replace(/\/$/u, "") ?? "https://cli.archgate.dev";
const pathname = Astro.url.pathname;
const pageUrl = `${siteUrl}${pathname}`;
@@ -26,7 +26,7 @@ const template = hasRoute ? route.entry.data.template : undefined;
// ── hreflang alternate links ─────────────────────────────────────
// Map between English and pt-BR pages for search engine language targeting.
const isPtBr = pathname.startsWith("/pt-br/");
-const enPath = isPtBr ? pathname.replace(/^\/pt-br\//, "/") : pathname;
+const enPath = isPtBr ? pathname.replace(/^\/pt-br\//u, "/") : pathname;
const ptBrPath = isPtBr ? pathname : `/pt-br${pathname}`;
const enUrl = `${siteUrl}${enPath}`;
const ptBrUrl = `${siteUrl}${ptBrPath}`;
@@ -59,7 +59,7 @@ function toBreadcrumbName(segment: string): string {
.split(" ")
.filter((part) => part.length > 0)
.map((part) => {
- const isAllCaps = /^[A-Z0-9]+$/.test(part);
+ const isAllCaps = /^[A-Z0-9]+$/u.test(part);
if (isAllCaps || part.length <= 3) {
return part.toUpperCase();
}
diff --git a/package.json b/package.json
index 47effd29..15e09081 100644
--- a/package.json
+++ b/package.json
@@ -71,9 +71,9 @@
"inquirer": "13.4.2",
"knip": "6.12.1",
"meriyah": "7.1.0",
- "oxfmt": "0.47.0",
- "oxlint": "1.62.0",
- "posthog-node": "5.33.2",
+ "oxfmt": "0.48.0",
+ "oxlint": "1.63.0",
+ "posthog-node": "5.33.3",
"zod": "4.4.3"
},
"peerDependencies": {
diff --git a/src/cli.ts b/src/cli.ts
index 36715a73..c7791547 100755
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -203,9 +203,10 @@ function classifyErrorKind(err: unknown): string {
if (!(err instanceof Error)) return "unknown";
const name = err.name || "Error";
const msg = err.message || "";
- if (/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|EAI_AGAIN/i.test(msg)) return "network";
- if (/certificate|SELF_SIGNED|UNABLE_TO_VERIFY/i.test(msg)) return "tls";
- if (/EACCES|EPERM/.test(msg)) return "permission";
+ if (/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|EAI_AGAIN/iu.test(msg))
+ return "network";
+ if (/certificate|SELF_SIGNED|UNABLE_TO_VERIFY/iu.test(msg)) return "tls";
+ if (/EACCES|EPERM/u.test(msg)) return "permission";
if (name === "SyntaxError") return "syntax";
if (name === "TypeError") return "type";
return name;
diff --git a/src/commands/check.ts b/src/commands/check.ts
index eae2ee08..30b55a18 100644
--- a/src/commands/check.ts
+++ b/src/commands/check.ts
@@ -87,7 +87,7 @@ export function registerCheckCommand(program: Command) {
Bun.stdin.text(),
Bun.sleep(100).then(() => ""),
]);
- const piped = stdin.trim().split(/\r?\n/).filter(Boolean);
+ const piped = stdin.trim().split(/\r?\n/u).filter(Boolean);
filterFiles = [...filterFiles, ...piped];
} catch {
// stdin not readable — ignore
diff --git a/src/commands/upgrade.ts b/src/commands/upgrade.ts
index fc870006..cee36d67 100644
--- a/src/commands/upgrade.ts
+++ b/src/commands/upgrade.ts
@@ -324,7 +324,7 @@ export function registerUpgradeCommand(program: Command) {
const packageJson = await import("../../package.json");
const currentVersion = packageJson.default.version;
- const latestVersion = tag.replace(/^v/, "");
+ const latestVersion = tag.replace(/^v/u, "");
logDebug("Version comparison:", currentVersion, "vs", latestVersion);
const order = semver.order(currentVersion, latestVersion);
diff --git a/src/engine/context.ts b/src/engine/context.ts
index ddc1bef1..810092df 100644
--- a/src/engine/context.ts
+++ b/src/engine/context.ts
@@ -57,7 +57,7 @@ export function extractAdrSections(
};
for (const line of lines) {
- const headingMatch = line.match(/^## (.+)$/);
+ const headingMatch = line.match(/^## (.+)$/u);
if (headingMatch) {
flushSection();
currentSection = headingMatch[1].trim();
diff --git a/src/engine/loader.ts b/src/engine/loader.ts
index 46ccd3c4..acaa2934 100644
--- a/src/engine/loader.ts
+++ b/src/engine/loader.ts
@@ -103,7 +103,7 @@ function checkRuleSyntax(source: string): SyntaxViolation[] {
// Check for triple-slash reference to rules.d.ts
const hasTripleSlash =
- /^\/\/\/\s*$/m.test(
+ /^\/\/\/\s*$/mu.test(
source
);
if (!hasTripleSlash) {
@@ -119,7 +119,7 @@ function checkRuleSyntax(source: string): SyntaxViolation[] {
}
// Check for `satisfies RuleSet` on the default export
- const hasSatisfies = /\bsatisfies\s+RuleSet\b/.test(source);
+ const hasSatisfies = /\bsatisfies\s+RuleSet\b/u.test(source);
if (!hasSatisfies) {
// Point to the last line as a reasonable location for the missing satisfies
const lines = source.split("\n");
@@ -233,7 +233,7 @@ export async function loadRuleAdrs(
let rulesLine = 1;
let rulesEndCol = 0;
for (let i = 0; i < adrLines.length; i++) {
- const match = adrLines[i].match(/^rules:\s*true/);
+ const match = adrLines[i].match(/^rules:\s*true/u);
if (match) {
rulesLine = i + 1;
rulesEndCol = adrLines[i].length;
diff --git a/src/engine/rule-scanner.ts b/src/engine/rule-scanner.ts
index 60e33334..f6fba1ca 100644
--- a/src/engine/rule-scanner.ts
+++ b/src/engine/rule-scanner.ts
@@ -7,7 +7,7 @@ import { parseModule } from "meriyah";
* Safe modules NOT blocked: node:path, node:url, node:util, node:crypto
*/
const BANNED_MODULES =
- /^(node:)?(fs|child_process|net|dgram|http|https|http2|worker_threads|cluster|vm)(\/.*)?$/;
+ /^(node:)?(fs|child_process|net|dgram|http|https|http2|worker_threads|cluster|vm)(\/.*)?$/u;
/** Bun API properties that bypass the RuleContext sandbox. */
const BLOCKED_BUN_PROPS = new Set(["spawn", "spawnSync", "write", "$", "file"]);
diff --git a/src/formats/adr.ts b/src/formats/adr.ts
index bf1f0f9f..e666a171 100644
--- a/src/formats/adr.ts
+++ b/src/formats/adr.ts
@@ -68,7 +68,7 @@ function formatZodErrors(error: z.ZodError): string[] {
* Throws on invalid frontmatter.
*/
export function parseAdr(content: string, filePath: string): AdrDocument {
- const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/;
+ const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/u;
const match = content.match(frontmatterRegex);
if (!match) {
diff --git a/src/formats/project-config.ts b/src/formats/project-config.ts
index 3c299664..eeb74ccc 100644
--- a/src/formats/project-config.ts
+++ b/src/formats/project-config.ts
@@ -1,7 +1,7 @@
import { z } from "zod";
-export const DOMAIN_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
-const DOMAIN_PREFIX_PATTERN = /^[A-Z][A-Z0-9_]*$/;
+export const DOMAIN_NAME_PATTERN = /^[a-z][a-z0-9-]*$/u;
+const DOMAIN_PREFIX_PATTERN = /^[A-Z][A-Z0-9_]*$/u;
export const DomainNameSchema = z
.string()
diff --git a/src/helpers/adr-writer.ts b/src/helpers/adr-writer.ts
index 809678d0..636c84be 100644
--- a/src/helpers/adr-writer.ts
+++ b/src/helpers/adr-writer.ts
@@ -13,8 +13,8 @@ import { generateRulesTemplate } from "./rules-shim";
export function slugify(title: string): string {
return title
.toLowerCase()
- .replaceAll(/[^a-z0-9]+/g, "-")
- .replaceAll(/^-|-$/g, "");
+ .replaceAll(/[^a-z0-9]+/gu, "-")
+ .replaceAll(/^-|-$/gu, "");
}
export function getNextId(adrsDir: string, prefix: string): string {
@@ -24,7 +24,7 @@ export function getNextId(adrsDir: string, prefix: string): string {
let maxNum = 0;
for (const file of files) {
- const match = file.match(new RegExp(`^${prefix}-(\\d+)`));
+ const match = file.match(new RegExp(`^${prefix}-(\\d+)`, "u"));
if (match) {
const num = parseInt(match[1], 10);
if (num > maxNum) maxNum = num;
diff --git a/src/helpers/binary-upgrade.ts b/src/helpers/binary-upgrade.ts
index b846c202..8909a4cb 100644
--- a/src/helpers/binary-upgrade.ts
+++ b/src/helpers/binary-upgrade.ts
@@ -184,7 +184,7 @@ export async function downloadReleaseBinary(
});
if (checksumResponse.ok) {
const checksumText = await checksumResponse.text();
- const expectedHash = checksumText.trim().split(/\s+/)[0].toLowerCase();
+ const expectedHash = checksumText.trim().split(/\s+/u)[0].toLowerCase();
const actualHash = createHash("sha256")
.update(new Uint8Array(buffer))
.digest("hex");
diff --git a/src/helpers/install-info.ts b/src/helpers/install-info.ts
index cee9f904..910afa0c 100644
--- a/src/helpers/install-info.ts
+++ b/src/helpers/install-info.ts
@@ -95,7 +95,7 @@ export function getProjectContext(): ProjectContext {
const domainSet = new Set();
for (const f of mdFiles) {
- const match = f.match(/^([A-Z]+)-\d+/);
+ const match = f.match(/^([A-Z]+)-\d+/u);
if (match) domainSet.add(match[1]);
}
diff --git a/src/helpers/login-flow.ts b/src/helpers/login-flow.ts
index dbba9409..6a674ff2 100644
--- a/src/helpers/login-flow.ts
+++ b/src/helpers/login-flow.ts
@@ -126,7 +126,7 @@ async function runSignupPrompt(
message: "Email address:",
default: githubEmail ?? undefined,
validate: (v: string) =>
- /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v) || "Enter a valid email address",
+ /^[^\s@]+@[^\s@]+\.[^\s@]+$/u.test(v) || "Enter a valid email address",
});
resetCursor();
diff --git a/src/helpers/platform.ts b/src/helpers/platform.ts
index af9decc8..284dcb32 100644
--- a/src/helpers/platform.ts
+++ b/src/helpers/platform.ts
@@ -49,7 +49,7 @@ export function getPlatformInfo(): PlatformInfo {
// Fallback: /proc/version check (catches WSL1)
try {
const procVersion = readFileSync("/proc/version", "utf-8");
- if (/microsoft/i.test(procVersion)) {
+ if (/microsoft/iu.test(procVersion)) {
cachedPlatformInfo = { runtime, isWSL: true, wslDistro: null };
return cachedPlatformInfo;
}
diff --git a/src/helpers/repo.ts b/src/helpers/repo.ts
index 08ef5fbe..52d63f81 100644
--- a/src/helpers/repo.ts
+++ b/src/helpers/repo.ts
@@ -198,7 +198,7 @@ export function parseRemoteUrl(raw: string): ParsedRemote {
let path: string | null = null;
// SCP-like: git@github.com:foo/bar.git
- const scpMatch = trimmed.match(/^[^@\s]+@([^:]+):(.+)$/);
+ const scpMatch = trimmed.match(/^[^@\s]+@([^:]+):(.+)$/u);
if (scpMatch) {
host = scpMatch[1];
path = scpMatch[2];
@@ -206,7 +206,7 @@ export function parseRemoteUrl(raw: string): ParsedRemote {
try {
const url = new URL(trimmed);
host = url.hostname;
- path = url.pathname.replace(/^\//, "");
+ path = url.pathname.replace(/^\//u, "");
} catch {
return { host: null, owner: null, name: null, normalized: null };
}
@@ -220,7 +220,7 @@ export function parseRemoteUrl(raw: string): ParsedRemote {
const classified = classifyHost(lowerHost);
// Strip trailing .git, .git/, or /
- path = path.replace(/\.git\/?$/, "").replace(/\/$/, "");
+ path = path.replace(/\.git\/?$/u, "").replace(/\/$/u, "");
let segments = path.split("/").filter(Boolean);
// Azure DevOps URL quirks:
@@ -232,7 +232,7 @@ export function parseRemoteUrl(raw: string): ParsedRemote {
if (classified === "azure-devops") {
segments = segments.filter((s) => s !== "_git" && s !== "v3");
- const vsHostMatch = lowerHost.match(/^([^.]+)\.visualstudio\.com$/);
+ const vsHostMatch = lowerHost.match(/^([^.]+)\.visualstudio\.com$/u);
if (vsHostMatch && !segments.some((s) => s === vsHostMatch[1])) {
segments = [vsHostMatch[1], ...segments];
}
diff --git a/src/helpers/update-check.ts b/src/helpers/update-check.ts
index bcad81a0..a5362e75 100644
--- a/src/helpers/update-check.ts
+++ b/src/helpers/update-check.ts
@@ -42,7 +42,7 @@ export async function checkForUpdatesIfNeeded(
return null;
}
- const latestVersion = tag.replace(/^v/, "");
+ const latestVersion = tag.replace(/^v/u, "");
// Write new cache timestamp regardless of result
await Bun.write(cacheFile, String(Date.now()));
diff --git a/tests/commands/check-security.test.ts b/tests/commands/check-security.test.ts
index 52883697..f85b764c 100644
--- a/tests/commands/check-security.test.ts
+++ b/tests/commands/check-security.test.ts
@@ -35,7 +35,7 @@ describe("check command security", () => {
// Wrap rule code with required syntax conventions
const wrapped =
`/// \n\n` +
- ruleCode.trimEnd().replace(/};\s*$/, "} satisfies RuleSet;\n");
+ ruleCode.trimEnd().replace(/\};\s*$/u, "} satisfies RuleSet;\n");
writeFileSync(join(adrsDir, `${id}-sec.rules.ts`), wrapped);
}
diff --git a/tests/engine/runner-security.test.ts b/tests/engine/runner-security.test.ts
index ea4bf992..2dd05339 100644
--- a/tests/engine/runner-security.test.ts
+++ b/tests/engine/runner-security.test.ts
@@ -72,7 +72,7 @@ describe("runChecks path sandboxing", () => {
"traversal-grep": {
description: "Attempt path traversal via grep",
async check(ctx) {
- await ctx.grep("../../../etc/hosts", /localhost/);
+ await ctx.grep("../../../etc/hosts", /localhost/u);
},
},
},
@@ -148,7 +148,7 @@ describe("runChecks path sandboxing", () => {
"grepfiles-traversal": {
description: "Attempt grepFiles traversal",
async check(ctx) {
- await ctx.grepFiles(/secret/, "../**/*.env");
+ await ctx.grepFiles(/secret/u, "../**/*.env");
},
},
},
diff --git a/tests/engine/runner.test.ts b/tests/engine/runner.test.ts
index 2e9e9ecf..b0943b30 100644
--- a/tests/engine/runner.test.ts
+++ b/tests/engine/runner.test.ts
@@ -56,7 +56,7 @@ describe("runChecks", () => {
description: "No console.log",
async check(ctx) {
const results = await Promise.all(
- ctx.scopedFiles.map((file) => ctx.grep(file, /console\.log/))
+ ctx.scopedFiles.map((file) => ctx.grep(file, /console\.log/u))
);
for (const matches of results) {
for (const m of matches) {
@@ -91,7 +91,7 @@ describe("runChecks", () => {
description: "No console.log",
async check(ctx) {
const results = await Promise.all(
- ctx.scopedFiles.map((file) => ctx.grep(file, /console\.log/))
+ ctx.scopedFiles.map((file) => ctx.grep(file, /console\.log/u))
);
for (const matches of results) {
for (const m of matches) {
@@ -242,7 +242,7 @@ describe("runChecks", () => {
description: "Test grepFiles dot-prefix",
async check(ctx) {
matches = await ctx.grepFiles(
- /release/,
+ /release/u,
".github/workflows/*.yml"
);
},
@@ -274,7 +274,7 @@ describe("runChecks", () => {
"grep-test": {
description: "Test grepFiles",
async check(ctx) {
- matches = await ctx.grepFiles(/hello/, "src/**/*.ts");
+ matches = await ctx.grepFiles(/hello/u, "src/**/*.ts");
},
},
},
diff --git a/tests/fixtures/rules/TEST-001-sample.rules.ts b/tests/fixtures/rules/TEST-001-sample.rules.ts
index afda3b73..4a261c72 100644
--- a/tests/fixtures/rules/TEST-001-sample.rules.ts
+++ b/tests/fixtures/rules/TEST-001-sample.rules.ts
@@ -7,7 +7,7 @@ export default {
severity: "warning",
async check(ctx) {
const matches = await Promise.all(
- ctx.scopedFiles.map((file) => ctx.grep(file, /\/\/\s*TODO/i))
+ ctx.scopedFiles.map((file) => ctx.grep(file, /\/\/\s*TODO/iu))
);
for (const fileMatches of matches) {
for (const match of fileMatches) {
@@ -24,7 +24,7 @@ export default {
description: "Disallow console.log in source files",
async check(ctx) {
const matches = await Promise.all(
- ctx.scopedFiles.map((file) => ctx.grep(file, /console\.log\(/))
+ ctx.scopedFiles.map((file) => ctx.grep(file, /console\.log\(/u))
);
for (const fileMatches of matches) {
for (const match of fileMatches) {
diff --git a/tests/formats/adr-fuzz.test.ts b/tests/formats/adr-fuzz.test.ts
index 0ceecb24..372e7a6a 100644
--- a/tests/formats/adr-fuzz.test.ts
+++ b/tests/formats/adr-fuzz.test.ts
@@ -14,7 +14,7 @@ import {
/** Arbitrary that produces strings resembling kebab-case domain names. */
const domainArb = fc.oneof(
- fc.stringMatching(/^[a-z][a-z0-9-]{1,31}$/),
+ fc.stringMatching(/^[a-z][a-z0-9-]{1,31}$/u),
fc.constant(""),
fc.constant("a"),
fc.constant("BACKEND"),
diff --git a/tests/helpers/binary-upgrade.test.ts b/tests/helpers/binary-upgrade.test.ts
index 536c5eb1..60ab1265 100644
--- a/tests/helpers/binary-upgrade.test.ts
+++ b/tests/helpers/binary-upgrade.test.ts
@@ -30,9 +30,9 @@ describe("getArtifactInfo", () => {
// Should return non-null for any supported CI platform
if (info === null) return;
- expect(info.name).toMatch(/^archgate-(darwin-arm64|linux-x64|win32-x64)$/);
- expect(info.ext).toMatch(/^\.(tar\.gz|zip)$/);
- expect(info.binaryName).toMatch(/^archgate(\.exe)?$/);
+ expect(info.name).toMatch(/^archgate-(darwin-arm64|linux-x64|win32-x64)$/u);
+ expect(info.ext).toMatch(/^\.(tar\.gz|zip)$/u);
+ expect(info.binaryName).toMatch(/^archgate(\.exe)?$/u);
});
test("returns .zip extension for win32", () => {
diff --git a/tests/helpers/platform.test.ts b/tests/helpers/platform.test.ts
index cb61a141..05d3a3df 100644
--- a/tests/helpers/platform.test.ts
+++ b/tests/helpers/platform.test.ts
@@ -127,7 +127,7 @@ describe("toWindowsPath", () => {
test.skipIf(!inWSL)("converts WSL home path", async () => {
const result = await toWindowsPath("/mnt/c/Users");
- expect(result).toMatch(/^C:\\Users$/);
+ expect(result).toMatch(/^C:\\Users$/u);
});
test("returns null when not in WSL", async () => {
@@ -162,7 +162,7 @@ describe("getWindowsHomeDirFromWSL", () => {
test.skipIf(!inWSL)("returns a path under /mnt/", async () => {
const result = await getWindowsHomeDirFromWSL();
expect(result).not.toBeNull();
- expect(result!).toMatch(/^\/mnt\//);
+ expect(result!).toMatch(/^\/mnt\//u);
});
test.skipIf(!inWSL)("caches the result", async () => {
diff --git a/tests/helpers/project-config.test.ts b/tests/helpers/project-config.test.ts
index 1a225c9c..7a6159b1 100644
--- a/tests/helpers/project-config.test.ts
+++ b/tests/helpers/project-config.test.ts
@@ -47,32 +47,32 @@ describe("project-config", () => {
test("addCustomDomain rejects built-in domain names", async () => {
await expect(
addCustomDomain(projectRoot, "backend", "BE2")
- ).rejects.toThrow(/built-in/);
+ ).rejects.toThrow(/built-in/u);
});
test("addCustomDomain rejects invalid name format", async () => {
await expect(
addCustomDomain(projectRoot, "Bad Name", "BAD")
- ).rejects.toThrow(/kebab-case/);
+ ).rejects.toThrow(/kebab-case/u);
});
test("addCustomDomain rejects invalid prefix format", async () => {
await expect(
addCustomDomain(projectRoot, "infra", "lower")
- ).rejects.toThrow(/uppercase/);
+ ).rejects.toThrow(/uppercase/u);
});
test("addCustomDomain rejects prefix already used by a default", async () => {
await expect(
addCustomDomain(projectRoot, "backend2", "BE")
- ).rejects.toThrow(/built-in domain/);
+ ).rejects.toThrow(/built-in domain/u);
});
test("addCustomDomain rejects prefix already used by another custom domain", async () => {
await addCustomDomain(projectRoot, "security", "SEC");
await expect(
addCustomDomain(projectRoot, "secrets", "SEC")
- ).rejects.toThrow(/already used/);
+ ).rejects.toThrow(/already used/u);
});
test("removeCustomDomain deletes the entry", async () => {
@@ -89,7 +89,7 @@ describe("project-config", () => {
test("removeCustomDomain rejects built-in domains", async () => {
await expect(removeCustomDomain(projectRoot, "backend")).rejects.toThrow(
- /built-in/
+ /built-in/u
);
});
@@ -104,7 +104,7 @@ describe("project-config", () => {
test("resolveDomainPrefix throws on unknown domain with helpful hint", () => {
expect(() => resolveDomainPrefix(projectRoot, "nope")).toThrow(
- /archgate domain add/
+ /archgate domain add/u
);
});
diff --git a/tests/helpers/repo.test.ts b/tests/helpers/repo.test.ts
index e8648617..f4dffa3a 100644
--- a/tests/helpers/repo.test.ts
+++ b/tests/helpers/repo.test.ts
@@ -120,7 +120,7 @@ describe("repo helper", () => {
describe("hashRepoId", () => {
test("produces a stable 16-char hex id for a given normalized url", () => {
const id = hashRepoId("github.com/foo/bar");
- expect(id).toMatch(/^[0-9a-f]{16}$/);
+ expect(id).toMatch(/^[0-9a-f]{16}$/u);
expect(hashRepoId("github.com/foo/bar")).toBe(id);
});
@@ -172,7 +172,7 @@ describe("repo helper", () => {
const ctx = await getRepoContext();
expect(ctx.isGit).toBe(true);
if (ctx.host) {
- expect(ctx.repoId).toMatch(/^[0-9a-f]{16}$/);
+ expect(ctx.repoId).toMatch(/^[0-9a-f]{16}$/u);
}
});
});
diff --git a/tests/helpers/telemetry-config.test.ts b/tests/helpers/telemetry-config.test.ts
index 81b67075..966d0fb1 100644
--- a/tests/helpers/telemetry-config.test.ts
+++ b/tests/helpers/telemetry-config.test.ts
@@ -39,7 +39,7 @@ describe("telemetry-config", () => {
const config = loadTelemetryConfig();
expect(config.telemetry).toBe(true);
expect(config.installId).toMatch(
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
+ /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u
);
expect(config.createdAt).toBeTruthy();
});
diff --git a/tests/integration/cli-harness.ts b/tests/integration/cli-harness.ts
index f6ccfd3c..50f579b6 100644
--- a/tests/integration/cli-harness.ts
+++ b/tests/integration/cli-harness.ts
@@ -85,7 +85,7 @@ export function writeRules(
wrapped = `/// \n\n${wrapped}`;
}
if (!content.includes("satisfies RuleSet")) {
- wrapped = wrapped.trimEnd().replace(/};\s*$/, "} satisfies RuleSet;\n");
+ wrapped = wrapped.trimEnd().replace(/\};\s*$/u, "} satisfies RuleSet;\n");
}
writeFileSync(join(dir, ".archgate", "adrs", filename), wrapped);
}