@7n/rules 1.29.3 → 1.31.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/CHANGELOG.md +17 -0
- package/package.json +1 -1
- package/rules/k8s/dremio_logging/dremio_logging.mdc +1 -0
- package/scripts/docs/index.md +15 -14
- package/scripts/docs/tool-pins-refresh.md +28 -0
- package/scripts/docs/upgrade-n-rules-and-install.md +2 -1
- package/scripts/lib/docs/ensure-tool.md +69 -25
- package/scripts/lib/ensure-tool.mjs +150 -12
- package/scripts/lib/lint-surface/detect.mjs +22 -0
- package/scripts/lib/lint-surface/docs/detect.md +4 -4
- package/scripts/lib/tool-pins.json +15 -0
- package/scripts/tool-pins-refresh.mjs +54 -0
- package/scripts/upgrade-n-rules-and-install.mjs +86 -19
- package/skills/taze/js/docs/orchestrate.md +1 -1
- package/rules/style/admin_table/admin_table.mdc +0 -88
- package/rules/style/admin_table/concern.json +0 -7
- package/rules/style/admin_table/docs/index.md +0 -9
- package/rules/style/admin_table/docs/main.md +0 -14
- package/rules/style/admin_table/main.mjs +0 -46
- package/rules/style/colors/colors.mdc +0 -21
- package/rules/style/colors/concern.json +0 -3
- package/rules/style/docs/index.md +0 -11
- package/rules/style/gap/concern.json +0 -7
- package/rules/style/gap/docs/index.md +0 -9
- package/rules/style/gap/docs/main.md +0 -15
- package/rules/style/gap/gap.mdc +0 -22
- package/rules/style/gap/main.mjs +0 -51
- package/rules/style/lint/concern.json +0 -7
- package/rules/style/lint/docs/fix-lint.md +0 -29
- package/rules/style/lint/docs/index.md +0 -11
- package/rules/style/lint/docs/main.md +0 -29
- package/rules/style/lint/fix-lint.mjs +0 -66
- package/rules/style/lint/main.mjs +0 -68
- package/rules/style/main.json +0 -1
- package/rules/style/main.mdc +0 -12
- package/rules/style/package_json/concern.json +0 -9
- package/rules/style/package_json/docs/fix-package_json.md +0 -27
- package/rules/style/package_json/docs/index.md +0 -9
- package/rules/style/package_json/fix-package_json.mjs +0 -3
- package/rules/style/package_json/package_json.mdc +0 -18
- package/rules/style/package_json/package_json.rego +0 -31
- package/rules/style/package_json/template/package.json.snippet.json +0 -5
- package/rules/style/quasar/concern.json +0 -3
- package/rules/style/quasar/quasar.mdc +0 -7
- package/rules/style/quasar_fixes/concern.json +0 -7
- package/rules/style/quasar_fixes/docs/index.md +0 -9
- package/rules/style/quasar_fixes/docs/main.md +0 -16
- package/rules/style/quasar_fixes/main.mjs +0 -57
- package/rules/style/quasar_fixes/quasar_fixes.mdc +0 -32
- package/rules/style/tooling/concern.json +0 -14
- package/rules/style/tooling/docs/fix-tooling.md +0 -29
- package/rules/style/tooling/docs/index.md +0 -12
- package/rules/style/tooling/docs/main.md +0 -34
- package/rules/style/tooling/fix-tooling.mjs +0 -58
- package/rules/style/tooling/main.mjs +0 -73
- package/rules/style/tooling/tooling.mdc +0 -85
- package/rules/style/vscode_extensions/concern.json +0 -9
- package/rules/style/vscode_extensions/docs/fix-vscode_extensions.md +0 -25
- package/rules/style/vscode_extensions/docs/index.md +0 -11
- package/rules/style/vscode_extensions/fix-vscode_extensions.mjs +0 -1
- package/rules/style/vscode_extensions/template/extensions.json.snippet.json +0 -1
- package/rules/style/vscode_extensions/vscode_extensions.mdc +0 -13
- package/rules/style/vscode_extensions/vscode_extensions.rego +0 -13
- package/rules/style/vscode_settings/concern.json +0 -9
- package/rules/style/vscode_settings/docs/fix-vscode_settings.md +0 -27
- package/rules/style/vscode_settings/docs/index.md +0 -9
- package/rules/style/vscode_settings/fix-vscode_settings.mjs +0 -5
- package/rules/style/vscode_settings/template/settings.json.snippet.json +0 -5
- package/rules/style/vscode_settings/vscode_settings.mdc +0 -19
- package/rules/style/vscode_settings/vscode_settings.rego +0 -15
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/** @see ./docs/fix-lint.md */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* T0-autofix для `style/lint` — детермінований прогін `stylelint --fix` по css/scss/vue.
|
|
5
|
-
* Детектор емітить агрегований `stylelint-violation` без переліку файлів, тож фіксер
|
|
6
|
-
* самостійно перелічує цільові файли (ctx.files у дельті або tracked css/scss/vue у повному
|
|
7
|
-
* режимі), форматує їх і повертає лише фактично змінені. Запис permanent. Відсутній
|
|
8
|
-
* stylelint → no-op.
|
|
9
|
-
*/
|
|
10
|
-
import { readFileSync } from 'node:fs'
|
|
11
|
-
import { resolve } from 'node:path'
|
|
12
|
-
|
|
13
|
-
import { filterStyleFiles, resolveStylelint } from './main.mjs'
|
|
14
|
-
import { spawnAsync } from '../../../scripts/utils/spawn-async.mjs'
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Вміст файлу або null, якщо не читається.
|
|
18
|
-
* @param {string} abs абсолютний шлях
|
|
19
|
-
* @returns {string|null} вміст або null
|
|
20
|
-
*/
|
|
21
|
-
function readOrNull(abs) {
|
|
22
|
-
try {
|
|
23
|
-
return readFileSync(abs, 'utf8')
|
|
24
|
-
} catch {
|
|
25
|
-
return null
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Перелік цільових style-файлів: у дельті — з ctx.files; у повному режимі — tracked
|
|
31
|
-
* css/scss/vue через `git ls-files`.
|
|
32
|
-
* @param {string} cwd корінь
|
|
33
|
-
* @param {string[]|undefined} ctxFiles файли з контексту (дельта) або undefined (повний режим)
|
|
34
|
-
* @returns {Promise<string[]>} posix-relative шляхи
|
|
35
|
-
*/
|
|
36
|
-
async function listStyleFiles(cwd, ctxFiles) {
|
|
37
|
-
if (ctxFiles !== undefined) return filterStyleFiles(ctxFiles)
|
|
38
|
-
const r = await spawnAsync('git', ['ls-files', '-z', '--', '*.css', '*.scss', '*.vue'], { cwd })
|
|
39
|
-
if (r.exitCode !== 0) return []
|
|
40
|
-
return (r.stdout ?? '').split('\0').filter(Boolean)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** @type {import('../../../scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
|
|
44
|
-
export const patterns = [
|
|
45
|
-
{
|
|
46
|
-
id: 'style-stylelint-fix',
|
|
47
|
-
standalone: true, // §8 Phase 2: apply бере ctx.files (не violations), stylelint --fix сам ре-аналізує
|
|
48
|
-
test: violations => violations.some(v => v.reason === 'stylelint-violation'),
|
|
49
|
-
apply: async (violations, ctx) => {
|
|
50
|
-
const stylelint = resolveStylelint(ctx.cwd)
|
|
51
|
-
if (!stylelint) return { touchedFiles: [] }
|
|
52
|
-
const files = await listStyleFiles(ctx.cwd, ctx.files)
|
|
53
|
-
if (files.length === 0) return { touchedFiles: [] }
|
|
54
|
-
|
|
55
|
-
const abs = files.map(f => resolve(ctx.cwd, f))
|
|
56
|
-
const before = new Map(abs.map(a => [a, readOrNull(a)]))
|
|
57
|
-
await spawnAsync(stylelint, ['--fix', ...files], { cwd: ctx.cwd })
|
|
58
|
-
|
|
59
|
-
const touchedFiles = abs.filter(a => readOrNull(a) !== before.get(a))
|
|
60
|
-
for (const a of touchedFiles) ctx.recordWrite?.(a)
|
|
61
|
-
return touchedFiles.length > 0
|
|
62
|
-
? { touchedFiles, message: `stylelint --fix: ${touchedFiles.length} файл(ів)` }
|
|
63
|
-
: { touchedFiles: [] }
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
]
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* lint-поверхня style: read-only detector (stylelint без --fix) для css/scss/vue.
|
|
3
|
-
* Per-file (ctx.files) або весь проєкт (ctx.files === undefined). Якщо stylelint
|
|
4
|
-
* недоступний — крок пропускається (без npx-автовстановлення).
|
|
5
|
-
*/
|
|
6
|
-
import { existsSync } from 'node:fs'
|
|
7
|
-
import { join } from 'node:path'
|
|
8
|
-
|
|
9
|
-
import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
|
|
10
|
-
import { resolveCmd } from '../../../scripts/utils/resolve-cmd.mjs'
|
|
11
|
-
import { spawnAsync } from '../../../scripts/utils/spawn-async.mjs'
|
|
12
|
-
|
|
13
|
-
const STYLE_EXT_RE = /\.(?:css|scss|vue)$/u
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* @param {string[]} files список шляхів
|
|
17
|
-
* @returns {string[]} лише css/scss/vue
|
|
18
|
-
*/
|
|
19
|
-
export function filterStyleFiles(files) {
|
|
20
|
-
return files.filter(f => STYLE_EXT_RE.test(f))
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Резолвить бінарник stylelint: спершу локальний node_modules/.bin, потім PATH.
|
|
25
|
-
* @param {string} cwd корінь
|
|
26
|
-
* @returns {string | null} абсолютний шлях або null
|
|
27
|
-
*/
|
|
28
|
-
export function resolveStylelint(cwd) {
|
|
29
|
-
const local = join(cwd, 'node_modules', '.bin', 'stylelint')
|
|
30
|
-
if (existsSync(local)) return local
|
|
31
|
-
return resolveCmd('stylelint')
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Detector style/lint (read-only).
|
|
36
|
-
* @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd, files)
|
|
37
|
-
* @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
|
|
38
|
-
*/
|
|
39
|
-
export async function lint(ctx) {
|
|
40
|
-
const reporter = createViolationReporter(ctx)
|
|
41
|
-
const { fail } = reporter
|
|
42
|
-
const cwd = ctx.cwd
|
|
43
|
-
const files = ctx.files
|
|
44
|
-
|
|
45
|
-
/** @type {string[]} */
|
|
46
|
-
const targets = []
|
|
47
|
-
if (files === undefined) {
|
|
48
|
-
targets.push('**/*.{css,scss,vue}')
|
|
49
|
-
} else {
|
|
50
|
-
const style = filterStyleFiles(files)
|
|
51
|
-
if (style.length === 0) return reporter.result()
|
|
52
|
-
targets.push(...style)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const stylelint = resolveStylelint(cwd)
|
|
56
|
-
if (!stylelint) {
|
|
57
|
-
// stylelint недоступний → крок пропущено (без автовстановлення)
|
|
58
|
-
return reporter.result()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const r = await spawnAsync(stylelint, targets, { cwd, shell: false })
|
|
62
|
-
if (r.exitCode !== 0) {
|
|
63
|
-
const out = `${r.stdout ?? ''}${r.stderr ?? ''}`.trim().slice(0, 2000)
|
|
64
|
-
const outSuffix = out ? `\n${out}` : ''
|
|
65
|
-
fail(`lint-style: stylelint — порушення (код ${r.exitCode ?? 1}, style.mdc)${outSuffix}`, 'stylelint-violation')
|
|
66
|
-
}
|
|
67
|
-
return reporter.result()
|
|
68
|
-
}
|
package/rules/style/main.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "auto": { "glob": ["**/*.css", "**/*.vue"] } }
|
package/rules/style/main.mdc
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Правила стилів CSS та SCSS
|
|
3
|
-
version: '1.5'
|
|
4
|
-
globs: "**/*.{css,scss,vue}"
|
|
5
|
-
alwaysApply: false
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
Правило **style** для Vue-проєктів: Quasar як стильова система, SCSS-конвенції кольорів і відступів, фікси компонентів, stylelint через `@nitra/stylelint-config`.
|
|
9
|
-
|
|
10
|
-
- [settings.json.snippet.json](./vscode_settings/template/settings.json.snippet.json)
|
|
11
|
-
- [extensions.json.snippet.json](./vscode_extensions/template/extensions.json.snippet.json)
|
|
12
|
-
- [package.json.snippet.json](./package_json/template/package.json.snippet.json)
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: fix-package_json.mjs
|
|
4
|
-
resource: npm/rules/style/package_json/fix-package_json.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: deb26703
|
|
7
|
-
model: openai-codex/gpt-5.5
|
|
8
|
-
tier: cloud-avg
|
|
9
|
-
score: 100
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
Надає `patterns` для визначення очікуваних перевірок, що спираються на `package.json`. Використовується як read-only опис вимог до конфігурації пакета, без самостійних змін файлової системи.
|
|
16
|
-
|
|
17
|
-
## Поведінка
|
|
18
|
-
|
|
19
|
-
1. `patterns` визначає правило виправлення для `package.json`.
|
|
20
|
-
|
|
21
|
-
2. `patterns` забезпечує приведення `package.json` до проєктного шаблону стилю.
|
|
22
|
-
|
|
23
|
-
3. `patterns` не змінює файлову систему самостійно, а лише описує доступний сценарій автоматичного виправлення для зовнішнього механізму перевірок.
|
|
24
|
-
|
|
25
|
-
## Гарантії поведінки
|
|
26
|
-
|
|
27
|
-
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
## package.json: stylelint-конфіг та devDependencies
|
|
2
|
-
|
|
3
|
-
Rego-пакет: `style_lint.package_json`
|
|
4
|
-
|
|
5
|
-
Цільовий файл: `package.json`
|
|
6
|
-
|
|
7
|
-
Дві незалежні перевірки:
|
|
8
|
-
|
|
9
|
-
1. **snippet-walker** — якщо поле `stylelint` присутнє у `package.json`, перевіряє `stylelint.extends == "@nitra/stylelint-config"` (2-рівневий обхід через template).
|
|
10
|
-
2. **presence-check** — `@nitra/stylelint-config` має бути у `devDependencies` (ця перевірка завжди активна, не залежить від template).
|
|
11
|
-
|
|
12
|
-
FS-альтернативи (`.stylelintrc.*` файли) та `.stylelintignore` перевіряються у JS, не в Rego.
|
|
13
|
-
|
|
14
|
-
Канонічний template: [package.json.snippet.json](./template/package.json.snippet.json)
|
|
15
|
-
|
|
16
|
-
**✓ Правильно** — `devDependencies` містить `@nitra/stylelint-config`; якщо є поле `stylelint` — `extends` дорівнює `"@nitra/stylelint-config"`.
|
|
17
|
-
|
|
18
|
-
**✗ Неправильно** — відсутній `@nitra/stylelint-config` у `devDependencies`; або поле `stylelint.extends` має інше значення.
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Порт перевірок `package.json` (style.mdc).
|
|
2
|
-
#
|
|
3
|
-
# Канон надходить через --data: { "template": { "contains": ..., "snippet": ... } }
|
|
4
|
-
# Структура --data сформована з template/package.json.{contains,snippet}.json.
|
|
5
|
-
# FS-альтернативи (`.stylelintrc.*` файли) + `.stylelintignore` — у JS.
|
|
6
|
-
#
|
|
7
|
-
# Логіка, що ЛИШАЄТЬСЯ у rego (inverse — не виноситься у template):
|
|
8
|
-
# - `@nitra/stylelint-config` має бути у devDependencies (presence-check).
|
|
9
|
-
package style.package_json
|
|
10
|
-
|
|
11
|
-
import rego.v1
|
|
12
|
-
|
|
13
|
-
# ── deny: 2-level snippet walker (для stylelint.extends, якщо поле є) ────
|
|
14
|
-
|
|
15
|
-
deny contains msg if {
|
|
16
|
-
some section, expected_inner in data.template.snippet
|
|
17
|
-
cfg := object.get(input, section, null)
|
|
18
|
-
is_object(cfg)
|
|
19
|
-
some leaf_key, expected_value in expected_inner
|
|
20
|
-
actual := object.get(cfg, leaf_key, null)
|
|
21
|
-
actual != expected_value
|
|
22
|
-
msg := sprintf("package.json: %s.%s має бути %q (style.mdc)", [section, leaf_key, expected_value])
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
# ── deny: @nitra/stylelint-config у devDependencies (inverse) ────────────
|
|
26
|
-
|
|
27
|
-
deny contains msg if {
|
|
28
|
-
dev := object.get(input, "devDependencies", {})
|
|
29
|
-
not "@nitra/stylelint-config" in object.keys(dev)
|
|
30
|
-
msg := "@nitra/stylelint-config відсутній — bun add -d @nitra/stylelint-config (style.mdc)"
|
|
31
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
## Quasar як стильова основа
|
|
2
|
-
|
|
3
|
-
У Vue-проектах використовуй **Quasar** як базову стильову систему:
|
|
4
|
-
|
|
5
|
-
- **Класи компонентів:** `q-pa-*`, `q-ma-*`, `q-mt-*`, `q-mb-*`, `row`, `col`, `col-*`, `items-center`, `justify-between`, `text-*`, `bg-*`, `shadow-*` тощо — стандартні утиліти Quasar.
|
|
6
|
-
- **Кольори:** використовуй Quasar CSS-змінні через класи (`text-primary`, `bg-accent`, `text-negative` тощо) або через SCSS-змінні (`$primary`, `$accent`) у `.scss`-файлах.
|
|
7
|
-
- **Не пиши власні утиліти**, якщо є відповідний Quasar-клас.
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: main.mjs
|
|
4
|
-
resource: npm/rules/style/quasar_fixes/main.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 3eecca4c
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Огляд
|
|
10
|
-
|
|
11
|
-
Детектор concern-а `quasar_fixes` (read-only, whole-repo): якщо `.vue`-файл використовує
|
|
12
|
-
`<q-scroll-area>` або `<q-tooltip>`, десь у `.scss`/`.css`/`.vue` проєкту має бути
|
|
13
|
-
відповідний CSS-фікс (`.q-scrollarea` / `.q-tooltip`) — інакше порушення
|
|
14
|
-
`missing-quasar-fix`. iOS-zoom-фікс (тригер на `input`/`textarea`/`select`) навмисно не
|
|
15
|
-
перевіряється — надто загальний тригер, false-positive на майже будь-якій формі. Whole-repo
|
|
16
|
-
сканування, не залежить від `ctx.files`.
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/** @see ./docs/main.md */
|
|
2
|
-
import { readFile } from 'node:fs/promises'
|
|
3
|
-
|
|
4
|
-
import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
|
|
5
|
-
import { walkDir } from '../../../scripts/utils/walkDir.mjs'
|
|
6
|
-
|
|
7
|
-
const RELEVANT_RE = /\.(?:vue|scss|css)$/u
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Пари (usage у `.vue` → очікуваний CSS-фікс) з guide `quasar_fixes.mdc`. Навмисно НЕ
|
|
11
|
-
* включено iOS-zoom-фікс (тригер `input`/`textarea`/`select` — занадто загальний,
|
|
12
|
-
* false-positive на майже будь-якій формі; консервативно залишено лише narrative).
|
|
13
|
-
*/
|
|
14
|
-
const FIXES = [
|
|
15
|
-
{ usage: /<q-scroll-area\b/u, definition: /\.q-scrollarea\b/u, name: 'q-scroll-area', selector: '.q-scrollarea' },
|
|
16
|
-
{ usage: /<q-tooltip\b/u, definition: /\.q-tooltip\b/u, name: 'q-tooltip', selector: '.q-tooltip' }
|
|
17
|
-
]
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Detector style/quasar_fixes (read-only, whole-repo): якщо `.vue` використовує
|
|
21
|
-
* `<q-scroll-area>` або `<q-tooltip>`, у `.scss`/`.css`/`.vue` має бути відповідний
|
|
22
|
-
* CSS-фікс (guide: `quasar_fixes.mdc`). Крос-файлова перевірка usage↔definition —
|
|
23
|
-
* потребує whole-repo сканування незалежно від `ctx.files`.
|
|
24
|
-
* @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
|
|
25
|
-
* @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
|
|
26
|
-
*/
|
|
27
|
-
export async function lint(ctx) {
|
|
28
|
-
const reporter = createViolationReporter(ctx)
|
|
29
|
-
const { fail } = reporter
|
|
30
|
-
const cwd = ctx.cwd
|
|
31
|
-
|
|
32
|
-
/** @type {string[]} */
|
|
33
|
-
const files = []
|
|
34
|
-
await walkDir(cwd, f => {
|
|
35
|
-
if (RELEVANT_RE.test(f)) files.push(f)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
const used = new Set()
|
|
39
|
-
const defined = new Set()
|
|
40
|
-
for (const file of files) {
|
|
41
|
-
const content = await readFile(file, 'utf8')
|
|
42
|
-
for (const fix of FIXES) {
|
|
43
|
-
if (file.endsWith('.vue') && !used.has(fix.name) && fix.usage.test(content)) used.add(fix.name)
|
|
44
|
-
if (!defined.has(fix.name) && fix.definition.test(content)) defined.add(fix.name)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
for (const fix of FIXES) {
|
|
49
|
-
if (used.has(fix.name) && !defined.has(fix.name)) {
|
|
50
|
-
fail(
|
|
51
|
-
`Компонент \`${fix.name}\` використовується у \`.vue\`, але фікс \`${fix.selector}\` відсутній у \`.scss\`/\`.css\` (guide: style/quasar_fixes.mdc) — додай фікс до app.scss`,
|
|
52
|
-
'missing-quasar-fix'
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return reporter.result()
|
|
57
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
## Фікси компонентів Quasar
|
|
2
|
-
|
|
3
|
-
При використанні компонента `q-scroll-area` або `q-tooltip` додай до `app.scss` відповідні фікси. Аналогічно — фікс масштабування на iOS.
|
|
4
|
-
|
|
5
|
-
```scss
|
|
6
|
-
// FIX стилі для прокручуваної області по висоті екрана
|
|
7
|
-
.q-scrollarea {
|
|
8
|
-
display: flex;
|
|
9
|
-
flex-direction: column;
|
|
10
|
-
height: auto;
|
|
11
|
-
min-height: 0;
|
|
12
|
-
max-height: 100%;
|
|
13
|
-
|
|
14
|
-
.scroll {
|
|
15
|
-
flex: 10000 1 0%;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// FIX tooltip
|
|
20
|
-
.q-tooltip {
|
|
21
|
-
font-size: 1em;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// FIX не зумувати на iOS
|
|
25
|
-
@media (width <= 600px) {
|
|
26
|
-
input,
|
|
27
|
-
textarea,
|
|
28
|
-
select {
|
|
29
|
-
font-size: 16px;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://unpkg.com/@7n/rules/schemas/concern.json",
|
|
3
|
-
"fixability": "config",
|
|
4
|
-
"lint": {
|
|
5
|
-
"scope": "full",
|
|
6
|
-
"glob": [
|
|
7
|
-
"package.json",
|
|
8
|
-
".stylelintrc.{json,js,cjs,mjs}",
|
|
9
|
-
"stylelint.config.{js,cjs,mjs}",
|
|
10
|
-
".stylelintignore",
|
|
11
|
-
".github/workflows/lint-style.yml"
|
|
12
|
-
]
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: fix-tooling.mjs
|
|
4
|
-
resource: npm/rules/style/tooling/fix-tooling.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: a25e47d2
|
|
7
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
-
score: 100
|
|
9
|
-
issues: judge:inaccurate:0.98
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
Виконую завдання як технічний письменник.
|
|
16
|
-
|
|
17
|
-
Файл забезпечує детерміновані виправлення файлової системи для автоматичного налаштування інструменту Stylelint. Публічна функція `patterns` виконує перехоплення помилок (fail-safe), не генеруючи винятків. Код спирається на конфігурацію `package.json` і гарантує, що директорія `dist/` виключена з перевірки Stylelint через створення або доповнення `.stylelintignore`, а також додає необхідну конфігурацію Stylelint до `package.json`.
|
|
18
|
-
|
|
19
|
-
## Поведінка
|
|
20
|
-
|
|
21
|
-
Поведінка:
|
|
22
|
-
|
|
23
|
-
1. Перевіряється наявність файлу `.stylelintignore`. Якщо він відсутній, створюється з вмістом `dist/`.
|
|
24
|
-
2. Якщо файл `.stylelintignore` існує, перевіряється, чи містить він рядок `dist/`. Якщо ні, до файлу додається рядок `dist/`.
|
|
25
|
-
3. Перевіряється, чи міститься конфігурація `stylelint` у файлі `package.json`. Якщо конфігурація відсутня, вона додається до `package.json` з посиланням на `@nitra/stylelint-config`.
|
|
26
|
-
|
|
27
|
-
## Гарантії поведінки
|
|
28
|
-
|
|
29
|
-
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: Directory Index
|
|
3
|
-
title: npm/rules/style/tooling
|
|
4
|
-
resource: npm/rules/style/tooling/
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# npm/rules/style/tooling
|
|
8
|
-
|
|
9
|
-
| Файл | Тип |
|
|
10
|
-
| --------------------------------- | --------- |
|
|
11
|
-
| [fix-tooling.mjs](fix-tooling.md) | JS Module |
|
|
12
|
-
| [main.mjs](main.md) | JS Module |
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: main.mjs
|
|
4
|
-
resource: npm/rules/style/tooling/main.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 015d1c9a
|
|
7
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
-
score: 90
|
|
9
|
-
issues: anchor-miss:extensions.json,anchor-miss:settings.json,judge:inaccurate:0.99
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
Please provide the code file you want me to document. I will then generate the "Огляд" section based on the provided "Поведінка" and the file's content, adhering to all specified rules.
|
|
16
|
-
|
|
17
|
-
## Поведінка
|
|
18
|
-
|
|
19
|
-
Поведінка:
|
|
20
|
-
|
|
21
|
-
1. main: Перевіряє наявність конфігурації stylelint. Конфігурація може бути визначена у пакеті `package.json` або у зовнішніх файлах конфігурації, зокрема `.stylelintrc.json`, `.stylelintrc.js`, `.stylelintrc.cjs`, `.stylelintrc.mjs`, `stylelint.config.js`, `stylelint.config.cjs`, `stylelint.config.mjs`. Якщо жоден із цих варіантів відсутній, видається помилка, і пропонується додати конфігурацію до `package.json` з посиланням на `@nitra/stylelint-config` (згадка (js.mdc)).
|
|
22
|
-
2. main: Перевіряє існування файлу `.stylelintignore`. Якщо він не існує, видається помилка, і пропонується створити його з вмістом `dist/`.
|
|
23
|
-
3. main: Якщо `.stylelintignore` існує, він перевіряє, чи містить він рядок `dist/`. Якщо цього рядка немає, видається помилка з проханням додати його (згадка (style.mdc)).
|
|
24
|
-
4. main: Перевіряє існування файлу `.github/workflows/lint-style.yml`. Якщо він відсутній, видається помилка з проханням його створити.
|
|
25
|
-
5. Робота ігнорує шляхи в каталозі `.github` та `.git` під час перевірки.
|
|
26
|
-
|
|
27
|
-
## Публічний API
|
|
28
|
-
|
|
29
|
-
main — забезпечує дотримання стандартів стилізації проєкту відповідно до правил style.mdc
|
|
30
|
-
|
|
31
|
-
## Гарантії поведінки
|
|
32
|
-
|
|
33
|
-
- Read-only: не виконує операцій запису (ФС/БД).
|
|
34
|
-
- Свідомо пропускає шляхи: `.github`, `.git`.
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* T0-autofix паттерни для `style/tooling` — детерміновані FS-виправлення:
|
|
3
|
-
* створення або доповнення `.stylelintignore` та додавання `stylelint` до `package.json`.
|
|
4
|
-
*
|
|
5
|
-
* Unified lint surface: structured violations (test(violations)/apply(violations,ctx)).
|
|
6
|
-
* Тип порушення визначається за `v.message`, не за агрегованим output-рядком.
|
|
7
|
-
*/
|
|
8
|
-
import { appendFileSync, existsSync, readFileSync, writeFileSync } from 'node:fs'
|
|
9
|
-
import { join } from 'node:path'
|
|
10
|
-
|
|
11
|
-
const STYLELINTIGNORE_MISSING_RE = /\.stylelintignore не існує/u
|
|
12
|
-
const STYLELINTIGNORE_NO_DIST_RE = /\.stylelintignore не містить рядка dist\//u
|
|
13
|
-
const NO_STYLELINT_CONFIG_RE = /Немає конфігу stylelint/u
|
|
14
|
-
|
|
15
|
-
/** @type {import('../../../scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
|
|
16
|
-
export const patterns = [
|
|
17
|
-
{
|
|
18
|
-
id: 'style-stylelintignore-create',
|
|
19
|
-
test: violations => violations.some(v => STYLELINTIGNORE_MISSING_RE.test(v.message)),
|
|
20
|
-
apply: (_violations, ctx) => {
|
|
21
|
-
const target = join(ctx.cwd, '.stylelintignore')
|
|
22
|
-
ctx.recordWrite?.(target)
|
|
23
|
-
writeFileSync(target, 'dist/\n', 'utf8')
|
|
24
|
-
return { touchedFiles: [target], message: 'створено .stylelintignore' }
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
id: 'style-stylelintignore-dist-add',
|
|
30
|
-
test: violations => violations.some(v => STYLELINTIGNORE_NO_DIST_RE.test(v.message)),
|
|
31
|
-
apply: (_violations, ctx) => {
|
|
32
|
-
const target = join(ctx.cwd, '.stylelintignore')
|
|
33
|
-
ctx.recordWrite?.(target)
|
|
34
|
-
appendFileSync(target, '\ndist/\n', 'utf8')
|
|
35
|
-
return { touchedFiles: [target], message: 'додано dist/ до .stylelintignore' }
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
id: 'style-pkg-stylelint-add',
|
|
41
|
-
test: violations => violations.some(v => NO_STYLELINT_CONFIG_RE.test(v.message)),
|
|
42
|
-
apply: (_violations, ctx) => {
|
|
43
|
-
const pkgPath = join(ctx.cwd, 'package.json')
|
|
44
|
-
if (!existsSync(pkgPath)) return { touchedFiles: [] }
|
|
45
|
-
let pkg
|
|
46
|
-
try {
|
|
47
|
-
pkg = JSON.parse(readFileSync(pkgPath, 'utf8'))
|
|
48
|
-
} catch {
|
|
49
|
-
return { touchedFiles: [] }
|
|
50
|
-
}
|
|
51
|
-
if (pkg.stylelint) return { touchedFiles: [] }
|
|
52
|
-
ctx.recordWrite?.(pkgPath)
|
|
53
|
-
pkg.stylelint = { extends: '@nitra/stylelint-config' }
|
|
54
|
-
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8')
|
|
55
|
-
return { touchedFiles: [pkgPath], message: 'додано stylelint до package.json' }
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
]
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/** @see ./docs/tooling.md */
|
|
2
|
-
import { existsSync } from 'node:fs'
|
|
3
|
-
import { readFile } from 'node:fs/promises'
|
|
4
|
-
import { join } from 'node:path'
|
|
5
|
-
|
|
6
|
-
import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
|
|
7
|
-
|
|
8
|
-
// Зовнішні файли конфігу stylelint, які підхоплює cosmiconfig. Канон нових
|
|
9
|
-
// JS-конфігів — `.mjs`/`.cjs` (js.mdc), legacy `.js` лишається валідним.
|
|
10
|
-
const STYLELINT_CONFIG_FILES = [
|
|
11
|
-
'.stylelintrc.json',
|
|
12
|
-
'.stylelintrc.js',
|
|
13
|
-
'.stylelintrc.cjs',
|
|
14
|
-
'.stylelintrc.mjs',
|
|
15
|
-
'stylelint.config.js',
|
|
16
|
-
'stylelint.config.cjs',
|
|
17
|
-
'stylelint.config.mjs'
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Альтернатива полю `stylelint` у `package.json` — зовнішній файл конфігу. Якщо
|
|
22
|
-
* поля немає і файлу немає, фейлимося; якщо є хоч щось — пропускаємо. Поле
|
|
23
|
-
* `stylelint.extends == "@nitra/stylelint-config"` сам формат — у Rego.
|
|
24
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
25
|
-
* @param {string} cwd корінь репозиторію
|
|
26
|
-
*/
|
|
27
|
-
async function checkStylelintConfigPresence(reporter, cwd) {
|
|
28
|
-
const { pass, fail } = reporter
|
|
29
|
-
const pkgPath = join(cwd, 'package.json')
|
|
30
|
-
if (!existsSync(pkgPath)) return
|
|
31
|
-
const pkg = JSON.parse(await readFile(pkgPath, 'utf8'))
|
|
32
|
-
const hasField = pkg.stylelint && typeof pkg.stylelint === 'object'
|
|
33
|
-
const hasExternalCfg = STYLELINT_CONFIG_FILES.some(name => existsSync(join(cwd, name)))
|
|
34
|
-
if (hasField || hasExternalCfg) {
|
|
35
|
-
pass('Конфіг stylelint є — у package.json або окремим файлом')
|
|
36
|
-
} else {
|
|
37
|
-
fail('Немає конфігу stylelint — додай "stylelint": { "extends": "@nitra/stylelint-config" } до package.json')
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// `.vscode/extensions.json` (`stylelint.vscode-stylelint`) і `.vscode/settings.json`
|
|
42
|
-
// (`css.validate`/`scss.validate`/`less.validate: false`) — у rego-пакетах
|
|
43
|
-
// `style_lint.vscode_extensions` і `style_lint.vscode_settings`, прогоняє
|
|
44
|
-
// `npx @7n/rules fix`. JS-копії видалено, щоб не було двох джерел істини.
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Перевіряє відповідність проєкту правилам style.mdc
|
|
48
|
-
* @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd тощо)
|
|
49
|
-
* @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
|
|
50
|
-
*/
|
|
51
|
-
export async function lint(ctx) {
|
|
52
|
-
const cwd = ctx.cwd
|
|
53
|
-
const reporter = createViolationReporter(ctx)
|
|
54
|
-
const { pass, fail } = reporter
|
|
55
|
-
|
|
56
|
-
await checkStylelintConfigPresence(reporter, cwd)
|
|
57
|
-
|
|
58
|
-
const ignorePath = join(cwd, '.stylelintignore')
|
|
59
|
-
if (existsSync(ignorePath)) {
|
|
60
|
-
const ignoreContent = await readFile(ignorePath, 'utf8')
|
|
61
|
-
if (ignoreContent.split('\n').some(line => line.trim() === 'dist/')) {
|
|
62
|
-
pass('.stylelintignore існує і містить dist/')
|
|
63
|
-
} else {
|
|
64
|
-
fail('.stylelintignore не містить рядка dist/ — додай його (style.mdc)')
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
fail('.stylelintignore не існує — створи з вмістом: dist/')
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Existence/структуру lint-style.yml вимагає провайдер-плагін @7n/rules-ci-github
|
|
71
|
-
// (mixin style/lint_style_yml) — ядро провайдер-агностичне.
|
|
72
|
-
return reporter.result()
|
|
73
|
-
}
|