safeword 0.26.1 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{check-6763ESQ6.js → check-OH44W34Z.js} +3 -3
- package/dist/{chunk-NINE7AWZ.js → chunk-5A745HPE.js} +35 -36
- package/dist/chunk-5A745HPE.js.map +1 -0
- package/dist/{chunk-3GIBXEUI.js → chunk-6ZRDSDK4.js} +28 -5
- package/dist/chunk-6ZRDSDK4.js.map +1 -0
- package/dist/{chunk-5IOM3XLW.js → chunk-FK24HNGM.js} +2 -2
- package/dist/{chunk-Q4VPBNNZ.js → chunk-PEKTMTDF.js} +15 -1
- package/dist/chunk-PEKTMTDF.js.map +1 -0
- package/dist/cli.js +5 -5
- package/dist/{diff-O6NACWXR.js → diff-ASICF664.js} +3 -3
- package/dist/index.js +2 -2
- package/dist/presets/typescript/index.d.ts +7 -2
- package/dist/presets/typescript/index.js +2 -2
- package/dist/{reset-P5QGTALW.js → reset-7BFS4OJL.js} +3 -3
- package/dist/{setup-TGFZXS4G.js → setup-PGZOUKHI.js} +6 -5
- package/dist/{setup-TGFZXS4G.js.map → setup-PGZOUKHI.js.map} +1 -1
- package/dist/{upgrade-WL6K6B6O.js → upgrade-Y7AVKJTN.js} +4 -4
- package/package.json +22 -20
- package/templates/commands/audit.md +4 -1
- package/templates/hooks/lib/active-ticket.ts +43 -2
- package/templates/hooks/lib/lint.ts +35 -7
- package/templates/hooks/lib/quality-state.ts +4 -0
- package/templates/hooks/post-tool-bypass-warn.ts +1 -0
- package/templates/hooks/post-tool-quality.ts +16 -2
- package/templates/hooks/pre-tool-quality.ts +31 -23
- package/templates/hooks/stop-quality.ts +67 -4
- package/templates/skills/audit/SKILL.md +280 -0
- package/templates/skills/cleanup-zombies/SKILL.md +50 -0
- package/templates/skills/lint/SKILL.md +55 -0
- package/templates/skills/verify/SKILL.md +115 -0
- package/dist/chunk-3GIBXEUI.js.map +0 -1
- package/dist/chunk-NINE7AWZ.js.map +0 -1
- package/dist/chunk-Q4VPBNNZ.js.map +0 -1
- /package/dist/{check-6763ESQ6.js.map → check-OH44W34Z.js.map} +0 -0
- /package/dist/{chunk-5IOM3XLW.js.map → chunk-FK24HNGM.js.map} +0 -0
- /package/dist/{diff-O6NACWXR.js.map → diff-ASICF664.js.map} +0 -0
- /package/dist/{reset-P5QGTALW.js.map → reset-7BFS4OJL.js.map} +0 -0
- /package/dist/{upgrade-WL6K6B6O.js.map → upgrade-Y7AVKJTN.js.map} +0 -0
|
@@ -6,8 +6,8 @@ import {
|
|
|
6
6
|
createProjectContext,
|
|
7
7
|
getMissingPacks,
|
|
8
8
|
reconcile
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-5A745HPE.js";
|
|
10
|
+
import "./chunk-PEKTMTDF.js";
|
|
11
11
|
import {
|
|
12
12
|
VERSION
|
|
13
13
|
} from "./chunk-ORQHKDT2.js";
|
|
@@ -187,4 +187,4 @@ async function check(options) {
|
|
|
187
187
|
export {
|
|
188
188
|
check
|
|
189
189
|
};
|
|
190
|
-
//# sourceMappingURL=check-
|
|
190
|
+
//# sourceMappingURL=check-OH44W34Z.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detect
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-PEKTMTDF.js";
|
|
4
4
|
import {
|
|
5
5
|
VERSION
|
|
6
6
|
} from "./chunk-ORQHKDT2.js";
|
|
@@ -1279,8 +1279,7 @@ var pythonManagedFiles = {
|
|
|
1279
1279
|
},
|
|
1280
1280
|
// Project-level import-linter config (created only if layers detected and no existing config)
|
|
1281
1281
|
".importlinter": {
|
|
1282
|
-
//
|
|
1283
|
-
// eslint-disable-next-line sonarjs/no-inconsistent-returns
|
|
1282
|
+
// eslint-disable-next-line sonarjs/no-inconsistent-returns -- generator returns undefined to skip file
|
|
1284
1283
|
generator: (ctx) => {
|
|
1285
1284
|
if (!ctx.languages?.python) return;
|
|
1286
1285
|
if (ctx.projectType.existingImportLinterConfig) return;
|
|
@@ -1358,7 +1357,7 @@ function parseClippyKeys(content) {
|
|
|
1358
1357
|
const trimmed = line.trim();
|
|
1359
1358
|
if (trimmed && !trimmed.startsWith("#")) {
|
|
1360
1359
|
const match = /^([\w-]+)\s*=/.exec(trimmed);
|
|
1361
|
-
if (match) keys.add(match[1]);
|
|
1360
|
+
if (match?.[1]) keys.add(match[1]);
|
|
1362
1361
|
}
|
|
1363
1362
|
}
|
|
1364
1363
|
return keys;
|
|
@@ -1515,10 +1514,9 @@ function detectFromPythonDeps(cwd) {
|
|
|
1515
1514
|
content = readFileSync4(pyprojectPath, "utf8");
|
|
1516
1515
|
}
|
|
1517
1516
|
if (!content) return void 0;
|
|
1518
|
-
const
|
|
1519
|
-
for (const
|
|
1520
|
-
|
|
1521
|
-
const dialect = ADAPTER_TO_DIALECT[match[1]];
|
|
1517
|
+
const adapters = [...content.matchAll(/dbt-(\w+)/g)].map((m) => m[1]).filter((a) => a !== void 0 && a !== "core");
|
|
1518
|
+
for (const adapter of adapters) {
|
|
1519
|
+
const dialect = ADAPTER_TO_DIALECT[adapter];
|
|
1522
1520
|
if (dialect) return dialect;
|
|
1523
1521
|
}
|
|
1524
1522
|
return void 0;
|
|
@@ -1533,7 +1531,7 @@ function detectFromSqlcConfig(cwd) {
|
|
|
1533
1531
|
try {
|
|
1534
1532
|
const content = readFileSync4(nodePath9.join(directory, filename), "utf8");
|
|
1535
1533
|
const match = /engine['":\s]+(\w+)/.exec(content);
|
|
1536
|
-
if (match) return ADAPTER_TO_DIALECT[match[1]] ?? match[1];
|
|
1534
|
+
if (match?.[1]) return ADAPTER_TO_DIALECT[match[1]] ?? match[1];
|
|
1537
1535
|
} catch {
|
|
1538
1536
|
continue;
|
|
1539
1537
|
}
|
|
@@ -1546,7 +1544,7 @@ function detectFromPrismaSchema(cwd) {
|
|
|
1546
1544
|
try {
|
|
1547
1545
|
const content = readFileSync4(schemaPath, "utf8");
|
|
1548
1546
|
const match = /provider\s*=\s*"(\w+)"/.exec(content);
|
|
1549
|
-
if (!match) return void 0;
|
|
1547
|
+
if (!match?.[1]) return void 0;
|
|
1550
1548
|
return PROVIDER_TO_DIALECT[match[1]];
|
|
1551
1549
|
} catch {
|
|
1552
1550
|
return void 0;
|
|
@@ -1559,7 +1557,7 @@ function detectFromDrizzleConfig(cwd) {
|
|
|
1559
1557
|
try {
|
|
1560
1558
|
const content = readFileSync4(filePath, "utf8");
|
|
1561
1559
|
const match = /dialect\s*:\s*["'](\w+)["']/.exec(content);
|
|
1562
|
-
if (match) return DRIZZLE_TO_DIALECT[match[1]];
|
|
1560
|
+
if (match?.[1]) return DRIZZLE_TO_DIALECT[match[1]];
|
|
1563
1561
|
} catch {
|
|
1564
1562
|
continue;
|
|
1565
1563
|
}
|
|
@@ -1572,7 +1570,7 @@ function detectFromDatabaseUrl(cwd) {
|
|
|
1572
1570
|
try {
|
|
1573
1571
|
const content = readFileSync4(envPath, "utf8");
|
|
1574
1572
|
const match = /DATABASE_URL\s*=\s*["']?(\w+):/.exec(content);
|
|
1575
|
-
if (!match) return void 0;
|
|
1573
|
+
if (!match?.[1]) return void 0;
|
|
1576
1574
|
return SCHEME_TO_DIALECT[match[1]];
|
|
1577
1575
|
} catch {
|
|
1578
1576
|
return void 0;
|
|
@@ -1689,13 +1687,13 @@ const scopedNextConfigs = nextPaths?.flatMap((filePath) =>
|
|
|
1689
1687
|
configs.nextOnlyRules.map((config) => ({ ...config, files: [filePath] }))
|
|
1690
1688
|
) ?? [];`;
|
|
1691
1689
|
}
|
|
1692
|
-
var OPTIONAL_CONFIGS_SNIPPET = ` // Testing configs -
|
|
1693
|
-
...configs.vitest,
|
|
1694
|
-
...configs.playwright,
|
|
1695
|
-
// Storybook -
|
|
1696
|
-
...configs.storybook,
|
|
1697
|
-
// TanStack Query -
|
|
1698
|
-
...configs.tanstackQuery,
|
|
1690
|
+
var OPTIONAL_CONFIGS_SNIPPET = ` // Testing configs - only if detected (plugins have framework peer deps)
|
|
1691
|
+
...(detect.hasVitest(deps) ? configs.vitest : []),
|
|
1692
|
+
...(detect.hasPlaywright(deps) ? configs.playwright : []),
|
|
1693
|
+
// Storybook - only if detected (v10+ requires storybook peer dep)
|
|
1694
|
+
...(detect.hasStorybook(deps) ? configs.storybook : []),
|
|
1695
|
+
// TanStack Query - only if detected (has typescript peer dep)
|
|
1696
|
+
...(detect.hasTanstackQuery(deps) ? configs.tanstackQuery : []),
|
|
1699
1697
|
// Tailwind - only if detected (plugin needs tailwind config to validate classes)
|
|
1700
1698
|
...(detect.hasTailwind(deps) ? configs.tailwind : []),
|
|
1701
1699
|
// Turborepo - only if detected (validates env vars are declared in turbo.json)
|
|
@@ -2019,8 +2017,7 @@ var typescriptOwnedFiles = {
|
|
|
2019
2017
|
) : void 0
|
|
2020
2018
|
},
|
|
2021
2019
|
".safeword/.prettierrc": {
|
|
2022
|
-
//
|
|
2023
|
-
// eslint-disable-next-line sonarjs/no-inconsistent-returns
|
|
2020
|
+
// eslint-disable-next-line sonarjs/no-inconsistent-returns -- generator returns undefined to skip file
|
|
2024
2021
|
generator: (ctx) => {
|
|
2025
2022
|
if (!ctx.languages?.javascript || ctx.projectType.existingFormatter) {
|
|
2026
2023
|
return;
|
|
@@ -2034,8 +2031,7 @@ var typescriptOwnedFiles = {
|
|
|
2034
2031
|
var typescriptManagedFiles = {
|
|
2035
2032
|
// Project-level ESLint config (created only if no existing ESLint config)
|
|
2036
2033
|
"eslint.config.mjs": {
|
|
2037
|
-
//
|
|
2038
|
-
// eslint-disable-next-line sonarjs/no-inconsistent-returns
|
|
2034
|
+
// eslint-disable-next-line sonarjs/no-inconsistent-returns -- generator returns undefined to skip file
|
|
2039
2035
|
generator: (ctx) => {
|
|
2040
2036
|
if (ctx.projectType.existingEslintConfig) return;
|
|
2041
2037
|
if (!ctx.languages?.javascript) return;
|
|
@@ -2044,8 +2040,7 @@ var typescriptManagedFiles = {
|
|
|
2044
2040
|
},
|
|
2045
2041
|
// Minimal tsconfig for ESLint type-checked linting (only if missing)
|
|
2046
2042
|
"tsconfig.json": {
|
|
2047
|
-
//
|
|
2048
|
-
// eslint-disable-next-line sonarjs/no-inconsistent-returns
|
|
2043
|
+
// eslint-disable-next-line sonarjs/no-inconsistent-returns -- generator returns undefined to skip file
|
|
2049
2044
|
generator: (ctx) => {
|
|
2050
2045
|
if (!ctx.languages?.javascript) return;
|
|
2051
2046
|
if (!ctx.developmentDeps.typescript && !ctx.developmentDeps["typescript-eslint"]) {
|
|
@@ -2077,8 +2072,7 @@ var typescriptManagedFiles = {
|
|
|
2077
2072
|
},
|
|
2078
2073
|
// Project-level Prettier config (created only if no existing formatter)
|
|
2079
2074
|
".prettierrc": {
|
|
2080
|
-
//
|
|
2081
|
-
// eslint-disable-next-line sonarjs/no-inconsistent-returns
|
|
2075
|
+
// eslint-disable-next-line sonarjs/no-inconsistent-returns -- generator returns undefined to skip file
|
|
2082
2076
|
generator: (ctx) => {
|
|
2083
2077
|
if (!ctx.languages?.javascript) return;
|
|
2084
2078
|
if (ctx.projectType.existingFormatter) return;
|
|
@@ -2356,7 +2350,12 @@ var SAFEWORD_SCHEMA = {
|
|
|
2356
2350
|
".claude/commands/debug.md",
|
|
2357
2351
|
".claude/commands/quality-review.md",
|
|
2358
2352
|
".claude/commands/refactor.md",
|
|
2359
|
-
".claude/commands/testing.md"
|
|
2353
|
+
".claude/commands/testing.md",
|
|
2354
|
+
// Commands converted to skills (ticket 038)
|
|
2355
|
+
".claude/commands/lint.md",
|
|
2356
|
+
".claude/commands/verify.md",
|
|
2357
|
+
".claude/commands/audit.md",
|
|
2358
|
+
".claude/commands/cleanup-zombies.md"
|
|
2360
2359
|
],
|
|
2361
2360
|
// Packages to uninstall on upgrade (now bundled in safeword/eslint)
|
|
2362
2361
|
deprecatedPackages: [
|
|
@@ -2575,14 +2574,14 @@ var SAFEWORD_SCHEMA = {
|
|
|
2575
2574
|
".claude/skills/ticket-system/SKILL.md": {
|
|
2576
2575
|
template: "skills/ticket-system/SKILL.md"
|
|
2577
2576
|
},
|
|
2578
|
-
// Claude
|
|
2579
|
-
// Skills auto-create /slash-commands, so
|
|
2580
|
-
".claude/
|
|
2581
|
-
".claude/
|
|
2582
|
-
".claude/
|
|
2583
|
-
|
|
2577
|
+
// Claude skills — action commands with disable-model-invocation
|
|
2578
|
+
// Skills auto-create /slash-commands, so separate commands are unnecessary
|
|
2579
|
+
".claude/skills/lint/SKILL.md": { template: "skills/lint/SKILL.md" },
|
|
2580
|
+
".claude/skills/verify/SKILL.md": { template: "skills/verify/SKILL.md" },
|
|
2581
|
+
".claude/skills/audit/SKILL.md": { template: "skills/audit/SKILL.md" },
|
|
2582
|
+
".claude/skills/cleanup-zombies/SKILL.md": {
|
|
2583
|
+
template: "skills/cleanup-zombies/SKILL.md"
|
|
2584
2584
|
},
|
|
2585
|
-
".claude/commands/lint.md": { template: "commands/lint.md" },
|
|
2586
2585
|
// Cursor rules
|
|
2587
2586
|
".cursor/rules/safeword-core.mdc": {
|
|
2588
2587
|
template: "cursor/rules/safeword-core.mdc"
|
|
@@ -2937,4 +2936,4 @@ export {
|
|
|
2937
2936
|
detectLanguages2,
|
|
2938
2937
|
createProjectContext
|
|
2939
2938
|
};
|
|
2940
|
-
//# sourceMappingURL=chunk-
|
|
2939
|
+
//# sourceMappingURL=chunk-5A745HPE.js.map
|