@nitra/cursor 12.8.9 → 12.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-template/settings.template.json +1 -23
- package/CHANGELOG.md +14 -1
- package/bin/n-cursor.js +21 -48
- package/docs/stryker.config.md +0 -2
- package/lib/docs/llm.md +16 -21
- package/lib/docs/omlx.md +20 -25
- package/lib/llm.mjs +25 -7
- package/lib/omlx.mjs +10 -3
- package/package.json +5 -5
- package/rules/abie/docs/index.md +0 -1
- package/rules/abie/docs/main.md +0 -2
- package/rules/abie/lib/docs/http-route.md +9 -12
- package/rules/abie/lib/http-route.mjs +3 -0
- package/rules/abie/main.mdc +0 -22
- package/rules/abie/policy/health_check_policy/health_check_policy.mdc +3 -1
- package/rules/abie/policy/health_check_policy/health_check_policy.rego +27 -0
- package/rules/adr/docs/index.md +0 -1
- package/rules/adr/docs/main.md +0 -2
- package/rules/adr/js/madr_format.mdc +13 -1
- package/rules/adr/main.mdc +0 -9
- package/rules/bun/docs/index.md +0 -1
- package/rules/bun/docs/main.md +0 -2
- package/rules/bun/main.mdc +1 -15
- package/rules/bun/policy/package_json/package_json.rego +12 -0
- package/rules/capacitor/docs/index.md +0 -1
- package/rules/capacitor/docs/main.md +0 -2
- package/rules/capacitor/main.mdc +0 -6
- package/rules/changelog/docs/index.md +0 -1
- package/rules/changelog/docs/main.md +0 -2
- package/rules/changelog/js/agent-workflow.mdc +1 -1
- package/rules/changelog/js/consistency.mjs +3 -3
- package/rules/changelog/js/docs/consistency.md +18 -23
- package/rules/changelog/main.mdc +0 -5
- package/rules/ci4/docs/index.md +0 -1
- package/rules/ci4/docs/main.md +0 -2
- package/rules/ci4/main.mdc +0 -5
- package/rules/doc-files/docs/index.md +0 -1
- package/rules/doc-files/docs/main.md +7 -11
- package/rules/doc-files/js/docs/docgen-crc.md +0 -2
- package/rules/doc-files/js/docs/docgen-extract.md +0 -2
- package/rules/doc-files/js/docs/docgen-files-batch.md +0 -2
- package/rules/doc-files/js/docs/docgen-gen.md +0 -2
- package/rules/doc-files/js/docs/docgen-judge-measure.md +0 -2
- package/rules/doc-files/js/docs/docgen-judge.md +0 -2
- package/rules/doc-files/js/docs/docgen-scan.md +0 -2
- package/rules/doc-files/js/docs/run-lint.md +0 -2
- package/rules/doc-files/main.mjs +2 -3
- package/rules/docker/docs/index.md +0 -1
- package/rules/docker/docs/main.md +0 -2
- package/rules/docker/js/docs/lint.md +0 -2
- package/rules/docker/lib/docs/docker-hadolint.md +0 -2
- package/rules/docker/main.mdc +1 -21
- package/rules/efes/docs/index.md +0 -1
- package/rules/efes/docs/main.md +0 -2
- package/rules/efes/main.mdc +0 -1
- package/rules/feedback/docs/index.md +0 -1
- package/rules/feedback/docs/main.md +0 -2
- package/rules/ga/docs/index.md +0 -1
- package/rules/ga/docs/main.md +0 -2
- package/rules/ga/js/docs/index.md +0 -1
- package/rules/ga/main.mdc +1 -31
- package/rules/graphql/docs/index.md +0 -1
- package/rules/graphql/docs/main.md +0 -2
- package/rules/graphql/main.mdc +0 -5
- package/rules/hasura/docs/index.md +0 -1
- package/rules/hasura/docs/main.md +0 -2
- package/rules/hasura/js/docs/index.md +1 -0
- package/rules/hasura/js/docs/migrations.md +28 -0
- package/rules/hasura/js/migrations.mjs +47 -0
- package/rules/hasura/main.mdc +1 -11
- package/rules/image-avif/docs/index.md +0 -1
- package/rules/image-avif/docs/main.md +0 -2
- package/rules/image-avif/main.mdc +1 -9
- package/rules/image-compress/docs/index.md +0 -1
- package/rules/image-compress/docs/main.md +0 -2
- package/rules/image-compress/js/docs/index.md +0 -1
- package/rules/image-compress/main.mdc +1 -9
- package/rules/js/docs/index.md +0 -1
- package/rules/js/docs/main.md +0 -2
- package/rules/js/js/dep-policy.mjs +91 -0
- package/rules/js/js/docs/check.md +0 -2
- package/rules/js/js/docs/dep-policy.md +34 -0
- package/rules/js/js/docs/index.md +5 -4
- package/rules/js/js/docs/tooling.md +0 -2
- package/rules/js/js/docs/utils_imports.md +0 -2
- package/rules/js/main.mdc +0 -31
- package/rules/js/policy/package_json/package_json.rego +16 -0
- package/rules/js-bun-db/docs/index.md +0 -1
- package/rules/js-bun-db/docs/main.md +0 -2
- package/rules/js-bun-db/js/docs/safety.md +18 -23
- package/rules/js-bun-db/js/safety.mjs +31 -3
- package/rules/js-bun-db/lib/bun-sql-scan.mjs +123 -0
- package/rules/js-bun-db/lib/docs/bun-sql-scan.md +37 -331
- package/rules/js-bun-db/main.mdc +1 -23
- package/rules/js-bun-redis/docs/index.md +0 -1
- package/rules/js-bun-redis/docs/main.md +0 -2
- package/rules/js-bun-redis/main.mdc +0 -5
- package/rules/js-mssql/docs/index.md +0 -1
- package/rules/js-mssql/docs/main.md +0 -2
- package/rules/js-mssql/main.mdc +0 -12
- package/rules/js-run/docs/index.md +0 -1
- package/rules/js-run/docs/main.md +0 -2
- package/rules/js-run/js/docs/runtime.md +15 -13
- package/rules/js-run/js/runtime.mjs +48 -4
- package/rules/js-run/main.mdc +0 -25
- package/rules/k8s/docs/index.md +0 -1
- package/rules/k8s/docs/main.md +0 -2
- package/rules/k8s/main.mdc +0 -45
- package/rules/nginx-default-tpl/docs/index.md +0 -1
- package/rules/nginx-default-tpl/docs/main.md +0 -2
- package/rules/nginx-default-tpl/main.mdc +0 -13
- package/rules/npm-module/docs/index.md +0 -1
- package/rules/npm-module/docs/main.md +0 -2
- package/rules/npm-module/js/docs/header_doc_pointer.md +0 -2
- package/rules/npm-module/js/docs/rule_meta.md +0 -2
- package/rules/npm-module/js/docs/skill_meta.md +0 -2
- package/rules/npm-module/main.mdc +1 -15
- package/rules/php/docs/index.md +0 -1
- package/rules/php/docs/main.md +0 -2
- package/rules/php/js/docs/index.md +0 -1
- package/rules/php/main.mdc +1 -9
- package/rules/python/docs/index.md +0 -1
- package/rules/python/docs/main.md +0 -2
- package/rules/python/js/docs/index.md +0 -1
- package/rules/python/main.mdc +1 -13
- package/rules/rego/docs/index.md +0 -1
- package/rules/rego/docs/main.md +0 -2
- package/rules/rego/js/docs/index.md +1 -1
- package/rules/rego/js/docs/tooling.md +26 -0
- package/rules/rego/js/tooling.mdc +14 -0
- package/rules/rego/js/tooling.mjs +24 -0
- package/rules/rego/main.mdc +0 -9
- package/rules/rego/policy/package_json/package_json.mdc +12 -0
- package/rules/rego/policy/package_json/package_json.rego +21 -0
- package/rules/rego/policy/package_json/target.json +4 -0
- package/rules/release/docs/index.md +0 -1
- package/rules/release/docs/main.md +0 -2
- package/rules/release/main.mdc +2 -2
- package/rules/rust/docs/index.md +0 -1
- package/rules/rust/docs/main.md +0 -2
- package/rules/rust/js/docs/index.md +0 -1
- package/rules/rust/main.mdc +1 -11
- package/rules/rust/policy/lint_rust_yml/lint_rust_yml.rego +24 -0
- package/rules/rust/policy/package_json/package_json.mdc +12 -0
- package/rules/rust/policy/package_json/package_json.rego +20 -0
- package/rules/rust/policy/package_json/target.json +4 -0
- package/rules/security/docs/index.md +0 -1
- package/rules/security/docs/main.md +0 -2
- package/rules/security/js/docs/index.md +0 -1
- package/rules/security/main.mdc +0 -13
- package/rules/style/docs/index.md +0 -1
- package/rules/style/docs/main.md +0 -2
- package/rules/style/js/docs/index.md +0 -1
- package/rules/style/js/docs/tooling.md +12 -10
- package/rules/style/js/tooling.mjs +8 -2
- package/rules/style/main.mdc +1 -23
- package/rules/style/policy/lint_style_yml/lint_style_yml.rego +5 -0
- package/rules/tauri/docs/index.md +0 -1
- package/rules/tauri/docs/main.md +0 -2
- package/rules/tauri/main.mdc +1 -11
- package/rules/test/docs/index.md +0 -1
- package/rules/test/docs/main.md +0 -2
- package/rules/test/js/docs/index.md +2 -0
- package/rules/test/js/docs/no-console-store-restore.md +30 -0
- package/rules/test/js/docs/sandbox-aware-test.md +30 -0
- package/rules/test/js/docs/stryker_config.md +0 -2
- package/rules/test/js/docs/vitest-config-pool-forks.md +0 -2
- package/rules/test/js/no-console-store-restore.mjs +88 -0
- package/rules/test/js/sandbox-aware-test.mjs +89 -0
- package/rules/test/main.mdc +1 -21
- package/rules/text/docs/index.md +0 -1
- package/rules/text/docs/main.md +0 -2
- package/rules/text/js/docs/cspell-fix.md +0 -2
- package/rules/text/js/docs/run-dotenv-linter.md +0 -2
- package/rules/text/js/docs/run-shellcheck.md +0 -2
- package/rules/text/js/docs/run-v8r.md +0 -2
- package/rules/text/main.mdc +0 -33
- package/rules/tool-surface/docs/index.md +0 -1
- package/rules/tool-surface/docs/main.md +0 -2
- package/rules/vue/docs/index.md +0 -1
- package/rules/vue/docs/main.md +0 -2
- package/rules/vue/main.mdc +0 -22
- package/rules/worktree/docs/index.md +0 -1
- package/rules/worktree/docs/main.md +0 -2
- package/scripts/docs/auto-rules.md +0 -2
- package/scripts/docs/auto-skills.md +0 -2
- package/scripts/docs/hook.md +30 -0
- package/scripts/docs/index.md +1 -2
- package/scripts/docs/post-tool-use-check.md +0 -2
- package/scripts/docs/sync-claude-config.md +1 -3
- package/scripts/docs/sync-setup-bun-deps-action.md +0 -2
- package/scripts/hook.mjs +71 -0
- package/scripts/lib/docs/check-mdc-template-refs.md +0 -2
- package/scripts/lib/docs/index.md +35 -36
- package/scripts/lib/docs/inline-template-links.md +6 -8
- package/scripts/lib/docs/list-project-rules-mdc.md +0 -2
- package/scripts/lib/docs/list-rule-ids.md +0 -2
- package/scripts/lib/docs/mirror-parity.md +8 -10
- package/scripts/lib/docs/read-n-cursor-config-lite.md +0 -2
- package/scripts/lib/docs/rule-meta.md +0 -2
- package/scripts/lib/docs/run-lint.md +9 -10
- package/scripts/lib/docs/run-rule-cli.md +0 -2
- package/scripts/lib/docs/run-rule.md +7 -9
- package/scripts/lib/docs/run-standard-lint.md +0 -2
- package/scripts/lib/docs/run-standard-rule.md +0 -2
- package/scripts/lib/docs/skill-meta.md +0 -2
- package/scripts/lib/docs/timing-summary.md +0 -2
- package/scripts/lib/docs/worktree-notice.md +0 -2
- package/scripts/lib/fix/docs/analyze-escalation.md +0 -2
- package/scripts/lib/fix/docs/index.md +10 -10
- package/scripts/lib/fix/docs/llm-worker.md +18 -8
- package/scripts/lib/fix/docs/orchestrator.md +44 -20
- package/scripts/lib/fix/docs/run-conformance-check.md +0 -2
- package/scripts/lib/fix/docs/t0.md +0 -2
- package/scripts/lib/fix/docs/verbose-block.md +27 -0
- package/scripts/lib/fix/llm-worker.mjs +75 -22
- package/scripts/lib/fix/orchestrator.mjs +13 -3
- package/scripts/lib/fix/verbose-block.mjs +82 -0
- package/scripts/lib/inline-template-links.mjs +32 -22
- package/scripts/lib/mirror-parity.mjs +2 -2
- package/scripts/lib/run-lint.mjs +15 -2
- package/scripts/lib/run-rule.mjs +1 -2
- package/scripts/sync-claude-config.mjs +7 -4
- package/scripts/utils/docs/resolve-js-root.md +0 -2
- package/skills/adr-normalize/SKILL.md +1 -0
- package/skills/coverage-fix/SKILL.md +1 -0
- package/skills/doc-aggregate/SKILL.md +1 -0
- package/skills/doc-files/SKILL.md +10 -24
- package/skills/lint/SKILL.md +24 -19
- package/skills/llm-patch/SKILL.md +5 -4
- package/skills/publish-telegram/SKILL.md +1 -0
- package/skills/start-check/SKILL.md +1 -0
- package/skills/taze/SKILL.md +3 -2
- package/types/bin/n-cursor.d.ts +1 -1
- package/rules/abie/docs/fix.md +0 -37
- package/rules/adr/docs/fix.md +0 -37
- package/rules/bun/docs/fix.md +0 -30
- package/rules/capacitor/docs/fix.md +0 -36
- package/rules/changelog/docs/fix.md +0 -37
- package/rules/ci4/docs/fix.md +0 -32
- package/rules/doc-files/docs/fix.md +0 -29
- package/rules/docker/docs/fix.md +0 -35
- package/rules/efes/docs/fix.md +0 -37
- package/rules/feedback/docs/fix.md +0 -30
- package/rules/ga/docs/fix.md +0 -30
- package/rules/graphql/docs/fix.md +0 -37
- package/rules/hasura/docs/fix.md +0 -39
- package/rules/image-avif/docs/fix.md +0 -28
- package/rules/image-compress/docs/fix.md +0 -27
- package/rules/js/docs/fix.md +0 -37
- package/rules/js-bun-db/docs/fix.md +0 -30
- package/rules/js-bun-redis/docs/fix.md +0 -32
- package/rules/js-mssql/docs/fix.md +0 -30
- package/rules/js-run/docs/fix.md +0 -36
- package/rules/k8s/docs/fix.md +0 -31
- package/rules/nginx-default-tpl/docs/fix.md +0 -35
- package/rules/npm-module/docs/fix.md +0 -34
- package/rules/php/docs/fix.md +0 -35
- package/rules/python/docs/fix.md +0 -38
- package/rules/rego/docs/fix.md +0 -31
- package/rules/release/docs/fix.md +0 -28
- package/rules/rust/docs/fix.md +0 -32
- package/rules/security/docs/fix.md +0 -33
- package/rules/style/docs/fix.md +0 -28
- package/rules/tauri/docs/fix.md +0 -39
- package/rules/test/docs/fix.md +0 -31
- package/rules/text/docs/fix.md +0 -37
- package/rules/tool-surface/docs/fix.md +0 -32
- package/rules/vue/docs/fix.md +0 -32
- package/rules/worktree/docs/fix.md +0 -40
- package/scripts/docs/post-tool-use-fix.md +0 -32
- package/scripts/docs/worktree-cli.md +0 -27
- package/scripts/lib/docs/worktree.md +0 -42
- package/scripts/lib/fix/docs/run-fix-check.md +0 -33
|
@@ -16,32 +16,10 @@
|
|
|
16
16
|
"hooks": [
|
|
17
17
|
{
|
|
18
18
|
"type": "command",
|
|
19
|
-
"command": "npx --no @nitra/cursor post-tool-use
|
|
19
|
+
"command": "npx --no @nitra/cursor hook --post-tool-use",
|
|
20
20
|
"timeout": 300
|
|
21
21
|
}
|
|
22
22
|
]
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"matcher": "Edit|Write|MultiEdit",
|
|
26
|
-
"hooks": [
|
|
27
|
-
{
|
|
28
|
-
"type": "command",
|
|
29
|
-
"command": "npx --no @nitra/cursor lint-doc-files --hook",
|
|
30
|
-
"timeout": 120
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"Stop": [
|
|
36
|
-
{
|
|
37
|
-
"matcher": "",
|
|
38
|
-
"hooks": [
|
|
39
|
-
{
|
|
40
|
-
"type": "command",
|
|
41
|
-
"command": "npx --no @nitra/cursor lint-doc-files --git",
|
|
42
|
-
"timeout": 120
|
|
43
|
-
}
|
|
44
|
-
]
|
|
45
23
|
}
|
|
46
24
|
]
|
|
47
25
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [12.10.0] - 2026-06-24
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Оновлено LLM-виклик для повернення багатого об'єкта з reasoning та thinkingBudget
|
|
8
|
+
|
|
9
|
+
## [12.9.0] - 2026-06-24
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Додано підтримку hook-режиму для linting через `n-cursor
|
|
14
|
+
- Додано перевірку порту 8080 для HTTPRoute та політики HealthCheckPolicy
|
|
15
|
+
|
|
3
16
|
## [12.8.9] - 2026-06-22
|
|
4
17
|
|
|
5
18
|
### Changed
|
|
@@ -10,7 +23,7 @@
|
|
|
10
23
|
|
|
11
24
|
### Changed
|
|
12
25
|
|
|
13
|
-
- ✨ feat(rules): policy mdc для всіх npm/rules
|
|
26
|
+
- ✨ feat(rules): policy mdc для всіх npm/rules/\*/policy/<concern>/
|
|
14
27
|
|
|
15
28
|
## [12.8.7] - 2026-06-22
|
|
16
29
|
|
package/bin/n-cursor.js
CHANGED
|
@@ -7,17 +7,13 @@
|
|
|
7
7
|
* `npx \@nitra/cursor` — завантажити cursor-правила (синк); якщо в корені вже є `.n-cursor.json`,
|
|
8
8
|
* спочатку зчитується конфіг і за потреби дописується `$schema`
|
|
9
9
|
* `npx \@nitra/cursor rename-yaml-extensions` — k8s `*.yml` → `*.yaml`, `.github` `*.yaml` → `*.yml` (опції: `--dry-run`, `--root=…`; див. bin/rename-yaml-extensions.mjs)
|
|
10
|
-
* `npx \@nitra/cursor post-tool-use
|
|
11
|
-
*
|
|
12
|
-
* (`*.mjs` → `js-lint`, `*.vue` → `js-lint style vue` тощо) і викликає
|
|
13
|
-
* `fix` лише з ними. Прописується автоматично в `.claude/settings.json`.
|
|
10
|
+
* `npx \@nitra/cursor hook --post-tool-use` — PostToolUse hook: per-file lint правила для зміненого файлу (stdin JSON `tool_input.file_path`). Прописується автоматично в `.claude/settings.json`.
|
|
11
|
+
* `npx \@nitra/cursor hook --stop` — Stop hook: per-file lint по всіх змінених файлах (git diff HEAD + untracked).
|
|
14
12
|
* `npx \@nitra/cursor lint` — data-driven оркестратор lint+конформності по `rules/<id>/meta.json` (`lint: per-file|full`):
|
|
15
13
|
* за замовчуванням fix-by-default по дельті vs origin (лише `per-file` правила); `--full` =
|
|
16
14
|
* весь репо (`per-file` ∪ `full`); `--read-only` = без мутацій/LLM (CI); позиційні
|
|
17
15
|
* (не-флаг) аргументи — фільтр правил конформності (мапить колишній `fix <rule>`).
|
|
18
16
|
* CI = `lint --read-only --full` (весь репо, нуль мутацій/LLM).
|
|
19
|
-
* `npx \@nitra/cursor lint-doc-files` — детермінований детектор застарілості файлових док (`stale`: `missing`|`crc-mismatch`); правило doc-files (ignore-glob у `npm/rules/doc-files/js/docgen-ignore.mjs`; тека `docs/` поряд із джерелом). Режими: повний (exit 1), `--json` (exit 0), `--missing-only`, `--hook`/`--git` (hook-протокол, exit 2), `--degraded`
|
|
20
|
-
* `npx \@nitra/cursor fix-doc-files` — JS-оркестрована генерація файлових док (роутинг local/cloud) зі штампом CRC (`--limit`/`--from`/`--overwrite`); `--stamp` — детерміноване перештампування CRC без LLM
|
|
21
17
|
* `npx \@nitra/cursor doc-aggregate modules` — JSON-лістинг логічних модулів (межі за `package.json`) для Tier 2 скілу doc-aggregate
|
|
22
18
|
* `npx \@nitra/cursor skill list` — скіли пакета без синку в проєкт
|
|
23
19
|
* `npx \@nitra/cursor skill taze` — промпт на stdout
|
|
@@ -74,7 +70,7 @@ import { fileURLToPath } from 'node:url'
|
|
|
74
70
|
|
|
75
71
|
import { buildAgentsCommandBulletItems } from '../scripts/build-agents-commands.mjs'
|
|
76
72
|
import { formatGeneratedMarkdownLines, renderAgentsTemplate } from '../scripts/lib/generated-markdown.mjs'
|
|
77
|
-
import {
|
|
73
|
+
import { appendDiscoveredMdcFiles, inlineTemplateLinks } from '../scripts/lib/inline-template-links.mjs'
|
|
78
74
|
import {
|
|
79
75
|
detectAutoRules,
|
|
80
76
|
detectLegacyRuleIds,
|
|
@@ -86,7 +82,6 @@ import { detectAutoSkills } from '../scripts/auto-skills.mjs'
|
|
|
86
82
|
import { readSkillMetaRaw } from '../scripts/lib/skill-meta.mjs'
|
|
87
83
|
import { injectWorktreeNotice } from '../scripts/lib/worktree-notice.mjs'
|
|
88
84
|
import { injectRootNotice } from '../scripts/lib/root-notice.mjs'
|
|
89
|
-
import { runPostToolUseCheckCli } from '../scripts/post-tool-use-check.mjs'
|
|
90
85
|
import { listProjectRulesMdcFiles } from '../scripts/lib/list-project-rules-mdc.mjs'
|
|
91
86
|
import { ensureNitraCursorInRootDevDependencies } from '../scripts/ensure-nitra-cursor-dev-dependencies.mjs'
|
|
92
87
|
import { assertCwdIsProjectRoot } from '../scripts/lib/assert-project-root.mjs'
|
|
@@ -142,7 +137,7 @@ function sortConfigIdArrays(config) {
|
|
|
142
137
|
|
|
143
138
|
/**
|
|
144
139
|
* Імена правил з каталогу `rules/` поточної інсталяції пакету. Кожне правило — окремий
|
|
145
|
-
* підкаталог `rules/<id>/`, у якому має бути
|
|
140
|
+
* підкаталог `rules/<id>/`, у якому має бути `main.mdc`.
|
|
146
141
|
* @param {string} [bundledRulesDir] каталог `rules/` у корені пакету
|
|
147
142
|
* @returns {Promise<string[]>} відсортовані id правил (імена підкаталогів)
|
|
148
143
|
*/
|
|
@@ -157,11 +152,11 @@ async function discoverBundledRuleNames(bundledRulesDir = BUNDLED_RULES_DIR) {
|
|
|
157
152
|
const entries = await readdir(bundledRulesDir, { withFileTypes: true })
|
|
158
153
|
const rules = entries
|
|
159
154
|
.filter(e => e.isDirectory() && !e.name.startsWith('.'))
|
|
160
|
-
.filter(e => existsSync(join(bundledRulesDir, e.name,
|
|
155
|
+
.filter(e => existsSync(join(bundledRulesDir, e.name, 'main.mdc')))
|
|
161
156
|
.map(e => e.name)
|
|
162
157
|
.toSorted((a, b) => a.localeCompare(b))
|
|
163
158
|
if (rules.length === 0) {
|
|
164
|
-
throw new Error(`У каталозі rules/ пакету немає підкаталогів з
|
|
159
|
+
throw new Error(`У каталозі rules/ пакету немає підкаталогів з main.mdc. Створіть ${CONFIG_FILE} вручну.`)
|
|
165
160
|
}
|
|
166
161
|
return rules
|
|
167
162
|
}
|
|
@@ -407,23 +402,23 @@ function normalizeRuleName(ruleName) {
|
|
|
407
402
|
}
|
|
408
403
|
|
|
409
404
|
/**
|
|
410
|
-
* Читає вміст правила з каталогу `rules/<id
|
|
411
|
-
* (наприклад `node_modules/@nitra/cursor/rules/<id
|
|
405
|
+
* Читає вміст правила з каталогу `rules/<id>/main.mdc` установленого пакету
|
|
406
|
+
* (наприклад `node_modules/@nitra/cursor/rules/<id>/main.mdc` або кеш npx).
|
|
412
407
|
* @param {string} rule елемент масиву rules з `.n-cursor.json`
|
|
413
408
|
* @param {string} [bundledRulesDir] каталог `rules/` у корені пакету-джерела
|
|
414
409
|
* @returns {Promise<string>} текст правила для запису в `.cursor/rules/n-*.mdc`
|
|
415
410
|
*/
|
|
416
411
|
async function readBundledRuleContent(rule, bundledRulesDir = BUNDLED_RULES_DIR) {
|
|
417
412
|
const id = normalizeRuleName(rule)
|
|
418
|
-
const bundledPath = join(bundledRulesDir, id,
|
|
413
|
+
const bundledPath = join(bundledRulesDir, id, 'main.mdc')
|
|
419
414
|
if (!existsSync(bundledPath)) {
|
|
420
415
|
throw new Error(
|
|
421
|
-
`Немає файлу ${id}
|
|
416
|
+
`Немає файлу ${id}/main.mdc у ${bundledRulesDir}. Оновіть ${PACKAGE_NAME} або приберіть "${rule}" з rules у ${CONFIG_FILE}.`
|
|
422
417
|
)
|
|
423
418
|
}
|
|
424
419
|
const text = await readFile(bundledPath, 'utf8')
|
|
425
420
|
const withTemplates = await inlineTemplateLinks(text, dirname(bundledPath))
|
|
426
|
-
return
|
|
421
|
+
return appendDiscoveredMdcFiles(withTemplates, dirname(bundledPath))
|
|
427
422
|
}
|
|
428
423
|
|
|
429
424
|
/**
|
|
@@ -655,7 +650,7 @@ function buildClaudeDocFilesSectionLines() {
|
|
|
655
650
|
'',
|
|
656
651
|
'## Файлова документація (`doc-files` — обовʼязковий крок, як lint)',
|
|
657
652
|
'',
|
|
658
|
-
'Після зміни чи додавання кодового файлу його файлова дока (`<dir>/docs/<stem>.md`) має бути **актуальною** — це **обовʼязковий крок кожної задачі**, нарівні з lint. Застарілість детермінується за **CRC** джерела у frontmatter доки. PostToolUse hook (`
|
|
653
|
+
'Після зміни чи додавання кодового файлу його файлова дока (`<dir>/docs/<stem>.md`) має бути **актуальною** — це **обовʼязковий крок кожної задачі**, нарівні з lint. Застарілість детермінується за **CRC** джерела у frontmatter доки. PostToolUse hook (`hook --post-tool-use`) **сигналить** про дрейф після правки через per-file lint правила. Регенерація — `/doc-files` (JS-оркестрована, не диспатч субагентів). Агрегуюча дока (module-summary, доменні) — окремий скіл `/doc-aggregate`, за запитом.',
|
|
659
654
|
''
|
|
660
655
|
]
|
|
661
656
|
}
|
|
@@ -1459,7 +1454,7 @@ async function runSync() {
|
|
|
1459
1454
|
/**
|
|
1460
1455
|
* Команди, що мутують проєкт у CWD і вимагають кореня репо. `undefined`/`''` —
|
|
1461
1456
|
* дефолтний sync; `check` — deprecated-alias `fix`. Решта (read-only `trace`,
|
|
1462
|
-
* `--root`-команди `
|
|
1457
|
+
* `--root`-команди `doc-aggregate`/`rename-yaml-extensions`,
|
|
1463
1458
|
* sub-лінтери) гард не зачіпає.
|
|
1464
1459
|
*/
|
|
1465
1460
|
const ROOT_GUARDED_COMMANDS = new Set([undefined, '', 'lint', 'coverage', 'change', 'release'])
|
|
@@ -1501,7 +1496,7 @@ try {
|
|
|
1501
1496
|
// .n-cursor.json + bun install, а fix/lint/coverage/change/release переписують файли в CWD —
|
|
1502
1497
|
// усе це ключиться на cwd(). Запуск із піддиректорії git-репо (типово прямий
|
|
1503
1498
|
// `bun npm/bin/n-cursor.js` не з кореня) зачепив би не той каталог → STOP. Read-only та
|
|
1504
|
-
// `--root`-команди (trace, graph,
|
|
1499
|
+
// `--root`-команди (trace, graph, doc-aggregate, rename-yaml-extensions) не зачіпаємо.
|
|
1505
1500
|
if (ROOT_GUARDED_COMMANDS.has(command)) {
|
|
1506
1501
|
assertCwdIsProjectRoot(cwd(), describeRootGuardedAction(command))
|
|
1507
1502
|
}
|
|
@@ -1515,11 +1510,12 @@ try {
|
|
|
1515
1510
|
|
|
1516
1511
|
break
|
|
1517
1512
|
}
|
|
1518
|
-
case '
|
|
1519
|
-
//
|
|
1520
|
-
//
|
|
1521
|
-
|
|
1522
|
-
|
|
1513
|
+
case 'hook': {
|
|
1514
|
+
// Thin hook entrypoint для Claude Code hooks. Делегує в runLint, перекодовує exit 1→2.
|
|
1515
|
+
// --post-tool-use PostToolUse: file_path зі stdin JSON
|
|
1516
|
+
// --stop Stop: робоче дерево vs HEAD
|
|
1517
|
+
const { runHookCli } = await import('../scripts/hook.mjs')
|
|
1518
|
+
process.exitCode = await runHookCli(args)
|
|
1523
1519
|
|
|
1524
1520
|
break
|
|
1525
1521
|
}
|
|
@@ -1606,29 +1602,6 @@ try {
|
|
|
1606
1602
|
|
|
1607
1603
|
break
|
|
1608
1604
|
}
|
|
1609
|
-
case 'lint-doc-files': {
|
|
1610
|
-
// n-cursor lint-doc-files — детермінований детектор застарілості файлових док
|
|
1611
|
-
// (missing ∪ crc-mismatch). Режими: (повний) exit 1, --json exit 0, --missing-only,
|
|
1612
|
-
// --hook/--git/--degraded — hook-протокол (exit 2/0). Деталі — doc-files.mdc.
|
|
1613
|
-
const { runLintDocFilesCli } = await import('../rules/doc-files/main.mjs')
|
|
1614
|
-
process.exitCode = await runLintDocFilesCli(args)
|
|
1615
|
-
|
|
1616
|
-
break
|
|
1617
|
-
}
|
|
1618
|
-
case 'fix-doc-files': {
|
|
1619
|
-
// n-cursor fix-doc-files — local-only генерація файлових док (omlx) + CRC-штамп
|
|
1620
|
-
// (--limit/--from/--overwrite); --stamp — детерміноване
|
|
1621
|
-
// перештампування source+crc без LLM. У CI не запускається (потрібна локальна модель).
|
|
1622
|
-
if (args.includes('--stamp')) {
|
|
1623
|
-
const { runDocFilesStampCli } = await import('../rules/doc-files/js/docgen-files-batch.mjs')
|
|
1624
|
-
process.exitCode = runDocFilesStampCli(args.filter(a => a !== '--stamp'))
|
|
1625
|
-
} else {
|
|
1626
|
-
const { runDocFilesGenCli } = await import('../rules/doc-files/js/docgen-files-batch.mjs')
|
|
1627
|
-
process.exitCode = await runDocFilesGenCli(args)
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
break
|
|
1631
|
-
}
|
|
1632
1605
|
case 'adr-normalize-local': {
|
|
1633
1606
|
// Local-backend ADR-нормалізації: викликається з .claude/hooks/normalize-decisions.sh
|
|
1634
1607
|
// як заміна single-shot LLM-виклику. Проганяє конвеєр (retrieval→edge-judge→
|
|
@@ -1661,7 +1634,7 @@ try {
|
|
|
1661
1634
|
default: {
|
|
1662
1635
|
console.error(`❌ Невідома команда: ${command}`)
|
|
1663
1636
|
console.error(
|
|
1664
|
-
` Очікується: (без аргументів) синхронізація правил, rename-yaml-extensions,
|
|
1637
|
+
` Очікується: (без аргументів) синхронізація правил, rename-yaml-extensions, hook, adr-normalize-local, lint (включно зі scope: lint ga|rego|k8s|docker|text), coverage, coverage-fix, analyze-escalation, taze, start-check, release, skill, trace, doc-aggregate`
|
|
1665
1638
|
)
|
|
1666
1639
|
process.exitCode = 1
|
|
1667
1640
|
}
|
package/docs/stryker.config.md
CHANGED
|
@@ -8,8 +8,6 @@ docgen:
|
|
|
8
8
|
score: 100
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
## Огляд
|
|
12
|
-
|
|
13
11
|
Цей файл конфігурує процес тестування та мутаційного аналізу, використовуючи Vitest як тестовий раннер. Він визначає, які файли підлягають мутації (у `scripts`, `rules`, `bin`) та які виключаються, спираючись на `mutation.json`. Конфігурація налаштовує Stryker для запуску лише тестів, що покривають мутовані рядки. Також конфігурація використовує `incremental.json` для збереження даних між запусками.
|
|
14
12
|
|
|
15
13
|
## Поведінка
|
package/lib/docs/llm.md
CHANGED
|
@@ -3,36 +3,31 @@ type: JS Module
|
|
|
3
3
|
title: llm.mjs
|
|
4
4
|
resource: npm/lib/llm.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 22d2906f
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
7
8
|
score: 100
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
Файл
|
|
11
|
+
Файл є єдиною точкою LLM-викликів для JS-оркестраторів (див. ADR 260610-2228). Він маршрутизує запити виключно за префіксом `model-id` (конвенція `npm/lib/models.mjs`): `omlx/<model>` — прямий HTTP до локального omlx-сервера (`callOmlx`), будь-що інше — через `pi` CLI (хмарні провайдери або pi-дефолт). Рядок моделі сам визначає транспорт; відсутні env-перемикачі бекенду. Кожен виклик має **always-on** багатий JSONL-запис трасування (reasoning + слід). Для `omlx` захоплюються `content/reasoning/usage/finish_reason/attempts`, для `pi` — лише те, що надає CLI (rich-поля null). Код спирається на конфігурації, визначені у settings.json.
|
|
11
12
|
|
|
12
13
|
## Поведінка
|
|
13
14
|
|
|
14
|
-
pickBackend
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
omlxHealthCheck
|
|
21
|
-
Перевіряє стан omlx сервера для визначення доступності моделі
|
|
15
|
+
pickBackend визначає, чи має бути використаний локальний omlx-сервер для виклику LLM, чи зовнішній CLI `pi`, на основі префікса `model-id`.
|
|
16
|
+
callLlmRich виконує універсальний виклик LLM з маршрутизацією між omlx та `pi` CLI, завжди записуючи детальний слід (wire-trace) для обох каналів, і повертає вміст та монолог обробки.
|
|
17
|
+
callLlm повертає лише текстовий вміст відповіді від LLM, використовуючи `callLlmRich` як внутрішню обгортку.
|
|
18
|
+
classifyOmlxError класифікує помилку, отриману від omlx-сервера, як тимчасову, системну чи постійну, для прийняття рішення оркестратором.
|
|
19
|
+
omlxHealthCheck виконує мінімальний перевірочний виклик до omlx-сервера для визначення його стану (працює, потребує ключа, перевантажений).
|
|
20
|
+
preflightLocalModel перевіряє стан локальної omlx-моделі, щоб визначити, чи можна безпечно ініціювати виклик, надаючи зрозуміле повідомлення про проблеми з пам'яттю, автентифікацією чи доступністю сервера.
|
|
22
21
|
|
|
23
22
|
## Публічний API
|
|
24
23
|
|
|
25
|
-
pickBackend —
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
error — Інша помилка API.
|
|
32
|
-
Порожній контент відповіді — означає, що сервер живий і модель завантажена.
|
|
24
|
+
pickBackend — Визначає, який механізм зв'язку використовувати для моделі: прямий HTTP або CLI.
|
|
25
|
+
callLlmRich — Виконує універсальний запит до LLM, маршрутизуючи його за префіксом моделі та відстежуючи трасування, повертаючи детальний об'єкт з відповіддю та логікою обґрунтування.
|
|
26
|
+
callLlm — Викликає LLM, повертаючи лише текстовий вміст відповіді, зберігаючи сумісність зі старими споживачами.
|
|
27
|
+
classifyOmlxError — Аналізує помилки omlx після вичерпання внутрішніх спроб, щоб визначити, чи потрібно ігнорувати, зупинити роботу (circuit-breaker) чи обробляти як звичайну помилку.
|
|
28
|
+
omlxHealthCheck — Перевіряє готовність omlx-сервера мінімальним запитом, щоб визначити його стан: відсутність відповіді, обмеження пам'яті, відсутність ключа або інша помилка.
|
|
29
|
+
preflightLocalModel — Перевіряє можливість використання локальної моделі для швидкого пропуску викликів, використовуючи файли документації та словники.
|
|
33
30
|
|
|
34
31
|
## Гарантії поведінки
|
|
35
32
|
|
|
36
|
-
- Read-only:
|
|
37
|
-
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
38
|
-
- Не звертається до мережі.
|
|
33
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
package/lib/docs/omlx.md
CHANGED
|
@@ -3,44 +3,39 @@ type: JS Module
|
|
|
3
3
|
title: omlx.mjs
|
|
4
4
|
resource: npm/lib/omlx.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
|
|
6
|
+
crc: 23163fe9
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
Модуль реалізує логіку маршрутизації запитів до локального omlx-сервера, який надає OpenAI-сумісні відповіді за адресою `http://localhost:8000/v1/chat/completions`. Константа DEFAULT_OMLX_URL визначає цю базову адресу. Модуль визначає, чи є модель локальною, аналізуючи префікс у `model-id` (`omlx/<model>`). Якщо модель локальна, виконується прямий HTTP-запит до omlx. Якщо ж модель не локальна, запит спрямовується до pi CLI. При необхідності, API-ключ для omlx резолвиться з конфігураційного файлу settings.json або змінної N_CURSOR_OMLX_KEY і передається у заголовку `Authorization: Bearer …`. Обробка обмежується лише текстовим контентом, оскільки сервер не підтримує виклики інструментів.
|
|
11
12
|
|
|
12
13
|
## Поведінка
|
|
13
14
|
|
|
14
|
-
DEFAULT_OMLX_URL
|
|
15
|
+
DEFAULT_OMLX_URL надає стандартний URL для доступу до omlx-сервера, який є `http://127.0.0.1:8000/v1/chat/completions`.
|
|
16
|
+
resolveOmlxApiKey визначає API-ключ для omlx-сервера, шукаючи його в опціях виклику, змінній середовища `N_CURSOR_OMLX_KEY` або в файлі `~/.omlx/settings.json`.
|
|
17
|
+
isOmlxModel перевіряє, чи відповідає наданий model-id локальному omlx-бекенду, тобто чи починається він з префікса `omlx/`.
|
|
18
|
+
omlxModelId видаляє префікс `omlx/` з model-id, якщо він присутній, для отримання чистого ідентифікатора для omlx API.
|
|
19
|
+
extractReasoning витягує текст думок (reasoning) з відповіді omlx-сервера, надаючи його разом із джерелом вилучення (поле, тег ``або зрізаний контент).
|
|
20
|
+
callOmlxRaw виконує блокуючий HTTP-виклик до omlx-сервера через`curl`, повторюючи спроби при транзієнтних помилках, і повертає багатий об'єкт з контентом, думками, використанням та статусом завершення.
|
|
21
|
+
callOmlx викликає `callOmlxRaw` і повертає лише текстовий контент відповіді від omlx-сервера.
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
DEFAULT_OMLX_MODEL: Дефолтна модель для omlx
|
|
23
|
+
## Публічний API
|
|
19
24
|
|
|
20
|
-
|
|
25
|
+
DEFAULT_OMLX_URL — Дефолтний URL для звернення до omlx-сервера, який може бути перевизначений.
|
|
21
26
|
|
|
22
|
-
|
|
27
|
+
resolveOmlxApiKey — Визначає ключ доступу до omlx-сервера, використовуючи пріоритет: явний ключ, змінна середовища, конфігурація з `settings.json` або відсутність ключа.
|
|
23
28
|
|
|
24
|
-
|
|
29
|
+
isOmlxModel — Визначає, чи ідентифікатор моделі вказує на локальний omlx-бекенд (за наявністю префікса `omlx/`).
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
omlxModelId — Видаляє префікс `omlx/` з ідентифікатора моделі, залишаючи чистий ідентифікатор для API.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
extractReasoning — Витягує внутрішні роздуми моделі з відповіді omlx, шукаючи їх у спеціальному полі, тегу `` або в тексті, якщо відповідь була обрізана.
|
|
29
34
|
|
|
30
|
-
|
|
35
|
+
callOmlxRaw — Здійснює прямий HTTP-запит до omlx, повертаючи повний об'єкт відповіді (включаючи контент, роздуми, використання та причину завершення). Автоматично повторює запит при тимчасових збоях.
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
resolveOmlxApiKey — отримує API-ключ для omlx-сервера, коли ввімкнено автентифікацію (`auth.skip_api_key_verification: false`). Порядок: явний `apiKey` → env `N_CURSOR_OMLX_KEY` → `auth.api_key` з `~/.omlx/settings.json` (для локальної машини, з читанням як за замовчуванням; читання як за замовчуванням; безпечне читання) → `null` (відсутність заголовка).
|
|
34
|
-
DEFAULT_OMLX_MODEL — дефолтна модель, якщо в ідентифікаторі залишився префікс `omlx/` (перевизначається як `N_CURSOR_OMLX_MODEL`).
|
|
35
|
-
isOmlxModel — перевіряє, чи адресує цей model-id локальний omlx-бекенед (наявність префікса `omlx/`).
|
|
36
|
-
omlxModelId — видаляє префікс `omlx/` — отримує чистий model-id для omlx API. Не-omlx-рядки повертаються без змін.
|
|
37
|
-
extractReasoning — витягує обґрунтування з відповіді.
|
|
38
|
-
callOmlxRaw — виконує прямий HTTP-виклик до omlx через `curl` (за допомогою `spawnSync`). Повертає збагачений об'єкт: контент, обґрунтування, використання, результат завершення та кількість спроб. Перезапускає лише тимчасові помилки curl (18 = закритий трансфер, 52 = порожня відповідь, 56 = збій при отриманні).
|
|
39
|
-
callOmlx — тонко інкапсулює `callOmlxRaw` для споживачів, яким потрібен лише текст. Контракт: повертає вміст з `choices[0].message.content`. Без використання заголовків чи загальних фраз.
|
|
37
|
+
callOmlx — Спрощує виклик до omlx, повертаючи лише текстовий вміст відповіді, ігноруючи інші деталі.
|
|
40
38
|
|
|
41
39
|
## Гарантії поведінки
|
|
42
40
|
|
|
43
|
-
- Read-only:
|
|
44
|
-
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
45
|
-
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
46
|
-
- Не звертається до мережі.
|
|
41
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
package/lib/llm.mjs
CHANGED
|
@@ -52,14 +52,14 @@ function callPi(messages, model, timeoutMs) {
|
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* Універсальний LLM-виклик з маршрутизацією за префіксом model-id і always-on
|
|
55
|
-
* wire-trace (обидва канали).
|
|
55
|
+
* wire-trace (обидва канали). Повертає **багатий** обʼєкт із вмістом і reasoning.
|
|
56
56
|
* @param {Array<{role:string, content:string}>} messages OpenAI-style messages (system зберігається на omlx)
|
|
57
57
|
* @param {string} model model-id; `omlx/<m>` → прямий HTTP, інакше → pi CLI
|
|
58
|
-
* @param {{ timeoutMs?: number, temperature?: number, maxTokens?: number, url?: string, caller?: string }} [opts] timeout, температура, ліміт виходу, override URL, мітка викликача для trace
|
|
59
|
-
* @returns {string
|
|
58
|
+
* @param {{ timeoutMs?: number, temperature?: number, maxTokens?: number, url?: string, caller?: string, thinkingBudget?: number }} [opts] timeout, температура, ліміт виходу, override URL, мітка викликача для trace, бюджет thinking-токенів (лише omlx)
|
|
59
|
+
* @returns {{ content: string, reasoning: string|null, reasoningSource: string|null }} вміст відповіді і thinking-монолог
|
|
60
60
|
*/
|
|
61
|
-
export function
|
|
62
|
-
const { timeoutMs = DEFAULT_TIMEOUT_MS, temperature = 0.2, maxTokens, url, caller } = opts
|
|
61
|
+
export function callLlmRich(messages, model, opts = {}) {
|
|
62
|
+
const { timeoutMs = DEFAULT_TIMEOUT_MS, temperature = 0.2, maxTokens, url, caller, thinkingBudget } = opts
|
|
63
63
|
const backend = pickBackend(model)
|
|
64
64
|
const resolvedCaller = caller ?? env.N_CURSOR_TRACE_CALLER ?? 'unknown'
|
|
65
65
|
const t0 = Date.now()
|
|
@@ -71,7 +71,13 @@ export function callLlm(messages, model, opts = {}) {
|
|
|
71
71
|
let usage = null
|
|
72
72
|
let attempts = 1
|
|
73
73
|
if (backend === 'omlx') {
|
|
74
|
-
const raw = callOmlxRaw(messages, model, {
|
|
74
|
+
const raw = callOmlxRaw(messages, model, {
|
|
75
|
+
url,
|
|
76
|
+
timeoutMs,
|
|
77
|
+
temperature,
|
|
78
|
+
...(maxTokens ? { maxTokens } : {}),
|
|
79
|
+
...(thinkingBudget ? { thinkingBudget } : {})
|
|
80
|
+
})
|
|
75
81
|
;({ content, reasoning, reasoningSource, finishReason, usage, attempts } = raw)
|
|
76
82
|
} else {
|
|
77
83
|
content = callPi(messages, model, timeoutMs)
|
|
@@ -96,7 +102,7 @@ export function callLlm(messages, model, opts = {}) {
|
|
|
96
102
|
error: null
|
|
97
103
|
})
|
|
98
104
|
)
|
|
99
|
-
return content
|
|
105
|
+
return { content, reasoning, reasoningSource }
|
|
100
106
|
} catch (error) {
|
|
101
107
|
writeTrace(
|
|
102
108
|
buildTraceRecord({
|
|
@@ -117,6 +123,18 @@ export function callLlm(messages, model, opts = {}) {
|
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Тонка обгортка над `callLlmRich` — повертає лише рядок контенту. Зберігає
|
|
128
|
+
* backward-compatible контракт для споживачів, яким reasoning не потрібен.
|
|
129
|
+
* @param {Array<{role:string, content:string}>} messages OpenAI-style messages
|
|
130
|
+
* @param {string} model model-id
|
|
131
|
+
* @param {{ timeoutMs?: number, temperature?: number, maxTokens?: number, url?: string, caller?: string }} [opts]
|
|
132
|
+
* @returns {string} текст відповіді
|
|
133
|
+
*/
|
|
134
|
+
export function callLlm(messages, model, opts = {}) {
|
|
135
|
+
return callLlmRich(messages, model, opts).content
|
|
136
|
+
}
|
|
137
|
+
|
|
120
138
|
/** Фрагмент повідомлення omlx про memory-guard (динамічна стеля пам'яті). */
|
|
121
139
|
const MEMORY_GUARD_MARKER = 'memory ceiling'
|
|
122
140
|
/** Тип помилки omlx про відсутній/хибний API-ключ. */
|
package/lib/omlx.mjs
CHANGED
|
@@ -130,7 +130,7 @@ function parseOmlxResponse(stdout, attempt) {
|
|
|
130
130
|
* transient-помилки (curl 18/28/52/56 + spawnSync ETIMEDOUT) із backoff 2s→8s.
|
|
131
131
|
* @param {Array<{role:string, content:string}>} messages OpenAI-messages (system+user збережено)
|
|
132
132
|
* @param {string} model model-id (з/без `omlx/`-префікса); порожній і без `fallbackModel` → throw
|
|
133
|
-
* @param {{ url?: string, timeoutMs?: number, temperature?: number, maxTokens?: number, fallbackModel?: string, apiKey?: string, backoffMs?: number[] }} [opts] URL, timeout, температура, ліміт виходу, fallback-модель, API-ключ, backoff між ретраями (мс)
|
|
133
|
+
* @param {{ url?: string, timeoutMs?: number, temperature?: number, maxTokens?: number, fallbackModel?: string, apiKey?: string, backoffMs?: number[], thinkingBudget?: number }} [opts] URL, timeout, температура, ліміт виходу, fallback-модель, API-ключ, backoff між ретраями (мс), бюджет thinking-токенів (0 = вимкнено)
|
|
134
134
|
* @returns {{ content:string, reasoning:string|null, reasoningSource:string|null, finishReason:string|null, usage:object|null, attempts:number }} багатий результат виклику
|
|
135
135
|
* @throws {Error} на curl-помилці, не-200 exit, поганому JSON чи порожньому контенті
|
|
136
136
|
*/
|
|
@@ -142,14 +142,21 @@ export function callOmlxRaw(messages, model, opts = {}) {
|
|
|
142
142
|
maxTokens = 4096,
|
|
143
143
|
fallbackModel = env.N_CURSOR_OMLX_MODEL ?? '',
|
|
144
144
|
apiKey,
|
|
145
|
-
backoffMs = BACKOFF_MS
|
|
145
|
+
backoffMs = BACKOFF_MS,
|
|
146
|
+
thinkingBudget = 0
|
|
146
147
|
} = opts
|
|
147
148
|
|
|
148
149
|
const m = omlxModelId(model) || fallbackModel
|
|
149
150
|
if (!m) {
|
|
150
151
|
throw new Error('omlx: модель не задано — постав N_LOCAL_MIN_MODEL (або N_CURSOR_OMLX_MODEL)')
|
|
151
152
|
}
|
|
152
|
-
const body = JSON.stringify({
|
|
153
|
+
const body = JSON.stringify({
|
|
154
|
+
model: m,
|
|
155
|
+
messages,
|
|
156
|
+
max_tokens: maxTokens,
|
|
157
|
+
temperature,
|
|
158
|
+
...(thinkingBudget > 0 ? { thinking_budget: thinkingBudget } : {})
|
|
159
|
+
})
|
|
153
160
|
// Ключ локального сервера в argv допустимий: localhost-секрет власної машини,
|
|
154
161
|
// короткоживучий процес; stdin уже зайнятий body (`--data-binary @-`).
|
|
155
162
|
const key = resolveOmlxApiKey(apiKey)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitra/cursor",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.10.0",
|
|
4
4
|
"description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"rename-yaml-extensions": "bun ./bin/n-cursor.js rename-yaml-extensions"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@7n/mt": "^0.5.
|
|
57
|
-
"oxc-parser": "^0.
|
|
56
|
+
"@7n/mt": "^0.5.1",
|
|
57
|
+
"oxc-parser": "^0.137.0",
|
|
58
58
|
"picomatch": "^4.0.4",
|
|
59
|
-
"smol-toml": "^1.
|
|
60
|
-
"yaml": "^2.
|
|
59
|
+
"smol-toml": "^1.7.0",
|
|
60
|
+
"yaml": "^2.9.0",
|
|
61
61
|
"zod": "^4.4.3"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
package/rules/abie/docs/index.md
CHANGED
package/rules/abie/docs/main.md
CHANGED
|
@@ -8,8 +8,6 @@ docgen:
|
|
|
8
8
|
score: 100
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
## Огляд
|
|
12
|
-
|
|
13
11
|
Модуль застосовує політику до JS-запитів, посилаючись на MDC-ресурси відповідно до конфігурації `meta.json`. При запуску як окремий інструмент (CLI) він виконує повний цикл обробки, завантажує конфігурації та формує підсумковий звіт. Модуль є Read-only, тобто не здійснює записів у файлову систему чи бази даних. Кешування даних відбувається у межах одного прогону.
|
|
14
12
|
|
|
15
13
|
## Поведінка
|
|
@@ -3,26 +3,23 @@ type: JS Module
|
|
|
3
3
|
title: http-route.mjs
|
|
4
4
|
resource: npm/rules/abie/lib/http-route.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 1ffd9c0b
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
Виконує крос-документну аналітику для підрахунку `backendRefs` до спільних сервісів (`auth-run-hl`, `file-link-hl`) у base-маніфестах пакета, що знаходяться поза overlay `ua`. Використовується фіксований список спільних сервісів, визначений через `ABIE_SHARED_CROSS_NS_BACKEND_NAMES`. Функція `analyzeAbieSharedBackendRefsInPackageK8s` підраховує ці посилання. Це забезпечує синхронізацію числа патчів namespace в overlay із кількістю base-reference, використовуючи `ua_http_route-концерном` для забезпечення узгодженості (abie.mdc).
|
|
10
12
|
|
|
11
13
|
## Поведінка
|
|
12
14
|
|
|
13
|
-
ABIE_SHARED_CROSS_NS_BACKEND_NAMES
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
analyzeAbieSharedBackendRefsInPackageK8s
|
|
17
|
-
Збирає кількість посилань на спільні бекенди та порушення вимог до namespace у базових документах HTTPRoute пакета.
|
|
15
|
+
ABIE_SHARED_CROSS_NS_BACKEND_NAMES надає фіксований список назв спільних сервісів (`auth-run-hl`, `file-link-hl`), які підлягають аналізу.
|
|
16
|
+
analyzeAbieSharedBackendRefsInPackageK8s збирає кількість посилань на спільні сервіси (`backendRefs`) у base-маніфестах пакета (виключаючи overlay `ua`) та виявляє порушення вимог до цих посилань (наприклад, відсутність `namespace: dev` або `port: 8080` (abie.mdc)).
|
|
18
17
|
|
|
19
18
|
## Публічний API
|
|
20
19
|
|
|
21
|
-
ABIE_SHARED_CROSS_NS_BACKEND_NAMES —
|
|
22
|
-
|
|
23
|
-
analyzeAbieSharedBackendRefsInPackageK8s — Збирає кількість спільних посилань `backendRefs` та базові помилки з YAML-файлів пакета, ігноруючи неймспейс `dev`. (abie.mdc)
|
|
20
|
+
ABIE_SHARED_CROSS_NS_BACKEND_NAMES — Визначає імена бекендів, що використовуються між різними неймспейсами.
|
|
21
|
+
analyzeAbieSharedBackendRefsInPackageK8s — Підраховує кількість посилань на спільні бекенди у YAML-файлах пакета (крім overlay ua) та фіксує базові помилки (без неймспейсу dev). (abie.mdc)
|
|
24
22
|
|
|
25
23
|
## Гарантії поведінки
|
|
26
24
|
|
|
27
|
-
- Read-only:
|
|
28
|
-
- Не звертається до мережі.
|
|
25
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -27,6 +27,9 @@ function checkSharedBackendRef(br, rel, errors) {
|
|
|
27
27
|
if (typeof brRec.namespace !== 'string' || brRec.namespace !== 'dev') {
|
|
28
28
|
errors.push(`${rel}: HTTPRoute backendRefs до ${name} має містити namespace: dev (abie.mdc)`)
|
|
29
29
|
}
|
|
30
|
+
if (brRec.port !== 8080) {
|
|
31
|
+
errors.push(`${rel}: HTTPRoute backendRefs до ${name} має містити port: 8080 (abie.mdc)`)
|
|
32
|
+
}
|
|
30
33
|
return 1
|
|
31
34
|
}
|
|
32
35
|
|
package/rules/abie/main.mdc
CHANGED
|
@@ -16,16 +16,6 @@ version: '1.22'
|
|
|
16
16
|
|
|
17
17
|
Без цього запису `@nitra/cursor` пропускає всі abie-перевірки (JS-концерни та rego-полісі).
|
|
18
18
|
|
|
19
|
-
[k8s-hc-yaml](./js/hc_pairing.mdc)
|
|
20
|
-
|
|
21
|
-
[k8s-http-route-base](./js/http_route_base.mdc)
|
|
22
|
-
|
|
23
|
-
[k8s-http-route-ua](./js/ua_http_route.mdc)
|
|
24
|
-
|
|
25
|
-
[k8s-nodeselector](./js/ua_node_selector.mdc)
|
|
26
|
-
|
|
27
|
-
[env-dns](./js/env_dns.mdc)
|
|
28
|
-
|
|
29
19
|
## `@nitra/abie-shared` у `devDependencies`
|
|
30
20
|
|
|
31
21
|
У кореневому **`package.json`** abie-проєкту в **`devDependencies`** має бути **`@nitra/abie-shared`** — пакет зі спільними abie-ресурсами: канонічні GraphQL-схеми, скіли, типи (наприклад, шляхи `node_modules/@nitra/abie-shared/schema/...` для імпорту схем). Версію правило не фіксує — лише presence. Додати:
|
|
@@ -34,8 +24,6 @@ version: '1.22'
|
|
|
34
24
|
bun add -d @nitra/abie-shared
|
|
35
25
|
```
|
|
36
26
|
|
|
37
|
-
[firebase](./js/firebase_hosting.mdc)
|
|
38
|
-
|
|
39
27
|
## Git branches
|
|
40
28
|
|
|
41
29
|
У **`.github/workflows/clean-merged-branch.yml`** у кроці **`phpdocker-io/github-actions-delete-abandoned-branches`** значення **`with.ignore_branches`** має містити **dev** та **ua** (разом з іншими гілками, якщо потрібно):
|
|
@@ -48,16 +36,6 @@ bun add -d @nitra/abie-shared
|
|
|
48
36
|
|
|
49
37
|
Пакети (директорія в **`npm/policy/abie/`** → namespace → що перевіряє):
|
|
50
38
|
|
|
51
|
-
[abie-http-route-base](./policy/http_route_base/http_route_base.mdc)
|
|
52
|
-
|
|
53
|
-
[abie-health-check-policy](./policy/health_check_policy/health_check_policy.mdc)
|
|
54
|
-
|
|
55
|
-
[abie-base-deployment-preem](./policy/base_deployment_preem/base_deployment_preem.mdc)
|
|
56
|
-
|
|
57
|
-
[abie-clean-merged-ignore-branches](./policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc)
|
|
58
|
-
|
|
59
|
-
[abie-package-json-shared](./policy/package_json_shared/package_json_shared.mdc)
|
|
60
|
-
|
|
61
39
|
Cross-file / FS-логіка лишається у JS-частинах (`js/<concern>.mjs`) — Rego не читає файлову систему й не робить cross-document резолюцію:
|
|
62
40
|
|
|
63
41
|
- парність HCP↔Deployment у каталозі та modeline `hc.yaml` — `js/hc_pairing.mjs`;
|