@7n/rules 1.27.0 → 1.28.1
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 +12 -0
- package/package.json +1 -5
- package/schemas/v8r-catalog.json +10 -1
- package/scripts/auto-rules.mjs +2 -3
- package/scripts/docs/auto-rules.md +1 -1
- package/scripts/lib/docs/glob-to-regex.md +31 -0
- package/scripts/lib/docs/index.md +2 -0
- package/scripts/lib/docs/js-source-signals.md +32 -0
- package/scripts/lib/glob-to-regex.mjs +79 -0
- package/scripts/lib/js-source-signals.mjs +50 -0
- package/scripts/utils/ast-scan-utils.mjs +2 -2
- package/scripts/utils/docs/ast-scan-utils.md +1 -1
- package/rules/bun/bunfig/bunfig.mdc +0 -17
- package/rules/bun/bunfig/bunfig.rego +0 -29
- package/rules/bun/bunfig/concern.json +0 -9
- package/rules/bun/bunfig/template/bunfig.toml.snippet.toml +0 -2
- package/rules/bun/docs/index.md +0 -11
- package/rules/bun/layout/concern.json +0 -16
- package/rules/bun/layout/docs/fix-layout.md +0 -29
- package/rules/bun/layout/docs/main.md +0 -34
- package/rules/bun/layout/fix-layout.mjs +0 -63
- package/rules/bun/layout/layout.mdc +0 -60
- package/rules/bun/layout/main.mjs +0 -53
- package/rules/bun/licensee/concern.json +0 -7
- package/rules/bun/licensee/docs/fix-licensee.md +0 -27
- package/rules/bun/licensee/docs/index.md +0 -12
- package/rules/bun/licensee/docs/main.md +0 -30
- package/rules/bun/licensee/fix-licensee.mjs +0 -31
- package/rules/bun/licensee/main.mjs +0 -68
- package/rules/bun/lint-surface/concern.json +0 -3
- package/rules/bun/lint-surface/lint-surface.mdc +0 -13
- package/rules/bun/main.json +0 -1
- package/rules/bun/main.mdc +0 -11
- package/rules/bun/package_json/concern.json +0 -9
- package/rules/bun/package_json/docs/fix-package_json.md +0 -28
- package/rules/bun/package_json/docs/index.md +0 -9
- package/rules/bun/package_json/fix-package_json.mjs +0 -311
- package/rules/bun/package_json/package_json.mdc +0 -14
- package/rules/bun/package_json/package_json.rego +0 -64
- package/rules/bun/package_json/template/package.json.deny.json +0 -4
- package/rules/js/check/check.mdc +0 -26
- package/rules/js/check/concern.json +0 -19
- package/rules/js/check/docs/eslint-config.md +0 -56
- package/rules/js/check/docs/fix-check.md +0 -48
- package/rules/js/check/docs/index.md +0 -13
- package/rules/js/check/docs/main.md +0 -48
- package/rules/js/check/eslint-config.mjs +0 -262
- package/rules/js/check/fix-check.mjs +0 -82
- package/rules/js/check/main.mjs +0 -310
- package/rules/js/dep-policy/concern.json +0 -4
- package/rules/js/dep-policy/dep-policy.mdc +0 -36
- package/rules/js/dep-policy/docs/main.md +0 -35
- package/rules/js/dep-policy/main.mjs +0 -99
- package/rules/js/docs/index.md +0 -11
- package/rules/js/eslint/concern.json +0 -8
- package/rules/js/eslint/docs/fix-eslint.md +0 -50
- package/rules/js/eslint/docs/fix-worker.md +0 -31
- package/rules/js/eslint/docs/index.md +0 -11
- package/rules/js/eslint/docs/main.md +0 -35
- package/rules/js/eslint/fix-eslint.mjs +0 -160
- package/rules/js/eslint/fix-worker.mjs +0 -139
- package/rules/js/eslint/main.mjs +0 -115
- package/rules/js/file-extensions/concern.json +0 -3
- package/rules/js/file-extensions/file-extensions.mdc +0 -12
- package/rules/js/jscpd_config/concern.json +0 -11
- package/rules/js/jscpd_config/docs/fix-jscpd_config.md +0 -26
- package/rules/js/jscpd_config/docs/index.md +0 -9
- package/rules/js/jscpd_config/fix-jscpd_config.mjs +0 -3
- package/rules/js/jscpd_config/jscpd_config.mdc +0 -42
- package/rules/js/jscpd_config/jscpd_config.rego +0 -44
- package/rules/js/jscpd_config/template/.jscpd.json.snippet.json +0 -7
- package/rules/js/jscpd_duplicates/concern.json +0 -7
- package/rules/js/jscpd_duplicates/docs/main.md +0 -29
- package/rules/js/jscpd_duplicates/main.mjs +0 -69
- package/rules/js/knip/concern.json +0 -7
- package/rules/js/knip/docs/main.md +0 -32
- package/rules/js/knip/knip.mdc +0 -15
- package/rules/js/knip/main.mjs +0 -68
- package/rules/js/lint-findings/concern.json +0 -3
- package/rules/js/lint-findings/docs/main.md +0 -41
- package/rules/js/lint-findings/main.mjs +0 -125
- package/rules/js/main.json +0 -1
- package/rules/js/main.mdc +0 -18
- package/rules/js/package_json/concern.json +0 -9
- package/rules/js/package_json/docs/fix-package_json.md +0 -26
- package/rules/js/package_json/docs/index.md +0 -9
- package/rules/js/package_json/fix-package_json.mjs +0 -3
- package/rules/js/package_json/package_json.mdc +0 -15
- package/rules/js/package_json/package_json.rego +0 -142
- package/rules/js/package_json/template/package.json.snippet.json +0 -6
- package/rules/js/tooling/concern.json +0 -3
- package/rules/js/tooling/data/tooling/knip-canonical.json +0 -30
- package/rules/js/tooling/data/tooling/oxlint-canonical.json +0 -400
- package/rules/js/tooling/docs/main.md +0 -53
- package/rules/js/tooling/main.mjs +0 -183
- package/rules/js/utils_imports/concern.json +0 -4
- package/rules/js/utils_imports/docs/main.md +0 -50
- package/rules/js/utils_imports/main.mjs +0 -185
- package/rules/js/utils_imports/utils_imports.mdc +0 -15
- package/rules/js/vscode_extensions/concern.json +0 -11
- package/rules/js/vscode_extensions/docs/fix-vscode_extensions.md +0 -25
- package/rules/js/vscode_extensions/docs/index.md +0 -11
- package/rules/js/vscode_extensions/fix-vscode_extensions.mjs +0 -1
- package/rules/js/vscode_extensions/template/extensions.json.snippet.json +0 -6
- package/rules/js/vscode_extensions/vscode_extensions.mdc +0 -11
- package/rules/js/vscode_extensions/vscode_extensions.rego +0 -12
- package/rules/js-bun-db/connection/concern.json +0 -3
- package/rules/js-bun-db/connection/connection.mdc +0 -42
- package/rules/js-bun-db/docs/index.md +0 -11
- package/rules/js-bun-db/lib/bun-sql-scan.mjs +0 -1055
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +0 -63
- package/rules/js-bun-db/lib/docs/index.md +0 -11
- package/rules/js-bun-db/main.json +0 -1
- package/rules/js-bun-db/main.mdc +0 -8
- package/rules/js-bun-db/package_json/concern.json +0 -9
- package/rules/js-bun-db/package_json/package_json.mdc +0 -31
- package/rules/js-bun-db/package_json/package_json.rego +0 -15
- package/rules/js-bun-db/package_json/template/package.json.deny.json +0 -6
- package/rules/js-bun-db/pg_format_identifiers/concern.json +0 -3
- package/rules/js-bun-db/pg_format_identifiers/pg_format_identifiers.mdc +0 -104
- package/rules/js-bun-db/safety/concern.json +0 -4
- package/rules/js-bun-db/safety/docs/main.md +0 -34
- package/rules/js-bun-db/safety/main.mjs +0 -430
- package/rules/js-bun-db/safety/safety.mdc +0 -458
- package/rules/js-bun-redis/docs/index.md +0 -11
- package/rules/js-bun-redis/imports/concern.json +0 -4
- package/rules/js-bun-redis/imports/docs/main.md +0 -36
- package/rules/js-bun-redis/imports/imports.mdc +0 -47
- package/rules/js-bun-redis/imports/main.mjs +0 -88
- package/rules/js-bun-redis/lib/docs/index.md +0 -11
- package/rules/js-bun-redis/lib/docs/redis-imports.md +0 -227
- package/rules/js-bun-redis/lib/redis-imports.mjs +0 -130
- package/rules/js-bun-redis/main.json +0 -1
- package/rules/js-bun-redis/main.mdc +0 -8
- package/rules/js-bun-redis/package_json/concern.json +0 -9
- package/rules/js-bun-redis/package_json/package_json.mdc +0 -11
- package/rules/js-bun-redis/package_json/package_json.rego +0 -15
- package/rules/js-bun-redis/package_json/template/package.json.deny.json +0 -12
- package/rules/js-mssql/deps/concern.json +0 -4
- package/rules/js-mssql/deps/docs/main.md +0 -33
- package/rules/js-mssql/deps/main.mjs +0 -297
- package/rules/js-mssql/docs/index.md +0 -11
- package/rules/js-mssql/lib/docs/index.md +0 -11
- package/rules/js-mssql/lib/docs/mssql-pool-scan.md +0 -380
- package/rules/js-mssql/lib/mssql-pool-scan.mjs +0 -610
- package/rules/js-mssql/main.json +0 -1
- package/rules/js-mssql/main.mdc +0 -144
- package/rules/js-mssql/mssql-tvp/concern.json +0 -3
- package/rules/js-mssql/mssql-tvp/mssql-tvp.mdc +0 -77
- package/rules/js-mssql/package_json/concern.json +0 -9
- package/rules/js-mssql/package_json/package_json.mdc +0 -9
- package/rules/js-mssql/package_json/package_json.rego +0 -57
- package/rules/js-run/configmap/concern.json +0 -9
- package/rules/js-run/configmap/configmap.mdc +0 -37
- package/rules/js-run/configmap/configmap.rego +0 -21
- package/rules/js-run/configmap/template/configmap.yaml.contains.yml +0 -4
- package/rules/js-run/docs/index.md +0 -11
- package/rules/js-run/jsconfig/concern.json +0 -9
- package/rules/js-run/jsconfig/docs/fix-jsconfig.md +0 -29
- package/rules/js-run/jsconfig/docs/index.md +0 -9
- package/rules/js-run/jsconfig/fix-jsconfig.mjs +0 -119
- package/rules/js-run/jsconfig/jsconfig.mdc +0 -48
- package/rules/js-run/jsconfig/jsconfig.rego +0 -59
- package/rules/js-run/jsconfig/template/jsconfig.json.snippet.json +0 -10
- package/rules/js-run/lib/bunyan-imports.mjs +0 -98
- package/rules/js-run/lib/check-env-scan.mjs +0 -338
- package/rules/js-run/lib/conn-file-rules.mjs +0 -214
- package/rules/js-run/lib/conn-imports-scan.mjs +0 -154
- package/rules/js-run/lib/docs/bunyan-imports.md +0 -121
- package/rules/js-run/lib/docs/check-env-scan.md +0 -438
- package/rules/js-run/lib/docs/conn-file-rules.md +0 -304
- package/rules/js-run/lib/docs/conn-imports-scan.md +0 -208
- package/rules/js-run/lib/docs/index.md +0 -16
- package/rules/js-run/lib/docs/promise-settimeout-scan.md +0 -334
- package/rules/js-run/lib/docs/temporal-scan.md +0 -29
- package/rules/js-run/lib/promise-settimeout-scan.mjs +0 -128
- package/rules/js-run/lib/temporal-scan.mjs +0 -52
- package/rules/js-run/main.json +0 -1
- package/rules/js-run/main.mdc +0 -16
- package/rules/js-run/package_json/concern.json +0 -9
- package/rules/js-run/package_json/package_json.mdc +0 -44
- package/rules/js-run/package_json/package_json.rego +0 -37
- package/rules/js-run/package_json/template/package.json.deny.json +0 -22
- package/rules/js-run/project-structure/concern.json +0 -3
- package/rules/js-run/project-structure/project-structure.mdc +0 -11
- package/rules/js-run/runtime/concern.json +0 -12
- package/rules/js-run/runtime/docs/fix-runtime.md +0 -27
- package/rules/js-run/runtime/docs/main.md +0 -35
- package/rules/js-run/runtime/fix-runtime.mjs +0 -46
- package/rules/js-run/runtime/main.mjs +0 -494
- package/rules/js-run/runtime/runtime.mdc +0 -184
- package/rules/js-run/scope/concern.json +0 -3
- package/rules/js-run/scope/scope.mdc +0 -11
- package/rules/npm-module/docs/index.md +0 -11
- package/rules/npm-module/emit_types_config/concern.json +0 -9
- package/rules/npm-module/emit_types_config/docs/fix-emit_types_config.md +0 -25
- package/rules/npm-module/emit_types_config/docs/index.md +0 -9
- package/rules/npm-module/emit_types_config/emit_types_config.mdc +0 -43
- package/rules/npm-module/emit_types_config/emit_types_config.rego +0 -28
- package/rules/npm-module/emit_types_config/fix-emit_types_config.mjs +0 -5
- package/rules/npm-module/emit_types_config/template/tsconfig.emit-types.json.snippet.json +0 -9
- package/rules/npm-module/header_doc_pointer/concern.json +0 -5
- package/rules/npm-module/header_doc_pointer/docs/main.md +0 -40
- package/rules/npm-module/header_doc_pointer/header_doc_pointer.mdc +0 -18
- package/rules/npm-module/header_doc_pointer/main.mjs +0 -131
- package/rules/npm-module/main.json +0 -1
- package/rules/npm-module/main.mdc +0 -36
- package/rules/npm-module/npm_package_json/concern.json +0 -9
- package/rules/npm-module/npm_package_json/docs/fix-npm_package_json.md +0 -27
- package/rules/npm-module/npm_package_json/docs/index.md +0 -9
- package/rules/npm-module/npm_package_json/fix-npm_package_json.mjs +0 -5
- package/rules/npm-module/npm_package_json/npm_package_json.mdc +0 -57
- package/rules/npm-module/npm_package_json/npm_package_json.rego +0 -73
- package/rules/npm-module/npm_package_json/template/package.json.snippet.json +0 -1
- package/rules/npm-module/package_structure/concern.json +0 -5
- package/rules/npm-module/package_structure/docs/main.md +0 -37
- package/rules/npm-module/package_structure/main.mjs +0 -515
- package/rules/npm-module/package_structure/package_structure.mdc +0 -63
- package/rules/npm-module/root_package_json/concern.json +0 -9
- package/rules/npm-module/root_package_json/docs/fix-root_package_json.md +0 -26
- package/rules/npm-module/root_package_json/docs/index.md +0 -9
- package/rules/npm-module/root_package_json/fix-root_package_json.mjs +0 -5
- package/rules/npm-module/root_package_json/root_package_json.mdc +0 -41
- package/rules/npm-module/root_package_json/root_package_json.rego +0 -28
- package/rules/npm-module/root_package_json/template/package.json.snippet.json +0 -1
- package/rules/npm-module/rule_meta/concern.json +0 -8
- package/rules/npm-module/rule_meta/docs/main.md +0 -35
- package/rules/npm-module/rule_meta/main.mjs +0 -119
- package/rules/npm-module/rule_meta/rule_meta.mdc +0 -11
- package/rules/npm-module/skill_meta/concern.json +0 -5
- package/rules/npm-module/skill_meta/docs/main.md +0 -149
- package/rules/npm-module/skill_meta/main.mjs +0 -91
- package/rules/npm-module/skill_meta/skill_meta.mdc +0 -11
- package/rules/tool-surface/docs/index.md +0 -11
- package/rules/tool-surface/main.json +0 -6
- package/rules/tool-surface/main.mdc +0 -72
- package/rules/vue/composition-api/composition-api.mdc +0 -82
- package/rules/vue/composition-api/concern.json +0 -3
- package/rules/vue/docs/index.md +0 -11
- package/rules/vue/lib/docs/index.md +0 -11
- package/rules/vue/lib/docs/vue-forbidden-imports.md +0 -265
- package/rules/vue/lib/vue-forbidden-imports.mjs +0 -264
- package/rules/vue/main.json +0 -1
- package/rules/vue/main.mdc +0 -18
- package/rules/vue/nheader-layout/concern.json +0 -3
- package/rules/vue/nheader-layout/nheader-layout.mdc +0 -171
- package/rules/vue/package_json/concern.json +0 -9
- package/rules/vue/package_json/package_json.mdc +0 -30
- package/rules/vue/package_json/package_json.rego +0 -140
- package/rules/vue/packages/concern.json +0 -6
- package/rules/vue/packages/docs/index.md +0 -11
- package/rules/vue/packages/docs/main.md +0 -35
- package/rules/vue/packages/main.mjs +0 -575
- package/rules/vue/packages/packages.mdc +0 -56
- package/rules/vue/quasar-ui/concern.json +0 -3
- package/rules/vue/quasar-ui/quasar-ui.mdc +0 -32
- package/rules/vue/structure/concern.json +0 -3
- package/rules/vue/structure/structure.mdc +0 -101
- package/rules/vue/testing/concern.json +0 -3
- package/rules/vue/testing/testing.mdc +0 -40
- package/rules/vue/tfm-translations/concern.json +0 -7
- package/rules/vue/tfm-translations/docs/main.md +0 -29
- package/rules/vue/tfm-translations/main.mjs +0 -55
- package/rules/vue/tfm-translations/tfm-translations.mdc +0 -32
- package/rules/vue/vite-config/concern.json +0 -3
- package/rules/vue/vite-config/vite-config.mdc +0 -153
- package/rules/vue/vite-env/concern.json +0 -3
- package/rules/vue/vite-env/vite-env.mdc +0 -61
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
## Rego-gate: валідація кореневого `package.json`
|
|
2
|
-
|
|
3
|
-
Rego-пакет: `npm-module.root_package_json`
|
|
4
|
-
|
|
5
|
-
Цільовий файл: `package.json` (корінь репозиторію)
|
|
6
|
-
|
|
7
|
-
### Що перевіряється
|
|
8
|
-
|
|
9
|
-
Subset-of перевірка масиву `workspaces`: кожне значення з канонічного сніпету має бути присутнє у `workspaces`. За замовчуванням обовʼязковий елемент — `"npm"`.
|
|
10
|
-
|
|
11
|
-
Якщо `workspaces` відсутнє або не є масивом — окрема deny-помилка.
|
|
12
|
-
|
|
13
|
-
Канонічний сніпет: [package.json.snippet.json](./template/package.json.snippet.json)
|
|
14
|
-
|
|
15
|
-
Решта перевірок кореневого `package.json` (заборонені поля, devDeps лише `@nitra/*`) — у пакеті `bun.package_json`. FS-перевірки (наявність директорії `npm/`, `npm/package.json`) — у JS.
|
|
16
|
-
|
|
17
|
-
### Приклади
|
|
18
|
-
|
|
19
|
-
✓ Правильно — `workspaces` містить `"npm"`:
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{ "workspaces": ["npm"] }
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
✓ Правильно — `workspaces` містить `"npm"` разом з іншими:
|
|
26
|
-
|
|
27
|
-
```json
|
|
28
|
-
{ "workspaces": ["demo", "npm", "tests"] }
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
✗ Неправильно — `workspaces` відсутній:
|
|
32
|
-
|
|
33
|
-
```json
|
|
34
|
-
{ "name": "monorepo" }
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
✗ Неправильно — `workspaces` без `"npm"`:
|
|
38
|
-
|
|
39
|
-
```json
|
|
40
|
-
{ "workspaces": ["demo"] }
|
|
41
|
-
```
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Перевірка кореневого `package.json` для npm-module (npm-module.mdc).
|
|
2
|
-
#
|
|
3
|
-
# Канон надходить через --data: { "template": { "snippet": ... } }
|
|
4
|
-
# Структура --data сформована з template/package.json.snippet.json.
|
|
5
|
-
# Snippet-array subset-of: кожне значення з template-масиву має бути у input-масиві.
|
|
6
|
-
# Решта кореневих `package.json`-перевірок (заборонені поля, devDeps лише @nitra/*)
|
|
7
|
-
# — у `bun.package_json`. FS-перевірки (наявність каталогу `npm/`, `npm/package.json`)
|
|
8
|
-
# — у JS.
|
|
9
|
-
package npm_module.root_package_json
|
|
10
|
-
|
|
11
|
-
import rego.v1
|
|
12
|
-
|
|
13
|
-
# Поле має бути масивом — інакше окрема deny.
|
|
14
|
-
deny contains msg if {
|
|
15
|
-
some field in object.keys(data.template.snippet)
|
|
16
|
-
not is_array(object.get(input, field, null))
|
|
17
|
-
msg := sprintf("package.json: масив %s відсутній або не масив (npm-module.mdc)", [field])
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
# Subset-of: кожне значення з template має бути в input-масиві.
|
|
21
|
-
deny contains msg if {
|
|
22
|
-
some field, expected_values in data.template.snippet
|
|
23
|
-
is_array(object.get(input, field, null))
|
|
24
|
-
actual_set := {v | some v in input[field]}
|
|
25
|
-
some required in expected_values
|
|
26
|
-
not required in actual_set
|
|
27
|
-
msg := sprintf("package.json: %s має містити %q (npm-module.mdc)", [field, required])
|
|
28
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{ "workspaces": ["npm"] }
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: main.mjs
|
|
4
|
-
resource: npm/rules/npm-module/rule_meta/main.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: 3c4c2ca7
|
|
7
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
-
score: 95
|
|
9
|
-
issues: anchor-miss:(scripts.mdc),judge:inaccurate:0.98
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
Lint-детектор concern-а `npm-module/rule_meta`: валідує метадані кожного правила у `npm/rules/<id>/` — файл `main.json` та супутні конвенції каталогу правила.
|
|
16
|
-
|
|
17
|
-
## Поведінка
|
|
18
|
-
|
|
19
|
-
1. Якщо `npm/rules/` відсутній — pass (немає правил для валідації).
|
|
20
|
-
2. Для кожної теки правила:
|
|
21
|
-
- `auto.md` є пережитком — якщо файл лишився, порушення (метадані тепер у `main.json`).
|
|
22
|
-
- `main.mdc` обовʼязковий (канон scripts.mdc) — відсутність = порушення.
|
|
23
|
-
- `main.json` має існувати і бути валідним JSON-обʼєктом.
|
|
24
|
-
- Поле `auto` (опційне) має відповідати одній з форм: `"завжди"` / масив / `{ glob }` / `{ predicate }`; предикат має бути зареєстрований у `RULE_PREDICATES`.
|
|
25
|
-
- Поле `lint` заборонене: rule-level lint-scope скасовано (spec 2026-06-28-concern-lint-scope-design) — lint-поверхня декларується у `<rule>/<concern>/concern.json#lint`.
|
|
26
|
-
- Поле `llmFix` заборонене: opt-in-прапорця немає — fix-можливість концерну визначається наявністю `fix-*.mjs`/`fix-worker.mjs`.
|
|
27
|
-
3. Повертає `LintResult` зі списком порушень; валідні правила репортяться як pass.
|
|
28
|
-
|
|
29
|
-
## Публічний API
|
|
30
|
-
|
|
31
|
-
lint — перевіряє `main.json` усіх правил у `npm/rules/` і повертає `{ violations }`.
|
|
32
|
-
|
|
33
|
-
## Гарантії поведінки
|
|
34
|
-
|
|
35
|
-
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/** @see ./docs/main.md */
|
|
2
|
-
import { existsSync, readdirSync } from 'node:fs'
|
|
3
|
-
import { join } from 'node:path'
|
|
4
|
-
|
|
5
|
-
import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
|
|
6
|
-
import { parseRuleAutoSpec, readRuleMetaRaw } from '../../../scripts/lib/rule-meta.mjs'
|
|
7
|
-
import { RULE_PREDICATES } from '../../../scripts/lib/rule-predicates.mjs'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Перевіряє поле `auto` у meta.json одного правила.
|
|
11
|
-
* @param {string} id ідентифікатор правила
|
|
12
|
-
* @param {Record<string, unknown>} raw сирий meta.json
|
|
13
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
14
|
-
* @returns {boolean} true, якщо поле валідне (або відсутнє)
|
|
15
|
-
*/
|
|
16
|
-
function checkAutoField(id, raw, reporter) {
|
|
17
|
-
if (raw.auto === undefined) return true
|
|
18
|
-
const spec = parseRuleAutoSpec(raw.auto)
|
|
19
|
-
if (spec === null) {
|
|
20
|
-
const autoHint = 'нерозпізнане (очікується "завжди" / масив / {glob} / {predicate})'
|
|
21
|
-
reporter.fail(`rules/${id}: main.json.auto ${autoHint}`)
|
|
22
|
-
return false
|
|
23
|
-
}
|
|
24
|
-
if ('predicate' in spec && !Object.hasOwn(RULE_PREDICATES, spec.predicate)) {
|
|
25
|
-
reporter.fail(`rules/${id}: main.json — невідомий predicate "${spec.predicate}" (немає в RULE_PREDICATES)`)
|
|
26
|
-
return false
|
|
27
|
-
}
|
|
28
|
-
return true
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Забороняє залишкове поле `lint` у meta.json правила.
|
|
33
|
-
* Канон (spec 2026-06-28-concern-lint-scope-design): lint-scope живе у
|
|
34
|
-
* `<rule>/<concern>/concern.json#lint`, rule-level `main.json.lint` скасовано.
|
|
35
|
-
* @param {string} id ідентифікатор правила
|
|
36
|
-
* @param {Record<string, unknown>} raw сирий meta.json
|
|
37
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
38
|
-
* @returns {boolean} true, якщо поле відсутнє
|
|
39
|
-
*/
|
|
40
|
-
function checkLintField(id, raw, reporter) {
|
|
41
|
-
if (raw.lint === undefined) return true
|
|
42
|
-
reporter.fail(`rules/${id}: main.json.lint скасовано — lint-scope декларується у <concern>/concern.json#lint`)
|
|
43
|
-
return false
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Забороняє залишкове поле `llmFix` у meta.json правила.
|
|
48
|
-
* Канон (scripts.mdc, spec 2026-06-28-concern-lint-scope-design): opt-in-прапорця
|
|
49
|
-
* llmFix немає — fix-можливість концерну визначається наявністю `fix-*.mjs`/`fix-worker.mjs`.
|
|
50
|
-
* @param {string} id ідентифікатор правила
|
|
51
|
-
* @param {Record<string, unknown>} raw сирий meta.json
|
|
52
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
53
|
-
* @returns {boolean} true, якщо поле відсутнє
|
|
54
|
-
*/
|
|
55
|
-
function checkLlmFixField(id, raw, reporter) {
|
|
56
|
-
if (raw.llmFix === undefined) return true
|
|
57
|
-
reporter.fail(
|
|
58
|
-
`rules/${id}: main.json.llmFix скасовано — fix-можливість = наявність fix-*.mjs/fix-worker.mjs у концерні`
|
|
59
|
-
)
|
|
60
|
-
return false
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Валідує meta.json одного правила.
|
|
65
|
-
* @param {string} id ідентифікатор правила
|
|
66
|
-
* @param {string} ruleDir каталог правила
|
|
67
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
68
|
-
* @returns {void}
|
|
69
|
-
*/
|
|
70
|
-
function checkRule(id, ruleDir, reporter) {
|
|
71
|
-
let ruleOk = true
|
|
72
|
-
|
|
73
|
-
if (existsSync(join(ruleDir, 'auto.md'))) {
|
|
74
|
-
reporter.fail(`rules/${id}: залишковий auto.md — видали (метадані тепер у main.json)`)
|
|
75
|
-
ruleOk = false
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Канон (scripts.mdc): main.mdc — ОБОВ'ЯЗКОВИЙ у кожному npm/rules/<id>/.
|
|
79
|
-
if (!existsSync(join(ruleDir, 'main.mdc'))) {
|
|
80
|
-
reporter.fail(`rules/${id}: відсутній main.mdc — обов'язковий (scripts.mdc)`)
|
|
81
|
-
ruleOk = false
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const raw = readRuleMetaRaw(ruleDir)
|
|
85
|
-
if (!raw) {
|
|
86
|
-
reporter.fail(`rules/${id}: відсутній або невалідний main.json`)
|
|
87
|
-
return
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
if (!checkAutoField(id, raw, reporter)) ruleOk = false
|
|
91
|
-
if (!checkLintField(id, raw, reporter)) ruleOk = false
|
|
92
|
-
if (!checkLlmFixField(id, raw, reporter)) ruleOk = false
|
|
93
|
-
|
|
94
|
-
if (ruleOk) {
|
|
95
|
-
reporter.pass(`rules/${id}: main.json валідний`)
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Валідує всі `npm/rules/<id>/meta.json`.
|
|
101
|
-
* @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx Контекст лінту (`cwd` тощо).
|
|
102
|
-
* @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} Результат лінту зі списком violations.
|
|
103
|
-
*/
|
|
104
|
-
export function lint(ctx) {
|
|
105
|
-
const cwd = ctx.cwd
|
|
106
|
-
const reporter = createViolationReporter(ctx)
|
|
107
|
-
const rulesDir = join(cwd, 'npm', 'rules')
|
|
108
|
-
if (!existsSync(rulesDir)) {
|
|
109
|
-
reporter.pass('npm/rules/ відсутній — немає правил для валідації')
|
|
110
|
-
return Promise.resolve(reporter.result())
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
for (const entry of readdirSync(rulesDir, { withFileTypes: true })) {
|
|
114
|
-
if (!entry.isDirectory() || entry.name.startsWith('.')) continue
|
|
115
|
-
checkRule(entry.name, join(rulesDir, entry.name), reporter)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return Promise.resolve(reporter.result())
|
|
119
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
## Валідація `main.json` правил
|
|
2
|
-
|
|
3
|
-
Кожне правило у `npm/rules/<id>/` повинно мати коректний `main.json` (метадані правила).
|
|
4
|
-
|
|
5
|
-
Перевірки (`rule_meta.mjs`):
|
|
6
|
-
|
|
7
|
-
- **`main.mdc` обовʼязковий** у кожному `npm/rules/<id>/` — без нього `check` падає.
|
|
8
|
-
- **`auto.md` є пережитком** — якщо такий файл залишився, `check` вимагає його видалити (метадані тепер у `main.json`).
|
|
9
|
-
- **`main.json` має бути валідним JSON** із коректними полями:
|
|
10
|
-
- **`auto`** (опційне): `"завжди"` / масив glob-рядків / `{ glob }` / `{ predicate }`. Якщо `predicate` вказано — він має бути зареєстрований у `RULE_PREDICATES`.
|
|
11
|
-
- **`lint` заборонене**: rule-level scope скасовано — lint-поверхня декларується per-concern у `<rule>/<concern>/concern.json#lint` (spec 2026-06-28-concern-lint-scope-design).
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: JS Module
|
|
3
|
-
title: main.mjs
|
|
4
|
-
resource: npm/rules/npm-module/skill_meta/main.mjs
|
|
5
|
-
docgen:
|
|
6
|
-
crc: cefe56b0
|
|
7
|
-
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
-
score: 100
|
|
9
|
-
issues: judge:inaccurate:0.99
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Огляд
|
|
14
|
-
|
|
15
|
-
system_message:
|
|
16
|
-
You are an expert coding assistant operating inside pi, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.
|
|
17
|
-
|
|
18
|
-
Available tools:
|
|
19
|
-
(none)
|
|
20
|
-
|
|
21
|
-
In addition to the tools above, you may have access to other custom tools depending on the project.
|
|
22
|
-
|
|
23
|
-
Guidelines:
|
|
24
|
-
|
|
25
|
-
- Be concise in your responses
|
|
26
|
-
- Show file paths clearly when working with files
|
|
27
|
-
|
|
28
|
-
Pi documentation (read only when the user asks about pi itself, its SDK, extensions, themes, skills, or TUI):
|
|
29
|
-
|
|
30
|
-
- Main documentation: /Users/vitalii/www/nitra/cursor/node_modules/@earendil-works/pi-coding-agent/README.md
|
|
31
|
-
- Additional docs: /Users/vitalii/www/nitra/cursor/node_modules/@earendil-works/pi-coding-agent/docs
|
|
32
|
-
- Examples: /Users/vitalii/www/nitra/cursor/node_modules/@earendil-works/pi-coding-agent/examples (extensions, custom tools, SDK)
|
|
33
|
-
- When reading pi docs or examples, resolve docs/... under Additional docs and examples/... under Examples, not the current working directory
|
|
34
|
-
- When asked about: extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), pi packages (docs/packages.md)
|
|
35
|
-
- When working on pi topics, read the pi .md files completely and follow .md cross-references before implementing
|
|
36
|
-
- Always read pi .md files completely and follow links to related docs (e.g., tui.md for TUI API details)
|
|
37
|
-
|
|
38
|
-
<project_context>
|
|
39
|
-
Project-specific instructions and guidelines:
|
|
40
|
-
|
|
41
|
-
<project_instructions path="/Users/vitalii/www/nitra/cursor/AGENTS.md">
|
|
42
|
-
|
|
43
|
-
# AGENTS.md version: '1.0'
|
|
44
|
-
|
|
45
|
-
## Purpose
|
|
46
|
-
|
|
47
|
-
This file is the entry point for all AI agents working with this repository.
|
|
48
|
-
|
|
49
|
-
## Rule source
|
|
50
|
-
|
|
51
|
-
The primary development rules are stored in the Cursor rules directory:
|
|
52
|
-
|
|
53
|
-
- .cursor/rules/conftest.mdc
|
|
54
|
-
- .cursor/rules/dev-dep.mdc
|
|
55
|
-
- .cursor/rules/n-adr.mdc
|
|
56
|
-
- .cursor/rules/n-bun.mdc
|
|
57
|
-
- .cursor/rules/n-changelog.mdc
|
|
58
|
-
- .cursor/rules/n-ci4.mdc
|
|
59
|
-
- .cursor/rules/n-doc-files.mdc
|
|
60
|
-
- .cursor/rules/n-feedback.mdc
|
|
61
|
-
- .cursor/rules/n-ga.mdc
|
|
62
|
-
- .cursor/rules/n-js-run.mdc
|
|
63
|
-
- .cursor/rules/n-js.mdc
|
|
64
|
-
- .cursor/rules/n-npm-module.mdc
|
|
65
|
-
- .cursor/rules/n-python.mdc
|
|
66
|
-
- .cursor/rules/n-rego.mdc
|
|
67
|
-
- .cursor/rules/n-security.mdc
|
|
68
|
-
- .cursor/rules/n-style.mdc
|
|
69
|
-
- .cursor/rules/n-test.mdc
|
|
70
|
-
- .cursor/rules/n-text.mdc
|
|
71
|
-
- .cursor/rules/n-tool-surface.mdc
|
|
72
|
-
- .cursor/rules/n-vue.mdc
|
|
73
|
-
- .cursor/rules/n-worktree.mdc
|
|
74
|
-
- .cursor/rules/scripts.mdc
|
|
75
|
-
|
|
76
|
-
## Skills
|
|
77
|
-
|
|
78
|
-
- `.cursor/skills/mdc-check/SKILL.md` — Проаналізувати правило в npm/mdc: максимум перевірюваної логіки й деталей — у check-{id}.mjs з зрозумілими коментарями/JSDoc; у .mdc залишати людинозрозумілий зміст без дублювання алгоритму перевірки
|
|
79
|
-
- `.cursor/skills/n-adr-normalize/SKILL.md` — Ручний запуск ADR-нормалізації — обхід порогу й min-interval, прогон одного батчу чернеток через LLM, перегляд результату через git diff
|
|
80
|
-
- `.cursor/skills/n-doc-files/SKILL.md` — Обовʼязковий крок задачі (як lint): для кожного зміненого/нового кодового файлу (js/mjs/ts/vue/py) JS-оркестрована генерація лаконічної поведінкової української md-документації у теку docs/ поряд із кодом, зі звіркою застарілості за CRC у frontmatter
|
|
81
|
-
- `.cursor/skills/n-lint/SKILL.md` — Запустити дельта-лінт (npx @7n/rules lint) по змінених файлах vs origin, виправити порушення й підтвердити чистий вихід
|
|
82
|
-
- `.cursor/skills/n-llm-patch/SKILL.md` — Підготовка самодостатнього текстового промпта для іншого Claude/Cursor-агента — read-only аналіз CWD без жодних змін у поточному репо
|
|
83
|
-
- `.cursor/skills/n-publish-telegram/SKILL.md` — Підготовка матеріалу з поточного контексту для публікації в Telegram-каналі команди
|
|
84
|
-
- `.cursor/skills/n-taze/SKILL.md` — Оновлення версій модулів проекту з аналізом major-змін і автоматичним рефакторингом несумісного коду
|
|
85
|
-
|
|
86
|
-
## Commands
|
|
87
|
-
|
|
88
|
-
Generated from the root `package.json` on each `npx @7n/rules` sync. Prefer `bun run <script>` for project scripts.
|
|
89
|
-
|
|
90
|
-
- **Залежності**: `bun i`
|
|
91
|
-
- **test**: `bun run test`
|
|
92
|
-
- **start**: `bun run start`
|
|
93
|
-
- **Оновити правила та AGENTS.md** (після змін у правилах/шаблоні CLI): `npx @7n/rules`
|
|
94
|
-
- **Перевірки правил (programmatic)**: `npx @7n/rules fix`
|
|
95
|
-
- **knip (невикористані залежності та експорти)**: `bunx knip`
|
|
96
|
-
|
|
97
|
-
## Instructions for all agents
|
|
98
|
-
|
|
99
|
-
Before making changes, read the relevant rule files for the area you are working on.
|
|
100
|
-
|
|
101
|
-
## Інваріант після змін
|
|
102
|
-
|
|
103
|
-
`n-changelog.mdc` (alwaysApply) релевантне після **будь-якої** зміни файлів, не лише для релізу. Перед фінальною відповіддю виконай `npx @7n/rules fix changelog` (exit `0`) і познач результат рядком `Changelog: …` у відповіді.
|
|
104
|
-
|
|
105
|
-
## Priority
|
|
106
|
-
|
|
107
|
-
If rules conflict:
|
|
108
|
-
|
|
109
|
-
1. AGENTS.md
|
|
110
|
-
2. task-specific rule file
|
|
111
|
-
3. core rule file
|
|
112
|
-
|
|
113
|
-
## Language
|
|
114
|
-
|
|
115
|
-
Respond in Ukrainian.
|
|
116
|
-
Keep technical terms in English.
|
|
117
|
-
|
|
118
|
-
## Behavior
|
|
119
|
-
|
|
120
|
-
Do not ignore referenced rule files.
|
|
121
|
-
Explicitly follow repository conventions before proposing or applying changes.
|
|
122
|
-
|
|
123
|
-
</project_instructions>
|
|
124
|
-
</project_context>
|
|
125
|
-
|
|
126
|
-
## Поведінка
|
|
127
|
-
|
|
128
|
-
Поведінка:
|
|
129
|
-
|
|
130
|
-
1. Перевіряє наявність каталогу `npm/skills` у корені репозиторію. Якщо відсутній, операція завершується успіхом.
|
|
131
|
-
2. Ітерується по всім підкаталогах у `npm/skills`. Для кожного каталогу виконується перевірка відповідності метаданих скіла.
|
|
132
|
-
3. Для кожного скіла перевіряється, чи відсутній файл `auto.md`. Якщо знайдено, фіксується порушення, оскільки метадані мають знаходитися у `main.json`.
|
|
133
|
-
4. Зчитується вміст `main.json` скіла. Якщо файл відсутній або недійсний, фіксується порушення.
|
|
134
|
-
5. Виконується перевірка полів у `main.json` скіла:
|
|
135
|
-
- Перевіряється тип поля `worktree` — має бути булевим значенням.
|
|
136
|
-
- Якщо поле `auto` визначене, аналізується його значення на відповідність очікуваним форматам.
|
|
137
|
-
- Перевіряється тип поля `requireRoot` — має бути булевим значенням.
|
|
138
|
-
- Перевіряється узгодженість: якщо `worktree` дорівнює `true`, поле `requireRoot` не може бути `false`.
|
|
139
|
-
- Якщо поле `tier` визначене, воно має відповідати одному з визначених рівнів.
|
|
140
|
-
6. Якщо всі перевірки для скіла успішно пройдені, фіксується успішний статус для цього скіла.
|
|
141
|
-
7. Завершення виконання `main` та повернення коду виходу, що відображає кількість виявлених порушень.
|
|
142
|
-
|
|
143
|
-
## Публічний API
|
|
144
|
-
|
|
145
|
-
main — перевіряє, що всі файли `npm/skills/<id>/meta.json` відповідають встановленим вимогам.
|
|
146
|
-
|
|
147
|
-
## Гарантії поведінки
|
|
148
|
-
|
|
149
|
-
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/** @see ./docs/skill_meta.md */
|
|
2
|
-
import { existsSync, readdirSync } from 'node:fs'
|
|
3
|
-
import { join } from 'node:path'
|
|
4
|
-
|
|
5
|
-
import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
|
|
6
|
-
import { SKILL_TIERS, parseSkillAutoSpec, readSkillMetaRaw } from '../../../scripts/lib/skill-meta.mjs'
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Перевіряє поля сирого meta.json одного скіла (без auto.md / відсутності файлу).
|
|
10
|
-
* @param {string} id ідентифікатор скіла
|
|
11
|
-
* @param {Record<string, unknown>} raw сирий meta.json
|
|
12
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
13
|
-
* @returns {boolean} true, якщо всі поля валідні
|
|
14
|
-
*/
|
|
15
|
-
function checkSkillFields(id, raw, reporter) {
|
|
16
|
-
let ok = true
|
|
17
|
-
if (typeof raw.worktree !== 'boolean') {
|
|
18
|
-
reporter.fail(`skills/${id}: main.json.worktree має бути boolean`)
|
|
19
|
-
ok = false
|
|
20
|
-
}
|
|
21
|
-
if (raw.auto !== undefined && parseSkillAutoSpec(raw.auto) === null) {
|
|
22
|
-
reporter.fail(`skills/${id}: main.json.auto нерозпізнане — очікується "завжди" або непорожній масив правил`)
|
|
23
|
-
ok = false
|
|
24
|
-
}
|
|
25
|
-
if (raw.requireRoot !== undefined && typeof raw.requireRoot !== 'boolean') {
|
|
26
|
-
reporter.fail(`skills/${id}: main.json.requireRoot має бути boolean`)
|
|
27
|
-
ok = false
|
|
28
|
-
}
|
|
29
|
-
if (raw.worktree === true && raw.requireRoot === false) {
|
|
30
|
-
reporter.fail(
|
|
31
|
-
`skills/${id}: requireRoot:false суперечить worktree:true (worktree вже вимагає кореня — прибери поле)`
|
|
32
|
-
)
|
|
33
|
-
ok = false
|
|
34
|
-
}
|
|
35
|
-
if (raw.tier !== undefined && !(typeof raw.tier === 'string' && SKILL_TIERS.includes(raw.tier))) {
|
|
36
|
-
const tierList = SKILL_TIERS.map(t => `"${t}"`).join(' | ')
|
|
37
|
-
reporter.fail(`skills/${id}: main.json.tier має бути ${tierList}`)
|
|
38
|
-
ok = false
|
|
39
|
-
}
|
|
40
|
-
return ok
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Валідує meta.json одного скіла.
|
|
45
|
-
* @param {string} id ідентифікатор скіла
|
|
46
|
-
* @param {string} skillDir каталог скіла
|
|
47
|
-
* @param {ReturnType<typeof createViolationReporter>} reporter репортер
|
|
48
|
-
* @returns {void}
|
|
49
|
-
*/
|
|
50
|
-
function checkSkill(id, skillDir, reporter) {
|
|
51
|
-
let skillOk = true
|
|
52
|
-
|
|
53
|
-
if (existsSync(join(skillDir, 'auto.md'))) {
|
|
54
|
-
reporter.fail(`skills/${id}: залишковий auto.md — видали (метадані тепер у main.json)`)
|
|
55
|
-
skillOk = false
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const raw = readSkillMetaRaw(skillDir)
|
|
59
|
-
if (!raw) {
|
|
60
|
-
reporter.fail(`skills/${id}: відсутній або невалідний main.json (очікується {"auto"?, "worktree": bool})`)
|
|
61
|
-
return
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!checkSkillFields(id, raw, reporter)) skillOk = false
|
|
65
|
-
|
|
66
|
-
if (skillOk) {
|
|
67
|
-
reporter.pass(`skills/${id}: main.json валідний`)
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Валідує всі `npm/skills/<id>/meta.json`.
|
|
73
|
-
* @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст лінту.
|
|
74
|
-
* @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат перевірки з порушеннями.
|
|
75
|
-
*/
|
|
76
|
-
export function lint(ctx) {
|
|
77
|
-
const cwd = ctx.cwd
|
|
78
|
-
const reporter = createViolationReporter(ctx)
|
|
79
|
-
const skillsDir = join(cwd, 'npm', 'skills')
|
|
80
|
-
if (!existsSync(skillsDir)) {
|
|
81
|
-
reporter.pass('npm/skills/ відсутній — немає скілів для валідації')
|
|
82
|
-
return Promise.resolve(reporter.result())
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
|
|
86
|
-
if (!entry.isDirectory() || entry.name.startsWith('.')) continue
|
|
87
|
-
checkSkill(entry.name, join(skillsDir, entry.name), reporter)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return Promise.resolve(reporter.result())
|
|
91
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
## Валідація `main.json` скілів
|
|
2
|
-
|
|
3
|
-
Кожен скіл у `npm/skills/<id>/` повинен мати коректний `main.json` (метадані скіла).
|
|
4
|
-
|
|
5
|
-
Перевірки (`skill_meta.mjs`):
|
|
6
|
-
|
|
7
|
-
- **`auto.md` є пережитком** — якщо такий файл залишився, `check` вимагає його видалити (метадані тепер у `main.json`).
|
|
8
|
-
- **`main.json` має бути валідним JSON** із коректними полями:
|
|
9
|
-
- **`worktree`** (обовʼязкове): `boolean`. Якщо `true` — скіл запускається виключно в окремому git-worktree.
|
|
10
|
-
- **`auto`** (опційне): `"завжди"` або непорожній масив ідентифікаторів правил-тригерів.
|
|
11
|
-
- **`requireRoot`** (опційне): `boolean`. Значення `false` несумісне з `worktree: true` — таку комбінацію `check` відхиляє.
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Tool Surface — будь-яка дія фронтенду має бути виконуваною без UI (CLI + LLM) через спільний каталог тулів; UI/оркестратор/LLM — рівноправні адаптери
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
version: '1.0'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Tool Surface — паритет «UI ↔ LLM ↔ оркестратор»
|
|
8
|
-
|
|
9
|
-
## Принцип
|
|
10
|
-
|
|
11
|
-
**Будь-яка дія, яку людина виконує через фронтенд, мусить бути виконуваною як `tool` — без UI — бо вона організована як іменований виклик зі схемою, до якого однаково дотягуються UI, скриптовий оркестратор і LLM.**
|
|
12
|
-
|
|
13
|
-
Ключовий новий споживач — **LLM**, тож одиниця називається `tool`. Фронтенд — лише один з адаптерів, а не єдині двері.
|
|
14
|
-
|
|
15
|
-
## Це НЕ про «винести логіку на бекенд»
|
|
16
|
-
|
|
17
|
-
Лінія поділу не «фронт ↔ бек», а:
|
|
18
|
-
|
|
19
|
-
> виклик, досяжний **лише через UI-взаємодію** → погано
|
|
20
|
-
> виклик, досяжний як **іменований tool зі схемою** → добре
|
|
21
|
-
|
|
22
|
-
JS-логіка може лишатися на фронті — її лише треба **витягнути** з обробника події в окремий tool (ім'я + параметри + схема), який однаково кличе UI, оркестратор і LLM. Tool Surface — це **call surface**, не обов'язково бекенд.
|
|
23
|
-
|
|
24
|
-
## Три шари
|
|
25
|
-
|
|
26
|
-
1. **Tool Catalog** (`src/tool/`) — декларативний каталог. Кожен tool: `name`, `summary`, схема входу/виходу, `handler`. Handler **може бути фронтендовою JS-функцією** (або делегувати в native/HTTP/DB). Це **єдине джерело правди**; з нього генеруються schema-маніфест (для LLM) і типи клієнта.
|
|
27
|
-
2. **Dispatch** — одна функція `dispatch(name, input) → { ok, output } | { ok: false, error }`: валідує вхід за схемою, кличе handler, повертає **уніфікований конверт**. Не прив'язана до UI-рендеру/подій.
|
|
28
|
-
3. **Споживачі** (усі обов'язкові):
|
|
29
|
-
- **UI** — компонент кличе `dispatch`, без inline-логіки дії.
|
|
30
|
-
- **Оркестратор** — машинний вхід `<bin> <tool> '<json>'` (+ `schema`/`list`). Кличуть скрипти, не люди — людський CLI з verb-ами не потрібен.
|
|
31
|
-
- **LLM** — tool-маніфест із каталогу; tool_call маршрутизується в `dispatch`.
|
|
32
|
-
|
|
33
|
-
## Інваріант паритету (серце правила)
|
|
34
|
-
|
|
35
|
-
- **Жодної дії, досяжної лише через UI-взаємодію.** Обробник події **делегує** в `dispatch`/каталог, а не містить inline-логіку (мережа, мутація моделі, виклик бекенду).
|
|
36
|
-
- Дозволено: логіка у фронтенд-коді. Заборонено: логіка **зашита** в обробник кліку/сабміту так, що дотягтись можна лише кліком.
|
|
37
|
-
- Кожен tool каталогу має **усіх** споживачів (UI + оркестратор + LLM), інакше це не headless.
|
|
38
|
-
|
|
39
|
-
## Єдине джерело схем
|
|
40
|
-
|
|
41
|
-
Схема входу tool-а живе в каталозі (zod / JSON Schema; для Rust — `schemars`). З неї генеруються: tool-маніфест для LLM (формат залежить від провайдера — OpenAI function-calling, Anthropic tools або MCP), CLI-довідка, типи клієнта. Тул-визначення **не повинні розходитися** з каталогом — лише деривація, не дублювання.
|
|
42
|
-
|
|
43
|
-
## Уніфікований конверт
|
|
44
|
-
|
|
45
|
-
```jsonc
|
|
46
|
-
{ "ok": true, "output": { /* результат */ } }
|
|
47
|
-
{ "ok": false, "error": { "code": "validation|not_found|io|…", "message": "…" } }
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Оркестратор: `ok:false` → ненульовий exit. UI/LLM: `Result` / tool_result з `is_error`.
|
|
51
|
-
|
|
52
|
-
## Дворівнева структура (архітектура спільна, реалізація per-stack)
|
|
53
|
-
|
|
54
|
-
Архітектура **спільна**, реалізація **навмисно розходиться** за стеком. Це правило тримає платформо-незалежне **ядро**; конкретику делегують профільні правила:
|
|
55
|
-
|
|
56
|
-
| Рівень | Що тут | Де |
|
|
57
|
-
|---|---|---|
|
|
58
|
-
| **Ядро** | принцип, інваріант паритету, контракт каталог/`dispatch`/схема/конверт, 3 споживачі | це правило |
|
|
59
|
-
| **Tauri+Rust** | handler делегує в Rust-крейт/бінарник; машинний bin; `invoke`/spawn | `n-tauri` |
|
|
60
|
-
| **Capacitor / pure-web** | handler — JS напряму; bin = node/bun-скрипт, що імпортує handlers | `n-capacitor` |
|
|
61
|
-
| **UI-адаптер** | компонент делегує в `dispatch`, нуль inline-логіки | `n-vue` |
|
|
62
|
-
|
|
63
|
-
## Конвенція файлів
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
src/tool/
|
|
67
|
-
catalog.(js|ts) ← каталог тулів (single source): name, summary, input schema, mapping
|
|
68
|
-
dispatch.(js|ts) ← dispatch(name, input) + валідація + конверт
|
|
69
|
-
manifest.(js|ts) ← каталог → LLM tools ; CLI help
|
|
70
|
-
transports.(js|ts) ← UI-транспорт (invoke/fetch) ; CLI-транспорт (spawn/import)
|
|
71
|
-
bin/<app>.mjs ← машинний вхід: <tool> '<json>' | schema | list
|
|
72
|
-
```
|