@nitra/cursor 3.22.0 → 3.23.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.
Files changed (228) hide show
  1. package/.pi-template/extensions/n-cursor-adr/docs/index.md +181 -0
  2. package/CHANGELOG.md +31 -3
  3. package/bin/docs/n-cursor.md +636 -0
  4. package/bin/docs/rename-yaml-extensions.md +207 -0
  5. package/bin/n-cursor.js +30 -3
  6. package/package.json +1 -1
  7. package/rules/abie/docs/fix.md +18 -0
  8. package/rules/abie/js/docs/applies.md +26 -0
  9. package/rules/abie/js/docs/env_dns.md +32 -0
  10. package/rules/abie/js/docs/firebase_hosting.md +23 -0
  11. package/rules/abie/js/docs/hc_pairing.md +35 -0
  12. package/rules/abie/js/docs/ua_http_route.md +28 -0
  13. package/rules/abie/js/docs/ua_node_selector.md +28 -0
  14. package/rules/abie/lib/docs/enabled.md +29 -0
  15. package/rules/abie/lib/docs/env-dns.md +35 -0
  16. package/rules/abie/lib/docs/hc-yaml.md +33 -0
  17. package/rules/abie/lib/docs/http-route.md +44 -0
  18. package/rules/abie/lib/docs/k8s-tree.md +40 -0
  19. package/rules/abie/lib/docs/kustomization-patches.md +47 -0
  20. package/rules/abie/lib/docs/overlay-paths.md +38 -0
  21. package/rules/abie/lib/docs/yaml.md +29 -0
  22. package/rules/adr/docs/fix.md +148 -0
  23. package/rules/adr/js/docs/hooks.md +259 -0
  24. package/rules/bun/docs/fix.md +156 -0
  25. package/rules/bun/js/docs/layout.md +393 -0
  26. package/rules/capacitor/docs/fix.md +121 -0
  27. package/rules/capacitor/js/docs/platforms.md +295 -0
  28. package/rules/changelog/changelog.mdc +2 -2
  29. package/rules/changelog/docs/fix.md +174 -0
  30. package/rules/changelog/js/consistency.mjs +114 -13
  31. package/rules/changelog/js/docs/consistency.md +387 -0
  32. package/rules/changelog/lib/docs/package-manifest.md +210 -0
  33. package/rules/ci4/docs/fix.md +179 -0
  34. package/rules/ci4/js/docs/marksman_config.md +128 -0
  35. package/rules/docker/docker.mdc +8 -3
  36. package/rules/docker/docs/fix.md +171 -0
  37. package/rules/docker/js/docs/lint.md +258 -0
  38. package/rules/docker/lib/docs/docker-hadolint.md +184 -0
  39. package/rules/docker/lib/docs/docker-mirror.md +247 -0
  40. package/rules/docker/lib/docs/docker-native-addon.md +170 -0
  41. package/rules/docker/lib/docs/docker-nginx-user.md +219 -0
  42. package/rules/docker/lint/docs/lint.md +193 -0
  43. package/rules/efes/docs/fix.md +203 -0
  44. package/rules/feedback/docs/fix.md +140 -0
  45. package/rules/flow/docs/fix.md +152 -0
  46. package/rules/ga/docs/fix.md +158 -0
  47. package/rules/ga/js/docs/lint.md +100 -0
  48. package/rules/ga/js/docs/workflows.md +217 -0
  49. package/rules/ga/lint/docs/lint.md +209 -0
  50. package/rules/ga/policy/clean_merged_branch/clean_merged_branch.rego +11 -2
  51. package/rules/ga/policy/clean_merged_branch/template/clean-merged-branch.yml.snippet.yml +3 -4
  52. package/rules/graphql/docs/fix.md +126 -0
  53. package/rules/graphql/js/docs/tooling.md +264 -0
  54. package/rules/graphql/lib/docs/graphql-gql-scan.md +219 -0
  55. package/rules/hasura/docs/fix.md +120 -0
  56. package/rules/hasura/hasura.mdc +14 -0
  57. package/rules/hasura/js/docs/internal_urls.md +326 -0
  58. package/rules/image-avif/docs/fix.md +132 -0
  59. package/rules/image-avif/js/docs/avif_generation.md +241 -0
  60. package/rules/image-compress/docs/fix.md +150 -0
  61. package/rules/image-compress/js/docs/package_setup.md +191 -0
  62. package/rules/js-bun-db/docs/fix.md +148 -0
  63. package/rules/js-bun-db/js/docs/safety.md +231 -0
  64. package/rules/js-bun-db/js-bun-db.mdc +42 -13
  65. package/rules/js-bun-db/lib/docs/bun-sql-scan.md +347 -0
  66. package/rules/js-bun-redis/docs/fix.md +123 -0
  67. package/rules/js-bun-redis/js/docs/imports.md +176 -0
  68. package/rules/js-bun-redis/lib/docs/redis-imports.md +223 -0
  69. package/rules/js-lint/docs/fix.md +117 -0
  70. package/rules/js-lint/js/docs/lint.md +250 -0
  71. package/rules/js-lint/js/docs/tooling.md +348 -0
  72. package/rules/js-lint/js/docs/utils_imports.md +207 -0
  73. package/rules/js-lint-ci/docs/fix.md +154 -0
  74. package/rules/js-lint-ci/js/docs/lint.md +144 -0
  75. package/rules/js-mssql/docs/fix.md +128 -0
  76. package/rules/js-mssql/js/docs/deps.md +263 -0
  77. package/rules/js-mssql/lib/docs/mssql-pool-scan.md +367 -0
  78. package/rules/js-run/docs/fix.md +144 -0
  79. package/rules/js-run/js/docs/runtime.md +388 -0
  80. package/rules/js-run/lib/docs/bunyan-imports.md +117 -0
  81. package/rules/js-run/lib/docs/check-env-scan.md +433 -0
  82. package/rules/js-run/lib/docs/conn-file-rules.md +300 -0
  83. package/rules/js-run/lib/docs/conn-imports-scan.md +204 -0
  84. package/rules/js-run/lib/docs/promise-settimeout-scan.md +326 -0
  85. package/rules/k8s/docs/fix.md +129 -0
  86. package/rules/k8s/js/docs/manifests.md +344 -0
  87. package/rules/k8s/js/manifests.mjs +6 -2
  88. package/rules/k8s/k8s.mdc +4 -2
  89. package/rules/k8s/lint/docs/lint.md +411 -0
  90. package/rules/k8s/policy/network_policy/template/deployment.snippet.yaml +2 -0
  91. package/rules/k8s/policy/network_policy/template/stateful-set.snippet.yaml +2 -0
  92. package/rules/nginx-default-tpl/docs/fix.md +124 -0
  93. package/rules/nginx-default-tpl/js/docs/template.md +378 -0
  94. package/rules/npm-module/docs/fix.md +98 -0
  95. package/rules/npm-module/js/docs/package_structure.md +274 -0
  96. package/rules/npm-module/js/docs/rule_meta.md +137 -0
  97. package/rules/npm-module/js/docs/skill_meta.md +190 -0
  98. package/rules/php/docs/fix.md +107 -0
  99. package/rules/php/js/docs/tooling.md +152 -0
  100. package/rules/php/lint/docs/lint.md +215 -0
  101. package/rules/python/docs/fix.md +163 -0
  102. package/rules/python/js/docs/applies.md +108 -0
  103. package/rules/python/js/docs/tooling.md +153 -0
  104. package/rules/python/lint/docs/lint.md +322 -0
  105. package/rules/rego/docs/fix.md +121 -0
  106. package/rules/rego/js/docs/applies.md +174 -0
  107. package/rules/rego/js/docs/lint.md +118 -0
  108. package/rules/rego/lint/docs/lint.md +204 -0
  109. package/rules/release/docs/change.md +185 -0
  110. package/rules/release/docs/fix.md +119 -0
  111. package/rules/release/docs/release.md +222 -0
  112. package/rules/release/lib/docs/aggregate.md +246 -0
  113. package/rules/release/lib/docs/change-file.md +200 -0
  114. package/rules/release/lib/docs/fallback.md +203 -0
  115. package/rules/rust/docs/fix.md +129 -0
  116. package/rules/rust/js/docs/applies.md +140 -0
  117. package/rules/rust/lib/docs/has-cargo-toml.md +130 -0
  118. package/rules/security/docs/fix.md +86 -0
  119. package/rules/security/js/docs/lint.md +171 -0
  120. package/rules/security/js/docs/sample_secret.md +190 -0
  121. package/rules/security/js/docs/trufflehog.md +137 -0
  122. package/rules/security/js/lint.mjs +9 -1
  123. package/rules/style-lint/docs/fix.md +155 -0
  124. package/rules/style-lint/js/docs/lint.md +184 -0
  125. package/rules/style-lint/js/docs/tooling.md +194 -0
  126. package/rules/tauri/docs/fix.md +158 -0
  127. package/rules/tauri/js/docs/cargo_mutants_config.md +168 -0
  128. package/rules/tauri/js/docs/tooling.md +228 -0
  129. package/rules/test/coverage/coverage.mjs +15 -3
  130. package/rules/test/docs/fix.md +132 -0
  131. package/rules/test/js/data/stryker_config/docs/stryker-vue-macros-ignorer.md +138 -0
  132. package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +134 -0
  133. package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +160 -0
  134. package/rules/test/js/data/vitest_config/docs/vitest.config.baseline.md +195 -0
  135. package/rules/test/js/docs/cargo_mutants_config.md +173 -0
  136. package/rules/test/js/docs/location.md +136 -0
  137. package/rules/test/js/docs/no-process-chdir.md +160 -0
  138. package/rules/test/js/docs/no-relative-fs-path.md +271 -0
  139. package/rules/test/js/docs/stryker_config.md +152 -0
  140. package/rules/test/js/docs/vitest-config-pool-forks.md +174 -0
  141. package/rules/text/docs/fix.md +118 -0
  142. package/rules/text/js/docs/forbidden-prettier.md +143 -0
  143. package/rules/text/js/docs/formatting.md +256 -0
  144. package/rules/text/js/docs/lint.md +122 -0
  145. package/rules/text/lint/docs/lint.md +220 -0
  146. package/rules/text/lint/docs/run-dotenv-linter.md +157 -0
  147. package/rules/text/lint/docs/run-shellcheck.md +212 -0
  148. package/rules/text/lint/docs/run-v8r.md +197 -0
  149. package/rules/vue/docs/fix.md +127 -0
  150. package/rules/vue/js/docs/packages.md +335 -0
  151. package/rules/vue/lib/docs/vue-forbidden-imports.md +261 -0
  152. package/rules/worktree/docs/fix.md +161 -0
  153. package/schemas/rule-meta.json +5 -1
  154. package/scripts/auto-rules.mjs +7 -4
  155. package/scripts/coverage-classify/docs/apply.md +202 -0
  156. package/scripts/coverage-classify/docs/cache.md +203 -0
  157. package/scripts/coverage-classify/docs/index.md +218 -0
  158. package/scripts/coverage-classify/docs/prompt.md +132 -0
  159. package/scripts/coverage-classify/docs/verdict-schema.md +169 -0
  160. package/scripts/coverage-fix-extract.mjs +122 -0
  161. package/scripts/coverage-fix.mjs +1 -1
  162. package/scripts/dispatcher/docs/graph.md +346 -0
  163. package/scripts/dispatcher/docs/index.md +236 -0
  164. package/scripts/dispatcher/docs/trace.md +296 -0
  165. package/scripts/dispatcher/index.mjs +1 -1
  166. package/scripts/dispatcher/lib/active.mjs +4 -8
  167. package/scripts/dispatcher/lib/commands.mjs +7 -11
  168. package/scripts/dispatcher/lib/docs/active.md +348 -0
  169. package/scripts/dispatcher/lib/docs/artifact.md +232 -0
  170. package/scripts/dispatcher/lib/docs/budget.md +167 -0
  171. package/scripts/dispatcher/lib/docs/capability.md +196 -0
  172. package/scripts/dispatcher/lib/docs/commands.md +210 -0
  173. package/scripts/dispatcher/lib/docs/events.md +182 -0
  174. package/scripts/dispatcher/lib/docs/executor.md +190 -0
  175. package/scripts/dispatcher/lib/docs/flow-lock.md +161 -0
  176. package/scripts/dispatcher/lib/docs/flow-resolve.md +267 -0
  177. package/scripts/dispatcher/lib/docs/gate.md +231 -0
  178. package/scripts/dispatcher/lib/docs/level.md +335 -0
  179. package/scripts/dispatcher/lib/docs/plan-panel.md +181 -0
  180. package/scripts/dispatcher/lib/docs/plan.md +200 -0
  181. package/scripts/dispatcher/lib/docs/planner.md +269 -0
  182. package/scripts/dispatcher/lib/docs/review.md +255 -0
  183. package/scripts/dispatcher/lib/docs/reviewer.md +240 -0
  184. package/scripts/dispatcher/lib/docs/snapshot.md +247 -0
  185. package/scripts/dispatcher/lib/docs/spec.md +203 -0
  186. package/scripts/dispatcher/lib/docs/state-store.md +303 -0
  187. package/scripts/dispatcher/lib/docs/subagent-runner.md +173 -0
  188. package/scripts/dispatcher/lib/executor.mjs +6 -1
  189. package/scripts/dispatcher/lib/flow-resolve.mjs +3 -1
  190. package/scripts/dispatcher/lib/level.mjs +29 -3
  191. package/scripts/dispatcher/lib/review.mjs +1 -1
  192. package/scripts/dispatcher/lib/subagent-runner.mjs +5 -3
  193. package/scripts/docs/auto-rules.md +376 -0
  194. package/scripts/docs/auto-skills.md +173 -0
  195. package/scripts/docs/build-agents-commands.md +183 -0
  196. package/scripts/docs/cli-entry.md +153 -0
  197. package/scripts/docs/coverage-fix.md +177 -0
  198. package/scripts/docs/ensure-nitra-cursor-dev-dependencies.md +189 -0
  199. package/scripts/lib/changed-files.mjs +4 -1
  200. package/scripts/lib/docs/changed-files.md +149 -0
  201. package/scripts/lib/docs/check-mdc-template-refs.md +222 -0
  202. package/scripts/lib/docs/check-reporter.md +175 -0
  203. package/scripts/lib/docs/discover-check-rules-from-cursor.md +157 -0
  204. package/scripts/lib/docs/discover-checkable-rules.md +165 -0
  205. package/scripts/lib/docs/ensure-tool.md +254 -0
  206. package/scripts/lib/docs/generated-markdown.md +275 -0
  207. package/scripts/lib/docs/gha-workflow.md +326 -0
  208. package/scripts/lib/docs/inline-template-links.md +303 -0
  209. package/scripts/lib/docs/list-rule-ids.md +156 -0
  210. package/scripts/lib/docs/load-cursor-config.md +147 -0
  211. package/scripts/lib/docs/mirror-parity.md +167 -0
  212. package/scripts/lib/worktree.mjs +26 -0
  213. package/scripts/worktree-cli.mjs +12 -2
  214. package/skills/coverage-fix/SKILL.md +34 -45
  215. package/skills/docgen/SKILL.md +44 -23
  216. package/skills/docgen/bench/etalon/firebase_hosting.md +19 -0
  217. package/skills/docgen/bench/etalon/k8s-tree.md +24 -0
  218. package/skills/docgen/bench/etalon/overlay-paths.md +24 -0
  219. package/skills/docgen/js/docgen-ignore.mjs +54 -0
  220. package/skills/docgen/js/docgen-scan.mjs +37 -21
  221. package/skills/llm-patch/SKILL.md +23 -2
  222. package/skills/start-check/SKILL.md +26 -53
  223. package/skills/start-check/js/check.mjs +211 -0
  224. package/skills/taze/SKILL.md +9 -3
  225. package/skills/taze/js/diff.mjs +154 -0
  226. package/types/bin/n-cursor.d.ts +1 -1
  227. package/skills/fix-tests/SKILL.md +0 -119
  228. package/skills/fix-tests/meta.json +0 -1
