@nitra/cursor 12.6.1 → 12.7.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/.claude-template/settings.template.json +1 -1
- package/CHANGELOG.md +10 -0
- package/bin/docs/n-cursor.md +4 -20
- package/bin/n-cursor.js +7 -53
- package/docs/stryker.config.md +20 -28
- package/package.json +1 -1
- package/rules/abie/docs/index.md +1 -0
- package/rules/abie/docs/main.md +29 -0
- package/rules/abie/{fix.mjs → main.mjs} +5 -3
- package/rules/adr/docs/index.md +1 -0
- package/rules/adr/docs/main.md +29 -0
- package/rules/adr/{fix.mjs → main.mjs} +5 -3
- package/rules/bun/docs/index.md +1 -0
- package/rules/bun/docs/main.md +30 -0
- package/rules/bun/js/docs/layout.md +11 -36
- package/rules/bun/{fix.mjs → main.mjs} +5 -3
- package/rules/capacitor/docs/index.md +1 -0
- package/rules/capacitor/docs/main.md +29 -0
- package/rules/capacitor/{fix.mjs → main.mjs} +5 -3
- package/rules/changelog/docs/index.md +1 -0
- package/rules/changelog/docs/main.md +27 -0
- package/rules/changelog/main.mjs +20 -0
- package/rules/ci4/docs/index.md +1 -0
- package/rules/ci4/docs/main.md +30 -0
- package/rules/ci4/main.mjs +20 -0
- package/rules/doc-files/docs/index.md +1 -0
- package/rules/doc-files/docs/main.md +31 -0
- package/rules/doc-files/js/docgen-files-batch.mjs +47 -3
- package/rules/doc-files/js/docgen-scan.mjs +89 -9
- package/rules/doc-files/js/docs/docgen-files-batch.md +15 -15
- package/rules/doc-files/js/docs/docgen-scan.md +34 -34
- package/rules/doc-files/js/docs/index.md +1 -0
- package/rules/doc-files/js/docs/run-lint.md +27 -0
- package/rules/doc-files/{lint/lint.mjs → js/run-lint.mjs} +23 -9
- package/rules/doc-files/{js/lint.mjs → main.mjs} +60 -10
- package/rules/docker/docs/index.md +1 -0
- package/rules/docker/docs/main.md +28 -0
- package/rules/docker/js/docs/lint.md +26 -54
- package/rules/docker/js/lint.mjs +11 -0
- package/rules/docker/lib/docker-hadolint.mjs +1 -1
- package/rules/docker/lib/docs/docker-hadolint.md +16 -173
- package/rules/docker/main.mjs +20 -0
- package/rules/efes/docs/index.md +1 -0
- package/rules/efes/docs/main.md +29 -0
- package/rules/efes/main.mjs +20 -0
- package/rules/feedback/docs/index.md +1 -0
- package/rules/feedback/docs/main.md +30 -0
- package/rules/feedback/main.mjs +20 -0
- package/rules/ga/docs/index.md +1 -0
- package/rules/ga/docs/main.md +29 -0
- package/rules/ga/{lint/lint.mjs → main.mjs} +36 -10
- package/rules/graphql/docs/index.md +1 -0
- package/rules/graphql/docs/main.md +36 -0
- package/rules/graphql/main.mjs +20 -0
- package/rules/hasura/docs/index.md +1 -0
- package/rules/hasura/docs/main.md +30 -0
- package/rules/hasura/main.mjs +20 -0
- package/rules/image-avif/docs/index.md +1 -0
- package/rules/image-avif/docs/main.md +30 -0
- package/rules/image-avif/js/docs/avif_generation.md +20 -233
- package/rules/image-avif/main.mjs +20 -0
- package/rules/image-compress/docs/index.md +1 -0
- package/rules/image-compress/docs/main.md +29 -0
- package/rules/image-compress/js/docs/package_setup.md +12 -11
- package/rules/image-compress/{js/lint.mjs → main.mjs} +21 -5
- package/rules/js-bun-db/docs/index.md +1 -0
- package/rules/js-bun-db/docs/main.md +30 -0
- package/rules/js-bun-db/main.mjs +20 -0
- package/rules/js-bun-redis/docs/index.md +1 -0
- package/rules/js-bun-redis/docs/main.md +29 -0
- package/rules/js-bun-redis/main.mjs +20 -0
- package/rules/js-lint/docs/index.md +1 -0
- package/rules/js-lint/docs/main.md +29 -0
- package/rules/js-lint/js/check.mjs +268 -0
- package/rules/js-lint/js/docs/check.md +39 -0
- package/rules/js-lint/js/docs/index.md +1 -1
- package/rules/js-lint/js/docs/tooling.md +12 -32
- package/rules/js-lint/js/tooling.mjs +1 -265
- package/rules/js-lint/{js/lint.mjs → main.mjs} +19 -2
- package/rules/js-lint-ci/docs/index.md +1 -0
- package/rules/js-lint-ci/docs/main.md +27 -0
- package/rules/js-lint-ci/main.mjs +33 -0
- package/rules/js-mssql/docs/index.md +1 -0
- package/rules/js-mssql/docs/main.md +30 -0
- package/rules/js-mssql/main.mjs +20 -0
- package/rules/js-run/docs/index.md +1 -0
- package/rules/js-run/docs/main.md +30 -0
- package/rules/js-run/main.mjs +20 -0
- package/rules/k8s/docs/index.md +1 -0
- package/rules/k8s/docs/main.md +40 -0
- package/rules/k8s/js/docs/index.md +12 -0
- package/rules/k8s/{lint/lint.mjs → main.mjs} +32 -10
- package/rules/nginx-default-tpl/docs/index.md +1 -0
- package/rules/nginx-default-tpl/docs/main.md +30 -0
- package/rules/nginx-default-tpl/main.mjs +20 -0
- package/rules/npm-module/docs/index.md +1 -0
- package/rules/npm-module/docs/main.md +29 -0
- package/rules/npm-module/js/docs/rule_meta.md +17 -16
- package/rules/npm-module/js/rule_meta.mjs +13 -3
- package/rules/npm-module/main.mjs +20 -0
- package/rules/php/docs/index.md +1 -0
- package/rules/php/docs/main.md +33 -0
- package/rules/php/js/docs/tooling.md +10 -10
- package/rules/php/{lint/lint.mjs → main.mjs} +32 -6
- package/rules/python/docs/index.md +1 -0
- package/rules/python/docs/main.md +31 -0
- package/rules/python/js/docs/tooling.md +17 -17
- package/rules/python/{lint/lint.mjs → main.mjs} +29 -5
- package/rules/rego/docs/index.md +1 -0
- package/rules/rego/docs/main.md +37 -0
- package/rules/rego/{lint/lint.mjs → main.mjs} +27 -5
- package/rules/release/docs/index.md +1 -0
- package/rules/release/docs/main.md +29 -0
- package/rules/release/docs/release.md +0 -3
- package/rules/release/release.mdc +10 -0
- package/rules/rust/docs/index.md +1 -0
- package/rules/rust/docs/main.md +27 -0
- package/rules/rust/{js/lint.mjs → main.mjs} +20 -3
- package/rules/security/docs/index.md +1 -0
- package/rules/security/docs/main.md +28 -0
- package/rules/security/main.mjs +45 -0
- package/rules/style-lint/docs/index.md +1 -0
- package/rules/style-lint/docs/main.md +29 -0
- package/rules/style-lint/{js/lint.mjs → main.mjs} +19 -1
- package/rules/tauri/docs/index.md +1 -0
- package/rules/tauri/docs/main.md +29 -0
- package/rules/tauri/main.mjs +20 -0
- package/rules/test/docs/index.md +1 -0
- package/rules/test/docs/main.md +30 -0
- package/rules/test/main.mjs +20 -0
- package/rules/text/docs/index.md +1 -0
- package/rules/text/docs/main.md +29 -0
- package/rules/text/js/docs/cspell-fix.md +30 -0
- package/rules/text/js/docs/formatting.md +12 -45
- package/rules/text/js/docs/index.md +4 -0
- package/rules/text/js/docs/run-dotenv-linter.md +31 -0
- package/rules/text/js/docs/run-shellcheck.md +28 -0
- package/rules/text/js/docs/run-v8r.md +29 -0
- package/rules/text/{lint/lint.mjs → main.mjs} +38 -9
- package/rules/tool-surface/docs/index.md +1 -0
- package/rules/tool-surface/docs/main.md +29 -0
- package/rules/tool-surface/main.mjs +20 -0
- package/rules/vue/docs/index.md +1 -0
- package/rules/vue/docs/main.md +29 -0
- package/rules/vue/main.mjs +20 -0
- package/rules/worktree/docs/index.md +1 -0
- package/rules/worktree/docs/main.md +28 -0
- package/rules/worktree/main.mjs +20 -0
- package/scripts/docs/index.md +1 -0
- package/scripts/docs/post-tool-use-check.md +29 -0
- package/scripts/docs/sync-claude-config.md +64 -92
- package/scripts/lib/adr/docs/normalize-cli.md +0 -3
- package/scripts/lib/adr/docs/normalize-pipeline.md +0 -3
- package/scripts/lib/docs/gha-workflow.md +25 -317
- package/scripts/lib/docs/index.md +1 -0
- package/scripts/lib/docs/list-project-rules-mdc.md +5 -4
- package/scripts/lib/docs/list-rule-ids.md +15 -148
- package/scripts/lib/docs/read-n-cursor-config-lite.md +12 -16
- package/scripts/lib/docs/run-lint-step.md +13 -13
- package/scripts/lib/docs/run-lint.md +30 -0
- package/scripts/lib/docs/run-rule-cli.md +14 -10
- package/scripts/lib/docs/run-standard-lint.md +27 -10
- package/scripts/lib/docs/run-standard-rule.md +12 -11
- package/scripts/lib/docs/timing-summary.md +11 -12
- package/scripts/lib/docs/worktree-notice.md +0 -3
- package/scripts/lib/fix/docs/index.md +1 -0
- package/scripts/lib/fix/docs/orchestrator.md +23 -18
- package/scripts/lib/fix/docs/run-conformance-check.md +32 -0
- package/scripts/lib/fix/docs/t0.md +10 -9
- package/scripts/lib/fix/orchestrator.mjs +5 -5
- package/scripts/lib/fix/{run-fix-check.mjs → run-conformance-check.mjs} +13 -13
- package/scripts/lib/fix/t0.mjs +3 -3
- package/scripts/lib/list-project-rules-mdc.mjs +1 -1
- package/scripts/lib/list-rule-ids.mjs +12 -3
- package/scripts/lib/read-n-cursor-config-lite.mjs +2 -2
- package/{rules/lint/js/orchestrate.mjs → scripts/lib/run-lint.mjs} +42 -20
- package/scripts/lib/run-rule-cli.mjs +4 -4
- package/scripts/lib/run-standard-lint.mjs +19 -6
- package/scripts/lib/run-standard-rule.mjs +4 -4
- package/scripts/lib/timing-summary.mjs +1 -1
- package/scripts/{post-tool-use-fix.mjs → post-tool-use-check.mjs} +9 -9
- package/scripts/sync-claude-config.mjs +2 -2
- package/rules/changelog/fix.mjs +0 -18
- package/rules/ci4/fix.mjs +0 -18
- package/rules/doc-files/fix.mjs +0 -19
- package/rules/doc-files/js/docs/lint.md +0 -34
- package/rules/doc-files/lint/docs/index.md +0 -11
- package/rules/doc-files/lint/docs/lint.md +0 -35
- package/rules/docker/fix.mjs +0 -18
- package/rules/docker/lint/docs/index.md +0 -11
- package/rules/docker/lint/docs/lint.md +0 -200
- package/rules/docker/lint/lint.mjs +0 -95
- package/rules/efes/fix.mjs +0 -18
- package/rules/feedback/fix.mjs +0 -18
- package/rules/ga/fix.mjs +0 -18
- package/rules/ga/js/docs/lint.md +0 -20
- package/rules/ga/js/lint.mjs +0 -12
- package/rules/ga/lint/docs/index.md +0 -11
- package/rules/ga/lint/docs/lint.md +0 -31
- package/rules/graphql/fix.mjs +0 -18
- package/rules/hasura/fix.mjs +0 -18
- package/rules/image-avif/fix.mjs +0 -18
- package/rules/image-compress/fix.mjs +0 -18
- package/rules/image-compress/js/docs/lint.md +0 -24
- package/rules/js-bun-db/fix.mjs +0 -18
- package/rules/js-bun-redis/fix.mjs +0 -18
- package/rules/js-lint/fix.mjs +0 -18
- package/rules/js-lint/js/docs/lint.md +0 -32
- package/rules/js-lint-ci/fix.mjs +0 -18
- package/rules/js-lint-ci/js/docs/lint.md +0 -22
- package/rules/js-lint-ci/js/lint.mjs +0 -15
- package/rules/js-mssql/fix.mjs +0 -18
- package/rules/js-run/fix.mjs +0 -18
- package/rules/k8s/fix.mjs +0 -18
- package/rules/k8s/js/lint.mjs +0 -14
- package/rules/k8s/lint/docs/index.md +0 -11
- package/rules/k8s/lint/docs/lint.md +0 -413
- package/rules/lint/docs/fix.md +0 -25
- package/rules/lint/docs/index.md +0 -11
- package/rules/lint/fix.mjs +0 -18
- package/rules/lint/js/docs/index.md +0 -11
- package/rules/lint/js/docs/orchestrate.md +0 -31
- package/rules/lint/meta.json +0 -1
- package/rules/nginx-default-tpl/fix.mjs +0 -18
- package/rules/npm-module/fix.mjs +0 -18
- package/rules/php/fix.mjs +0 -18
- package/rules/php/js/docs/lint.md +0 -20
- package/rules/php/js/lint.mjs +0 -15
- package/rules/php/lint/docs/index.md +0 -11
- package/rules/php/lint/docs/lint.md +0 -219
- package/rules/python/fix.mjs +0 -18
- package/rules/python/js/docs/lint.md +0 -21
- package/rules/python/js/lint.mjs +0 -14
- package/rules/python/lint/docs/index.md +0 -11
- package/rules/python/lint/docs/lint.md +0 -29
- package/rules/rego/fix.mjs +0 -18
- package/rules/rego/js/docs/lint.md +0 -21
- package/rules/rego/js/lint.mjs +0 -12
- package/rules/rego/lint/docs/index.md +0 -11
- package/rules/rego/lint/docs/lint.md +0 -208
- package/rules/rust/fix.mjs +0 -18
- package/rules/rust/js/docs/lint.md +0 -21
- package/rules/security/fix.mjs +0 -18
- package/rules/security/js/docs/lint.md +0 -175
- package/rules/security/js/lint.mjs +0 -26
- package/rules/style-lint/fix.mjs +0 -18
- package/rules/style-lint/js/docs/lint.md +0 -31
- package/rules/tauri/fix.mjs +0 -18
- package/rules/test/fix.mjs +0 -18
- package/rules/text/fix.mjs +0 -18
- package/rules/text/js/docs/lint.md +0 -23
- package/rules/text/js/lint.mjs +0 -15
- package/rules/text/lint/docs/cspell-fix.md +0 -32
- package/rules/text/lint/docs/index.md +0 -15
- package/rules/text/lint/docs/lint.md +0 -36
- package/rules/text/lint/docs/run-dotenv-linter.md +0 -161
- package/rules/text/lint/docs/run-shellcheck.md +0 -216
- package/rules/text/lint/docs/run-v8r.md +0 -201
- package/rules/tool-surface/fix.mjs +0 -18
- package/rules/vue/fix.mjs +0 -18
- package/rules/worktree/fix.mjs +0 -18
- /package/rules/release/{fix.mjs → main.mjs} +0 -0
- /package/rules/text/{lint → js}/cspell-fix.mjs +0 -0
- /package/rules/text/{lint → js}/run-dotenv-linter.mjs +0 -0
- /package/rules/text/{lint → js}/run-shellcheck.mjs +0 -0
- /package/rules/text/{lint → js}/run-v8r.mjs +0 -0
|
@@ -2,7 +2,19 @@
|
|
|
2
2
|
import { join, dirname, basename, extname } from 'node:path'
|
|
3
3
|
import { existsSync, readdirSync } from 'node:fs'
|
|
4
4
|
|
|
5
|
-
import { describeFile, isDocCandidate, isSourceFile, scanForDocFiles } from './docgen-scan.mjs'
|
|
5
|
+
import { describeFile, isDocCandidate, isSourceFile, scanForDocFiles, scanOrphanedDocs } from './js/docgen-scan.mjs'
|
|
6
|
+
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
7
|
+
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня (applies → JS-concerns
|
|
11
|
+
* → policy → mdc-refs); `lint()` нижче — lint-поверхня (детект застарілих файлових док), імпл інлайн тут.
|
|
12
|
+
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону
|
|
13
|
+
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
14
|
+
*/
|
|
15
|
+
export function run(ctx) {
|
|
16
|
+
return runStandardRule(import.meta.dirname, ctx)
|
|
17
|
+
}
|
|
6
18
|
|
|
7
19
|
/** Дока живе у `<dir>/docs/<stem>.md`; повертає `<dir>/<stem>` для реверс-мапінгу. */
|
|
8
20
|
const DOC_MD_RE = /(?:^|\/)docs\/[^/]+\.md$/u
|
|
@@ -89,14 +101,52 @@ function collectStale(files, cwd) {
|
|
|
89
101
|
*/
|
|
90
102
|
export async function lint(files, cwd = process.cwd(), { readOnly = false, llmFix = false } = {}) {
|
|
91
103
|
const stale = collectStale(files, cwd)
|
|
92
|
-
|
|
93
|
-
|
|
104
|
+
// Orphan-детект тільки при повному скані; при точковому (files визначено) — не релевантно
|
|
105
|
+
const orphans = files === undefined ? scanOrphanedDocs(cwd) : []
|
|
106
|
+
|
|
107
|
+
if (stale.length === 0 && orphans.length === 0) return 0
|
|
108
|
+
if (readOnly || !llmFix) {
|
|
109
|
+
if (stale.length > 0) reportStale(stale)
|
|
110
|
+
if (orphans.length > 0) {
|
|
111
|
+
const list = orphans.map(f => ` - ${f}`).join('\n')
|
|
112
|
+
process.stderr.write(
|
|
113
|
+
`✗ doc-files: сирітських доків (source видалено) ${orphans.length}:\n${list}\n→ очисти: npx @nitra/cursor fix-doc-files\n`
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
return 1
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// fix-by-default: opportunistic-генерація stale + purge orphans.
|
|
120
|
+
// omlx недоступний → runGenerationBatch друкує причину й повертає !=0;
|
|
121
|
+
// purgeOrphanedDocs не залежить від LLM і виконується завжди.
|
|
122
|
+
if (stale.length > 0) {
|
|
123
|
+
process.stdout.write(`ℹ️ doc-files: ${stale.length} застарілих — пробую авто-фікс (omlx)…\n`)
|
|
124
|
+
}
|
|
125
|
+
const { runGenerationBatch, purgeOrphanedDocs } = await import('./js/docgen-files-batch.mjs')
|
|
126
|
+
if (stale.length > 0) {
|
|
127
|
+
await runGenerationBatch(stale, cwd, { headline: `📋 doc-files: генерація ${stale.length} файл(ів)` })
|
|
128
|
+
}
|
|
129
|
+
if (orphans.length > 0) {
|
|
130
|
+
const deleted = purgeOrphanedDocs(cwd)
|
|
131
|
+
if (deleted > 0) process.stdout.write(`🗑 doc-files: видалено ${deleted} сирітських доки(ів)\n`)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const stillStale = collectStale(files, cwd)
|
|
135
|
+
const stillOrphans = files === undefined ? scanOrphanedDocs(cwd) : []
|
|
136
|
+
if (stillStale.length === 0 && stillOrphans.length === 0) return 0
|
|
137
|
+
if (stillStale.length > 0) reportStale(stillStale)
|
|
138
|
+
if (stillOrphans.length > 0) {
|
|
139
|
+
const list = stillOrphans.map(f => ` - ${f}`).join('\n')
|
|
140
|
+
process.stderr.write(
|
|
141
|
+
`✗ doc-files: сирітських доків (source видалено) ${stillOrphans.length}:\n${list}\n→ очисти: npx @nitra/cursor fix-doc-files\n`
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
return 1
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { runLintDocFilesCli } from './js/run-lint.mjs'
|
|
94
148
|
|
|
95
|
-
|
|
96
|
-
//
|
|
97
|
-
|
|
98
|
-
process.stdout.write(`ℹ️ doc-files: ${stale.length} застарілих — пробую авто-фікс (omlx)…\n`)
|
|
99
|
-
const { runGenerationBatch } = await import('./docgen-files-batch.mjs')
|
|
100
|
-
await runGenerationBatch(stale, cwd, { headline: `📋 doc-files: генерація ${stale.length} файл(ів)` })
|
|
101
|
-
return reportStale(collectStale(files, cwd))
|
|
149
|
+
if (isRunAsCli(import.meta.url)) {
|
|
150
|
+
// Standalone: bun rules/doc-files/main.mjs — повний еквівалент `npx @nitra/cursor check doc-files`.
|
|
151
|
+
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
102
152
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: main.mjs
|
|
4
|
+
resource: npm/rules/docker/main.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: 10e84989
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Модуль виконує перевірку на відповідність логіці JS-зацікавленостей, політикам та посиланням MDC. Запуск правила ініціюється через публічну функцію `run`.
|
|
14
|
+
|
|
15
|
+
## Поведінка
|
|
16
|
+
|
|
17
|
+
1. Викликається функція `run` для виконання перевірки.
|
|
18
|
+
2. Виконання перевірки застосовує логіку, пов'язану з JS-зацікавленостями, політиками та посиланнями MDC.
|
|
19
|
+
3. Якщо скрипт виконується як окрема утиліта, ініціюється повний запуск правила.
|
|
20
|
+
|
|
21
|
+
## Публічний API
|
|
22
|
+
|
|
23
|
+
run — виконує послідовність перевірок: застосовує логіку, перевіряє аспекти JavaScript, застосовує політику та посилання MDC.
|
|
24
|
+
lint — виконує перевірку синтаксису та стилю коду, делегуючи складну логіку зовнішньому модулю.
|
|
25
|
+
|
|
26
|
+
## Гарантії поведінки
|
|
27
|
+
|
|
28
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -3,70 +3,42 @@ type: JS Module
|
|
|
3
3
|
title: lint.mjs
|
|
4
4
|
resource: npm/rules/docker/js/lint.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: bf935f19
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
7
8
|
score: 100
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
## Огляд
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
isDockerfileName
|
|
15
|
-
Перевіряє, чи є вхідний рядок назвою Dockerfile або Containerfile.
|
|
16
|
-
|
|
17
|
-
findDockerfilePaths
|
|
18
|
-
Збирає абсолютні шляхи до Dockerfile або Containerfile від заданого кореня репозиторію, враховуючи виключені шляхи.
|
|
19
|
-
|
|
20
|
-
parseFromStages
|
|
21
|
-
Витягує інструкції FROM з вмісту файлу.
|
|
22
|
-
|
|
23
|
-
splitDockerfileStages
|
|
24
|
-
Розбиває вміст Dockerfile на окремі стадії на основі інструкцій FROM.
|
|
25
|
-
|
|
26
|
-
getMultistageAndRuntimeHint
|
|
27
|
-
Перевіряє, чи має Dockerfile мінімум дві інструкції FROM і чи є фінальний образ дозволеним runtime-образом (docker.mdc).
|
|
13
|
+
Модуль аналізує файли `Dockerfile` та `Containerfile` у репозиторії, використовуючи `isDockerfileName` та `findDockerfilePaths` для ідентифікації конфігурацій. Він розбиває знайдені файли на етапи за допомогою `parseFromStages` та `splitDockerfileStages`. Модуль перевіряє конфігурацію, використовуючи `check` та `lint`, щоб оцінити відповідність стандартам, враховуючи дані з `package.json`. Він визначає інформацію про багатоетапну збірку, теги образів та права користувача, відповідно до вимог (docker.mdc).
|
|
28
14
|
|
|
29
|
-
|
|
30
|
-
Перевіряє наявність інструкцій `bun install` та відсутності `bun build --compile` для виявлення необхідності компіляції бінарника (docker.mdc).
|
|
31
|
-
|
|
32
|
-
getNginxAlpineSlimTagHint
|
|
33
|
-
Перевіряє, чи містить інструкція FROM для образу nginx потрібний тег `alpine-slim` (docker.mdc).
|
|
34
|
-
|
|
35
|
-
getNonRootRuntimeHint
|
|
36
|
-
Перевіряє, чи присутня інструкція USER у фінальній стадії і чи не використовується `root` або `0` для запуску (docker.mdc).
|
|
37
|
-
|
|
38
|
-
check
|
|
39
|
-
Запускає перевірки Dockerfile через hadolint, включаючи перевірки multistage, компіляції, non-root, тегів nginx та загальну валідацію.
|
|
40
|
-
|
|
41
|
-
readNearestDependencies
|
|
42
|
-
Читає залежності з найближчого package.json, розташованого у каталогах Dockerfile або вище.
|
|
15
|
+
## Поведінка
|
|
43
16
|
|
|
44
|
-
|
|
45
|
-
|
|
17
|
+
isDockerfileName визначає, чи є наданий шлях назвою Dockerfile або Containerfile.
|
|
18
|
+
findDockerfilePaths збирає відсортований список абсолютних шляхів до всіх Dockerfile/Containerfile, ігноруючи вказані шляхи каталогів.
|
|
19
|
+
parseFromStages витягує список усіх інструкцій `FROM <image>` з вмісту Dockerfile/Containerfile.
|
|
20
|
+
splitDockerfileStages розбиває вміст Dockerfile/Containerfile на окремі етапи (stages) на основі інструкцій `FROM`.
|
|
21
|
+
getMultistageAndRuntimeHint перевіряє, чи відповідає структура Dockerfile вимогам multistage build та дозволеним образам для фінального runtime (docker.mdc).
|
|
22
|
+
getBunCompileHint перевіряє, чи виконано необхідну компіляцію застосунку у бінарник для bun-проєктів, якщо фінальний образ — alpine (docker.mdc).
|
|
23
|
+
getNginxAlpineSlimTagHint перевіряє, чи використовується тег `alpine-slim` для nginx-образів (docker.mdc).
|
|
24
|
+
getNonRootRuntimeHint перевіряє, чи має фінальний stage інструкцію `USER <non-root>` для забезпечення не превілейованого образу (docker.mdc).
|
|
25
|
+
check перевіряє всі знайдені Dockerfile/Containerfile, виконуючи перевірки на відповідність стандартам, включаючи hadolint (docker.mdc).
|
|
26
|
+
lint оркеструє обхід репозиторію та викликає `check` для всіх знайдених Dockerfile/Containerfile.
|
|
46
27
|
|
|
47
28
|
## Публічний API
|
|
48
29
|
|
|
49
|
-
isDockerfileName —
|
|
50
|
-
findDockerfilePaths — збирає повні шляхи до файлів `Dockerfile` або `Containerfile` від
|
|
51
|
-
parseFromStages — витягує всі
|
|
52
|
-
splitDockerfileStages — розділяє
|
|
53
|
-
getMultistageAndRuntimeHint —
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
getNginxAlpineSlimTagHint — перевіряє, чи містить `FROM` для nginx-образу (`mirror.gcr.io/nginxinc/nginx-unprivileged`) тег `alpine-slim` (`docker.mdc`).
|
|
60
|
-
getNonRootRuntimeHint — перевіряє вимогу "non-root" у фінальному runtime-етапі (`docker.mdc`).
|
|
61
|
-
Очікування — перевіряє, чи містить build stage інструкцію `bun build --compile`.
|
|
62
|
-
Очікування — перевіряє, чи відсутні виклики `bun` у фінальному етапі (залишкові інструменти збірки).
|
|
63
|
-
Очікування — перевіряє, чи містить фінальний етап інструкцію `USER <name|uid>`.
|
|
64
|
-
Очікування — перевіряє, чи користувач у фінальному етапі не є `root` і не дорівнює `0`.
|
|
65
|
-
check — виконує перевірку через hadolint (`docker.mdc`).
|
|
30
|
+
isDockerfileName — визначає, чи є файл `Dockerfile` або `Containerfile` у поточному каталозі.
|
|
31
|
+
findDockerfilePaths — збирає повні шляхи до файлів `Dockerfile` або `Containerfile` від кореня робочого каталогу.
|
|
32
|
+
parseFromStages — витягує всі образи, зазначені в інструкціях `FROM` у файлі.
|
|
33
|
+
splitDockerfileStages — розділяє вміст файлу на окремі етапи згідно з інструкціями `FROM`.
|
|
34
|
+
getMultistageAndRuntimeHint — оцінює відповідність структури файлу: мінімум два етапи `FROM` та відповідність базових образів списку дозволених у `docker.mdc` (з додатковим дозволом для `bun` у випадку нативного `.node-аддону`).
|
|
35
|
+
getBunCompileHint — перевіряє, чи вимагає проєкт на базі Bun компіляції в бінарний файл для бекенд-рантайму.
|
|
36
|
+
getNginxAlpineSlimTagHint — перевіряє, чи використовується тег `alpine-slim` для образів Nginx, як зазначено в `docker.mdc`.
|
|
37
|
+
getNonRootRuntimeHint — перевіряє, чи встановлено користувача, відмінного від `root` (не `0`), у фінальному етапі виконання, згідно з `docker.mdc`.
|
|
38
|
+
check — виконує статичний аналіз файлу `Dockerfile`/`Containerfile` за допомогою hadolint (`docker.mdc`).
|
|
39
|
+
lint — запускає стандартний лінтер для Docker-файлів через адаптер `n-cursor lint docker`.
|
|
66
40
|
|
|
67
41
|
## Гарантії поведінки
|
|
68
42
|
|
|
69
|
-
- Read-only:
|
|
43
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
70
44
|
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
71
|
-
- За невдалої перевірки повертає `false`/`null` замість винятку.
|
|
72
|
-
- Не звертається до мережі.
|
package/rules/docker/js/lint.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @see ./docs/lint.md */
|
|
2
2
|
import { readFile } from 'node:fs/promises'
|
|
3
3
|
import { basename, dirname, join } from 'node:path'
|
|
4
|
+
import { runStandardLint } from '../../../scripts/lib/run-standard-lint.mjs'
|
|
4
5
|
|
|
5
6
|
import { getMirrorGcrHint, getFromImageToken } from '../lib/docker-mirror.mjs'
|
|
6
7
|
import { getNativeAddonDeps, getNativeAddonNoCompileHint } from '../lib/docker-native-addon.mjs'
|
|
@@ -369,3 +370,13 @@ async function checkDockerfile(reporter, root, abs) {
|
|
|
369
370
|
fail(`${rel} (${via})${detail}`)
|
|
370
371
|
}
|
|
371
372
|
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Оркестраторний адаптер `n-cursor lint docker`: обгортає `check()` у `runStandardLint` (лок).
|
|
376
|
+
* @param {string[] | undefined} _files ігнорується (whole-repo обхід)
|
|
377
|
+
* @param {string} [cwd] корінь
|
|
378
|
+
* @returns {Promise<number>} exit code
|
|
379
|
+
*/
|
|
380
|
+
export function lint(_files, cwd = process.cwd()) {
|
|
381
|
+
return runStandardLint(import.meta.dirname, () => check(cwd))
|
|
382
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Відносні шляхи з прямими слешами; hadolint резолвиться через `ensureTool`
|
|
5
5
|
* (PATH → кеш → авто-install brew/scoop/GitHub Release per-platform). Docker-fallback
|
|
6
6
|
* прибрано — hadolint ставиться як **нативний бінарник**, без `docker run`.
|
|
7
|
-
* Використовується
|
|
7
|
+
* Використовується `../js/lint.mjs` (правило `n-cursor lint docker` / check-docker).
|
|
8
8
|
*/
|
|
9
9
|
import { spawnSync } from 'node:child_process'
|
|
10
10
|
import { relative, sep } from 'node:path'
|
|
@@ -3,186 +3,29 @@ type: JS Module
|
|
|
3
3
|
title: docker-hadolint.mjs
|
|
4
4
|
resource: npm/rules/docker/lib/docker-hadolint.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: ebab2135
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 90
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Спільна логіка виклику hadolint для шляхів до Dockerfile. Модуль створює стандартизовані відносні шляхи з прямими слешами. Він ініціює перевірку Dockerfile, використовуючи hadolint як нативний бінарник, який резолвиться через `ensureTool` (PATH → кеш → авто-install brew/scoop/GitHub Release per-platform). Для отримання інформації про встановлення можна звертатися до https://github.com/hadolint/hadolint/releases. Публічна функція `lintDockerfileWithHadolint` виконує перевірку за правилом `n-cursor lint docker` / check-docker.
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
- Розв’язання шляху до бінарника делеговано в `ensureTool('hadolint')`, який реалізує ланцюжок `PATH → локальний кеш інструментів → авто-install` через `brew` / `scoop` / GitHub Release, відповідно до платформи.
|
|
15
|
-
- Якщо `ensureTool` падає (інструмент відсутній і авто-install вимкнено через `N_CURSOR_NO_AUTO_INSTALL` або фізично не вдався), модуль **не кидає виняток назовні**, а повертає структурований результат `{ ok: false, stderr: <інструкція з установки> }`. Це дозволяє викликачам однаково обробляти і реальні порушення hadolint, і відсутність інструмента.
|
|
16
|
-
- Шляхи у виводі нормалізуються через `posixRel` (відносно `root`, з прямими слешами `/`), щоб лог і повідомлення про помилки були стабільними між macOS / Linux / Windows.
|
|
15
|
+
## Поведінка
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
posixRel
|
|
18
|
+
Створює відносний шлях від кореня з використанням прямих слешів.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
lintDockerfileWithHadolint
|
|
21
|
+
Запускає hadolint як нативний бінарник для перевірки Dockerfile. Якщо не вдається знайти hadolint, повертає помилку з інструкцією для встановлення (наприклад, https://github.com/hadolint/hadolint/releases).
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
| ------------------------------------------- | -------- | ---------------------------------------------------------------------------------- |
|
|
24
|
-
| `posixRel(root, absPath)` | function | Перетворити абсолютний шлях на відносний від `root` з прямими слешами. |
|
|
25
|
-
| `lintDockerfileWithHadolint(root, absPath)` | function | Запустити `hadolint` для одного `Dockerfile` і повернути структурований результат. |
|
|
23
|
+
## Публічний API
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
* posixRel — Генерує абсолютний шлях від кореня з використанням лише слешів, забезпечуючи стабільність незалежно від операційної системи.
|
|
26
|
+
* lintDockerfileWithHadolint — Запускає інструмент hadolint для аналізу Dockerfile. Якщо інструмент не знайдено у системних шляхах, він намагається встановити його. У разі невдачі встановлення або відключення автоматичного встановлення, повертає помилку, надаючи користувачеві підказку для ручного запуску (детальніше про інструмент можна знайти на https://github.com/hadolint/hadolint/releases).
|
|
28
27
|
|
|
29
|
-
##
|
|
28
|
+
## Гарантії поведінки
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Утиліта нормалізації шляхів для стабільного логування й передачі в `hadolint`.
|
|
34
|
-
|
|
35
|
-
**Сигнатура:**
|
|
36
|
-
|
|
37
|
-
```js
|
|
38
|
-
export function posixRel(root: string, absPath: string): string
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Параметри:**
|
|
42
|
-
|
|
43
|
-
- `root` — абсолютний шлях до кореня репозиторію (або будь-якого опорного каталогу), відносно якого треба отримати шлях.
|
|
44
|
-
- `absPath` — абсолютний шлях до файлу, який треба представити відносно `root`.
|
|
45
|
-
|
|
46
|
-
**Повертає:**
|
|
47
|
-
|
|
48
|
-
- Рядок із відносним шляхом, де всі системні розділювачі (`path.sep`) замінено на прямий слеш `/`. На POSIX-системах результат фактично збігається з `path.relative`, на Windows — конвертує `\` на `/`.
|
|
49
|
-
|
|
50
|
-
**Алгоритм:**
|
|
51
|
-
|
|
52
|
-
1. Викликає `relative(root, absPath)` з `node:path` для обчислення відносного шляху.
|
|
53
|
-
2. Розбиває результат за поточним `sep` (`path.sep`) і склеює знову через `'/'`.
|
|
54
|
-
|
|
55
|
-
**Side effects:** немає; функція чиста й детермінована.
|
|
56
|
-
|
|
57
|
-
**Примітка:** функція не валідовує, чи `absPath` справді абсолютний і чи він знаходиться під `root` — у такому випадку `relative` поверне відносний шлях із `..`, що теж буде нормалізовано до прямих слешів.
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
### `lintDockerfileWithHadolint(root, absPath)`
|
|
62
|
-
|
|
63
|
-
Основна точка входу модуля: виконує `hadolint` для одного `Dockerfile` і повертає уніфікований результат.
|
|
64
|
-
|
|
65
|
-
**Сигнатура:**
|
|
66
|
-
|
|
67
|
-
```js
|
|
68
|
-
export function lintDockerfileWithHadolint(
|
|
69
|
-
root: string,
|
|
70
|
-
absPath: string
|
|
71
|
-
): {
|
|
72
|
-
ok: boolean,
|
|
73
|
-
stdout: string,
|
|
74
|
-
stderr: string,
|
|
75
|
-
via: string
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**Параметри:**
|
|
80
|
-
|
|
81
|
-
- `root` — абсолютний шлях до кореня репозиторію. Використовується одночасно як `cwd` для дочірнього процесу і як база для `posixRel`.
|
|
82
|
-
- `absPath` — абсолютний шлях до конкретного `Dockerfile` (або файлу, який треба перевірити hadolint’ом).
|
|
83
|
-
|
|
84
|
-
**Повертає об’єкт із полями:**
|
|
85
|
-
|
|
86
|
-
- `ok` — `true`, якщо `hadolint` завершився з кодом виходу `0` (порушень немає). `false` — у будь-якому іншому випадку: інструмент знайшов проблеми, не запустився, або не зміг бути встановленим/знайденим.
|
|
87
|
-
- `stdout` — stdout процесу hadolint як рядок (UTF-8). При помилці отримання інструмента — порожній рядок.
|
|
88
|
-
- `stderr` — stderr процесу hadolint як рядок. Якщо інструмент не вдалося отримати, тут міститься українська інструкція з установки (`brew install hadolint` / `scoop install hadolint` / посилання на GitHub Releases) разом із повідомленням оригінальної помилки.
|
|
89
|
-
- `via` — завжди константа `'hadolint'`. Поле залишене для зворотної сумісності з API, де раніше міг бути ще варіант на кшталт `'docker'`; зараз інших значень не повертається.
|
|
90
|
-
|
|
91
|
-
**Алгоритм:**
|
|
92
|
-
|
|
93
|
-
1. Обчислює відносний шлях `rel = posixRel(root, absPath)`.
|
|
94
|
-
2. Намагається отримати шлях до бінарника через `hadolintPath = ensureTool('hadolint')`.
|
|
95
|
-
- Якщо `ensureTool` кидає виняток, функція **перехоплює** його і повертає об’єкт з `ok: false`, порожнім `stdout`, інструктивним `stderr` (текст помилки + поради з установки) і `via: 'hadolint'`. На цьому виконання завершується.
|
|
96
|
-
3. Викликає `spawnSync(hadolintPath, [rel], { cwd: root, encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 })`:
|
|
97
|
-
- `cwd: root` — щоб hadolint бачив правильну робочу директорію і `rel` коректно резолвився.
|
|
98
|
-
- `encoding: 'utf8'` — `stdout`/`stderr` одразу приходять як рядки, а не `Buffer`.
|
|
99
|
-
- `maxBuffer: 10 МіБ` — захист від великих обсягів виводу при множинних попередженнях.
|
|
100
|
-
4. Формує результат: `ok = local.status === 0`, `stdout`/`stderr` приходять з процесу (з фолбеком на порожній рядок через `??`), `via: 'hadolint'`.
|
|
101
|
-
|
|
102
|
-
**Side effects:**
|
|
103
|
-
|
|
104
|
-
- Може ініціювати **авто-install** `hadolint` через `ensureTool` (мережа, brew/scoop/завантаження GitHub Release, запис у локальний кеш інструментів), якщо інструмент відсутній і авто-install не вимкнено `N_CURSOR_NO_AUTO_INSTALL`.
|
|
105
|
-
- Синхронно запускає дочірній процес `hadolint`, що блокує цикл подій Node.js до завершення (через `spawnSync`).
|
|
106
|
-
- Не пише в stdout/stderr поточного процесу самостійно — увесь вивід hadolint повертає викликачу.
|
|
107
|
-
- Не змінює `process.cwd()` поточного процесу (тільки `cwd` дочірнього).
|
|
108
|
-
|
|
109
|
-
**Обробка помилок:**
|
|
110
|
-
|
|
111
|
-
- Виняток від `ensureTool` ловиться і конвертується у м’який `ok: false` з підказкою.
|
|
112
|
-
- Помилки запуску `spawnSync` (наприклад, права доступу) **не обгортаються окремо**: у такому разі `spawnSync` повертає об’єкт з `status: null` і `error`-полем, відповідно `ok` буде `false`, а `stdout`/`stderr` — порожніми (через `??`). Поле `error` об’єкта `spawnSync` у результат не транслюється.
|
|
113
|
-
- Ненульовий `status` від самого `hadolint` (тобто знайдені порушення) трактується як `ok: false`, але `stderr`/`stdout` несуть звіт hadolint для подальшого парсингу/виводу користувачу.
|
|
114
|
-
|
|
115
|
-
## Залежності
|
|
116
|
-
|
|
117
|
-
### Node.js (стандартні)
|
|
118
|
-
|
|
119
|
-
- `node:child_process` — імпортується `spawnSync` для синхронного запуску `hadolint`.
|
|
120
|
-
- `node:path` — імпортуються `relative` і `sep` для побудови відносного шляху з нормалізацією роздільників.
|
|
121
|
-
|
|
122
|
-
### Внутрішні (моноpепо)
|
|
123
|
-
|
|
124
|
-
- `../../../scripts/lib/ensure-tool.mjs` — функція `ensureTool(name)`, яка:
|
|
125
|
-
- повертає абсолютний шлях до бінарника;
|
|
126
|
-
- намагається знайти його у `PATH`, у локальному кеші інструментів;
|
|
127
|
-
- за потреби виконує авто-install через `brew` (macOS), `scoop` (Windows) чи GitHub Release (Linux);
|
|
128
|
-
- кидає виняток, якщо інструмент недоступний і авто-install неможливий / вимкнено `N_CURSOR_NO_AUTO_INSTALL`.
|
|
129
|
-
|
|
130
|
-
### Зовнішні (runtime)
|
|
131
|
-
|
|
132
|
-
- Бінарник `hadolint` (нативний; брати з `brew`, `scoop`, GitHub Release). **Не** використовується `docker run hadolint/hadolint` — Docker-fallback явно прибраний.
|
|
133
|
-
|
|
134
|
-
### Імпорт-споживачі (всередині правила `docker`)
|
|
135
|
-
|
|
136
|
-
- `./check.mjs` — скіл `check-docker`: разова перевірка обраних `Dockerfile`-ів.
|
|
137
|
-
- `../../lint/lint.mjs` — скіл `run-docker`: інтеграція в загальний `lint`-конвеєр.
|
|
138
|
-
|
|
139
|
-
## Потік виконання / Використання
|
|
140
|
-
|
|
141
|
-
Типовий сценарій використання модуля викликачем:
|
|
142
|
-
|
|
143
|
-
1. Викликач (наприклад, `check-docker` або `run-docker`) визначає `root` репозиторію і список абсолютних шляхів до `Dockerfile`-ів.
|
|
144
|
-
2. Для кожного шляху викликається `lintDockerfileWithHadolint(root, absPath)`.
|
|
145
|
-
3. Модуль:
|
|
146
|
-
- нормалізує шлях у POSIX-форму (`posixRel`);
|
|
147
|
-
- резолвить `hadolint` через `ensureTool` (можливо з авто-install);
|
|
148
|
-
- синхронно запускає `hadolint <rel>` у `cwd = root`;
|
|
149
|
-
- повертає `{ ok, stdout, stderr, via }`.
|
|
150
|
-
4. Викликач інтерпретує результат:
|
|
151
|
-
- `ok === true` → файл чистий, нічого не виводити (або вивести позитивний статус);
|
|
152
|
-
- `ok === false` → показати `stdout`/`stderr` користувачу, зарахувати як порушення; якщо `stderr` містить інструкцію з установки — повідомити користувача, як отримати інструмент.
|
|
153
|
-
|
|
154
|
-
### Приклад використання
|
|
155
|
-
|
|
156
|
-
```js
|
|
157
|
-
import { lintDockerfileWithHadolint, posixRel } from './docker-hadolint.mjs'
|
|
158
|
-
|
|
159
|
-
const root = process.cwd()
|
|
160
|
-
const absPath = '/abs/path/to/repo/services/api/Dockerfile'
|
|
161
|
-
|
|
162
|
-
const result = lintDockerfileWithHadolint(root, absPath)
|
|
163
|
-
|
|
164
|
-
if (!result.ok) {
|
|
165
|
-
console.error(`hadolint failed for ${posixRel(root, absPath)} (via=${result.via})`)
|
|
166
|
-
if (result.stdout) console.error(result.stdout)
|
|
167
|
-
if (result.stderr) console.error(result.stderr)
|
|
168
|
-
process.exitCode = 1
|
|
169
|
-
}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Поведінка за відсутності `hadolint`
|
|
173
|
-
|
|
174
|
-
- Якщо `hadolint` відсутній і `N_CURSOR_NO_AUTO_INSTALL` **не** виставлена, `ensureTool` спробує встановити бінарник автоматично (за платформою).
|
|
175
|
-
- Якщо `N_CURSOR_NO_AUTO_INSTALL` виставлена або авто-install не вдався, `lintDockerfileWithHadolint` повертає:
|
|
176
|
-
- `ok: false`,
|
|
177
|
-
- `stdout: ''`,
|
|
178
|
-
- `stderr: 'Не вдалося отримати hadolint (<повідомлення>). Встанови: brew install hadolint (macOS) / scoop install hadolint (Windows) / https://github.com/hadolint/hadolint/releases (Linux).'`,
|
|
179
|
-
- `via: 'hadolint'`.
|
|
180
|
-
- Завдяки м’якій обробці викликач може коректно показати інструкцію користувачу замість аварійного завершення.
|
|
181
|
-
|
|
182
|
-
### Особливості та обмеження
|
|
183
|
-
|
|
184
|
-
- **Синхронність**: усі виклики блокуючі (`spawnSync`). Для пакетної перевірки сотень файлів варіант — викликати модуль із зовнішнього оркестратора, який сам керує паралелізмом (з урахуванням обмежень середовища).
|
|
185
|
-
- **Один файл за виклик**: функція передає у `hadolint` рівно один аргумент `rel`. Для масової перевірки слід викликати функцію в циклі — це свідомий вибір, щоб уніфікувати результат і прив’язку до конкретного файлу.
|
|
186
|
-
- **Розмір буфера**: `maxBuffer = 10 МіБ` достатньо для звичайних `Dockerfile`-звітів; для аномально великих виводів значення доведеться змінювати на рівні форку модуля.
|
|
187
|
-
- **`via` константно `'hadolint'`**: поле залишене для майбутньої сумісності, але наразі ніколи не приймає інших значень.
|
|
188
|
-
- **Стабільність шляхів**: завдяки `posixRel` повідомлення про порушення містять однакові шляхи з прямими слешами на всіх ОС — це важливо для дифу логів у CI.
|
|
30
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
31
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
+
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня: applies →
|
|
6
|
+
* JS-concerns → policy → mdc-refs. `lint()` — lint-поверхня; важка реалізація лишається
|
|
7
|
+
* у js/-хелпері `js/lint.mjs` (main.mjs тонкий — лише re-export).
|
|
8
|
+
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону
|
|
9
|
+
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
10
|
+
*/
|
|
11
|
+
export function run(ctx) {
|
|
12
|
+
return runStandardRule(import.meta.dirname, ctx)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { lint } from './js/lint.mjs'
|
|
16
|
+
|
|
17
|
+
if (isRunAsCli(import.meta.url)) {
|
|
18
|
+
// Standalone: bun rules/<id>/main.mjs — повний еквівалент `npx @nitra/cursor check <id>`.
|
|
19
|
+
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
20
|
+
}
|
package/rules/efes/docs/index.md
CHANGED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: main.mjs
|
|
4
|
+
resource: npm/rules/efes/main.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: 762b6875
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Модуль перевіряє відповідність коду визначеним правилам, використовуючи конфігурацію з meta.json. Він виконує аналіз, який може бути ініційований через публічну функцію run. Модуль є read-only, тобто не здійснює записів у файлову систему чи бази даних. Кешування даних відбувається у межах одного прогону. При завершенні роботи як окремий інструмент, він надає підсумковий звіт.
|
|
14
|
+
|
|
15
|
+
## Поведінка
|
|
16
|
+
|
|
17
|
+
1. Виконує перевірку правила, застосовуючи логіку, визначену в конфігах, зокрема `meta.json`.
|
|
18
|
+
2. Виконує перевірку, що включає аналіз JS-залежностей та політик.
|
|
19
|
+
3. Виконує перевірку, що включає посилання на MDC.
|
|
20
|
+
4. Якщо код запускається як окремий інструмент (standalone), виконується повний цикл роботи з конфігурацією, білистами дозволених елементів та підсумковим звітом, завершуючи роботу з відповідним кодом виходу.
|
|
21
|
+
|
|
22
|
+
## Публічний API
|
|
23
|
+
|
|
24
|
+
run — єдиний вхідний пункт правила; виконує послідовність перевірок: застосовує JS-занепокоєння, застосовує політику, перевіряє посилання MDC.
|
|
25
|
+
|
|
26
|
+
## Гарантії поведінки
|
|
27
|
+
|
|
28
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
29
|
+
- Кешує результати в межах одного прогону.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
+
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня: applies →
|
|
6
|
+
* JS-concerns → policy → mdc-refs (через runStandardRule). Lint-поверхні правило не має
|
|
7
|
+
* (`meta.json` без `lint`), тож експорту `lint` тут немає.
|
|
8
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
9
|
+
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
10
|
+
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
11
|
+
*/
|
|
12
|
+
export function run(ctx) {
|
|
13
|
+
return runStandardRule(import.meta.dirname, ctx)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (isRunAsCli(import.meta.url)) {
|
|
17
|
+
// Standalone: bun rules/<id>/main.mjs — повний еквівалент `npx @nitra/cursor check <id>`
|
|
18
|
+
// (config-loading + whitelist + summary): library-роль (run) + standalone-роль (CLI-блок).
|
|
19
|
+
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
20
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: main.mjs
|
|
4
|
+
resource: npm/rules/feedback/main.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: 762b6875
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Модуль перевіряє відповідність даних заданим правилам, використовуючи конфігурації, політики та посилання на MDC, які визначаються у meta.json. Він застосовує білий список для формування підсумку. Публічний інтерфейс run завершує роботу, інформуючи про успішне виконання або виявлені порушення. Модуль є Read-only і не виконує записів у файлову систему чи бази даних.
|
|
14
|
+
|
|
15
|
+
## Поведінка
|
|
16
|
+
|
|
17
|
+
1. Викликається функція `run` для виконання перевірки.
|
|
18
|
+
2. Виконання `run` застосовує логіку правила, включаючи перевірку конфігурацій, політик та посилання на MDC.
|
|
19
|
+
3. Якщо скрипт виконується як окрема програма (CLI), виконується логіка оркестрації правила.
|
|
20
|
+
4. Оркестрація правила зчитує конфігурації, застосовує білий список та генерує підсумок.
|
|
21
|
+
5. Вихідний код завершує роботу з кодом, що вказує на успіх або наявність порушень.
|
|
22
|
+
|
|
23
|
+
## Публічний API
|
|
24
|
+
|
|
25
|
+
run — виконує основну логіку правила: застосовує перевірки JS-зацікавленостей, політики та посилання на MDC.
|
|
26
|
+
|
|
27
|
+
## Гарантії поведінки
|
|
28
|
+
|
|
29
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
30
|
+
- Кешує результати в межах одного прогону.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { isRunAsCli, runRuleCli } from '../../scripts/lib/run-rule-cli.mjs'
|
|
2
|
+
import { runStandardRule } from '../../scripts/lib/run-standard-rule.mjs'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Єдиний entrypoint правила (ADR 2026-06-21). `run()` — check-поверхня: applies →
|
|
6
|
+
* JS-concerns → policy → mdc-refs (через runStandardRule). Lint-поверхні правило не має
|
|
7
|
+
* (`meta.json` без `lint`), тож експорту `lint` тут немає.
|
|
8
|
+
* Library mode: викликається CLI orchestration через `import + run(ctx)`.
|
|
9
|
+
* @param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx] контекст прогону (walkCache тощо)
|
|
10
|
+
* @returns {Promise<number>} 0 — OK, 1 — порушення
|
|
11
|
+
*/
|
|
12
|
+
export function run(ctx) {
|
|
13
|
+
return runStandardRule(import.meta.dirname, ctx)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (isRunAsCli(import.meta.url)) {
|
|
17
|
+
// Standalone: bun rules/<id>/main.mjs — повний еквівалент `npx @nitra/cursor check <id>`
|
|
18
|
+
// (config-loading + whitelist + summary): library-роль (run) + standalone-роль (CLI-блок).
|
|
19
|
+
process.exitCode = await runRuleCli(import.meta.dirname)
|
|
20
|
+
}
|
package/rules/ga/docs/index.md
CHANGED