@nitra/cursor 12.8.5 → 12.8.7

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.
Files changed (202) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/bin/n-cursor.js +5 -5
  3. package/package.json +1 -1
  4. package/rules/abie/js/http_route_base.mdc +25 -0
  5. package/rules/abie/js/ua_http_route.mdc +1 -1
  6. package/rules/abie/main.mdc +12 -0
  7. package/rules/adr/js/hooks.mdc +32 -0
  8. package/rules/adr/js/madr_format.mdc +96 -0
  9. package/rules/adr/js/settings_policy.mdc +34 -0
  10. package/rules/adr/main.mdc +13 -95
  11. package/rules/bun/js/bunfig.mdc +12 -0
  12. package/rules/bun/js/layout.mdc +60 -0
  13. package/rules/bun/js/lint.mdc +9 -0
  14. package/rules/bun/js/package_json.mdc +19 -0
  15. package/rules/bun/main.mdc +9 -61
  16. package/rules/capacitor/js/ios_spm.mdc +69 -0
  17. package/rules/capacitor/js/version.mdc +29 -0
  18. package/rules/capacitor/main.mdc +8 -22
  19. package/rules/changelog/js/agent-workflow.mdc +15 -0
  20. package/rules/changelog/js/changelog-format.mdc +33 -0
  21. package/rules/changelog/js/comparison-models.mdc +40 -0
  22. package/rules/changelog/main.mdc +4 -98
  23. package/rules/ci4/js/marksman_config.mdc +31 -0
  24. package/rules/ci4/js/vscode_extensions.mdc +33 -0
  25. package/rules/ci4/main.mdc +14 -14
  26. package/rules/docker/js/compile.mdc +44 -0
  27. package/rules/docker/js/hadolint.mdc +50 -0
  28. package/rules/docker/js/mirror.mdc +13 -0
  29. package/rules/docker/js/multistage.mdc +13 -0
  30. package/rules/docker/js/native-addon.mdc +43 -0
  31. package/rules/docker/js/nginx-tag.mdc +7 -0
  32. package/rules/docker/js/nginx-user.mdc +37 -0
  33. package/rules/docker/js/non-root.mdc +39 -0
  34. package/rules/docker/main.mdc +15 -196
  35. package/rules/ga/js/lint_toolchain.mdc +15 -0
  36. package/rules/ga/js/required_workflows.mdc +35 -0
  37. package/rules/ga/js/vscode.mdc +17 -0
  38. package/rules/ga/js/workflow_common.mdc +108 -0
  39. package/rules/ga/js/workflows.mdc +32 -0
  40. package/rules/ga/js/zizmor.mdc +7 -0
  41. package/rules/ga/main.mdc +17 -125
  42. package/rules/graphql/js/tooling.mdc +13 -0
  43. package/rules/graphql/js/vscode_extensions.mdc +13 -0
  44. package/rules/graphql/main.mdc +3 -22
  45. package/rules/hasura/js/internal_urls.mdc +27 -0
  46. package/rules/hasura/js/migrations.mdc +13 -0
  47. package/rules/hasura/js/svc_hl.mdc +17 -0
  48. package/rules/hasura/main.mdc +8 -30
  49. package/rules/image-avif/js/avif_generation.mdc +26 -0
  50. package/rules/image-avif/js/package_json_optout.mdc +21 -0
  51. package/rules/image-avif/main.mdc +7 -34
  52. package/rules/image-compress/js/package_json.mdc +7 -0
  53. package/rules/image-compress/js/package_setup.mdc +13 -0
  54. package/rules/image-compress/main.mdc +4 -12
  55. package/rules/js/docs/index.md +3 -3
  56. package/rules/js/js/dep-policy.mdc +17 -0
  57. package/rules/js/js/eslint-config.mdc +28 -0
  58. package/rules/js/js/extensions.mdc +8 -0
  59. package/rules/js/js/file-extensions.mdc +12 -0
  60. package/rules/js/js/for-in.mdc +26 -0
  61. package/rules/js/js/jscpd.mdc +42 -0
  62. package/rules/js/js/knip.mdc +15 -0
  63. package/rules/js/js/lint-js-workflow.mdc +58 -0
  64. package/rules/js/js/oxlintrc.mdc +20 -0
  65. package/rules/js/js/package-json.mdc +31 -0
  66. package/rules/js/js/tests.mdc +9 -0
  67. package/rules/js/js/utils-lib-structure.mdc +15 -0
  68. package/rules/js/main.mdc +21 -214
  69. package/rules/js-bun-db/js/bun-sql-migration.mdc +15 -0
  70. package/rules/js-bun-db/js/connection.mdc +42 -0
  71. package/rules/js-bun-db/js/pg-format-identifiers.mdc +102 -0
  72. package/rules/js-bun-db/js/pg-format-shim.mdc +99 -0
  73. package/rules/js-bun-db/js/pg-leftover.mdc +27 -0
  74. package/rules/js-bun-db/js/pg-listen-notify.mdc +51 -0
  75. package/rules/js-bun-db/js/query-safety.mdc +117 -0
  76. package/rules/js-bun-db/js/sql-array.mdc +88 -0
  77. package/rules/js-bun-db/js/unsafe.mdc +65 -0
  78. package/rules/js-bun-db/main.mdc +15 -605
  79. package/rules/js-bun-redis/js/imports.mdc +47 -0
  80. package/rules/js-bun-redis/js/package_json.mdc +44 -0
  81. package/rules/js-bun-redis/main.mdc +3 -11
  82. package/rules/js-mssql/js/mssql-in-list.mdc +38 -0
  83. package/rules/js-mssql/js/mssql-pool.mdc +56 -0
  84. package/rules/js-mssql/js/mssql-query-template.mdc +33 -0
  85. package/rules/js-mssql/js/mssql-tvp.mdc +75 -0
  86. package/rules/js-mssql/js/mssql-version.mdc +7 -0
  87. package/rules/js-mssql/main.mdc +10 -198
  88. package/rules/js-run/js/check-env.mdc +35 -0
  89. package/rules/js-run/js/conn-aliases.mdc +109 -0
  90. package/rules/js-run/js/jsconfig.mdc +20 -0
  91. package/rules/js-run/js/otel-configmap.mdc +6 -0
  92. package/rules/js-run/js/pino.mdc +6 -0
  93. package/rules/js-run/js/project-structure.mdc +11 -0
  94. package/rules/js-run/js/runtime.mdc +14 -0
  95. package/rules/js-run/js/scope.mdc +11 -0
  96. package/rules/js-run/js/settimeout.mdc +11 -0
  97. package/rules/js-run/js/temporal.mdc +5 -0
  98. package/rules/js-run/main.mdc +16 -218
  99. package/rules/k8s/js/configmap.mdc +41 -0
  100. package/rules/k8s/js/deployment_resources.mdc +49 -0
  101. package/rules/k8s/js/hasura_httproute.mdc +91 -0
  102. package/rules/k8s/js/hpa_apiversion.mdc +27 -0
  103. package/rules/k8s/js/ingress_gateway.mdc +16 -0
  104. package/rules/k8s/js/kustomize_structure.mdc +144 -0
  105. package/rules/k8s/js/lint_k8s.mdc +72 -0
  106. package/rules/k8s/js/multidoc_yaml.mdc +5 -0
  107. package/rules/k8s/js/network_policy.mdc +136 -0
  108. package/rules/k8s/js/schema_modeline.mdc +57 -0
  109. package/rules/k8s/js/service.mdc +44 -0
  110. package/rules/k8s/js/topology_hpa_pdb.mdc +181 -0
  111. package/rules/k8s/main.mdc +30 -843
  112. package/rules/nginx-default-tpl/js/dockerfile.mdc +36 -0
  113. package/rules/nginx-default-tpl/js/http-route.mdc +41 -0
  114. package/rules/nginx-default-tpl/js/ini-keys.mdc +21 -0
  115. package/rules/nginx-default-tpl/js/template-structure.mdc +86 -0
  116. package/rules/nginx-default-tpl/js/vscode.mdc +37 -0
  117. package/rules/nginx-default-tpl/main.mdc +6 -112
  118. package/rules/npm-module/js/docs/index.md +5 -5
  119. package/rules/npm-module/js/docs/rule_meta.md +6 -6
  120. package/rules/npm-module/js/docs/skill_meta.md +8 -8
  121. package/rules/npm-module/js/header_doc_pointer.mdc +18 -0
  122. package/rules/npm-module/js/package_structure.mdc +62 -0
  123. package/rules/npm-module/js/rule_meta.mdc +11 -0
  124. package/rules/npm-module/js/skill_meta.mdc +11 -0
  125. package/rules/npm-module/main.mdc +10 -55
  126. package/rules/php/js/lint_php_yml.mdc +12 -0
  127. package/rules/php/js/tooling.mdc +66 -0
  128. package/rules/php/main.mdc +7 -66
  129. package/rules/python/js/lint_python_yml.mdc +23 -0
  130. package/rules/python/js/pyproject_toml.mdc +32 -0
  131. package/rules/python/js/tooling.mdc +23 -0
  132. package/rules/python/main.mdc +9 -33
  133. package/rules/rego/js/rego-lint.mdc +31 -0
  134. package/rules/rego/js/vscode_extensions.mdc +11 -0
  135. package/rules/rego/js/vscode_settings.mdc +13 -0
  136. package/rules/rego/main.mdc +8 -24
  137. package/rules/rust/js/coverage.mdc +28 -0
  138. package/rules/rust/js/lint.mdc +22 -0
  139. package/rules/rust/js/tauri_composition.mdc +8 -0
  140. package/rules/rust/js/vscode_extensions.mdc +12 -0
  141. package/rules/rust/main.mdc +8 -38
  142. package/rules/security/js/rego_policies.mdc +15 -0
  143. package/rules/security/js/sample_secret.mdc +19 -0
  144. package/rules/security/js/trufflehog.mdc +21 -0
  145. package/rules/security/main.mdc +7 -35
  146. package/rules/style/js/admin-table.mdc +88 -0
  147. package/rules/style/js/colors.mdc +21 -0
  148. package/rules/style/js/gap.mdc +22 -0
  149. package/rules/style/js/quasar-fixes.mdc +32 -0
  150. package/rules/style/js/quasar.mdc +7 -0
  151. package/rules/style/js/tooling.mdc +85 -0
  152. package/rules/style/main.mdc +13 -253
  153. package/rules/tauri/js/cargo_mutants_config.mdc +39 -0
  154. package/rules/tauri/js/tool_surface.mdc +21 -0
  155. package/rules/tauri/js/tooling.mdc +25 -0
  156. package/rules/tauri/main.mdc +8 -78
  157. package/rules/test/js/cargo_mutants_config.mdc +18 -0
  158. package/rules/test/js/docs/index.md +7 -7
  159. package/rules/test/js/location.mdc +52 -0
  160. package/rules/test/js/no-console-store-restore.mdc +11 -0
  161. package/rules/test/js/no-process-chdir.mdc +15 -0
  162. package/rules/test/js/no-relative-fs-path.mdc +22 -0
  163. package/rules/test/js/sandbox-aware-test.mdc +28 -0
  164. package/rules/test/js/stryker_config.mdc +26 -0
  165. package/rules/test/js/vitest-config-pool-forks.mdc +33 -0
  166. package/rules/test/main.mdc +18 -184
  167. package/rules/text/js/ci-lint-text.mdc +15 -0
  168. package/rules/text/js/cspell.mdc +81 -0
  169. package/rules/text/js/dotenv-linter.mdc +16 -0
  170. package/rules/text/js/forbidden-prettier.mdc +13 -0
  171. package/rules/text/js/markdownlint.mdc +25 -0
  172. package/rules/text/js/oxfmt.mdc +35 -0
  173. package/rules/text/js/package-json.mdc +26 -0
  174. package/rules/text/js/shellcheck.mdc +18 -0
  175. package/rules/text/js/v8r.mdc +23 -0
  176. package/rules/text/js/vscode.mdc +86 -0
  177. package/rules/text/main.mdc +20 -237
  178. package/rules/vue/js/composition-api.mdc +82 -0
  179. package/rules/vue/js/nheader-layout.mdc +171 -0
  180. package/rules/vue/js/node-imports.mdc +25 -0
  181. package/rules/vue/js/quasar-ui.mdc +32 -0
  182. package/rules/vue/js/structure.mdc +101 -0
  183. package/rules/vue/js/testing.mdc +32 -0
  184. package/rules/vue/js/tfm-translations.mdc +26 -0
  185. package/rules/vue/js/vite-config.mdc +126 -0
  186. package/rules/vue/js/vite-env.mdc +55 -0
  187. package/rules/vue/js/vue-imports.mdc +25 -0
  188. package/rules/vue/main.mdc +16 -640
  189. package/scripts/auto-rules.mjs +6 -6
  190. package/scripts/auto-skills.mjs +3 -3
  191. package/scripts/docs/auto-rules.md +17 -31
  192. package/scripts/docs/auto-skills.md +18 -163
  193. package/scripts/docs/index.md +16 -16
  194. package/scripts/lib/docs/index.md +36 -36
  195. package/scripts/lib/docs/mirror-parity.md +7 -7
  196. package/scripts/lib/docs/rule-meta.md +12 -12
  197. package/scripts/lib/docs/skill-meta.md +9 -9
  198. package/scripts/lib/docs/worktree-notice.md +10 -8
  199. package/scripts/lib/rule-meta.mjs +6 -6
  200. package/scripts/lib/skill-meta.mjs +6 -6
  201. package/scripts/lib/worktree-notice.mjs +2 -2
  202. package/scripts/utils/docs/index.md +14 -14
