@nitra/cursor 5.0.3 → 5.2.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 +22 -0
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +15 -9
- package/CHANGELOG.md +18 -1
- package/bin/n-cursor.js +73 -16
- package/docs/stryker.config.md +6 -0
- package/docs/vitest.config.md +6 -0
- package/lib/docs/llm.md +29 -0
- package/lib/docs/omlx.md +32 -0
- package/lib/llm.mjs +137 -0
- package/lib/models.mjs +9 -1
- package/lib/omlx.mjs +147 -0
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +6 -0
- package/rules/abie/js/docs/applies.md +6 -0
- package/rules/abie/js/docs/env_dns.md +25 -22
- package/rules/abie/js/docs/firebase_hosting.md +6 -0
- package/rules/abie/js/docs/hc_pairing.md +21 -25
- package/rules/abie/js/docs/ua_http_route.md +27 -19
- package/rules/abie/js/docs/ua_node_selector.md +24 -19
- package/rules/abie/lib/docs/enabled.md +13 -7
- package/rules/abie/lib/docs/env-dns.md +9 -3
- package/rules/abie/lib/docs/hc-yaml.md +6 -0
- package/rules/abie/lib/docs/http-route.md +6 -0
- package/rules/abie/lib/docs/k8s-tree.md +6 -0
- package/rules/abie/lib/docs/kustomization-patches.md +6 -0
- package/rules/abie/lib/docs/overlay-paths.md +6 -0
- package/rules/abie/lib/docs/yaml.md +6 -0
- package/rules/adr/docs/fix.md +6 -0
- package/rules/adr/js/docs/hooks.md +29 -244
- package/rules/bun/docs/fix.md +6 -0
- package/rules/bun/js/docs/layout.md +37 -375
- package/rules/capacitor/docs/fix.md +22 -108
- package/rules/capacitor/js/docs/platforms.md +62 -268
- package/rules/changelog/docs/fix.md +6 -0
- package/rules/changelog/lib/docs/package-manifest.md +6 -0
- package/rules/ci4/docs/fix.md +23 -165
- package/rules/ci4/js/docs/marksman_config.md +9 -1
- package/rules/docker/docs/fix.md +6 -0
- package/rules/docker/js/docs/lint.md +55 -239
- package/rules/docker/lib/docs/docker-hadolint.md +6 -0
- package/rules/docker/lib/docs/docker-mirror.md +6 -0
- package/rules/docker/lib/docs/docker-native-addon.md +6 -0
- package/rules/docker/lib/docs/docker-nginx-user.md +6 -0
- package/rules/docker/lint/docs/lint.md +9 -1
- package/rules/efes/docs/fix.md +6 -0
- package/rules/ga/lint/docs/lint.md +6 -0
- package/rules/graphql/docs/fix.md +6 -0
- package/rules/graphql/lib/docs/graphql-gql-scan.md +6 -0
- package/rules/image-avif/docs/fix.md +6 -0
- package/rules/image-avif/js/docs/avif_generation.md +6 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +9 -3
- package/rules/js-bun-redis/lib/docs/redis-imports.md +6 -0
- package/rules/js-lint/js/docs/utils_imports.md +6 -0
- package/rules/js-lint-ci/docs/fix.md +7 -1
- package/rules/js-mssql/docs/fix.md +6 -0
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +6 -0
- package/rules/js-run/docs/fix.md +6 -0
- package/rules/js-run/lib/docs/bunyan-imports.md +6 -0
- package/rules/js-run/lib/docs/check-env-scan.md +6 -0
- package/rules/js-run/lib/docs/conn-file-rules.md +6 -0
- package/rules/js-run/lib/docs/conn-imports-scan.md +6 -0
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +6 -0
- package/rules/js-run/lib/docs/temporal-scan.md +6 -0
- package/rules/k8s/docs/fix.md +6 -0
- package/rules/k8s/lint/docs/lint.md +6 -0
- package/rules/nginx-default-tpl/docs/fix.md +6 -0
- package/rules/npm-module/js/docs/header_doc_pointer.md +7 -0
- package/rules/npm-module/js/header_doc_pointer.mjs +2 -8
- package/rules/php/docs/fix.md +6 -0
- package/rules/php/lint/docs/lint.md +6 -0
- package/rules/python/docs/fix.md +6 -0
- package/rules/python/lint/docs/lint.md +6 -0
- package/rules/rego/lint/docs/lint.md +6 -0
- package/rules/release/docs/change.md +6 -0
- package/rules/release/docs/fix.md +6 -0
- package/rules/release/docs/release.md +6 -0
- package/rules/release/lib/docs/aggregate.md +6 -0
- package/rules/release/lib/docs/change-file.md +6 -0
- package/rules/release/lib/docs/fallback.md +6 -0
- package/rules/rust/lib/docs/has-cargo-toml.md +6 -0
- package/rules/security/docs/fix.md +7 -1
- package/rules/security/js/docs/lint.md +6 -0
- package/rules/style-lint/docs/fix.md +6 -0
- package/rules/tauri/docs/fix.md +6 -0
- package/rules/test/docs/fix.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +6 -0
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +6 -0
- package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +6 -0
- package/rules/text/docs/fix.md +6 -0
- package/rules/text/lint/docs/lint.md +6 -0
- package/rules/text/lint/docs/run-dotenv-linter.md +6 -0
- package/rules/text/lint/docs/run-shellcheck.md +6 -0
- package/rules/text/lint/docs/run-v8r.md +6 -0
- package/rules/vue/lib/docs/vue-forbidden-imports.md +6 -0
- package/scripts/coverage-classify/cache.mjs +1 -1
- package/scripts/coverage-classify/docs/apply.md +6 -0
- package/scripts/coverage-classify/docs/cache.md +6 -0
- package/scripts/coverage-classify/docs/prompt.md +6 -0
- package/scripts/coverage-classify/docs/verdict-schema.md +6 -0
- package/scripts/coverage-classify/index.mjs +24 -15
- package/scripts/coverage-classify/prompt.mjs +1 -1
- package/scripts/coverage-fix-extract.mjs +1 -1
- package/scripts/coverage-fix.mjs +2 -1
- package/scripts/docs/auto-skills.md +6 -0
- package/scripts/docs/build-agents-commands.md +7 -1
- package/scripts/docs/cli-entry.md +6 -0
- package/scripts/docs/coverage-fix-extract.md +6 -0
- package/scripts/docs/coverage-fix.md +6 -0
- package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +6 -0
- package/scripts/docs/lint-cli.md +6 -0
- package/scripts/docs/post-tool-use-fix.md +6 -0
- package/scripts/docs/rename-yaml-extensions.md +6 -0
- package/scripts/docs/skills-cli.md +6 -0
- package/scripts/docs/sync-setup-bun-deps-action.md +6 -0
- package/scripts/docs/upgrade-nitra-cursor-and-install.md +6 -0
- package/scripts/docs/worktree-cli.md +6 -0
- package/scripts/lib/docs/assert-project-root.md +6 -0
- package/scripts/lib/docs/check-mdc-template-refs.md +6 -0
- package/scripts/lib/docs/check-reporter.md +6 -0
- package/scripts/lib/docs/diff-added-lines.md +6 -0
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +6 -0
- package/scripts/lib/docs/discover-checkable-rules.md +6 -0
- package/scripts/lib/docs/ensure-tool.md +6 -0
- package/scripts/lib/docs/generated-markdown.md +6 -0
- package/scripts/lib/docs/gha-workflow.md +6 -0
- package/scripts/lib/docs/inline-template-links.md +6 -0
- package/scripts/lib/docs/list-rule-ids.md +6 -0
- package/scripts/lib/docs/load-cursor-config.md +6 -0
- package/scripts/lib/docs/mirror-parity.md +6 -0
- package/scripts/lib/docs/read-n-cursor-config-lite.md +6 -0
- package/scripts/lib/docs/resolve-target-files.md +6 -0
- package/scripts/lib/docs/root-notice.md +6 -0
- package/scripts/lib/docs/rule-meta-helpers.md +6 -0
- package/scripts/lib/docs/rule-meta.md +6 -0
- package/scripts/lib/docs/run-conftest-batch.md +6 -0
- package/scripts/lib/docs/run-lint-step.md +6 -0
- package/scripts/lib/docs/run-rule-cli.md +6 -0
- package/scripts/lib/docs/run-rule.md +6 -0
- package/scripts/lib/docs/run-standard-lint.md +6 -0
- package/scripts/lib/docs/run-standard-rule.md +6 -0
- package/scripts/lib/docs/skill-meta.md +6 -0
- package/scripts/lib/docs/template.md +6 -0
- package/scripts/lib/docs/timing-summary.md +6 -0
- package/scripts/lib/docs/workspaces.md +6 -0
- package/scripts/lib/docs/worktree-notice.md +6 -0
- package/scripts/lib/docs/worktree.md +6 -0
- package/scripts/lib/mirror-parity.mjs +1 -1
- package/scripts/lib/root-notice.mjs +1 -1
- package/scripts/lib/worktree-notice.mjs +5 -5
- package/scripts/lib/worktree.mjs +1 -1
- package/scripts/sync-claude-config.mjs +3 -0
- package/scripts/utils/docs/ast-scan-utils.md +6 -0
- package/scripts/utils/docs/ensure-gitignore-entries.md +6 -0
- package/scripts/utils/docs/find-package-json-paths.md +6 -0
- package/scripts/utils/docs/lock-cache-dir.md +6 -0
- package/scripts/utils/docs/pass.md +6 -0
- package/scripts/utils/docs/resolve-cargo-manifest.md +6 -0
- package/scripts/utils/docs/resolve-cmd.md +6 -0
- package/scripts/utils/docs/resolve-js-root.md +6 -0
- package/scripts/utils/docs/test-helpers.md +6 -0
- package/scripts/utils/docs/walk-cache.md +6 -0
- package/scripts/utils/docs/walkDir.md +6 -0
- package/scripts/utils/docs/worktree-fingerprint.md +6 -0
- package/scripts/utils/resolve-js-root.mjs +1 -1
- package/skills/doc-aggregate/SKILL.md +129 -0
- package/skills/doc-aggregate/js/docgen-ignore.mjs +9 -0
- package/skills/{docgen → doc-aggregate}/js/docgen-scan.mjs +22 -67
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +21 -0
- package/skills/doc-files/SKILL.md +100 -0
- package/skills/doc-files/js/docgen-crc.mjs +164 -0
- package/skills/{docgen → doc-files}/js/docgen-extract-anchors.mjs +24 -15
- package/skills/{docgen → doc-files}/js/docgen-extract.mjs +15 -9
- package/skills/doc-files/js/docgen-files-batch.mjs +181 -0
- package/skills/doc-files/js/docgen-gen.mjs +291 -0
- package/skills/{docgen → doc-files}/js/docgen-prompts.mjs +43 -40
- package/skills/doc-files/js/docgen-scan.mjs +298 -0
- package/skills/doc-files/js/docs/docgen-crc.md +32 -0
- package/skills/doc-files/js/docs/docgen-extract-anchors.md +27 -0
- package/skills/doc-files/js/docs/docgen-extract.md +29 -0
- package/skills/doc-files/js/docs/docgen-files-batch.md +25 -0
- package/skills/doc-files/js/docs/docgen-gen.md +30 -0
- package/skills/doc-files/js/docs/docgen-prompts.md +32 -0
- package/skills/doc-files/js/docs/docgen-scan.md +25 -0
- package/skills/doc-files/meta.json +1 -0
- package/skills/fix/js/docs/llm-worker.md +6 -0
- package/skills/fix/js/docs/orchestrator.md +6 -0
- package/skills/fix/js/llm-worker.mjs +23 -14
- package/skills/fix/js/orchestrator.mjs +1 -1
- package/skills/start-check/js/check.mjs +5 -3
- package/skills/start-check/js/docs/check.md +6 -0
- package/skills/docgen/SKILL.md +0 -224
- package/skills/docgen/bench/etalon/firebase_hosting.md +0 -19
- package/skills/docgen/bench/etalon/k8s-tree.md +0 -24
- package/skills/docgen/bench/etalon/overlay-paths.md +0 -24
- package/skills/docgen/js/docgen-batch-omlx.mjs +0 -82
- package/skills/docgen/js/docgen-batch.mjs +0 -95
- package/skills/docgen/js/docgen-compare-pi-vs-direct.mjs +0 -95
- package/skills/docgen/js/docgen-gen.mjs +0 -339
- package/skills/docgen/js/docs/docgen-extract.md +0 -28
- package/skills/docgen/js/docs/docgen-gen.md +0 -41
- package/skills/docgen/js/docs/docgen-ignore.md +0 -24
- package/skills/docgen/js/docs/docgen-prompts.md +0 -24
- package/skills/docgen/js/docs/docgen-scan.md +0 -48
- /package/skills/{docgen → doc-aggregate}/meta.json +0 -0
- /package/skills/{docgen → doc-files}/js/docgen-ignore.mjs +0 -0
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/ci4/js/marksman_config.mjs
|
|
4
|
+
crc: 07883aa5
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# marksman_config.mjs
|
|
2
8
|
|
|
3
9
|
## Огляд
|
|
@@ -94,12 +100,14 @@ export async function check(cwd = process.cwd()): Promise<number>
|
|
|
94
100
|
### Інтеграція
|
|
95
101
|
|
|
96
102
|
1. Зовнішній runner (зазвичай CLI `n-cursor` або агрегатор правил) імпортує `check` і викликає його:
|
|
103
|
+
|
|
97
104
|
```js
|
|
98
105
|
import { check } from '@nitra/cursor/npm/rules/ci4/js/marksman_config.mjs'
|
|
99
|
-
|
|
106
|
+
|
|
100
107
|
const code = await check(process.cwd())
|
|
101
108
|
process.exit(code)
|
|
102
109
|
```
|
|
110
|
+
|
|
103
111
|
2. `check` повертає exit-код:
|
|
104
112
|
- `0` — concern пройдений, можна продовжувати.
|
|
105
113
|
- `1` — fatal, треба зупинитися або репортувати юзеру.
|
package/rules/docker/docs/fix.md
CHANGED
|
@@ -1,258 +1,74 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/docker/js/lint.mjs
|
|
4
|
+
crc: 495d03ee
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Модуль `npm/rules/docker/js/lint.mjs` реалізує комплексну перевірку файлів `Dockerfile` / `Containerfile` у репозиторії згідно з правилом `docker.mdc`. Він:
|
|
6
|
-
|
|
7
|
-
- знаходить усі `Dockerfile`, `Dockerfile.*`, `Containerfile`, `Containerfile.*` від кореня проєкту (з повагою до cursor-ignore шляхів);
|
|
8
|
-
- запускає на кожному з них нативний `hadolint` через утиліту `lintDockerfileWithHadolint` (PATH / кеш / авто-install через `ensureTool`, без `docker run`);
|
|
9
|
-
- додатково застосовує власні семантичні перевірки:
|
|
10
|
-
- усі `oven/bun`, `alpine`, `nginx`, `node` з Docker Hub мають іти через `mirror.gcr.io` (делегується `getMirrorGcrHint`);
|
|
11
|
-
- Dockerfile має бути **multistage** (мінімум 2 `FROM`);
|
|
12
|
-
- фінальний `FROM` має бути дозволеним runtime-образом (alpine, scratch, debian:_slim_, php, python, nginx-unprivileged, openresty; для проєктів із нативним `.node`-аддоном також `mirror.gcr.io/oven/bun:*`);
|
|
13
|
-
- якщо у Dockerfile є `bun install` і фінальний stage — alpine (backend), очікується `bun build --compile` у build stage, і у фінальному stage не повинно бути викликів `bun`;
|
|
14
|
-
- для проєктів із нативним `.node`-аддоном (sharp / @img/\* / argon2) компіляція через `bun build --compile` заборонена — застосовується окрема перевірка `getNativeAddonNoCompileHint`;
|
|
15
|
-
- фінальний stage має містити `USER <non-root>` (виняток — nginx-unprivileged, який і так від uid=101);
|
|
16
|
-
- для `mirror.gcr.io/nginxinc/nginx-unprivileged` у `FROM` тег має бути саме `alpine-slim`;
|
|
17
|
-
- додаткова перевірка nginx non-root (`getNginxUnprivilegedUserHint`).
|
|
18
|
-
|
|
19
|
-
Кореневий `.hadolint.yaml` підхоплюється hadolint автоматично. Модуль є точкою входу `check(cwd)` для CLI-перевірок і повертає exit code (0 — OK, 1 — є зауваження або помилка запуску).
|
|
20
|
-
|
|
21
|
-
## Експорти / API
|
|
22
|
-
|
|
23
|
-
| Експорт | Тип | Призначення |
|
|
24
|
-
| ------------------------------------------------- | -------------------- | ----------------------------------------------------------------------------------- |
|
|
25
|
-
| `isDockerfileName(name)` | named function | Перевіряє, чи basename відповідає Dockerfile / Containerfile (включно з суфіксами). |
|
|
26
|
-
| `findDockerfilePaths(root, ignorePaths?)` | named async function | Збирає абсолютні шляхи до Dockerfile/Containerfile у репозиторії. |
|
|
27
|
-
| `parseFromStages(fileContent)` | named function | Парсить інструкції `FROM` і повертає масив `{ line, image }`. |
|
|
28
|
-
| `splitDockerfileStages(fileContent)` | named function | Розбиває Dockerfile на масив stage-ів `{ from, stageContent }`. |
|
|
29
|
-
| `getMultistageAndRuntimeHint(fileContent, opts?)` | named function | Перевіряє multistage та дозволеність фінального runtime-образу. |
|
|
30
|
-
| `getBunCompileHint(fileContent)` | named function | Перевіряє правило компіляції bun у бінарник на backend runtime. |
|
|
31
|
-
| `getNginxAlpineSlimTagHint(fileContent)` | named function | Перевіряє тег `alpine-slim` для nginx-unprivileged. |
|
|
32
|
-
| `getNonRootRuntimeHint(fileContent)` | named function | Перевіряє наявність `USER <non-root>` у фінальному stage. |
|
|
33
|
-
| `check(cwd?)` | named async function | Точка входу: обходить репозиторій, запускає всі перевірки, повертає exit code. |
|
|
34
|
-
|
|
35
|
-
Внутрішні (не експортуються): `isAllowedFinalRuntimeImage`, `readNearestDependencies`, `checkDockerfile`, а також модульні константи (`NEWLINE_RE`, `BUN_INSTALL_RE`, `BUN_BUILD_COMPILE_RE`, `BUN_WORD_RE`, `USER_LINE_RE`, `NGINX_UNPRIVILEGED_MIRROR_PREFIX`, `RUNTIME_IMAGES`, `DEBIAN_VIA_MIRROR_RE`, `BUN_RUNTIME_IMAGE`).
|
|
36
|
-
|
|
37
|
-
## Типи
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
/**
|
|
41
|
-
* @typedef {{
|
|
42
|
-
* line: number
|
|
43
|
-
* image: string
|
|
44
|
-
* }} FromStage
|
|
45
|
-
*/
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
`FromStage` — описує одну `FROM`-інструкцію: 1-based номер рядка і строковий image-ref (як у Dockerfile, з можливим тегом та `@digest`).
|
|
49
|
-
|
|
50
|
-
## Функції
|
|
51
|
-
|
|
52
|
-
### `isDockerfileName(name)`
|
|
53
|
-
|
|
54
|
-
- **Сигнатура:** `(name: string) => boolean`
|
|
55
|
-
- **Параметри:** `name` — basename файлу.
|
|
56
|
-
- **Повертає:** `true`, якщо ім'я (case-insensitive) дорівнює `dockerfile` / `containerfile` або починається з `dockerfile.` / `containerfile.` (наприклад `Dockerfile.prod`); інакше `false`.
|
|
57
|
-
- **Side effects:** немає.
|
|
58
|
-
|
|
59
|
-
### `findDockerfilePaths(root, ignorePaths = [])`
|
|
60
|
-
|
|
61
|
-
- **Сигнатура:** `(root: string, ignorePaths?: string[]) => Promise<string[]>`
|
|
62
|
-
- **Параметри:**
|
|
63
|
-
- `root` — корінь репозиторію, від якого виконується обхід;
|
|
64
|
-
- `ignorePaths` — масив каталогів, повністю виключених з обходу (наприклад `node_modules`, `.git`); передається в `walkDir`.
|
|
65
|
-
- **Повертає:** відсортований (через `localeCompare`) масив абсолютних шляхів до знайдених Dockerfile/Containerfile.
|
|
66
|
-
- **Side effects:** I/O на читання директорій через `walkDir`.
|
|
67
|
-
|
|
68
|
-
### `parseFromStages(fileContent)`
|
|
69
|
-
|
|
70
|
-
- **Сигнатура:** `(fileContent: string) => FromStage[]`
|
|
71
|
-
- **Параметри:** `fileContent` — повний вміст Dockerfile/Containerfile.
|
|
72
|
-
- **Повертає:** масив `FromStage` для кожного рядка, де `getFromImageToken` повернув непорожній image-ref. Номер рядка — 1-based.
|
|
73
|
-
- **Side effects:** немає (чиста функція).
|
|
74
|
-
|
|
75
|
-
### `isAllowedFinalRuntimeImage(lastLower, hasNativeAddon = false)` _(внутрішня)_
|
|
8
|
+
# lint.mjs
|
|
76
9
|
|
|
77
|
-
|
|
78
|
-
- **Параметри:**
|
|
79
|
-
- `lastLower` — image-ref останнього `FROM` без digest, у нижньому регістрі;
|
|
80
|
-
- `hasNativeAddon` — чи має проєкт нативний `.node`-аддон (sharp / @img/\* / argon2).
|
|
81
|
-
- **Повертає:** `true`, якщо образ дозволений як фінальний runtime:
|
|
82
|
-
- `scratch` або `scratch:*`;
|
|
83
|
-
- якщо `hasNativeAddon` — додатково `mirror.gcr.io/oven/bun` або `mirror.gcr.io/oven/bun:*`;
|
|
84
|
-
- `mirror.gcr.io/library/debian:<tag>` за умови, що `<tag>` містить підрядок `slim`;
|
|
85
|
-
- будь-який з `RUNTIME_IMAGES` (alpine, php, python, nginx-unprivileged, openresty) як точне співпадіння або з тегом `:*`.
|
|
86
|
-
- **Side effects:** немає.
|
|
87
|
-
|
|
88
|
-
### `splitDockerfileStages(fileContent)`
|
|
89
|
-
|
|
90
|
-
- **Сигнатура:** `(fileContent: string) => Array<{ from: FromStage, stageContent: string }>`
|
|
91
|
-
- **Параметри:** `fileContent` — вміст Dockerfile.
|
|
92
|
-
- **Повертає:**
|
|
93
|
-
- порожній масив, якщо `FROM` немає;
|
|
94
|
-
- інакше масив об'єктів `{ from, stageContent }`: рядки від `FROM` поточного stage (включно) до рядка перед наступним `FROM` (а для останнього — до кінця файлу), з'єднані через `\n`.
|
|
95
|
-
- **Side effects:** немає.
|
|
96
|
-
|
|
97
|
-
### `getMultistageAndRuntimeHint(fileContent, opts?)`
|
|
98
|
-
|
|
99
|
-
- **Сигнатура:** `(fileContent: string, opts?: { hasNativeAddon?: boolean }) => string | null`
|
|
100
|
-
- **Параметри:**
|
|
101
|
-
- `fileContent` — вміст Dockerfile;
|
|
102
|
-
- `opts.hasNativeAddon` — чи проєкт залежить від нативних `.node`-аддонів.
|
|
103
|
-
- **Повертає:**
|
|
104
|
-
- `null`, якщо `FROM` немає або всі вимоги задоволені;
|
|
105
|
-
- повідомлення про відсутність multistage (`'має бути multistage build: мінімум 2 інструкції FROM (build stage + runtime stage)'`), якщо лише один `FROM`;
|
|
106
|
-
- повідомлення `'фінальний FROM має бути дозволеним runtime-образом (див. docker.mdc: multistage), зараз: <image> (рядок N)'`, якщо фінальний образ не пройшов `isAllowedFinalRuntimeImage`.
|
|
107
|
-
- **Side effects:** немає.
|
|
108
|
-
|
|
109
|
-
### `getBunCompileHint(fileContent)`
|
|
110
|
-
|
|
111
|
-
- **Сигнатура:** `(fileContent: string) => string | null`
|
|
112
|
-
- **Параметри:** `fileContent` — вміст Dockerfile.
|
|
113
|
-
- **Тригер активації:** у файлі є `bun install` / `bun i` (за `BUN_INSTALL_RE`) **та** фінальний `FROM` починається з `mirror.gcr.io/library/alpine:` **та** він не є nginx-unprivileged / openresty (frontend).
|
|
114
|
-
- **Повертає:**
|
|
115
|
-
- `null`, якщо немає stage-ів, немає `bun install`, фінал не alpine, або фінал — frontend (nginx/openresty);
|
|
116
|
-
- повідомлення `'є `bun install`, але немає `bun build --compile` …'`, якщо у файлі немає `bun build --compile`;
|
|
117
|
-
- повідомлення `'фінальний stage не має містити Bun …'`, якщо у `stageContent` останнього stage зустрічається слово `bun` (RUN/CMD/ENTRYPOINT з `bun`).
|
|
118
|
-
- **Side effects:** немає.
|
|
119
|
-
|
|
120
|
-
### `getNginxAlpineSlimTagHint(fileContent)`
|
|
121
|
-
|
|
122
|
-
- **Сигнатура:** `(fileContent: string) => string | null`
|
|
123
|
-
- **Параметри:** `fileContent` — вміст Dockerfile.
|
|
124
|
-
- **Повертає:**
|
|
125
|
-
- `null`, якщо немає `FROM` з префіксом `mirror.gcr.io/nginxinc/nginx-unprivileged` або всі такі `FROM` мають тег `alpine-slim`;
|
|
126
|
-
- повідомлення про відсутній явний тег (`FROM <prefix>` без `:tag`);
|
|
127
|
-
- повідомлення про неправильний тег (наприклад `:latest`, `:alpine`).
|
|
128
|
-
- **Side effects:** немає.
|
|
129
|
-
|
|
130
|
-
### `getNonRootRuntimeHint(fileContent)`
|
|
131
|
-
|
|
132
|
-
- **Сигнатура:** `(fileContent: string) => string | null`
|
|
133
|
-
- **Параметри:** `fileContent` — вміст Dockerfile.
|
|
134
|
-
- **Логіка:**
|
|
135
|
-
- бере останній stage через `splitDockerfileStages`;
|
|
136
|
-
- проходить рядки і запам'ятовує останній `USER <token>` (regex `USER_LINE_RE`, з лапок видаляються `"`/`'`);
|
|
137
|
-
- якщо `USER` відсутній і фінальний образ — `mirror.gcr.io/nginxinc/nginx-unprivileged:*`, повертає `null` (виняток для nginx-unprivileged, який стартує від uid=101);
|
|
138
|
-
- якщо `USER` відсутній — повертає повідомлення про необхідність `USER <non-root>`;
|
|
139
|
-
- якщо `USER` дорівнює `root` або `0` (без врахування регістру) — повертає повідомлення про заборону root.
|
|
140
|
-
- **Повертає:** `string | null` (повідомлення помилки або `null`).
|
|
141
|
-
- **Side effects:** немає.
|
|
142
|
-
|
|
143
|
-
### `check(cwd = process.cwd())`
|
|
144
|
-
|
|
145
|
-
- **Сигнатура:** `(cwd?: string) => Promise<number>`
|
|
146
|
-
- **Параметри:** `cwd` — корінь репозиторію; за замовчуванням `process.cwd()`.
|
|
147
|
-
- **Логіка:**
|
|
148
|
-
1. Створює репортер `createCheckReporter()`.
|
|
149
|
-
2. Завантажує `ignorePaths` через `loadCursorIgnorePaths(root)`.
|
|
150
|
-
3. Знаходить усі Dockerfile/Containerfile через `findDockerfilePaths`.
|
|
151
|
-
4. Якщо файлів немає — `pass('Немає Dockerfile / Containerfile — перевірку hadolint пропущено')` і виходить.
|
|
152
|
-
5. Інакше виводить `Знайдено файлів для hadolint: N` і послідовно викликає `checkDockerfile(reporter, root, abs)` для кожного.
|
|
153
|
-
6. Повертає `reporter.getExitCode()`.
|
|
154
|
-
- **Повертає:** `0` — все OK, `1` — є зауваження або помилка запуску.
|
|
155
|
-
- **Side effects:** читання файлової системи, синхронний/асинхронний запуск hadolint через `lintDockerfileWithHadolint` (нативний бінарник через `ensureTool`).
|
|
156
|
-
|
|
157
|
-
### `readNearestDependencies(abs, root)` _(внутрішня)_
|
|
158
|
-
|
|
159
|
-
- **Сигнатура:** `(abs: string, root: string) => Promise<Record<string, unknown>>`
|
|
160
|
-
- **Параметри:**
|
|
161
|
-
- `abs` — абсолютний шлях до Dockerfile;
|
|
162
|
-
- `root` — корінь репозиторію (зупинка піднімання).
|
|
163
|
-
- **Логіка:** піднімається від `dirname(abs)` вгору, шукаючи `package.json`. Як тільки знаходить — повертає `dependencies` (або `{}`, якщо `dependencies` відсутні / не об'єкт). Якщо досягає `root` або вищого каталогу без `package.json` — повертає `{}`.
|
|
164
|
-
- **Повертає:** `dependencies` найближчого `package.json` або порожній об'єкт.
|
|
165
|
-
- **Side effects:** I/O на читання `package.json`; помилки `readFile` поглинаються (catch без оголошення).
|
|
166
|
-
|
|
167
|
-
### `checkDockerfile(reporter, root, abs)` _(внутрішня)_
|
|
168
|
-
|
|
169
|
-
- **Сигнатура:** `(reporter: ReturnType<typeof createCheckReporter>, root: string, abs: string) => Promise<void>`
|
|
170
|
-
- **Параметри:**
|
|
171
|
-
- `reporter` — інстанс репортера з `pass` / `fail`;
|
|
172
|
-
- `root` — корінь репо (для розрахунку posix-relative шляху);
|
|
173
|
-
- `abs` — абсолютний шлях до Dockerfile.
|
|
174
|
-
- **Логіка (послідовно):**
|
|
175
|
-
1. `rel = posixRel(root, abs) || basename(abs)`.
|
|
176
|
-
2. Читає вміст файлу (`readFile(abs, 'utf8')`).
|
|
177
|
-
3. Визначає `nativeAddons` через `getNativeAddonDeps(await readNearestDependencies(abs, root))`; `hasNativeAddon = nativeAddons.length > 0`.
|
|
178
|
-
4. `getMirrorGcrHint(content)` → `fail` з префіксом `mirror.gcr.io`.
|
|
179
|
-
5. `getMultistageAndRuntimeHint(content, { hasNativeAddon })` → `fail` з префіксом `multistage`.
|
|
180
|
-
6. Якщо `hasNativeAddon` — `getNativeAddonNoCompileHint(content, nativeAddons)` → `fail` з префіксом `native-addon`; інакше — `getBunCompileHint(content)` → `fail` з префіксом `compile`.
|
|
181
|
-
7. `getNonRootRuntimeHint(content)` → `fail` з префіксом `non-root`.
|
|
182
|
-
8. `getNginxAlpineSlimTagHint(content)` → `fail` з префіксом `nginx tag`.
|
|
183
|
-
9. `getNginxUnprivilegedUserHint(content)` → `fail` з префіксом `nginx non-root`.
|
|
184
|
-
10. `lintDockerfileWithHadolint(root, abs)` (синхронний виклик з результатом `{ ok, stdout, stderr, via }`): якщо `ok` — `pass(`${rel} (${via})`)`, інакше `fail` з хвостом stdout+stderr.
|
|
185
|
-
- **Повертає:** `Promise<void>`.
|
|
186
|
-
- **Side effects:** I/O на читання Dockerfile/package.json, запуск hadolint, виклики `reporter.pass`/`reporter.fail`.
|
|
187
|
-
|
|
188
|
-
## Константи / regex
|
|
10
|
+
## Огляд
|
|
189
11
|
|
|
190
|
-
|
|
191
|
-
- `BUN_INSTALL_RE = /\bbun\s+(?:install|i)\b/iu` — детект `bun install` / `bun i`.
|
|
192
|
-
- `BUN_BUILD_COMPILE_RE = /\bbun\s+build\b[^\n]*\s--compile\b/iu` — детект `bun build … --compile`.
|
|
193
|
-
- `BUN_WORD_RE = /\bbun\b/iu` — будь-яке слово `bun`.
|
|
194
|
-
- `USER_LINE_RE = /^\s*USER\s+([^\s#]+)/iu` — інструкція `USER`.
|
|
195
|
-
- `NGINX_UNPRIVILEGED_MIRROR_PREFIX = 'mirror.gcr.io/nginxinc/nginx-unprivileged'`.
|
|
196
|
-
- `RUNTIME_IMAGES` — `const`-кортеж дозволених фінальних runtime-образів: `mirror.gcr.io/library/alpine`, `…/library/php`, `…/library/python`, `…/nginxinc/nginx-unprivileged`, `…/openresty/openresty`.
|
|
197
|
-
- `DEBIAN_VIA_MIRROR_RE = /^mirror\.gcr\.io\/library\/debian:(.+)$/i` — debian через mirror, для перевірки `slim` у тегу.
|
|
198
|
-
- `BUN_RUNTIME_IMAGE = 'mirror.gcr.io/oven/bun'` — bun як фінальний runtime (легітимний лише для нативних `.node`-аддонів).
|
|
12
|
+
Модуль забезпечує декомпозицію структури Dockerfile для вилучення даних про багатостадійні збірки та залежності середовища. Функції, такі як `findDockerfilePaths` та `splitDockerfileStages`, використовуються для ідентифікації та розділення стадій збірки. Модуль надає інструменти для отримання підказок про виконання, включаючи визначення багатостадійного режиму (`getMultistageAndRuntimeHint`), компіляційних налаштувань (`getBunCompileHint`), та підказок про використання образу Nginx Alpine Slim (`getNginxAlpineSlimTagHint`). Додатково, він визначає необхідність роботи без прав root (`getNonRootRuntimeHint`). (docker.mdc)
|
|
199
13
|
|
|
200
|
-
##
|
|
14
|
+
## Поведінка
|
|
201
15
|
|
|
202
|
-
|
|
16
|
+
isDockerfileName
|
|
17
|
+
Перевіряє, чи є вхідний рядок назвою Dockerfile або Containerfile.
|
|
203
18
|
|
|
204
|
-
|
|
205
|
-
|
|
19
|
+
findDockerfilePaths
|
|
20
|
+
Збирає абсолютні шляхи до Dockerfile або Containerfile від заданого кореня репозиторію, враховуючи виключені шляхи.
|
|
206
21
|
|
|
207
|
-
|
|
22
|
+
parseFromStages
|
|
23
|
+
Витягує інструкції FROM з вмісту файлу.
|
|
208
24
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
- `../lib/docker-nginx-user.mjs` → `getNginxUnprivilegedUserHint`.
|
|
212
|
-
- `../lib/docker-hadolint.mjs` → `lintDockerfileWithHadolint`, `posixRel`.
|
|
213
|
-
- `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` (з методами `pass`, `fail`, `getExitCode`).
|
|
214
|
-
- `../../../scripts/lib/load-cursor-config.mjs` → `loadCursorIgnorePaths`.
|
|
215
|
-
- `../../../scripts/utils/walkDir.mjs` → `walkDir`.
|
|
25
|
+
splitDockerfileStages
|
|
26
|
+
Розбиває вміст Dockerfile на окремі стадії на основі інструкцій FROM.
|
|
216
27
|
|
|
217
|
-
|
|
28
|
+
getMultistageAndRuntimeHint
|
|
29
|
+
Перевіряє, чи має Dockerfile мінімум дві інструкції FROM і чи є фінальний образ дозволеним runtime-образом (docker.mdc).
|
|
218
30
|
|
|
219
|
-
|
|
31
|
+
getBunCompileHint
|
|
32
|
+
Перевіряє наявність інструкцій `bun install` та відсутності `bun build --compile` для виявлення необхідності компіляції бінарника (docker.mdc).
|
|
220
33
|
|
|
221
|
-
|
|
34
|
+
getNginxAlpineSlimTagHint
|
|
35
|
+
Перевіряє, чи містить інструкція FROM для образу nginx потрібний тег `alpine-slim` (docker.mdc).
|
|
222
36
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
3. `findDockerfilePaths(root, ignorePaths)` за допомогою `walkDir` обходить дерево і збирає всі Dockerfile/Containerfile, відсортовані.
|
|
226
|
-
4. Якщо файлів немає — репорт `pass` і exit 0.
|
|
227
|
-
5. Інакше для кожного знайденого Dockerfile послідовно виконується `checkDockerfile`, який:
|
|
228
|
-
- читає вміст,
|
|
229
|
-
- підіймається до найближчого `package.json` для визначення `hasNativeAddon`,
|
|
230
|
-
- запускає шість статичних перевірок (mirror, multistage/runtime, compile **або** native-addon, non-root, nginx tag, nginx user),
|
|
231
|
-
- запускає `hadolint` через `lintDockerfileWithHadolint` і репортує результат.
|
|
232
|
-
6. Усі помилки агрегуються в репортері; підсумковий код повертає `reporter.getExitCode()` (0/1).
|
|
37
|
+
getNonRootRuntimeHint
|
|
38
|
+
Перевіряє, чи присутня інструкція USER у фінальній стадії і чи не використовується `root` або `0` для запуску (docker.mdc).
|
|
233
39
|
|
|
234
|
-
|
|
40
|
+
check
|
|
41
|
+
Запускає перевірки Dockerfile через hadolint, включаючи перевірки multistage, компіляції, non-root, тегів nginx та загальну валідацію.
|
|
235
42
|
|
|
236
|
-
|
|
237
|
-
|
|
43
|
+
readNearestDependencies
|
|
44
|
+
Читає залежності з найближчого package.json, розташованого у каталогах Dockerfile або вище.
|
|
238
45
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
```
|
|
46
|
+
checkDockerfile
|
|
47
|
+
Перевіряє індивідуальний Dockerfile/Containerfile на наявність інструкцій, пов'язаних з mirror.gcr.io, multistage, компіляції, non-root, тегів nginx та виконує перевірку через hadolint.
|
|
242
48
|
|
|
243
|
-
|
|
49
|
+
## Публічний API
|
|
244
50
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
51
|
+
isDockerfileName — перевіряє наявність файлів `Dockerfile` або `Containerfile` у назві.
|
|
52
|
+
findDockerfilePaths — збирає повні шляхи до файлів `Dockerfile` або `Containerfile` від поточної робочої директорії.
|
|
53
|
+
parseFromStages — витягує всі інструкції `FROM <image>` з вмісту файлів.
|
|
54
|
+
splitDockerfileStages — розділяє файл `Dockerfile` на послідовні етапи за інструкціями `FROM`. Повертає порожній масив, якщо інструкції `FROM` відсутні.
|
|
55
|
+
getMultistageAndRuntimeHint — перевіряє вимоги до структури Dockerfile:
|
|
56
|
+
multistage — вимагає мінімум два етапи `FROM`.
|
|
57
|
+
фінальний FROM — перевіряє, чи дозволений образ у `docker.mdc` (alpine, scratch, debian slim, php, python, nginx, openresty, тощо). Для проєктів з нативним .node-аддоном дозволено `mirror.gcr.io/oven/bun:*` (bun-рантайм).
|
|
58
|
+
getBunCompileHint — перевіряє наявність вимоги "компіляції в бінарник" для bun-проєктів на бекенд-рантаймах.
|
|
59
|
+
Тригер — перевіряє, чи присутній крок `bun install` або `bun i` у Dockerfile.
|
|
60
|
+
Тригер — перевіряє, чи фінальний образ — `mirror.gcr.io/library/alpine:*` (виключаючи фронтенд nginx/openresty).
|
|
61
|
+
getNginxAlpineSlimTagHint — перевіряє, чи містить `FROM` для nginx-образу (`mirror.gcr.io/nginxinc/nginx-unprivileged`) тег `alpine-slim` (`docker.mdc`).
|
|
62
|
+
getNonRootRuntimeHint — перевіряє вимогу "non-root" у фінальному runtime-етапі (`docker.mdc`).
|
|
63
|
+
Очікування — перевіряє, чи містить build stage інструкцію `bun build --compile`.
|
|
64
|
+
Очікування — перевіряє, чи відсутні виклики `bun` у фінальному етапі (залишкові інструменти збірки).
|
|
65
|
+
Очікування — перевіряє, чи містить фінальний етап інструкцію `USER <name|uid>`.
|
|
66
|
+
Очікування — перевіряє, чи користувач у фінальному етапі не є `root` і не дорівнює `0`.
|
|
67
|
+
check — виконує перевірку через hadolint (`docker.mdc`).
|
|
248
68
|
|
|
249
|
-
##
|
|
69
|
+
## Гарантії поведінки
|
|
250
70
|
|
|
251
|
-
-
|
|
252
|
-
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
- `nginx-unprivileged` без явного `USER` не вважається порушенням non-root (uid=101 за замовчуванням), але тег має бути саме `alpine-slim`.
|
|
256
|
-
- `scratch` (як точне співпадіння або з тегом) завжди дозволено як фінальний runtime.
|
|
257
|
-
- `debian` дозволено лише через `mirror.gcr.io/library/debian:<tag>` де `<tag>` містить `slim`.
|
|
258
|
-
- `posixRel` нормалізує шлях для уніфікованого виводу в репорті; якщо повертає порожній рядок — використовується `basename(abs)`.
|
|
71
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
72
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
73
|
+
- За невдалої перевірки повертає `false`/`null` замість винятку.
|
|
74
|
+
- Не звертається до мережі.
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/docker/lint/lint.mjs
|
|
4
|
+
crc: 98a98d10
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# lint.mjs — реалізація підкоманди `lint-docker`
|
|
2
8
|
|
|
3
9
|
## Огляд
|
|
@@ -165,11 +171,13 @@ if (isRunAsCli(import.meta.url)) {
|
|
|
165
171
|
|
|
166
172
|
- **CLI:** `bun run n-cursor lint-docker` (або відповідний bin-скрипт) — основний сценарій.
|
|
167
173
|
- **Програмно з інших скриптів:**
|
|
174
|
+
|
|
168
175
|
```js
|
|
169
176
|
import { runLintDocker } from 'npm/rules/docker/lint/lint.mjs'
|
|
170
|
-
|
|
177
|
+
|
|
171
178
|
const code = await runLintDocker() // 0 — OK, 1 — є зауваження/помилки
|
|
172
179
|
```
|
|
180
|
+
|
|
173
181
|
- **Тести/допоміжний код:**
|
|
174
182
|
|
|
175
183
|
```js
|
package/rules/efes/docs/fix.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/js-bun-db/lib/bun-sql-scan.mjs
|
|
4
|
+
crc: 990f04d7
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# bun-sql-scan.mjs
|
|
2
8
|
|
|
3
9
|
## Огляд
|
|
@@ -270,7 +276,7 @@ Set-константи:
|
|
|
270
276
|
|
|
271
277
|
```js
|
|
272
278
|
import { SQL } from 'bun'
|
|
273
|
-
|
|
279
|
+
|
|
274
280
|
/**
|
|
275
281
|
*
|
|
276
282
|
*/
|
|
@@ -284,7 +290,7 @@ Set-константи:
|
|
|
284
290
|
|
|
285
291
|
```js
|
|
286
292
|
import { sql } from 'bun'
|
|
287
|
-
|
|
293
|
+
|
|
288
294
|
const text = `select * from ${tableName}`
|
|
289
295
|
sql.unsafe(text) // <-- порушення: немає // allow-unsafe: <reason>
|
|
290
296
|
```
|
|
@@ -314,7 +320,7 @@ Set-константи:
|
|
|
314
320
|
|
|
315
321
|
```js
|
|
316
322
|
import { sql } from 'bun'
|
|
317
|
-
|
|
323
|
+
|
|
318
324
|
await sql.end() // <-- порушення: немає // allow-pg-leftover: <reason>
|
|
319
325
|
```
|
|
320
326
|
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/js-lint-ci/fix.mjs
|
|
4
|
+
crc: 12fc1644
|
|
5
|
+
---
|
|
6
|
+
|
|
1
7
|
# fix.mjs — точка входу правила `js-lint-ci`
|
|
2
8
|
|
|
3
9
|
## Огляд
|
|
@@ -82,7 +88,7 @@ if (isRunAsCli(import.meta.url)) {
|
|
|
82
88
|
- **Дія:** виконує `await runRuleCli(import.meta.dirname)` — повний CLI-сценарій (config-loading, whitelist, summary), а потім завершує процес `process.exit(<exit-code>)` з тим самим кодом, що повернув `runRuleCli` (0 або 1) — це критично для CI/IDE, які орієнтуються на код виходу.
|
|
83
89
|
- **Side effects:** завершення процесу (`process.exit`), вся I/O `runRuleCli`. Виклики `process.exit` тут спеціально дозволені директивою:
|
|
84
90
|
```js
|
|
85
|
-
|
|
91
|
+
|
|
86
92
|
```
|
|
87
93
|
|
|
88
94
|
## Залежності
|
package/rules/js-run/docs/fix.md
CHANGED