@@ -0,0 +1,181 @@
1
+ # `npm/.pi-template/extensions/n-cursor-adr/index.ts`
2
+
3
+ ## Огляд
4
+
5
+ Файл `npm/.pi-template/extensions/n-cursor-adr/index.ts` — це Pi.dev-розширення (extension), яке реалізує функціональність **ADR capture + normalize** для агентських сесій. Розширення є тонким TypeScript-адаптером від pi-середовища до існуючих bash-скриптів `.claude/hooks/capture-decisions.sh` та `.claude/hooks/normalize-decisions.sh`.
6
+
7
+ На подію `agent_end`, що її емітує Pi.dev runtime, розширення:
8
+
9
+ 1. Серіалізує entries сесії з `ctx.sessionManager.getEntries()` у Claude-сумісний формат **JSONL** у тимчасову теку (`os.tmpdir()`).
10
+ 2. Формує stdin JSON payload з шляхом до транскрипту та session id.
11
+ 3. Спавнить bash-хуки `capture-decisions.sh` і `normalize-decisions.sh` через `pi.exec` з відповідними таймаутами (180 с і 600 с).
12
+
13
+ Уся бізнес-логіка skip/throttle і вибір LLM CLI (`claude` чи `cursor-agent`) залишається у bash-скриптах — TS-частина лише транслює подію pi у виклик хуків. Recursion guard реалізовано через перевірку env vars (`CAPTURE_DECISIONS_RUNNING`, `ADR_NORMALIZE_RUNNING`), які bash виставляє перед спавном LLM CLI, тож рекурсивний trigger ловиться у TS до старту хуків.
14
+
15
+ ## Експорти / API
16
+
17
+ ### Default export
18
+
19
+ ```ts
20
+ export default function (pi: PiExec): void
21
+ ```
22
+
23
+ Default export — функція-реєстратор pi-розширення. Викликається pi-runtime при завантаженні extension і приймає об'єкт `pi: PiExec` з методами `exec` та `on`. Функція реєструє один listener на подію `agent_end` і нічого не повертає.
24
+
25
+ ### Внутрішні TypeScript-інтерфейси (не експортуються)
26
+
27
+ #### `PiContext`
28
+
29
+ Опис контексту, що його pi-runtime передає у handler події `agent_end`:
30
+
31
+ - `cwd: string` — поточний робочий каталог pi-сесії; передається у bash як `CLAUDE_PROJECT_DIR` і як `cwd` для `pi.exec`.
32
+ - `sessionId?: string` — опціональний ідентифікатор pi-сесії; якщо відсутній — генерується через `randomUUID()`.
33
+ - `signal?: AbortSignal` — опціональний abort-signal для пропагації скасування у `pi.exec`.
34
+ - `sessionManager: { getEntries(): Array<{ message?: { role?: string; content?: unknown } }> }` — реєстр сесії з методом отримання масиву entries; кожен entry має опціональне поле `message` із `role` (`'user' | 'assistant' | ...`) і `content`.
35
+ - `ui?: { notify?: (msg: string, level?: 'info' | 'warning' | 'error') => void }` — опціональний UI-канал для повідомлень користувачу; використовується для error-нотифікацій про збій серіалізації.
36
+
37
+ #### `PiExec`
38
+
39
+ Pi.dev extension API, що його runtime передає у default export:
40
+
41
+ - `exec(cmd: string, args: string[], opts?: { cwd?: string; env?: Record<string, string>; input?: string; signal?: AbortSignal; timeout?: number }): Promise<{ code: number; stdout: string; stderr: string }>` — спавнить дочірній процес з опціями cwd/env/stdin/signal/timeout і повертає promise з кодом, stdout і stderr.
42
+ - `on(event: string, handler: (event: unknown, ctx: PiContext) => Promise<void> | void): void` — реєструє handler для pi-події (тут — `'agent_end'`).
43
+
44
+ ### Константи-шляхи до хуків
45
+
46
+ - `CAPTURE_HOOK = '.claude/hooks/capture-decisions.sh'` — відносний шлях до bash-хука захоплення ADR-рішень.
47
+ - `NORMALIZE_HOOK = '.claude/hooks/normalize-decisions.sh'` — відносний шлях до bash-хука нормалізації ADR-чернеток через LLM.
48
+
49
+ Шляхи відносні і використовуються разом з `ctx.cwd` як параметром `cwd` у `pi.exec`.
50
+
51
+ ## Функції
52
+
53
+ ### `export default function (pi: PiExec): void`
54
+
55
+ **Сигнатура:** `(pi: PiExec) => void`.
56
+
57
+ **Параметри:**
58
+
59
+ - `pi: PiExec` — pi.dev extension API (див. інтерфейс `PiExec` вище).
60
+
61
+ **Що повертає:** `void`. Функція синхронно реєструє обробник через `pi.on('agent_end', ...)` і завершується.
62
+
63
+ **Side effects:**
64
+
65
+ 1. Реєструє listener на подію `'agent_end'` через `pi.on`.
66
+ 2. Решта side effects відбуваються асинхронно у listener'і `agent_end` (див. нижче).
67
+
68
+ ### Inline listener `pi.on('agent_end', async (_event, ctx) => { ... })`
69
+
70
+ **Сигнатура:** `(_event: unknown, ctx: PiContext) => Promise<void>`.
71
+
72
+ **Параметри:**
73
+
74
+ - `_event: unknown` — payload події `agent_end`; не використовується (префікс `_` сигналізує умисне ігнорування).
75
+ - `ctx: PiContext` — контекст pi-сесії.
76
+
77
+ **Що повертає:** `Promise<void>`. Резолвиться після завершення `Promise.allSettled` з двох викликів `pi.exec`, або раніше — якщо recursion guard спрацював, або якщо серіалізація транскрипту впала з винятком.
78
+
79
+ **Покроковий алгоритм:**
80
+
81
+ 1. **Recursion guard:**
82
+ - Якщо `env.CAPTURE_DECISIONS_RUNNING` або `env.ADR_NORMALIZE_RUNNING` truthy — `return` без жодних дій. Ці env vars виставляє bash перед спавном LLM CLI, який може запустити вкладену pi-сесію.
83
+
84
+ 2. **Серіалізація транскрипту (у блоці `try/catch`):**
85
+ - Викликає `ctx.sessionManager.getEntries()` → масив entries.
86
+ - Фільтрує entries, де `e.message?.role === 'user' || e.message?.role === 'assistant'`.
87
+ - Map'ить кожен entry у JSON-рядок виду `{ type: <role>, message: <message> }` через `JSON.stringify`.
88
+ - Об'єднує рядки через `'\n'`.
89
+ - Генерує шлях `jsonlPath = join(tmpdir(), \`n-cursor-pi-transcript-${Date.now()}-${randomUUID()}.jsonl\`)`.
90
+ - Пише файл `jsonlPath` через `writeFileSync(jsonlPath, lines + '\n', 'utf8')`.
91
+ - У catch-блоці: викликає `ctx.ui?.notify?.(\`@nitra/cursor: transcript serialization failed — ${(error as Error).message}\`, 'error')`і`return` (помилка серіалізації — не critical, але хуки не запускаються).
92
+
93
+ 3. **Підготовка stdin payload:**
94
+ - `stdinPayload = JSON.stringify({ transcript_path: jsonlPath, session_id: ctx.sessionId ?? randomUUID() })`.
95
+
96
+ 4. **Підготовка env override:**
97
+ - `envOverride = { ...env, CLAUDE_PROJECT_DIR: ctx.cwd }` — копія поточного env з доданим/перевизначеним `CLAUDE_PROJECT_DIR`.
98
+
99
+ 5. **Паралельний спавн bash-хуків через `Promise.allSettled`:**
100
+ - `pi.exec('bash', [CAPTURE_HOOK], { cwd: ctx.cwd, env: envOverride, input: stdinPayload, signal: ctx.signal, timeout: 180_000 })` — capture-хук, таймаут 180 секунд (180_000 мс).
101
+ - `pi.exec('bash', [NORMALIZE_HOOK], { cwd: ctx.cwd, env: envOverride, input: stdinPayload, signal: ctx.signal, timeout: 600_000 })` — normalize-хук, таймаут 600 секунд (600_000 мс).
102
+ - `Promise.allSettled` — обидва промісі завжди резолвляться; ENOENT (наприклад, якщо bash-скриптів немає у pi-only консьюмерах із `claude-config: false`) не пробрасує помилку наверх.
103
+
104
+ **Side effects:**
105
+
106
+ - Запис файлу в `os.tmpdir()` через `writeFileSync` (синхронно, всередині async-функції).
107
+ - Можливий виклик `ctx.ui?.notify?.` з рівнем `'error'` при збої серіалізації.
108
+ - Два дочірні процеси `bash` через `pi.exec` (capture + normalize).
109
+ - Передача транскрипту і session id у bash через stdin.
110
+ - Перевизначення env var `CLAUDE_PROJECT_DIR` у child-процесах.
111
+ - Жодного запису у файли проєкту з самого TS — усі такі операції делеговано bash-скриптам.
112
+
113
+ ## Залежності
114
+
115
+ ### Node.js built-in модулі
116
+
117
+ - `node:crypto` — імпорт `randomUUID` для генерації унікальної частини імені JSONL-файлу та для fallback session id (`ctx.sessionId ?? randomUUID()`).
118
+ - `node:fs` — імпорт `writeFileSync` для синхронного запису JSONL у tmpdir.
119
+ - `node:os` — імпорт `tmpdir` для отримання шляху до системної тимчасової теки.
120
+ - `node:path` — імпорт `join` для побудови абсолютного шляху до JSONL-файлу.
121
+ - `node:process` — імпорт `env` для читання env vars (`CAPTURE_DECISIONS_RUNNING`, `ADR_NORMALIZE_RUNNING`) і успадкування у `envOverride`.
122
+
123
+ ### Зовнішні залежності (runtime)
124
+
125
+ - **Pi.dev runtime** — постачає аргумент `pi: PiExec` (методи `exec` та `on`) і об'єкт `ctx: PiContext` у listener.
126
+ - **Bash-скрипти проєкту:**
127
+ - `.claude/hooks/capture-decisions.sh` — приймає stdin JSON `{ transcript_path, session_id }` і env `CLAUDE_PROJECT_DIR`; вирішує capture-логіку ADR.
128
+ - `.claude/hooks/normalize-decisions.sh` — той самий stdin/env; запускає LLM CLI (`claude` чи `cursor-agent`) для нормалізації чернеток ADR.
129
+ - **Env vars контракту з bash:**
130
+ - `CAPTURE_DECISIONS_RUNNING`, `ADR_NORMALIZE_RUNNING` — виставляються bash перед спавном LLM CLI; служать як recursion guard для вкладеного pi-trigger.
131
+ - `CLAUDE_PROJECT_DIR` — встановлюється у `ctx.cwd` для bash-хуків.
132
+
133
+ ### TypeScript-залежності
134
+
135
+ - TypeScript-інтерфейси `PiContext` і `PiExec` — локально оголошені, не імпортовані з зовнішніх типів.
136
+ - Жодних NPM-пакетів runtime не імпортується.
137
+
138
+ ## Потік виконання / Використання
139
+
140
+ ### Реєстрація розширення
141
+
142
+ Pi.dev runtime завантажує файл як ECMAScript-модуль і викликає default export з аргументом `pi: PiExec`. Default export реєструє один listener:
143
+
144
+ ```
145
+ pi.on('agent_end', listener)
146
+ ```
147
+
148
+ Після реєстрації функція повертає `void`. Сам listener виконується пізніше — на кожну подію `agent_end`.
149
+
150
+ ### Тригер події `agent_end`
151
+
152
+ Pi-runtime емітує `agent_end`, коли агент завершує сесію. Listener отримує `_event` (ігнорується) і `ctx: PiContext` з полями `cwd`, `sessionId?`, `signal?`, `sessionManager`, `ui?`.
153
+
154
+ ### Гілка recursion guard
155
+
156
+ Якщо у поточному env-проміжку є truthy `CAPTURE_DECISIONS_RUNNING` або `ADR_NORMALIZE_RUNNING` — listener виходить негайно без запису транскрипту і без спавну хуків. Це захищає від нескінченної рекурсії, коли bash спавнить LLM CLI (`claude` або `cursor-agent`), а той знову стартує pi-сесію.
157
+
158
+ ### Гілка нормальної обробки
159
+
160
+ 1. Виклик `ctx.sessionManager.getEntries()` повертає масив entries сесії.
161
+ 2. Фільтр залишає лише entries з `role` = `'user'` або `'assistant'`.
162
+ 3. Map створює JSONL-рядки `{ "type": "<role>", "message": <message> }`.
163
+ 4. Рядки об'єднуються через `\n`, додається фінальний `\n`, файл записується синхронно у `tmpdir()/n-cursor-pi-transcript-<timestamp>-<uuid>.jsonl`.
164
+ 5. Якщо серіалізація кинула виняток — `ctx.ui?.notify?.` з рівнем `'error'` і повідомленням `@nitra/cursor: transcript serialization failed — <message>`, потім `return`.
165
+ 6. Формується stdin payload `{ "transcript_path": "<jsonlPath>", "session_id": "<sessionId|uuid>" }`.
166
+ 7. Створюється `envOverride = { ...env, CLAUDE_PROJECT_DIR: ctx.cwd }`.
167
+ 8. Через `Promise.allSettled` паралельно запускаються:
168
+ - `bash .claude/hooks/capture-decisions.sh` з cwd=`ctx.cwd`, env=`envOverride`, stdin=`stdinPayload`, signal=`ctx.signal`, timeout=180 секунд.
169
+ - `bash .claude/hooks/normalize-decisions.sh` з тими ж параметрами і timeout=600 секунд.
170
+ 9. `Promise.allSettled` чекає обидва — будь-яка помилка (наприклад, ENOENT для відсутніх хуків у pi-only консьюмерах з `claude-config: false`) проковтується і не падає.
171
+ 10. Listener резолвиться, pi-runtime продовжує обробку події.
172
+
173
+ ### Контракт з bash
174
+
175
+ - Бізнес-логіка skip/throttle, мін-інтервалів і вибору LLM CLI (`claude` чи `cursor-agent`) — повністю у `.claude/hooks/capture-decisions.sh` і `.claude/hooks/normalize-decisions.sh`.
176
+ - TS-розширення `npm/.pi-template/extensions/n-cursor-adr/index.ts` є **тонким адаптером** pi → bash і не дублює жодної бізнес-логіки.
177
+ - Recursion guard через `env.CAPTURE_DECISIONS_RUNNING` і `env.ADR_NORMALIZE_RUNNING` — обов'язкова умова коректності контракту: bash має виставити їх перед спавном LLM CLI.
178
+
179
+ ### Сценарій pi-only консьюмера
180
+
181
+ Якщо консьюмер pi-template має `claude-config: false` і bash-скриптів `.claude/hooks/capture-decisions.sh` / `.claude/hooks/normalize-decisions.sh` фізично немає — `pi.exec` повертає ENOENT, але `Promise.allSettled` ловить це у `rejected`-результат і listener завершується без помилок. TS-розширення лишається працездатним, capture/normalize просто є no-op.
package/CHANGELOG.md CHANGED
@@ -1,11 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.23.0] - 2026-06-05
4
+
5
+ ### Added
6
+
7
+ - changelog: autofix-режим (env `N_CURSOR_CHANGELOG_AUTOFIX`) — за відсутності change-файлу правило саме створює його (patch/Changed, subject останнього коміту) і ставить у git-індекс, тож pre-commit-хук не падає
8
+ - coverage-fix: новий read-only CLI `n-cursor coverage-fix index|slice --file <path>` — скрипт парсить COVERAGE.md (може бути МБ) за 0 LLM-токенів і віддає агенту лише компактний index або зріз під один файл (контекст ±3 рядки). Скіл n-coverage-fix більше не змушує агента читати весь COVERAGE.md (вузьке місце ~700K токенів). Експортовано buildFixPrompt; модуль scripts/coverage-fix-extract.mjs
9
+ - taze: новий read-only CLI `n-cursor taze diff` — детермінований semver-diff package.json ↔ package.json.taze-bak (root + воркспейси), класифікує major за caret-семантикою (найлівіша ненульова компонента). Скіл n-taze (крок 3) більше не змушує LLM вручну порівнювати бекапи — отримує готовий {major[],minorPatch}. Модуль skills/taze/js/diff.mjs
10
+ - start-check: новий CLI `n-cursor start-check scan|run` — scan виявляє воркспейси зі start і класифікує тип (server/cli), run запускає один із grace-таймаутом (крос-платформно spawnSync, без perl alarm), класифікує OK/FAIL, парсить лог (ready/firstError) і рахує read-only git-sideEffects. Скіл n-start-check більше не змушує LLM розгортати glob, інтерпретувати exit-коди й regex-ити лог. Модуль skills/start-check/js/check.mjs
11
+
12
+ ### Changed
13
+
14
+ - js-lint: додано e18e/\* deny-правила та канонічні ignorePatterns у .oxlintrc.json
15
+ - k8s.network_policy: додано NATS-порт TCP 4222 до in-cluster egress-allowlist (namespaceSelector: {}) канонічних snippet'ів deployment.snippet.yaml і stateful-set.snippet.yaml. Згенерований base/networkpolicy.yaml тепер дозволяє вихід на nats.nats.svc:4222 — поди з NATS-клієнтом більше не падають у CrashLoopBackOff. Bump k8s.mdc 1.42 → 1.43.
16
+ - docker rule: non-root сам по собі не є підставою переходити Alpine→Debian-slim — oven/bun:alpine уже має bun (uid/gid 1000); розписано два шляхи non-root (alpine standalone vs ship node_modules на bun)
17
+ - n-llm-patch: промпти вимагають change-file flow (npx @nitra/cursor change + fix changelog) замість ручного CHANGELOG.md / version bump
18
+
19
+ ### Removed
20
+
21
+ - skills: злито n-fix-tests у канонічний n-coverage-fix — n-fix-tests видалено (skill+command+pi, прибрано з .n-cursor.json). coverage-fix увібрав детекцію test/coverage-команд з package.json#scripts (Крок 0) і early-skip уже свіжого COVERAGE.md; підказку у coverage.mjs renderMarkdown перенаправлено на /n-coverage-fix
22
+
3
23
  ## [3.22.0] - 2026-06-04
