From a6a4d4fee3f066931b35fee25a824d1bff235929 Mon Sep 17 00:00:00 2001 From: Aleksey Shakhmatov Date: Thu, 16 Jul 2026 12:56:35 +0300 Subject: [PATCH 1/6] feat(install): interactive environment setup (URLs + secrets) - prompt TRACKER_URL (visible, current value as default) and JIRA_TOKEN/GITLAB_TOKEN/provider key (hidden read -rs, never echoed) via /dev/tty (works under curl|bash) - persist to ~/.config/pi-kit/env.sh (umask 077 => chmod 600), sourced from shell rc via idempotent managed block - ask provider key only if none already set; empty input keeps existing value; re-runs load stored values as defaults - non-interactive / PI_KIT_SETUP_ENV=0 falls back to printed guidance - README documents the flow, env.sh, and the skip switch Unit-tested: single-quote escaping round-trip, 600 perms, empty-value omission, rc-block idempotency. --- README.md | 8 +++- install.sh | 132 +++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 120 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 7c1eb9b..4a7b4a8 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,15 @@ curl -fsSL https://git.codelab.vc/ai/pi-kit/-/raw/main/install.sh | bash ``` Скрипт проверит Node.js (>= 20), поставит Pi (если нет), установит этот пакет, **спросит -твой профиль**, поставит нужные скилы и подскажет, какие переменные окружения нужны -(ключ вашего LLM-провайдера, `TRACKER_URL`, `JIRA_TOKEN`). +твой профиль**, поставит нужные скилы и **интерактивно настроит окружение** (`TRACKER_URL`, +`JIRA_TOKEN`, `GITLAB_TOKEN`, ключ LLM-провайдера). Секреты вводятся скрыто и сохраняются в +`~/.config/pi-kit/env.sh` (`chmod 600`), который подключается из твоего `~/.zshrc`/`~/.bashrc`. Pi провайдер-агностичен — модель/провайдера пакет не навязывает, каждый выбирает свой (Anthropic, OpenAI, OpenRouter, …). +Пропустить интерактивную настройку окружения: `PI_KIT_SETUP_ENV=0`. Значения потом можно +поменять прямо в `~/.config/pi-kit/env.sh` или перезапустив `./install.sh`. + Профиль можно задать заранее (для CI/неинтерактивной установки): ```bash diff --git a/install.sh b/install.sh index 2154db2..5200103 100755 --- a/install.sh +++ b/install.sh @@ -187,10 +187,17 @@ if [ "${#PROFILE_PUBLIC[@]}" -gt 0 ]; then done fi -# --- 7. Provider API keys --------------------------------------------------- -# Pi is provider-agnostic: engineers use different LLM providers (Anthropic, -# OpenAI, OpenRouter, Google, ...). The package does NOT pin a provider/model. -# We only check that *some* provider key is present and hint if none is. +# --- 7. Environment (URLs + secrets) --------------------------------------- +# Interactive setup: prompts (via /dev/tty so it works under curl | bash), +# stores chosen values in ~/.config/pi-kit/env.sh (chmod 600) and sources it +# from the shell rc. Secrets are read hidden and never echoed/logged. +# URLs have no package default yet (config/company.json is filled by maintainers); +# the current value is offered as the default. Skip with PI_KIT_SETUP_ENV=0. +CONFIG_DIR="$HOME/.config/pi-kit" +ENV_FILE="$CONFIG_DIR/env.sh" +RC_MARK=">>> pi-kit >>>" + +# Which provider key (if any) is already present in the environment. PROVIDER_KEYS=(ANTHROPIC_API_KEY OPENAI_API_KEY OPENROUTER_API_KEY GEMINI_API_KEY GOOGLE_API_KEY GROQ_API_KEY) found_key="" for k in "${PROVIDER_KEYS[@]}"; do @@ -199,21 +206,109 @@ for k in "${PROVIDER_KEYS[@]}"; do break fi done -if [ -n "$found_key" ]; then - info "Найден ключ LLM-провайдера: ${found_key} — ок." -else - warn "Не найден ни один ключ LLM-провайдера." - cat <<'EOF' - Pi работает с разными провайдерами — выбери свой и задай ключ, например: - export ANTHROPIC_API_KEY="..." # Anthropic - export OPENAI_API_KEY="..." # OpenAI - export OPENROUTER_API_KEY="..." # OpenRouter - Провайдер и модель выбираются флагами --provider/--model или в настройках Pi - (см. `pi --list-models`) — пакет их не навязывает. - Для скилла работы с трекером также понадобятся: - export TRACKER_URL="..." # адрес Jira (или возьмётся из корп. контекста) - export JIRA_TOKEN="..." # Jira personal access token (Server/DC) +detect_rc() { + case "$(basename "${SHELL:-}")" in + zsh) echo "$HOME/.zshrc" ;; + bash) echo "$HOME/.bashrc" ;; + *) echo "$HOME/.profile" ;; + esac +} + +# Escape a value for safe embedding inside single quotes. +esc_sq() { printf "%s" "$1" | sed "s/'/'\\\\''/g"; } + +env_setup_interactive() { + info "Настройка окружения — значения сохранятся в ${ENV_FILE} (chmod 600)." + # Load previously stored values so re-runs keep them as defaults. + # shellcheck disable=SC1090 + [ -f "$ENV_FILE" ] && . "$ENV_FILE" || true + + local tracker="${TRACKER_URL:-}" jira="${JIRA_TOKEN:-}" gitlab="${GITLAB_TOKEN:-}" ans="" + + # TRACKER_URL (not a secret): visible prompt, current value as default. + printf 'TRACKER_URL (адрес Jira)%s: ' "${tracker:+ [${tracker}]}" >/dev/tty + read -r ans /dev/tty + read -rs ans /dev/tty + [ -n "$ans" ] && jira="$ans" + + # GITLAB_TOKEN (secret, для create-mr.sh): hidden input. + printf 'GITLAB_TOKEN (скрытый ввод, Enter — пропустить): ' >/dev/tty + read -rs ans /dev/tty + [ -n "$ans" ] && gitlab="$ans" + + # LLM provider key — only ask if none is already set. + local prov_name="" prov_val="" + if [ -z "$found_key" ]; then + printf 'LLM-провайдер: 1) anthropic 2) openai 3) openrouter 4) пропустить [1-4]: ' >/dev/tty + read -r ans /dev/tty + read -rs prov_val /dev/tty + fi + fi + + # Write env file with restrictive permissions (umask 077 => 600). + mkdir -p "$CONFIG_DIR" + ( + umask 077 + { + echo "# Managed by pi-kit install.sh — не коммить. chmod 600, plaintext." + [ -n "$tracker" ] && echo "export TRACKER_URL='$(esc_sq "$tracker")'" + [ -n "$jira" ] && echo "export JIRA_TOKEN='$(esc_sq "$jira")'" + [ -n "$gitlab" ] && echo "export GITLAB_TOKEN='$(esc_sq "$gitlab")'" + [ -n "$prov_name" ] && [ -n "$prov_val" ] && echo "export ${prov_name}='$(esc_sq "$prov_val")'" + } >"$ENV_FILE" + ) + chmod 600 "$ENV_FILE" + info "Сохранено: ${ENV_FILE}" + + # Ensure the shell rc sources the env file (managed block, idempotent). + local rc + rc="$(detect_rc)" + if [ -f "$rc" ] && grep -qF "$RC_MARK" "$rc" 2>/dev/null; then + info "Подключение уже есть в ${rc}." + else + { + echo "" + echo "# ${RC_MARK}" + echo '[ -f "$HOME/.config/pi-kit/env.sh" ] && . "$HOME/.config/pi-kit/env.sh"' + echo "# <<< pi-kit <<<" + } >>"$rc" + info "Добавил подключение в ${rc}. Применить сейчас: source ${rc}" + fi + warn "Токены лежат в ${ENV_FILE} (chmod 600, plaintext). Для строгих требований — секрет-менеджер." +} + +if [ "${PI_KIT_SETUP_ENV:-1}" != 0 ] && [ -r /dev/tty ]; then + env_setup_interactive +else + # Non-interactive fallback: just check for a provider key and print guidance. + if [ -n "$found_key" ]; then + info "Найден ключ LLM-провайдера: ${found_key} — ок." + else + warn "Не найден ключ LLM-провайдера (установка неинтерактивная — пропускаю настройку)." + fi + cat <<'EOF' + Задай нужные переменные вручную (например, в ~/.config/pi-kit/env.sh): + export ANTHROPIC_API_KEY="..." # или OPENAI_API_KEY / OPENROUTER_API_KEY + export TRACKER_URL="..." # адрес Jira (Server/DC) + export JIRA_TOKEN="..." # Jira personal access token + export GITLAB_TOKEN="..." # для создания MR (scripts/create-mr.sh) + Провайдер/модель — флагами --provider/--model или в настройках Pi (пакет не навязывает). EOF fi @@ -225,6 +320,7 @@ cat < /feature <тикет> /review [фокус] /rfc <тема> /kit-config From e6903f8b131b8e68389e51966bb184caa8568a57 Mon Sep 17 00:00:00 2001 From: Aleksey Shakhmatov Date: Thu, 16 Jul 2026 13:03:03 +0300 Subject: [PATCH 2/6] config: set company URLs (gitHost, tracker, docs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gitHost: gitlab.tech.mvideo.ru (где живёт код компании) - trackerUrl: https://jira.mvideo.ru - docsUrl: https://wiki.mvideo.ru (Confluence) - repoMap остаётся TODO Verified: /kit-config reflects the new values (source: local). --- config/company.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/company.json b/config/company.json index b5aa2a7..a0fee83 100644 --- a/config/company.json +++ b/config/company.json @@ -1,7 +1,7 @@ { - "gitHost": "git.codelab.vc", - "trackerUrl": "TODO", - "docsUrl": "TODO", + "gitHost": "gitlab.tech.mvideo.ru", + "trackerUrl": "https://jira.mvideo.ru", + "docsUrl": "https://wiki.mvideo.ru", "repoMap": "TODO: где какой код лежит", "rules": [ "не коммитить секреты", From c2cdf40cad384db8a2964b6eb8dec7308e1ffa1f Mon Sep 17 00:00:00 2001 From: Aleksey Shakhmatov Date: Thu, 16 Jul 2026 13:10:34 +0300 Subject: [PATCH 3/6] docs(skills): fill cross-cutting Git/Jira conventions - commit format: Conventional Commits (all six *-standards) - branches/deploy: feature branches from main; release-* -> stage, tag v* -> prod (all six *-standards) - jira-workflow: statuses To Do -> In Progress -> Review -> Done; who moves status when; MR link + status transition policy; comment guidance - key-prefix list stays TODO (unknown project prefixes) Verified: no leftover commit-format TODOs, deploy convention in all 6, skills still load via pi. --- skills/go-standards/SKILL.md | 6 ++++-- skills/jira-workflow/SKILL.md | 13 +++++++------ skills/kotlin-standards/SKILL.md | 5 ++++- skills/python-standards/SKILL.md | 5 ++++- skills/rust-standards/SKILL.md | 5 ++++- skills/swift-standards/SKILL.md | 5 ++++- skills/typescript-standards/SKILL.md | 5 ++++- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/skills/go-standards/SKILL.md b/skills/go-standards/SKILL.md index 24261f5..3db86bb 100644 --- a/skills/go-standards/SKILL.md +++ b/skills/go-standards/SKILL.md @@ -40,8 +40,10 @@ api/ # спецификации API (proto/openapi) ## Коммиты и MR -- **Формат коммитов:** ``. -- **Ветки:** от основной, именование ``. +- **Формат коммитов:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:` …). +- **Ветки и деплой:** фича-ветки — от `main` (в имя ветки желательно включать ключ тикета). + Деплой управляется ветками/тегами: ветка `release-*` → раскатка на **stage**; тег `v*` → раскатка в **прод**. + Ветки `release-*` и теги `v*` без необходимости не пушь — `permission-gate` переспросит. - **MR обязателен** (см. корпоративные правила из контекста сессии). Прямой push в защищённые ветки запрещён — расширение `permission-gate` дополнительно переспросит. - **Описание MR:** что и зачем изменено, как проверено (линтеры + тесты), ссылка на тикет diff --git a/skills/jira-workflow/SKILL.md b/skills/jira-workflow/SKILL.md index a0c9d87..67a7048 100644 --- a/skills/jira-workflow/SKILL.md +++ b/skills/jira-workflow/SKILL.md @@ -56,12 +56,13 @@ MR из защищённой ветки (`main`/`master`/`release/*`) скрип ## Соглашения - - -- **Формат ключей задач:** `` -- **Статусы и переходы:** `` -- **Кто и когда меняет статус:** `` -- **Что писать в комментарии при старте/готовности:** `` +- **Формат ключей задач:** вида `PROJ-123` (буквенный префикс проекта + номер). + `` +- **Статусы и переходы:** To Do → In Progress → Review → Done. +- **Кто и когда меняет статус:** разработчик переводит тикет: в **In Progress** — при старте работы; + в **Review** — при выставлении MR (в тикет добавляется ссылка на MR); в **Done** — после мержа. +- **Что писать в комментарии:** при старте — кратко о начале работы; при готовности — ссылку на MR + (используй `create-mr.sh`, который сразу приложит ссылку, либо `link-mr.sh`). ## Полезное diff --git a/skills/kotlin-standards/SKILL.md b/skills/kotlin-standards/SKILL.md index 8ee9039..a4c1b8c 100644 --- a/skills/kotlin-standards/SKILL.md +++ b/skills/kotlin-standards/SKILL.md @@ -44,7 +44,10 @@ app/ # Android-модуль приложения ## Коммиты и MR -- **Формат коммитов:** ``. +- **Формат коммитов:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:` …). +- **Ветки и деплой:** фича-ветки — от `main` (в имя ветки желательно включать ключ тикета). + Деплой управляется ветками/тегами: ветка `release-*` → раскатка на **stage**; тег `v*` → раскатка в **прод**. + Ветки `release-*` и теги `v*` без необходимости не пушь — `permission-gate` переспросит. - **MR обязателен** (см. корпоративные правила из контекста сессии). Прямой push в защищённые ветки запрещён — расширение `permission-gate` дополнительно переспросит. - Перед MR: `ktlintCheck`, `detekt`, `test` (и `lint`) — всё зелёное. diff --git a/skills/python-standards/SKILL.md b/skills/python-standards/SKILL.md index 64899f3..ad7775f 100644 --- a/skills/python-standards/SKILL.md +++ b/skills/python-standards/SKILL.md @@ -40,7 +40,10 @@ tests/ ## Коммиты и MR -- **Формат коммитов:** ``. +- **Формат коммитов:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:` …). +- **Ветки и деплой:** фича-ветки — от `main` (в имя ветки желательно включать ключ тикета). + Деплой управляется ветками/тегами: ветка `release-*` → раскатка на **stage**; тег `v*` → раскатка в **прод**. + Ветки `release-*` и теги `v*` без необходимости не пушь — `permission-gate` переспросит. - **MR обязателен** (см. корпоративные правила из контекста сессии). Прямой push в защищённые ветки запрещён — расширение `permission-gate` дополнительно переспросит. - Перед MR: `ruff check .`, `ruff format --check .`, `mypy .`, `pytest` — всё зелёное. diff --git a/skills/rust-standards/SKILL.md b/skills/rust-standards/SKILL.md index 1899286..7529d92 100644 --- a/skills/rust-standards/SKILL.md +++ b/skills/rust-standards/SKILL.md @@ -44,7 +44,10 @@ benches/ # бенчмарки (если есть) ## Коммиты и MR -- **Формат коммитов:** ``. +- **Формат коммитов:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:` …). +- **Ветки и деплой:** фича-ветки — от `main` (в имя ветки желательно включать ключ тикета). + Деплой управляется ветками/тегами: ветка `release-*` → раскатка на **stage**; тег `v*` → раскатка в **прод**. + Ветки `release-*` и теги `v*` без необходимости не пушь — `permission-gate` переспросит. - **MR обязателен** (см. корпоративные правила из контекста сессии). Прямой push в защищённые ветки запрещён — расширение `permission-gate` дополнительно переспросит. - Перед MR: `cargo fmt --check`, `cargo clippy -D warnings`, `cargo test` — всё зелёное. diff --git a/skills/swift-standards/SKILL.md b/skills/swift-standards/SKILL.md index 673ba6a..a9d221a 100644 --- a/skills/swift-standards/SKILL.md +++ b/skills/swift-standards/SKILL.md @@ -39,7 +39,10 @@ Tests/Tests/... ## Коммиты и MR -- **Формат коммитов:** ``. +- **Формат коммитов:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:` …). +- **Ветки и деплой:** фича-ветки — от `main` (в имя ветки желательно включать ключ тикета). + Деплой управляется ветками/тегами: ветка `release-*` → раскатка на **stage**; тег `v*` → раскатка в **прод**. + Ветки `release-*` и теги `v*` без необходимости не пушь — `permission-gate` переспросит. - **MR обязателен** (см. корпоративные правила из контекста сессии). Прямой push в защищённые ветки запрещён — расширение `permission-gate` дополнительно переспросит. - Перед MR: `swiftformat --lint .`, `swiftlint --strict`, тесты — всё зелёное. diff --git a/skills/typescript-standards/SKILL.md b/skills/typescript-standards/SKILL.md index 21bc037..7613bfe 100644 --- a/skills/typescript-standards/SKILL.md +++ b/skills/typescript-standards/SKILL.md @@ -42,7 +42,10 @@ test/ | *.test.ts # рядом с кодом или в test/ ## Коммиты и MR -- **Формат коммитов:** ``. +- **Формат коммитов:** Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:` …). +- **Ветки и деплой:** фича-ветки — от `main` (в имя ветки желательно включать ключ тикета). + Деплой управляется ветками/тегами: ветка `release-*` → раскатка на **stage**; тег `v*` → раскатка в **прод**. + Ветки `release-*` и теги `v*` без необходимости не пушь — `permission-gate` переспросит. - **MR обязателен** (см. корпоративные правила из контекста сессии). Прямой push в защищённые ветки запрещён — расширение `permission-gate` дополнительно переспросит. - Перед MR: `tsc --noEmit`, `eslint .`, `prettier --check .`, тесты — всё зелёное. From 6521d9c43199178532c5b2f0ad9c8611ffabaf27 Mon Sep 17 00:00:00 2001 From: Aleksey Shakhmatov Date: Thu, 16 Jul 2026 13:13:35 +0300 Subject: [PATCH 4/6] fix(permission-gate): guard release-* branch and v* tag pushes (deploy convention) Deploy convention at M.Video: a release-* branch push deploys to stage and a v* tag push deploys to PROD. The old guard only matched release/* (slash) and never caught tag pushes, so a prod deploy could run unconfirmed. - permission-gate: match main/master, release-[-/], --tags/--follow-tags, and whitespace-preceded v tags; false-positive-safe (space discriminator) - create-mr.sh: refuse source branch release-* (not just release/*) - jira-workflow doc updated to release-* Verified with a behavioral test suite (10 cases incl. v2, false-positive checks). --- extensions/permission-gate.ts | 10 ++++++---- skills/jira-workflow/SKILL.md | 2 +- skills/jira-workflow/scripts/create-mr.sh | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/extensions/permission-gate.ts b/extensions/permission-gate.ts index 9887003..271d3a2 100644 --- a/extensions/permission-gate.ts +++ b/extensions/permission-gate.ts @@ -22,10 +22,12 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; const DANGEROUS_PATTERNS: Array<{ re: RegExp; reason: string }> = [ { re: /\brm\s+(-\w*r\w*f|-\w*f\w*r|--recursive)/i, reason: "recursive force delete (rm -rf)" }, { re: /\bgit\s+push\b[^\n]*(--force\b|--force-with-lease\b|\s-f\b)/i, reason: "force push" }, - { - re: /\bgit\s+push\b[^\n]*\b(main|master|release\/[^\s]+)\b/i, - reason: "push to a protected branch (main/master/release/*)", - }, + { re: /\bgit\s+push\b[^\n]*\b(main|master)\b/i, reason: "push to main/master" }, + // Deploy convention: a `release-*` branch push deploys to STAGE, and a `v*` + // tag push deploys to PROD. Guard both the branch and the tag pushes. + { re: /\bgit\s+push\b[^\n]*\brelease[-/]\S+/i, reason: "push to a release-* branch (deploys to stage)" }, + { re: /\bgit\s+push\b[^\n]*(--tags\b|--follow-tags\b)/i, reason: "push tags (a v* tag deploys to PROD)" }, + { re: /\bgit\s+push\b[^\n]*\sv\d[\w.-]*/i, reason: "push a v* version tag (deploys to PROD)" }, { re: /\bkubectl\b[^\n]*(--context[=\s]?\S*prod|--namespace[=\s]?\S*prod|\bctx-prod\b)/i, reason: "kubectl against a production context/namespace", diff --git a/skills/jira-workflow/SKILL.md b/skills/jira-workflow/SKILL.md index a0c9d87..afe6287 100644 --- a/skills/jira-workflow/SKILL.md +++ b/skills/jira-workflow/SKILL.md @@ -52,7 +52,7 @@ GITLAB_TOKEN=... ./scripts/create-mr.sh "Fix PROJ-123: NPE" main "" PROJ-123 Флаги окружения `create-mr.sh`: `GITLAB_TOKEN` (обязателен), `GITLAB_HOST` (override хоста), `MR_PUSH=0` (не пушить ветку), `MR_DRY_RUN=1` (показать запрос без вызова API). -MR из защищённой ветки (`main`/`master`/`release/*`) скрипт создавать откажется. +MR из защищённой/релизной ветки (`main`/`master`/`release-*`) скрипт создавать откажется. ## Соглашения diff --git a/skills/jira-workflow/scripts/create-mr.sh b/skills/jira-workflow/scripts/create-mr.sh index 613e1c2..992d74b 100755 --- a/skills/jira-workflow/scripts/create-mr.sh +++ b/skills/jira-workflow/scripts/create-mr.sh @@ -26,8 +26,8 @@ JIRA_KEY="${4:-}" # --- Refuse to open an MR *from* a protected branch (safety). ---------------- case "$SOURCE" in - main | master | release/*) - echo "Refusing: source branch '$SOURCE' looks protected. Create a feature branch first." >&2 + main | master | release-* | release/*) + echo "Refusing: source branch '$SOURCE' looks protected/release. Create a feature branch first." >&2 exit 1 ;; esac From 489a63be6980a3a3de0d11e4258f66d2e043484e Mon Sep 17 00:00:00 2001 From: Aleksey Shakhmatov Date: Thu, 16 Jul 2026 13:16:36 +0300 Subject: [PATCH 5/6] docs(skills): set Python=uv and TypeScript=pnpm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - python-standards: uv (uv sync/add, uv.lock committed, run via 'uv run …') - typescript-standards: pnpm (pnpm install/build/test, pnpm-lock.yaml committed) - test runner still TODO (vitest/jest) --- skills/python-standards/SKILL.md | 7 ++++--- skills/typescript-standards/SKILL.md | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/skills/python-standards/SKILL.md b/skills/python-standards/SKILL.md index ad7775f..376df0d 100644 --- a/skills/python-standards/SKILL.md +++ b/skills/python-standards/SKILL.md @@ -19,7 +19,7 @@ src// # src-layout tests/ ``` - + ## Линтеры и форматирование @@ -35,8 +35,9 @@ tests/ ## Окружение и зависимости -- Менеджер зависимостей и lock: `` — lock коммитим. -- Виртуальное окружение — обязательно; глобально пакеты не ставим. +- Менеджер зависимостей: **uv** — `uv sync` (установка), `uv add `; lock `uv.lock` коммитим. +- Команды запускай через `uv run …` (напр. `uv run pytest`, `uv run ruff check .`, `uv run mypy .`). +- Виртуальное окружение (`.venv`) создаёт uv; глобально пакеты не ставим. ## Коммиты и MR diff --git a/skills/typescript-standards/SKILL.md b/skills/typescript-standards/SKILL.md index 7613bfe..a4e9648 100644 --- a/skills/typescript-standards/SKILL.md +++ b/skills/typescript-standards/SKILL.md @@ -21,7 +21,7 @@ src/ test/ | *.test.ts # рядом с кодом или в test/ ``` - + ## Линтеры и форматирование @@ -32,13 +32,13 @@ test/ | *.test.ts # рядом с кодом или в test/ ## Тесты -- Прогон: `` — напр. `npm test`. +- Прогон: `` — напр. `pnpm test`. - Требования к покрытию: ``. ## Сборка и зависимости -- Сборка: `npm run build` (или скрипт проекта). -- Пакетный менеджер и lock-файл: `` — lock коммитим. +- Сборка: `pnpm build` (или скрипт проекта). +- Пакетный менеджер: **pnpm** — `pnpm install`; lock `pnpm-lock.yaml` коммитим. ## Коммиты и MR From e04a2ddb7276abc3500fe34928c54fad0937d143 Mon Sep 17 00:00:00 2001 From: Aleksey Shakhmatov Date: Thu, 16 Jul 2026 13:25:18 +0300 Subject: [PATCH 6/6] docs(skills): fill language standards with industry defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per decision to use common industry practice now and tune later: - structures: standard layouts (go cmd/internal/pkg, python src-layout, rust cargo, ts pnpm workspaces, kotlin Gradle modules, swift SwiftPM) - linters: default rulesets (golangci base, clippy -D warnings, ruff+mypy, typescript-eslint+prettier, ktlint+detekt, swiftlint+swiftformat) - test runners: TS=vitest; coverage soft targets (~70-80%) marked '(пороги уточним)' - swift deps: SwiftPM (Package.resolved), CocoaPods legacy-only - reworded intros: values are industry defaults to be tuned, no raw TODO markers left Verified: no TODO markers remain in *-standards; all six skills load via pi. --- skills/go-standards/SKILL.md | 10 ++++++---- skills/kotlin-standards/SKILL.md | 8 ++++---- skills/python-standards/SKILL.md | 8 ++++---- skills/rust-standards/SKILL.md | 8 ++++---- skills/swift-standards/SKILL.md | 10 +++++----- skills/typescript-standards/SKILL.md | 10 +++++----- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/skills/go-standards/SKILL.md b/skills/go-standards/SKILL.md index 3db86bb..ebad78f 100644 --- a/skills/go-standards/SKILL.md +++ b/skills/go-standards/SKILL.md @@ -7,7 +7,7 @@ description: Используй при написании, ревью и про Наш основной стек — **Go**. Скилл описывает, как писать, проверять и оформлять код. Реалистичные общепринятые дефолты приведены ниже; то, что специфично для компании, -помечено `TODO` — уточняй, не выдумывай. +заполнено дефолтами индустрии — тюним под M.Video позже. ## Структура сервиса @@ -21,7 +21,7 @@ pkg/ # переиспользуемый публичный api/ # спецификации API (proto/openapi) ``` - +> Ориентир по индустрии: `cmd/` + `internal/` + `pkg/`. Эталон под M.Video уточним позже. ## Линтеры @@ -29,13 +29,15 @@ api/ # спецификации API (proto/openapi) - Статический анализ: `go vet ./...`. - Основной линтер: **golangci-lint** — `golangci-lint run ./...`. Набор линтеров задаётся в `.golangci.yml` в корне репозитория. - + Базовый набор: `govet`, `staticcheck`, `errcheck`, `ineffassign`, `gosimple`, `unused`. + Корпоративный `.golangci.yml` добавим позже. ## Тесты - Прогон всех тестов: `go test ./...`. - С гонками и покрытием: `go test -race -cover ./...`. -- Требования к покрытию и обязательные виды тестов: ``. +- Покрытие: мягкий ориентир ~70%+ для бизнес-логики, критичные пути — обязательно; + интеграционные тесты для внешних зависимостей. (пороги уточним) - Именование: `TestXxx`, табличные тесты приветствуются. ## Коммиты и MR diff --git a/skills/kotlin-standards/SKILL.md b/skills/kotlin-standards/SKILL.md index a4c1b8c..38e1a89 100644 --- a/skills/kotlin-standards/SKILL.md +++ b/skills/kotlin-standards/SKILL.md @@ -6,7 +6,7 @@ description: Используй при написании, ревью и про # Стандарты Kotlin Один из наших языков — **Kotlin** (в первую очередь Android). Ниже — общепринятые дефолты -экосистемы; специфичное для компании помечено `TODO` — уточняй, не выдумывай. +экосистемы; специфичное для компании заполнено дефолтами индустрии — тюним под M.Video позже. ## Структура @@ -22,20 +22,20 @@ app/ # Android-модуль приложения / # модульная структура ``` - +> Ориентир: модульный Android-проект на Gradle (Kotlin DSL), актуальные AGP/Gradle. Эталон уточним. ## Линтеры и форматирование - Стиль/формат: **ktlint** — `./gradlew ktlintCheck` (автоформат `./gradlew ktlintFormat`). - Статический анализ: **detekt** — `./gradlew detekt` (конфиг `detekt.yml`). - Android Lint: `./gradlew lint`. - + Дефолт: ktlint (official code style) + стартовый `detekt.yml`. Корпоративный пресет добавим позже. ## Тесты - Unit: `./gradlew test`. - Инструментальные (Android): `./gradlew connectedAndroidTest` (нужен эмулятор/устройство). -- Требования к покрытию / обязательные виды тестов: ``. +- Покрытие: замер через JaCoCo, мягкий ориентир; критичную логику — обязательно. (пороги уточним) ## Сборка и зависимости diff --git a/skills/python-standards/SKILL.md b/skills/python-standards/SKILL.md index 376df0d..1ca5933 100644 --- a/skills/python-standards/SKILL.md +++ b/skills/python-standards/SKILL.md @@ -6,7 +6,7 @@ description: Используй при написании, ревью и про # Стандарты Python Один из наших языков — **Python**. Ниже — общепринятые дефолты экосистемы; специфичное для -компании помечено `TODO` — уточняй, не выдумывай. +компании заполнено дефолтами индустрии — тюним под M.Video позже. ## Структура @@ -19,19 +19,19 @@ src// # src-layout tests/ ``` - +> Ориентир: src-layout, `pyproject.toml`, окружение через uv. Эталон уточним. ## Линтеры и форматирование - Линтер + форматтер: **ruff** — `ruff check .` и `ruff format --check .` (локально `ruff format .`). Конфиг — в `pyproject.toml` (`[tool.ruff]`). - Типы: **mypy** — `mypy .` (конфиг `[tool.mypy]`). - + Дефолт: ruff (правила `E`,`F`,`I`,`UP`,`B`) + mypy строгий для нового кода. Корпоративный пресет уточним. ## Тесты - Прогон: **pytest** — `pytest` (с покрытием — `pytest --cov`). -- Требования к покрытию / обязательные виды тестов: ``. +- Покрытие: `uv run pytest --cov`, мягкий ориентир ~80% для бизнес-логики. (пороги уточним) ## Окружение и зависимости diff --git a/skills/rust-standards/SKILL.md b/skills/rust-standards/SKILL.md index 7529d92..3b4006c 100644 --- a/skills/rust-standards/SKILL.md +++ b/skills/rust-standards/SKILL.md @@ -6,7 +6,7 @@ description: Используй при написании, ревью и про # Стандарты Rust Один из наших языков — **Rust**. Ниже — общепринятые дефолты экосистемы; специфичное для -компании помечено `TODO` — уточняй, не выдумывай. +компании заполнено дефолтами индустрии — тюним под M.Video позже. ## Структура @@ -21,20 +21,20 @@ tests/ # интеграционные тесты benches/ # бенчмарки (если есть) ``` - +> Ориентир: стандартный cargo-лейаут (`src/`, `tests/`), workspace при нескольких crate. Эталон уточним. ## Линтеры и форматирование - Форматирование: `cargo fmt --all` (проверка в CI — `cargo fmt --all -- --check`). - Линтер: **clippy** — `cargo clippy --all-targets --all-features -- -D warnings`. Настройки — в `clippy.toml` / атрибутах crate. - + Дефолт: clippy с `-D warnings`; точечные `allow` — только с комментарием. Корпоративный набор уточним. ## Тесты - Прогон: `cargo test --all-features`. - Для workspace: `cargo test --workspace`. -- Требования к покрытию / обязательные виды тестов: ``. +- Покрытие: `cargo-llvm-cov` (или tarpaulin), мягкий ориентир ~70%+. (пороги уточним) ## Сборка и зависимости diff --git a/skills/swift-standards/SKILL.md b/skills/swift-standards/SKILL.md index a9d221a..179b477 100644 --- a/skills/swift-standards/SKILL.md +++ b/skills/swift-standards/SKILL.md @@ -6,7 +6,7 @@ description: Используй при написании, ревью и про # Стандарты Swift Один из наших языков — **Swift** (iOS/macOS). Ниже — общепринятые дефолты экосистемы; -специфичное для компании помечено `TODO` — уточняй, не выдумывай. +значения под M.Video заполнены дефолтами индустрии — тюним позже. ## Структура @@ -18,24 +18,24 @@ Sources//... Tests/Tests/... ``` - +> Ориентир: SwiftPM-пакет (`Package.swift`), `Sources/` + `Tests/`. Эталон уточним. ## Линтеры и форматирование - Форматирование: **swiftformat** — `swiftformat --lint .` (автоформат `swiftformat .`). - Линтер: **swiftlint** — `swiftlint` (конфиг `.swiftlint.yml`), в CI `swiftlint --strict`. - + Дефолт: SwiftLint + SwiftFormat (дефолтные конфиги). Корпоративный пресет уточним. ## Тесты - SwiftPM: `swift test`. - Xcode-проект: `xcodebuild test -scheme -destination 'platform=iOS Simulator,name=iPhone 15'`. -- Требования к покрытию / обязательные виды тестов: ``. +- Покрытие: `swift test --enable-code-coverage`, мягкий ориентир. (пороги уточним) ## Сборка и зависимости - Сборка: `swift build` (или `xcodebuild build -scheme `). -- Зависимости: `` — lock (`Package.resolved`/`Podfile.lock`) коммитим. +- Зависимости: **SwiftPM** (`Package.resolved` коммитим); CocoaPods — только для легаси. ## Коммиты и MR diff --git a/skills/typescript-standards/SKILL.md b/skills/typescript-standards/SKILL.md index a4e9648..9121af1 100644 --- a/skills/typescript-standards/SKILL.md +++ b/skills/typescript-standards/SKILL.md @@ -6,7 +6,7 @@ description: Используй при написании, ревью и про # Стандарты TypeScript Один из наших языков — **TypeScript** (фронтенд и Node-сервисы). Ниже — общепринятые дефолты -экосистемы; специфичное для компании помечено `TODO` — уточняй, не выдумывай. +экосистемы; значения под M.Video заполнены дефолтами индустрии — тюним позже. ## Структура @@ -21,19 +21,19 @@ src/ test/ | *.test.ts # рядом с кодом или в test/ ``` - +> Ориентир: TS-проект/монорепо на pnpm workspaces, strict `tsconfig`. Эталон уточним. ## Линтеры и форматирование - Типы: `tsc --noEmit` — без ошибок типов. - Линтер: **ESLint** — `eslint .` (конфиг `.eslintrc*` / `eslint.config.*`). - Форматирование: **Prettier** — `prettier --check .` (в CI), `prettier --write .` локально. - + Дефолт: typescript-eslint (recommended) + Prettier (дефолтный конфиг). Корпоративный пресет уточним. ## Тесты -- Прогон: `` — напр. `pnpm test`. -- Требования к покрытию: ``. +- Прогон: **vitest** — `pnpm test` (покрытие `pnpm test --coverage`). +- Покрытие: мягкий ориентир ~80% для бизнес-логики. (пороги уточним) ## Сборка и зависимости