@@ -5,46 +5,18 @@ alwaysApply: false
5
5
  version: '2.1'
6
6
  ---
7
7
 
8
- [TruffleHog](https://github.com/trufflesecurity/trufflehog) глобальний CLI (як `shellcheck`, `conftest`); **не** додавай до `dependencies`/`devDependencies`.
8
+ Правило **security** забезпечує сканування секретів через [TruffleHog](https://github.com/trufflesecurity/trufflehog) локально та на CI, а також правильне використання placeholder-значень у прикладних файлах.
9
9
 
10
- ## Канон `package.json`
10
+ [security-trufflehog](./js/trufflehog.mdc)
11
11
 
12
- Скан запускається через `n-cursor lint security` (CI — `n-cursor lint security --read-only`); окремого `lint-*` скрипта в `package.json` немає.
12
+ [security-sample-secret](./js/sample_secret.mdc)
13
13
 
14
- - Заборонено `trufflehog` у `dependencies`/`devDependencies`: [package.json.deny.json](./policy/package_json/template/package.json.deny.json)
14
+ [security-rego-policies](./js/rego_policies.mdc)
15
15
 
16
- **Зауваження:**
16
+ ## Швидкий gate через conftest
17
17
 
18
- - `trufflehog filesystem .` сканує робоче дерево як директорію (включно з untracked/gitignored файлами); підкоманда `git file://.` лишається на CI для аудиту історії.
19
- - `--no-update` — вимикає self-update check (CI-friendly).
20
- - `--exclude-paths .trufflehog-exclude` — файл з regex-patterns, які треба пропускати (аналог `[allowlist].paths` із gitleaks).
21
- - `--results=verified,unknown` — показує лише верифіковані секрети + ті, що TruffleHog не зміг перевірити (`unverified` дублікат відсіюється).
22
- - `--fail` — exit-code `183` за наявності знахідок (щоб лінт падав).
23
-
24
- ## `.trufflehog-exclude` (рекомендована основа)
25
-
26
- Канон (допускає розширення): [.trufflehog-exclude.snippet.txt](./js/templates/trufflehog/.trufflehog-exclude.snippet.txt)
27
-
28
- **Важливо:** один regex-pattern на рядок, без TOML-обгортки; коментарі починаються з `#`.
29
-
30
- ## CI: `.github/workflows/lint-security.yml`
31
-
32
- Workflow обовʼязковий — забезпечує незалежний скан секретів на push/PR (агрегований `lint` локально + окремий fail-fast job на CI).
33
-
34
- - Канон: [lint-security.yml.snippet.yml](./policy/lint_security_yml/template/lint-security.yml.snippet.yml)
35
-
36
- Перевіряється policy `security.lint_security_yml`: серед `uses:` має бути крок з `trufflesecurity/trufflehog@main`. Універсальні workflow-перевірки (checkout, permissions, persist-credentials) — у `ga.workflow_common`. Для повного скану історії потрібен `fetch-depth: 0`.
37
-
38
- ## Placeholder для секретів — `sample-secret`
39
-
40
- Фейкові credential-значення у **прикладних файлах** (`.env.example`, `.env.dist`, `*.example`, `*.sample`, `*.template`, вміст каталогів `fixtures/`) пиши як `sample-secret`, а не як bare `secret`.
41
-
42
- `sample-secret` містить підрядок `sample` із вшитого списку `DefaultFalsePositives` TruffleHog — таке значення сканер відсіює **гарантовано** й незалежно від версії. Bare `secret` наразі не фіксується сканером лише тому, що випадково присутнє у словнику `fp_words.txt`; це крихка поведінка, що залежить від версії інструмента.
43
-
44
- - Правильно: `DB_PASSWORD=sample-secret`, `password: "sample-secret"`
45
- - Неправильно: `DB_PASSWORD=secret`, `password: "secret"`
46
-
47
- Перевіряється лише `secret` у позиції значення (після `=`, `:`, `=>`); імена ключів на кшталт `client_secret` не чіпаються. Concern `security.sample_secret` — деталі скану в `js/sample_secret.mjs`.
18
+ - `security.package_json`забороняє `trufflehog` у `dependencies`/`devDependencies`
19
+ - `security.lint_security_yml`перевіряє наявність кроку `trufflesecurity/trufflehog@main` у CI workflow
48
20
 
49
21
  ## Перевірка
50
22
 
@@ -0,0 +1,88 @@
1
+ ## Адмінські таблиці — n-admin-table
2
+
3
+ Для таблиць, що мають займати всю висоту сторінки (або блоку), додавай клас `n-admin-table` і атрибути `hide-no-data`, `dense`, `flat`. Таблиця автоматично розтягнеться на весь доступний простір. У блоках меншої висоти — задай їм явний `height`.
4
+
5
+ ```vue
6
+ <!-- ТАБЛИЦЯ -->
7
+ <q-table class="n-admin-table" hide-no-data flat dense />
8
+ ```
9
+
10
+ Якщо клас `.n-admin-table` не визначено в `app.scss` — додай:
11
+
12
+ ```scss
13
+ // ADMIN TABLE
14
+ .n-admin-table {
15
+ height: calc(100vh - 106px);
16
+
17
+ thead {
18
+ position: sticky;
19
+ z-index: 3;
20
+ top: 0;
21
+
22
+ tr th {
23
+ background-color: $grey-3;
24
+ height: 36px !important;
25
+ }
26
+ }
27
+
28
+ // tbody td {
29
+ // font-size: 14px;
30
+ // }
31
+
32
+ tbody tr:last-child td {
33
+ border-bottom: 1px solid rgb(0 0 0 / 12%) !important;
34
+ }
35
+
36
+ th:first-child,
37
+ td:first-child,
38
+ th:last-child,
39
+ td:last-child {
40
+ width: 1px;
41
+ white-space: nowrap;
42
+ }
43
+
44
+ .q-table__bottom {
45
+ background-color: $grey-3;
46
+ }
47
+
48
+ .q-table__progress th {
49
+ height: 1px !important;
50
+ }
51
+
52
+ .text-wrap {
53
+ max-width: 250px;
54
+ white-space: normal;
55
+ }
56
+
57
+ // sticky columns
58
+ td.sticky-left {
59
+ position: sticky;
60
+ left: 0;
61
+ z-index: 2;
62
+ background-color: white;
63
+ box-shadow: 2px 0 5px #0002;
64
+ }
65
+
66
+ td.sticky-right {
67
+ position: sticky;
68
+ right: 0;
69
+ z-index: 2;
70
+ background-color: white;
71
+ box-shadow: -2px 0 5px #0002;
72
+ }
73
+
74
+ th.sticky-left {
75
+ position: sticky;
76
+ left: 0;
77
+ z-index: 3;
78
+ box-shadow: 2px 0 5px #0002;
79
+ }
80
+
81
+ th.sticky-right {
82
+ position: sticky;
83
+ right: 0;
84
+ z-index: 3;
85
+ box-shadow: -2px 0 5px #0002;
86
+ }
87
+ }
88
+ ```
@@ -0,0 +1,21 @@
1
+ ## Кольори: quasar-variables.scss і app.scss
2
+
3
+ Основні кольори визначай виключно через стандартні Quasar-змінні: `$primary`, `$secondary`, `$accent`, `$positive`, `$negative`, `$warning`.
4
+
5
+ Якщо потрібен додатковий колір — визнач його в `quasar-variables.scss`, і **обов'язково** додай до `app.scss` відповідні `.text-*` / `.bg-*` класи:
6
+
7
+ ```scss
8
+ /* quasar-variables.scss */
9
+ $white-a1: color.adjust(white, $alpha: -0.85);
10
+ ```
11
+
12
+ ```scss
13
+ /* app.scss */
14
+ .text-white-a1 {
15
+ color: $white-a1 !important;
16
+ }
17
+
18
+ .bg-white-a1 {
19
+ background-color: $white-a1 !important;
20
+ }
21
+ ```
@@ -0,0 +1,22 @@
1
+ ## Gap між flex/grid-елементами — .n-gap-*
2
+
3
+ Для відступів між плаваючими елементами (flex, grid) використовуй класи `.n-gap-*` замість `q-gutter-*`. Якщо класів немає в `app.scss` — додай:
4
+
5
+ ```scss
6
+ // GAP
7
+ .n-gap-xs {
8
+ gap: 4px;
9
+ }
10
+
11
+ .n-gap-sm {
12
+ gap: 8px;
13
+ }
14
+
15
+ .n-gap-md {
16
+ gap: 16px;
17
+ }
18
+
19
+ .n-gap-lg {
20
+ gap: 24px;
21
+ }
22
+ ```
@@ -0,0 +1,32 @@
1
+ ## Фікси компонентів Quasar
2
+
3
+ При використанні компонента `q-scroll-area` або `q-tooltip` додай до `app.scss` відповідні фікси. Аналогічно — фікс масштабування на iOS.
4
+
5
+ ```scss
6
+ // FIX стилі для прокручуваної області по висоті екрана
7
+ .q-scrollarea {
8
+ display: flex;
9
+ flex-direction: column;
10
+ height: auto;
11
+ min-height: 0;
12
+ max-height: 100%;
13
+
14
+ .scroll {
15
+ flex: 10000 1 0%;
16
+ }
17
+ }
18
+
19
+ // FIX tooltip
20
+ .q-tooltip {
21
+ font-size: 1em;
22
+ }
23
+
24
+ // FIX не зумувати на iOS
25
+ @media (width <= 600px) {
26
+ input,
27
+ textarea,
28
+ select {
29
+ font-size: 16px;
30
+ }
31
+ }
32
+ ```
@@ -0,0 +1,7 @@
1
+ ## Quasar як стильова основа
2
+
3
+ У Vue-проектах використовуй **Quasar** як базову стильову систему:
4
+
5
+ - **Класи компонентів:** `q-pa-*`, `q-ma-*`, `q-mt-*`, `q-mb-*`, `row`, `col`, `col-*`, `items-center`, `justify-between`, `text-*`, `bg-*`, `shadow-*` тощо — стандартні утиліти Quasar.
6
+ - **Кольори:** використовуй Quasar CSS-змінні через класи (`text-primary`, `bg-accent`, `text-negative` тощо) або через SCSS-змінні (`$primary`, `$accent`) у `.scss`-файлах.
7
+ - **Не пиши власні утиліти**, якщо є відповідний Quasar-клас.
@@ -0,0 +1,85 @@
1
+ ## Генерація та редагування стилів (Cursor і інші агенти)
2
+
3
+ - **Джерело правил:** перед тим як писати або суттєво змінювати **`.css`**, **`.scss`** або стилі в **`.vue`**, переглянь у корені проєкту (і в релевантних пакетах монорепо, якщо є) поле **`stylelint`** у **`package.json`** (зокрема `extends`), наявні **`.stylelintrc.*`**, **`stylelint.config.*`** та **`.stylelintignore`**. Не покладайся на «типові» правила stylelint з пам'яті — дотримуйся **проєктного** **`@nitra/stylelint-config`** і будь-яких локальних доповнень у репозиторії.
4
+ - **Форматування** узгоджуй з **`n-text.mdc`** (oxfmt / `.oxfmtrc.json` для css, scss тощо), щоб форматер і stylelint не суперечили один одному.
5
+ - **Запуск stylelint:** лише через **`n-cursor lint style`** (локально — з auto-fix; у CI — `--read-only`, нуль мутацій). Під капотом — `npx stylelint`; **не** використовуй **`bunx stylelint`**. Після змін запускай **`n-cursor lint style`** і виправляй усе, що лишилось після auto-fix; за потреби — повний прогін `n-cursor lint --full`.
6
+ - **Не розширюй винятки:** не додавай зайві **`stylelint-disable`** без потреби; краще підлаштувати стилі під правила проєкту.
7
+
8
+ ## Канон налаштувань
9
+
10
+ ### `package.json`
11
+
12
+ - `stylelint.extends`: [package.json.snippet.json](./policy/package_json/template/package.json.snippet.json)
13
+
14
+ Окремого `lint-style` скрипта немає — запуск через **`n-cursor lint style`** (CI — `--read-only`).
15
+
16
+ ```json title="package.json"
17
+ "devDependencies": {
18
+ "@nitra/stylelint-config": "^1.4.0"
19
+ },
20
+ "stylelint": {
21
+ "extends": "@nitra/stylelint-config"
22
+ },
23
+ ```
24
+
25
+ У корені проєкту має бути **`.stylelintignore`**:
26
+
27
+ ```text title=".stylelintignore"
28
+ dist/
29
+ ```
30
+
31
+ ### `.vscode/extensions.json`
32
+
33
+ - Канон `recommendations`: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
34
+
35
+ ### `.vscode/settings.json`
36
+
37
+ - Вимкнення вбудованої CSS-валідації VS Code: [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
38
+
39
+ ### CI: `.github/workflows/lint-style.yml`
40
+
41
+ - Канон: [lint-style.yml.snippet.yml](./policy/lint_style_yml/template/lint-style.yml.snippet.yml)
42
+
43
+ Додай **`.github/workflows/lint-style.yml`** (лише **`.yml`**, **`ga.mdc`**): після **`checkout`** — локальний composite **`setup-bun-deps`**, далі `n-cursor lint style --read-only` у кроці **`run`**. **Не** дублюй окремі кроки **`setup-node`** / **`oven-sh/setup-bun`** / кеш / **`npm install`**.
44
+
45
+ ```yaml title=".github/workflows/lint-style.yml"
46
+ name: StyleLint
47
+
48
+ on:
49
+ push:
50
+ branches:
51
+ - dev
52
+ - main
53
+ paths:
54
+ - '**/*.css'
55
+ - '**/*.scss'
56
+ - '**/*.vue'
57
+
58
+ pull_request:
59
+ branches:
60
+ - dev
61
+ - main
62
+ paths:
63
+ - '**/*.css'
64
+ - '**/*.scss'
65
+ - '**/*.vue'
66
+
67
+ concurrency:
68
+ group: ${{ github.ref }}-${{ github.workflow }}
69
+ cancel-in-progress: true
70
+
71
+ jobs:
72
+ stylelint:
73
+ runs-on: ubuntu-latest
74
+ permissions:
75
+ contents: read
76
+ steps:
77
+ - uses: actions/checkout@v6
78
+ with:
79
+ persist-credentials: false
80
+
81
+ - uses: ./.github/actions/setup-bun-deps
82
+
83
+ - name: StyleLint
84
+ run: npx stylelint '**/*.{css,scss,vue}'
85
+ ```
@@ -5,265 +5,25 @@ globs: "**/*.{css,scss,vue}"
5
5
  alwaysApply: false
6
6
  ---
7
7
 
8
- ## Quasar як стильова основа
8
+ Правило **style** для Vue-проєктів: Quasar як стильова система, SCSS-конвенції кольорів і відступів, фікси компонентів, stylelint через `@nitra/stylelint-config`.
9
9
 
10
- У Vue-проектах використовуй **Quasar** як базову стильову систему:
10
+ [style-quasar](./js/quasar.mdc)
11
11
 
12
- - **Класи компонентів:** `q-pa-*`, `q-ma-*`, `q-mt-*`, `q-mb-*`, `row`, `col`, `col-*`, `items-center`, `justify-between`, `text-*`, `bg-*`, `shadow-*` тощо — стандартні утиліти Quasar.
13
- - **Кольори:** використовуй Quasar CSS-змінні через класи (`text-primary`, `bg-accent`, `text-negative` тощо) або через SCSS-змінні (`$primary`, `$accent`) у `.scss`-файлах.
14
- - **Не пиши власні утиліти**, якщо є відповідний Quasar-клас.
12
+ [style-colors](./js/colors.mdc)
15
13
 
16
- ## Кольори: quasar-variables.scss і app.scss
14
+ [style-gap](./js/gap.mdc)
17
15
 
18
- Основні кольори визначай виключно через стандартні Quasar-змінні: `$primary`, `$secondary`, `$accent`, `$positive`, `$negative`, `$warning`.
16
+ [style-quasar-fixes](./js/quasar-fixes.mdc)
19
17
 
20
- Якщо потрібен додатковий колір — визнач його в `quasar-variables.scss`, і **обов'язково** додай до `app.scss` відповідні `.text-*` / `.bg-*` класи:
18
+ [style-tooling](./js/tooling.mdc)
21
19
 
22
- ```scss
23
- /* quasar-variables.scss */
24
- $white-a1: color.adjust(white, $alpha: -0.85);
25
- ```
20
+ [style-admin-table](./js/admin-table.mdc)
26
21
 
27
- ```scss
28
- /* app.scss */
29
- .text-white-a1 {
30
- color: $white-a1 !important;
31
- }
22
+ ## Швидкий gate через conftest (Rego)
32
23
 
33
- .bg-white-a1 {
34
- background-color: $white-a1 !important;
35
- }
36
- ```
24
+ Пакети у `npm/rules/style/policy/`:
37
25
 
38
- ## Gap між flex/grid-елементами .n-gap-*
39
-
40
- Для відступів між плаваючими елементами (flex, grid) використовуй класи `.n-gap-*` замість `q-gutter-*`. Якщо класів немає в `app.scss` додай:
41
-
42
- ```scss
43
- // GAP
44
- .n-gap-xs {
45
- gap: 4px;
46
- }
47
-
48
- .n-gap-sm {
49
- gap: 8px;
50
- }
51
-
52
- .n-gap-md {
53
- gap: 16px;
54
- }
55
-
56
- .n-gap-lg {
57
- gap: 24px;
58
- }
59
- ```
60
-
61
- ## Фікси компонентів Quasar
62
-
63
- При використанні компонента `q-scroll-area` або `q-tooltip` додай до `app.scss` відповідні фікси. Аналогічно — фікс масштабування на iOS.
64
-
65
- ```scss
66
- // FIX стилі для прокручуваної області по висоті екрана
67
- .q-scrollarea {
68
- display: flex;
69
- flex-direction: column;
70
- height: auto;
71
- min-height: 0;
72
- max-height: 100%;
73
-
74
- .scroll {
75
- flex: 10000 1 0%;
76
- }
77
- }
78
-
79
- // FIX tooltip
80
- .q-tooltip {
81
- font-size: 1em;
82
- }
83
-
84
- // FIX не зумувати на iOS
85
- @media (width <= 600px) {
86
- input,
87
- textarea,
88
- select {
89
- font-size: 16px;
90
- }
91
- }
92
- ```
93
-
94
- ## Генерація та редагування стилів (Cursor і інші агенти)
95
-
96
- - **Джерело правил:** перед тим як писати або суттєво змінювати **`.css`**, **`.scss`** або стилі в **`.vue`**, переглянь у корені проєкту (і в релевантних пакетах монорепо, якщо є) поле **`stylelint`** у **`package.json`** (зокрема `extends`), наявні **`.stylelintrc.*`**, **`stylelint.config.*`** та **`.stylelintignore`**. Не покладайся на «типові» правила stylelint з пам’яті — дотримуйся **проєктного** **`@nitra/stylelint-config`** і будь-яких локальних доповнень у репозиторії.
97
- - **Форматування** узгоджуй з **`n-text.mdc`** (oxfmt / `.oxfmtrc.json` для css, scss тощо), щоб форматер і stylelint не суперечили один одному.
98
- - **Запуск stylelint:** лише через **`n-cursor lint style`** (локально — з auto-fix; у CI — `--read-only`, нуль мутацій). Під капотом — `npx stylelint`; **не** використовуй **`bunx stylelint`**. Після змін запускай **`n-cursor lint style`** і виправляй усе, що лишилось після auto-fix; за потреби — повний прогін `n-cursor lint --full`.
99
- - **Не розширюй винятки:** не додавай зайві **`stylelint-disable`** без потреби; краще підлаштувати стилі під правила проєкту.
100
-
101
- ## Канон
102
-
103
- ### `package.json`
104
-
105
- - `stylelint.extends`: [package.json.snippet.json](./policy/package_json/template/package.json.snippet.json)
106
-
107
- Окремого `lint-style` скрипта немає — запуск через **`n-cursor lint style`** (CI — `--read-only`).
108
-
109
- ### `.vscode/extensions.json`
110
-
111
- - Канон `recommendations`: [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
112
-
113
- ### `.vscode/settings.json`
114
-
115
- - Вимкнення вбудованої CSS-валідації VS Code: [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
116
-
117
- ### CI: `.github/workflows/lint-style.yml`
118
-
119
- - Канон: [lint-style.yml.snippet.yml](./policy/lint_style_yml/template/lint-style.yml.snippet.yml)
120
-
121
- **`package.json`:**
122
-
123
- ```json title="package.json"
124
- "devDependencies": {
125
- "@nitra/stylelint-config": "^1.4.0"
126
- },
127
- "stylelint": {
128
- "extends": "@nitra/stylelint-config"
129
- },
130
- ```
131
-
132
- Додай **`.github/workflows/lint-style.yml`** (лише **`.yml`**, **`ga.mdc`**): після **`checkout`** — локальний composite **`setup-bun-deps`**, далі `n-cursor lint style --read-only` у кроці **`run`**. **Не** дублюй окремі кроки **`setup-node`** / **`oven-sh/setup-bun`** / кеш / **`npm install`**.
133
-
134
- ```yaml title=".github/workflows/lint-style.yml"
135
- name: StyleLint
136
-
137
- on:
138
- push:
139
- branches:
140
- - dev
141
- - main
142
- paths:
143
- - '**/*.css'
144
- - '**/*.scss'
145
- - '**/*.vue'
146
-
147
- pull_request:
148
- branches:
149
- - dev
150
- - main
151
- paths:
152
- - '**/*.css'
153
- - '**/*.scss'
154
- - '**/*.vue'
155
-
156
- concurrency:
157
- group: ${{ github.ref }}-${{ github.workflow }}
158
- cancel-in-progress: true
159
-
160
- jobs:
161
- stylelint:
162
- runs-on: ubuntu-latest
163
- permissions:
164
- contents: read
165
- steps:
166
- - uses: actions/checkout@v6
167
- with:
168
- persist-credentials: false
169
-
170
- - uses: ./.github/actions/setup-bun-deps
171
-
172
- - name: StyleLint
173
- run: npx stylelint '**/*.{css,scss,vue}'
174
- ```
175
-
176
- У корені проєкту має бути **`.stylelintignore`**:
177
-
178
- ```text title=".stylelintignore"
179
- dist/
180
- ```
181
-
182
- ## Адмінські таблиці — n-admin-table
183
-
184
- Для таблиць, що мають займати всю висоту сторінки (або блоку), додавай клас `n-admin-table` і атрибути `hide-no-data`, `dense`, `flat`. Таблиця автоматично розтягнеться на весь доступний простір. У блоках меншої висоти — задай їм явний `height`.
185
-
186
- ```vue
187
- <!-- ТАБЛИЦЯ -->
188
- <q-table class="n-admin-table" hide-no-data flat dense />
189
- ```
190
-
191
- Якщо клас `.n-admin-table` не визначено в `app.scss` — додай:
192
-
193
- ```scss
194
- // ADMIN TABLE
195
- .n-admin-table {
196
- height: calc(100vh - 106px);
197
-
198
- thead {
199
- position: sticky;
200
- z-index: 3;
201
- top: 0;
202
-
203
- tr th {
204
- background-color: $grey-3;
205
- height: 36px !important;
206
- }
207
- }
208
-
209
- // tbody td {
210
- // font-size: 14px;
211
- // }
212
-
213
- tbody tr:last-child td {
214
- border-bottom: 1px solid rgb(0 0 0 / 12%) !important;
215
- }
216
-
217
- th:first-child,
218
- td:first-child,
219
- th:last-child,
220
- td:last-child {
221
- width: 1px;
222
- white-space: nowrap;
223
- }
224
-
225
- .q-table__bottom {
226
- background-color: $grey-3;
227
- }
228
-
229
- .q-table__progress th {
230
- height: 1px !important;
231
- }
232
-
233
- .text-wrap {
234
- max-width: 250px;
235
- white-space: normal;
236
- }
237
-
238
- // sticky columns
239
- td.sticky-left {
240
- position: sticky;
241
- left: 0;
242
- z-index: 2;
243
- background-color: white;
244
- box-shadow: 2px 0 5px #0002;
245
- }
246
-
247
- td.sticky-right {
248
- position: sticky;
249
- right: 0;
250
- z-index: 2;
251
- background-color: white;
252
- box-shadow: -2px 0 5px #0002;
253
- }
254
-
255
- th.sticky-left {
256
- position: sticky;
257
- left: 0;
258
- z-index: 3;
259
- box-shadow: 2px 0 5px #0002;
260
- }
261
-
262
- th.sticky-right {
263
- position: sticky;
264
- right: 0;
265
- z-index: 3;
266
- box-shadow: -2px 0 5px #0002;
267
- }
268
- }
269
- ```
26
+ - `style_lint.package_json` `package.json`: `stylelint.extends == "@nitra/stylelint-config"`, `@nitra/stylelint-config` у `devDependencies`.
27
+ - `style_lint.vscode_extensions` — `.vscode/extensions.json`: `recommendations` містить `stylelint.vscode-stylelint`.
28
+ - `style_lint.vscode_settings` `.vscode/settings.json`: `css.validate`, `less.validate`, `scss.validate` вимкнені (`false`).
29
+ - `style_lint.lint_style_yml` — `.github/workflows/lint-style.yml`: крок `run` містить команду `n-cursor lint style --read-only`.
@@ -0,0 +1,39 @@
1
+ ## Mutation-testing: семантика app shell та platform bridge
2
+
3
+ `tauri` rule володіє Tauri-specific семантикою mutation-testing для каталога `src-tauri/`. Концерн `js/cargo_mutants_config.mjs` без дублювання додає у `<ws>/src-tauri/.cargo/mutants.toml` такі канонічні ключі:
4
+
5
+ ```toml title="<ws>/src-tauri/.cargo/mutants.toml"
6
+ additional_cargo_test_args = ["--lib", "--tests"]
7
+
8
+ exclude_globs = [
9
+ "src/main.rs",
10
+ "src/lib.rs",
11
+ "src/**/android.rs",
12
+ "src/**/ios.rs",
13
+ "src/**/mobile.rs",
14
+ "src/**/desktop.rs",
15
+ "src/**/macos.rs",
16
+ "src/**/windows.rs",
17
+ "src/**/linux.rs"
18
+ ]
19
+ ```
20
+
21
+ Семантика (фіксована між Tauri-проєктами):
22
+
23
+ - **`src/main.rs`** — binary shell entrypoint: запускає Tauri runtime, реєструє plugins/handlers і повертає управління циклу подій. Тестується smoke/e2e (запуск бінарника), не mutation unit;
24
+ - **`src/lib.rs`** — Tauri runtime entrypoint (`pub fn run`): піднімає весь app shell. Один мутант там тримає весь Tauri runtime, тому ділить sandbox-фейл з `src/main.rs` і тестується smoke/e2e, а не mutation unit;
25
+ - **`*android.rs`, `*ios.rs`, `*mobile.rs`** — mobile plugin bridge / platform glue: тонка обгортка над JNI/Objective-C виклики, mapping platform errors, виклики Tauri AppHandle і native API;
26
+ - **`*macos.rs`, `*windows.rs`, `*linux.rs`, `*desktop.rs`** — desktop platform bridge / OS integration glue: opener/window APIs, OS-specific I/O, mapping platform errors.
27
+
28
+ Ці файли мають містити **тільки platform boundary**: виклик plugin/native API, Tauri AppHandle, opener/window APIs, OS-specific I/O, mapping platform errors. Якщо у bridge-файлі з'являється pure/business logic — її потрібно винести у platform-neutral модуль (`src/auth/oauth.rs`, `src/gmail/message.rs`, …) і тестувати mutation-testing там.
29
+
30
+ Це створює фіксовану семантику: `*android.rs`/`*macos.rs` — boundary-файли, а не місце для бізнес-логіки.
31
+
32
+ ### Ідемпотентність і взаємодія з `test`-rule
33
+
34
+ - `test` rule створює універсальний нейтральний `.cargo/mutants.toml` (порожній з коментарем) для кожного Cargo.toml-manifest-файла — без framework-specific exclude'ів. Це наш baseline.
35
+ - `tauri` rule додає Tauri-канонічні ключі **поверх** того, що вже є у `<ws>/src-tauri/.cargo/mutants.toml`:
36
+ - якщо файла немає — створює з повного Tauri-baseline;
37
+ - якщо обидва канонічні ключі (`additional_cargo_test_args`, `exclude_globs`) вже присутні — `manual cargo-mutants config preserved`, нічого не зміниться;
38
+ - якщо якийсь канонічний ключ відсутній — додається окремим блоком у кінці файла, без зміни існуючих значень.
39
+ - Послідовний `fix test` → `fix tauri` створює Tauri-config; повторний `fix tauri` не дублює секцій; повторний `fix test` не перетирає Tauri-tuning.
@@ -0,0 +1,21 @@
1
+ ## Tool Surface у Tauri (реалізація ядра `tool-surface`)
2
+
3
+ Це per-stack реалізація правила **`tool-surface`** (`n-tool-surface`) для Tauri+Rust. Контракт (каталог → `dispatch` → UI/оркестратор/LLM, інваріант паритету, конверт) — у тому правилі; тут — як він лягає на Tauri.
4
+
5
+ **Реальна робота живе в Rust, JS-каталог — тонкий call surface.** Handler тула не містить логіки сам — він **делегує** в native. Одна реалізація в Rust-крейті backs два споживачі:
6
+
7
+ - **Бінарник** (`src-tauri` як CLI, або окремий crate-bin) — headless-вхід для оркестратора;
8
+ - **Tauri-команда** (`#[tauri::command]`) — той самий крейт-fn, обгорнутий для UI.
9
+
10
+ **Два транспорти одного каталогу** (`src/tool/transports`):
11
+
12
+ - **UI (in-app):** `invoke(tool.tauri, input)` → Tauri-команда → крейт. Ключі `input` мапляться 1:1 на аргументи команди (camelCase, напр. `tasksDir`); поля вкладених struct лишаються snake_case (Tauri конвертить лише імена top-level аргументів).
13
+ - **Оркестратор (headless):** `bin/<app>.mjs` спавнить зібраний бінарник (`<bin> <verb> …` per-verb, або уніфікований `<bin> exec '<json>'`), парсить JSON stdout.
14
+
15
+ **Конверт:** Tauri-команда повертає `Result<T, String>`; адаптер мапить у `{ ok, output }` / `{ ok:false, error }`. Бінарник друкує конверт у stdout, exit ≠ 0 на `ok:false`.
16
+
17
+ **Єдине джерело схем:** надавай перевагу `schemars`-derive на Rust-param-структурах → бінарник віддає маніфест (`<bin> schema`); або тримай схему в JS-каталозі й валідуй до `invoke`. **Не дублюй** контракт між Rust і JS — лише деривація + спільні тест-вектори.
18
+
19
+ **Дозволи:** будь-який плагін, який смикають тули (`tauri-plugin-dialog`, `tauri-plugin-http` для локальної LLM тощо), має бути в `src-tauri/capabilities/*.json` і зареєстрований у `lib.rs` — інакше виклик тихо падає.
20
+
21
+ **LLM-раннер in-app:** chat-loop ходить до OpenAI-сумісного ендпоінта через `tauri-plugin-http` fetch (бо webview-fetch обмежений CSP/capability), а тули виконує через спільний `dispatch` (той самий, що й UI).