4
24
 
5
25
  ### Added
6
26
 
7
27
  - js-lint quick-режим класифікує lint-findings на introduced (рядок у diff від HEAD) vs pre-existing (борг файлу) і позначає у виводі (🆕/🗄) — щоб дотик до файлу не плутав «моє чи старий борг». Захоплює oxlint/eslint --format=json, парсить added-lines git-diff, групує. Блокування без змін (#6/A). Краш інструмента не пропускається тихо.
8
28
 
29
+ ### Changed
30
+
31
+ - detectLevel: сигнал складності (mdc/policy/rego/checker/правило/rules/суперечн/інваріант/violation тощо) разом із fix-дієсловом → L2, а не L0 — rules/checks-задачі не класифікуються як тривіальні. Лише складність перекриває L0 (L2-ключі порядок не міняють); 'правило/правила' замість 'правил' (не ловить 'правильно'); без 'conflict' (merge conflict не L2).
32
+
33
+ ### Fixed
34
+
35
+ - Виправлено canonical clean-merged-branch.yml: dry_run використовує підтримуване action значення no.
36
+
9
37
  ## [3.21.1] - 2026-06-04
10
38
 
11
39
  ### Changed
@@ -50,7 +78,7 @@
50
78
 
51
79
  ### Changed
52
80
 
53
- - image-compress переведено на glob-активацію (**/*.{png,jpg,jpeg,gif,svg}) замість залежності від bun — у проєктах без растрів/SVG правило більше не додається автоматично; globToRegex отримав підтримку brace-альтернатив {a,b,c}
81
+ - image-compress переведено на glob-активацію (\*_/_.{png,jpg,jpeg,gif,svg}) замість залежності від bun — у проєктах без растрів/SVG правило більше не додається автоматично; globToRegex отримав підтримку brace-альтернатив {a,b,c}
54
82
 
55
83
  ## [3.18.2] - 2026-06-03
56
84
 
@@ -230,7 +258,7 @@
230
258
 
231
259
  ### Added
232
260
 
233
- - docker: правило «нативний .node-аддон не компілювати» — sharp/@img/*/argon2 у deps + `bun build --compile` прапорцюється (компілятор не вшиває динамічний require → краш у рантаймі); канон — node_modules + `bun <entry>` на mirror.gcr.io/oven/bun:alpine (легітимний bun-рантайм як фінальний stage). lib/docker-native-addon.mjs + інтеграція в js/lint.mjs
261
+ - docker: правило «нативний .node-аддон не компілювати» — sharp/@img/\*/argon2 у deps + `bun build --compile` прапорцюється (компілятор не вшиває динамічний require → краш у рантаймі); канон — node_modules + `bun <entry>` на mirror.gcr.io/oven/bun:alpine (легітимний bun-рантайм як фінальний stage). lib/docker-native-addon.mjs + інтеграція в js/lint.mjs
234
262
 
235
263
  ### Changed
236
264
 
@@ -295,7 +323,7 @@
295
323
 
296
324
  ### Changed
297
325
 
298
- - js-lint: канон oxlint оновлено — додано 13 правил @e18e/eslint-plugin і ignorePatterns (npm/types/**, demo/node/rules-demo.js)
326
+ - js-lint: канон oxlint оновлено — додано 13 правил @e18e/eslint-plugin і ignorePatterns (npm/types/\*\*, demo/node/rules-demo.js)
299
327
  - js-lint: мінімальна версія @nitra/eslint-config піднята до 3.10.0 (Rego package_json + js-lint.mdc v1.27)
300
328
 
301
329
  ## [1.40.1] - 2026-05-31