From ce5fb6bea7431263d9d886706236a94a4333ff2f Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Wed, 3 Jun 2026 18:50:35 +0300 Subject: [PATCH] =?UTF-8?q?chore(skills):=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=B7=D1=83=D0=B5=D0=BC=D1=8B=D0=B5=20=D1=81=D0=BA=D0=B8=D0=BB?= =?UTF-8?q?=D0=BB=D1=8B,=20review-homework=20=D0=B2=D1=8B=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=D0=B5=D0=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Зачем: - разгрузить контекст сессии — каждый скилл грузит описание в каждый проект; убираем то, чем не пользуемся. - Что: - удалены security-audit, proxy-debug, dotfiles-check, jupyter-notebook, docstring. - review-homework удалён отсюда и перенесён в репозиторий kb-mentoring (.skills/), где он тематически на месте. - Проверка: - git status agents/.agents/skills — перечисленных папок больше нет; восстановимы из git-истории при необходимости. --- agents/.agents/skills/docstring/SKILL.md | 445 ------------------ agents/.agents/skills/dotfiles-check/SKILL.md | 23 - agents/.agents/skills/dotfiles-check/check.sh | 168 ------- .../skills/jupyter-notebook/LICENSE.txt | 201 -------- .../.agents/skills/jupyter-notebook/SKILL.md | 107 ----- .../jupyter-notebook/agents/openai.yaml | 6 - .../assets/experiment-template.ipynb | 110 ----- .../jupyter-notebook/assets/jupyter-small.svg | 3 - .../jupyter-notebook/assets/jupyter.png | Bin 2713 -> 0 bytes .../assets/tutorial-template.ipynb | 107 ----- .../references/experiment-patterns.md | 10 - .../references/notebook-structure.md | 17 - .../references/quality-checklist.md | 11 - .../references/tutorial-patterns.md | 9 - .../jupyter-notebook/scripts/new_notebook.py | 130 ----- agents/.agents/skills/proxy-debug/SKILL.md | 98 ---- .../.agents/skills/review-homework/SKILL.md | 76 --- agents/.agents/skills/security-audit/SKILL.md | 228 --------- 18 files changed, 1749 deletions(-) delete mode 100644 agents/.agents/skills/docstring/SKILL.md delete mode 100644 agents/.agents/skills/dotfiles-check/SKILL.md delete mode 100755 agents/.agents/skills/dotfiles-check/check.sh delete mode 100644 agents/.agents/skills/jupyter-notebook/LICENSE.txt delete mode 100644 agents/.agents/skills/jupyter-notebook/SKILL.md delete mode 100644 agents/.agents/skills/jupyter-notebook/agents/openai.yaml delete mode 100644 agents/.agents/skills/jupyter-notebook/assets/experiment-template.ipynb delete mode 100644 agents/.agents/skills/jupyter-notebook/assets/jupyter-small.svg delete mode 100644 agents/.agents/skills/jupyter-notebook/assets/jupyter.png delete mode 100644 agents/.agents/skills/jupyter-notebook/assets/tutorial-template.ipynb delete mode 100644 agents/.agents/skills/jupyter-notebook/references/experiment-patterns.md delete mode 100644 agents/.agents/skills/jupyter-notebook/references/notebook-structure.md delete mode 100644 agents/.agents/skills/jupyter-notebook/references/quality-checklist.md delete mode 100644 agents/.agents/skills/jupyter-notebook/references/tutorial-patterns.md delete mode 100644 agents/.agents/skills/jupyter-notebook/scripts/new_notebook.py delete mode 100644 agents/.agents/skills/proxy-debug/SKILL.md delete mode 100644 agents/.agents/skills/review-homework/SKILL.md delete mode 100644 agents/.agents/skills/security-audit/SKILL.md diff --git a/agents/.agents/skills/docstring/SKILL.md b/agents/.agents/skills/docstring/SKILL.md deleted file mode 100644 index 292b571..0000000 --- a/agents/.agents/skills/docstring/SKILL.md +++ /dev/null @@ -1,445 +0,0 @@ ---- -name: python-docstring -description: A skill for writing consistent, well-structured Python docstrings following the Google style convention. -metadata: - author: Deerhide - version: 1.0.0 ---- - -# Python Docstring Skill - -## When to use this skill? - -- Use this skill when writing or updating Python documentation strings (docstrings). -- This skill is useful for ensuring consistent documentation across a Python codebase. -- It should be applied when documenting modules, classes, functions, methods, and attributes. -- Use it during code reviews to verify docstring quality and completeness. - -# Language - -Язык docstring'ов определяется по проекту: если в существующем коде комментарии и docstring'ы на русском — пиши на русском, если на английском — на английском. Не смешивай языки внутри одного проекта. - -# Docstring Style Convention - -We follow the **Google style** docstring convention. This style is chosen for its: -- Readability and clean formatting -- Wide adoption in the Python community -- Excellent support in documentation tools (Sphinx, MkDocs) -- Native support in linting tools (Ruff, Pylint) - -# Module Docstrings - -Every Python module should start with a docstring describing its purpose. - -```python -"""Module for handling user authentication and session management. - -This module provides utilities for user authentication, token generation, -and session lifecycle management. It integrates with OAuth2 providers -and supports JWT-based authentication. - -Example: - Basic usage of the authentication service:: - - from auth import AuthService - - service = AuthService(secret_key="my-secret") - token = service.create_token(user_id=123) - -Attributes: - DEFAULT_TOKEN_EXPIRY (int): Default token expiration time in seconds. - SUPPORTED_ALGORITHMS (list): List of supported JWT algorithms. - -Todo: - * Add support for refresh tokens - * Implement rate limiting for failed attempts -""" - -DEFAULT_TOKEN_EXPIRY = 3600 -SUPPORTED_ALGORITHMS = ["HS256", "RS256"] -``` - -# Class Docstrings - -Class docstrings should describe the class purpose and list its attributes. - -```python -class UserRepository: - """Repository for managing user data persistence. - - This class provides CRUD operations for user entities and handles - database connections and transactions. - - Attributes: - connection: Database connection instance. - table_name: Name of the users table. - cache_enabled: Whether caching is enabled for queries. - - Example: - Creating and using a repository:: - - repo = UserRepository(connection=db_conn) - user = repo.find_by_id(user_id=42) - repo.save(user) - """ - - def __init__(self, connection: DatabaseConnection) -> None: - """Initialize the UserRepository. - - Args: - connection: Active database connection to use for operations. - """ - self.connection = connection - self.table_name = "users" - self.cache_enabled = True -``` - -# Function and Method Docstrings - -Functions and methods should document their purpose, arguments, return values, and exceptions. - -## Basic Function - -```python -def calculate_discount(price: float, percentage: float) -> float: - """Calculate the discounted price. - - Args: - price: Original price of the item. - percentage: Discount percentage (0-100). - - Returns: - The discounted price after applying the percentage reduction. - - Raises: - ValueError: If percentage is not between 0 and 100. - TypeError: If price or percentage are not numeric. - - Example: - >>> calculate_discount(100.0, 20) - 80.0 - """ - if not 0 <= percentage <= 100: - raise ValueError("Percentage must be between 0 and 100") - return price * (1 - percentage / 100) -``` - -## Method with Complex Arguments - -```python -def create_user( - self, - username: str, - email: str, - *, - role: str = "user", - metadata: dict[str, Any] | None = None, -) -> User: - """Create a new user in the system. - - Creates a user entity with the provided information and persists - it to the database. Sends a welcome email upon successful creation. - - Args: - username: Unique username for the new user. Must be alphanumeric - and between 3-50 characters. - email: Valid email address for the user. - role: User role assignment. Defaults to "user". - Valid options are "user", "admin", "moderator". - metadata: Optional dictionary of additional user metadata. - Keys must be strings, values can be any JSON-serializable type. - - Returns: - The newly created User instance with assigned ID. - - Raises: - DuplicateUserError: If username or email already exists. - ValidationError: If input validation fails. - DatabaseError: If database operation fails. - - Note: - This method triggers a background task for sending the welcome email. - The email sending is non-blocking and failures are logged but not raised. - - Example: - Creating a basic user:: - - user = service.create_user( - username="johndoe", - email="john@example.com" - ) - - Creating an admin user with metadata:: - - admin = service.create_user( - username="admin", - email="admin@example.com", - role="admin", - metadata={"department": "IT"} - ) - """ -``` - -## Async Functions - -```python -async def fetch_user_data(user_id: int, timeout: float = 30.0) -> UserData: - """Fetch user data from the remote service. - - Asynchronously retrieves user information from the external API - with automatic retry logic for transient failures. - - Args: - user_id: Unique identifier of the user to fetch. - timeout: Maximum time in seconds to wait for response. - Defaults to 30.0 seconds. - - Returns: - UserData object containing the user's information. - - Raises: - UserNotFoundError: If no user exists with the given ID. - TimeoutError: If the request exceeds the timeout duration. - ServiceUnavailableError: If the remote service is unreachable. - """ -``` - -# Generator and Iterator Docstrings - -```python -def paginate_results( - query: Query, - page_size: int = 100, -) -> Iterator[list[Record]]: - """Paginate through query results. - - Yields pages of records from the query, handling cursor-based - pagination automatically. - - Args: - query: Database query to paginate. - page_size: Number of records per page. Defaults to 100. - - Yields: - Lists of Record objects, each list containing up to page_size items. - - Example: - >>> for page in paginate_results(query, page_size=50): - ... process_records(page) - """ -``` - -# Property Docstrings - -```python -@property -def full_name(self) -> str: - """Return the full name of the user. - - Combines first_name and last_name with proper spacing. - Returns an empty string if both names are unset. - """ - return f"{self.first_name} {self.last_name}".strip() - - -@property -def is_active(self) -> bool: - """Return whether the user account is currently active. - - An account is considered active if it has been verified - and has not been suspended or deleted. - """ - return self.verified and not self.suspended -``` - -# Context Manager Docstrings - -```python -@contextmanager -def database_transaction( - connection: Connection, - isolation_level: str = "READ_COMMITTED", -) -> Iterator[Transaction]: - """Context manager for database transactions. - - Provides automatic commit on success and rollback on failure. - Nested transactions are supported via savepoints. - - Args: - connection: Active database connection. - isolation_level: Transaction isolation level. - Options: "READ_UNCOMMITTED", "READ_COMMITTED", - "REPEATABLE_READ", "SERIALIZABLE". - Defaults to "READ_COMMITTED". - - Yields: - Transaction object for executing queries. - - Raises: - TransactionError: If transaction cannot be started. - - Example: - >>> with database_transaction(conn) as tx: - ... tx.execute("INSERT INTO users VALUES (?)", [user]) - """ -``` - -# Dataclass and Pydantic Model Docstrings - -```python -@dataclass -class OrderItem: - """Represents a single item in an order. - - Attributes: - product_id: Unique identifier of the product. - quantity: Number of units ordered. Must be positive. - unit_price: Price per unit in the order currency. - discount: Applied discount as a decimal (0.0-1.0). - """ - - product_id: str - quantity: int - unit_price: Decimal - discount: Decimal = Decimal("0.0") - - -class UserSettings(BaseModel): - """User preference settings. - - Stores user-configurable settings for the application, - including notification preferences and display options. - - Attributes: - theme: UI theme preference. Either "light" or "dark". - notifications_enabled: Whether to send notifications. - language: Preferred language code (ISO 639-1). - timezone: User's timezone (IANA format). - """ - - theme: Literal["light", "dark"] = "light" - notifications_enabled: bool = True - language: str = "en" - timezone: str = "UTC" -``` - -# Enum Docstrings - -```python -class OrderStatus(Enum): - """Status values for order lifecycle. - - Attributes: - PENDING: Order created but not yet processed. - CONFIRMED: Order confirmed and awaiting fulfillment. - SHIPPED: Order has been shipped to customer. - DELIVERED: Order successfully delivered. - CANCELLED: Order was cancelled before fulfillment. - """ - - PENDING = "pending" - CONFIRMED = "confirmed" - SHIPPED = "shipped" - DELIVERED = "delivered" - CANCELLED = "cancelled" -``` - -# Exception Docstrings - -```python -class ValidationError(Exception): - """Raised when input validation fails. - - This exception is raised when user input or API request data - fails validation rules. - - Attributes: - field: Name of the field that failed validation. - message: Human-readable error message. - code: Machine-readable error code for client handling. - - Example: - >>> raise ValidationError( - ... field="email", - ... message="Invalid email format", - ... code="INVALID_EMAIL" - ... ) - """ - - def __init__(self, field: str, message: str, code: str) -> None: - """Initialize ValidationError. - - Args: - field: Name of the field that failed validation. - message: Human-readable description of the error. - code: Machine-readable error code. - """ - self.field = field - self.message = message - self.code = code - super().__init__(f"{field}: {message}") -``` - -# Docstring Sections Reference - -The following sections are supported in Google style docstrings: - -| Section | Purpose | -|---------|---------| -| `Args:` | Document function/method parameters | -| `Returns:` | Describe the return value | -| `Yields:` | Describe yielded values (generators) | -| `Raises:` | List exceptions that may be raised | -| `Attributes:` | Document class/module attributes | -| `Example:` / `Examples:` | Provide usage examples | -| `Note:` | Additional information or caveats | -| `Warning:` | Important warnings for users | -| `Todo:` | Future improvements or tasks | -| `See Also:` | References to related functions/classes | - -# Best Practices - -1. **Be Concise**: First line should be a brief summary under 79 characters. -2. **Use Imperative Mood**: Write "Calculate the sum" not "Calculates the sum". -3. **Document All Public APIs**: Every public function, class, and method needs a docstring. -4. **Rely on Type Hints**: Avoid duplicating type information in docstrings when type hints are present. Modern documentation tools extract types from annotations. -5. **Provide Examples**: Complex functions benefit from usage examples. -6. **Document Exceptions**: List all exceptions that can be raised. -7. **Keep Updated**: Update docstrings when code changes. -8. **Use Proper Indentation**: Continuation lines should be indented consistently. - -# Linting Configuration - -Recommended Ruff configuration for `pyproject.toml`: - -```toml -[tool.ruff] -line-length = 120 - -[tool.ruff.lint] -select = ["D", "F", "E", "W", "I", "UP", "B", "SIM", "S", "A", "C90", "RET", "PERF"] - -[tool.ruff.lint.pydocstyle] -convention = "google" -``` - -Key rule groups: **D** (docstrings), **F** (pyflakes), **E/W** (pycodestyle), -**I** (imports), **UP** (pyupgrade), **B** (bugbear), **SIM** (simplify), -**S** (security/bandit), **A** (builtins shadowing), **C90** (complexity), -**RET** (return statements), **PERF** (performance). - -# Common Ruff Docstring Rules - -| Rule | Description | -|------|-------------| -| D100 | Missing docstring in public module | -| D101 | Missing docstring in public class | -| D102 | Missing docstring in public method | -| D103 | Missing docstring in public function | -| D107 | Missing docstring in `__init__` | -| D200 | One-line docstring should fit on one line | -| D205 | 1 blank line required between summary and description | -| D400 | First line should end with a period | -| D401 | First line should be in imperative mood | -| D417 | Missing argument descriptions in docstring | - diff --git a/agents/.agents/skills/dotfiles-check/SKILL.md b/agents/.agents/skills/dotfiles-check/SKILL.md deleted file mode 100644 index 98a5750..0000000 --- a/agents/.agents/skills/dotfiles-check/SKILL.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -name: dotfiles-check -description: "Проверка целостности dotfiles: симлинки stow, права доступа, settings.local.json, bashrc. Вызывай когда пользователь просит проверить установку dotfiles или валидировать окружение." -disable-model-invocation: true ---- - -# Инструкция - -Запусти скрипт проверки: - -```bash -bash ~/.agents/skills/dotfiles-check/check.sh -``` - -Если пользователь передал путь к dotfiles-репозиторию: - -```bash -bash ~/.agents/skills/dotfiles-check/check.sh $ARGUMENTS -``` - -Скрипт сам обнаружит stow-пакеты, проверит симлинки, права и дополнительные условия из `install.sh`. - -Если есть ошибки (exit code 1) — кратко прокомментируй что сломалось и предложи команды для починки. diff --git a/agents/.agents/skills/dotfiles-check/check.sh b/agents/.agents/skills/dotfiles-check/check.sh deleted file mode 100755 index 24c21cb..0000000 --- a/agents/.agents/skills/dotfiles-check/check.sh +++ /dev/null @@ -1,168 +0,0 @@ -#!/usr/bin/env bash -# Проверка целостности dotfiles-установки через stow. -# Использование: bash check.sh [путь-к-dotfiles] - -set -euo pipefail - -DOTFILES_DIR="${1:-$(cd "$(dirname "$0")/../../../.." && pwd)}" - -GREEN='\033[0;32m' -RED='\033[0;31m' -YELLOW='\033[1;33m' -NC='\033[0m' - -ok=0; warn=0; fail=0 - -pass() { echo -e " ${GREEN}✅${NC} $*"; ok=$((ok + 1)); } -skip() { echo -e " ${YELLOW}⚠️${NC} $*"; warn=$((warn + 1)); } -err() { echo -e " ${RED}❌${NC} $*"; fail=$((fail + 1)); } - -echo "Проверка dotfiles ($DOTFILES_DIR)" -echo "═══════════════════════════════════════" - -# --- 1. Stow-пакеты: проверка симлинков --- -# Stow использует "tree folding": если вся директория принадлежит одному пакету, -# создаётся один симлинк на директорию, а не на каждый файл внутри. -# Поэтому проверяем точки входа верхнего уровня каждого пакета. - -for pkg_dir in "$DOTFILES_DIR"/*/; do - pkg=$(basename "$pkg_dir") - [[ "$pkg" == .* ]] && continue - # claude управляется вручную (симлинк settings.local.json), не через stow - [[ "$pkg" == "claude" ]] && continue - - # Точки входа — элементы первого уровня внутри пакета - entries=() - for entry in "$pkg_dir".* "$pkg_dir"*; do - [ -e "$entry" ] || continue - base=$(basename "$entry") - [[ "$base" == "." || "$base" == ".." ]] && continue - # Берём только dot-файлы/директории (то, что stow раскладывает в ~) - [[ "$base" == .* ]] && entries+=("$base") - done - - [ ${#entries[@]} -eq 0 ] && continue - - echo "" - echo "$pkg (${#entries[@]} точек входа):" - - for entry in "${entries[@]}"; do - home_path="$HOME/$entry" - expected="$DOTFILES_DIR/$pkg/$entry" - - # Если это директория в пакете — stow мог создать симлинк на неё целиком - # или "раскрыть" её и создать симлинки внутри. Проверяем оба варианта. - if [ -L "$home_path" ]; then - # Симлинк на верхнем уровне (tree folding) - actual=$(readlink -f "$home_path" 2>/dev/null || true) - expected_resolved=$(readlink -f "$expected" 2>/dev/null || true) - if [ "$actual" = "$expected_resolved" ]; then - pass "~/$entry" - else - err "~/$entry → $(readlink "$home_path") (ожидался $pkg/$entry)" - fi - elif [ -d "$home_path" ] && [ -d "$expected" ]; then - # Директория раскрыта — проверяем файлы внутри (один уровень) - inner_ok=0; inner_fail=0 - while IFS= read -r -d '' f; do - fname=$(basename "$f") - inner_home="$home_path/$fname" - if [ -L "$inner_home" ]; then - inner_actual=$(readlink -f "$inner_home" 2>/dev/null || true) - inner_expected=$(readlink -f "$f" 2>/dev/null || true) - if [ "$inner_actual" = "$inner_expected" ]; then - inner_ok=$((inner_ok + 1)) - else - inner_fail=$((inner_fail + 1)) - fi - elif [ -e "$inner_home" ]; then - inner_ok=$((inner_ok + 1)) # файл есть, но не симлинк — ок для stow unfolded - else - inner_fail=$((inner_fail + 1)) - fi - done < <(find "$expected" -maxdepth 1 -not -path "$expected" -print0) - - if [ "$inner_fail" -eq 0 ]; then - pass "~/$entry/ ($inner_ok элементов)" - else - err "~/$entry/ — $inner_fail из $((inner_ok + inner_fail)) элементов отсутствуют" - fi - elif [ -e "$home_path" ]; then - skip "~/$entry — обычный файл (не симлинк)" - else - err "~/$entry — не найден" - fi - done -done - -# --- 2. Дополнительные проверки из install.sh --- -install_script="$DOTFILES_DIR/install.sh" -if [ -f "$install_script" ]; then - echo "" - echo "Доп. проверки (install.sh):" - - # Claude Code: ~/.claude должна быть директорией, не симлинком - if [ -L "$HOME/.claude" ]; then - err "~/.claude — симлинк (должна быть директория). Запустите install.sh" - elif [ -d "$HOME/.claude" ]; then - pass "~/.claude — директория (не симлинк)" - else - err "~/.claude — не найден" - fi - - # Claude Code: settings.local.json должен быть симлинком на репозиторий - if [ -L "$HOME/.claude/settings.local.json" ]; then - local_target=$(readlink -f "$HOME/.claude/settings.local.json" 2>/dev/null || true) - local_expected=$(readlink -f "$DOTFILES_DIR/claude/.claude/settings.local.json" 2>/dev/null || true) - if [ "$local_target" = "$local_expected" ]; then - pass "~/.claude/settings.local.json → репозиторий" - else - err "~/.claude/settings.local.json → $local_target (ожидался $local_expected)" - fi - elif [ -f "$HOME/.claude/settings.local.json" ]; then - err "~/.claude/settings.local.json — обычный файл (должен быть симлинк). Запустите install.sh" - elif [ -e "$HOME/.claude/settings.local.json" ]; then - err "~/.claude/settings.local.json — не файл и не симлинк. Удалите вручную и запустите install.sh" - else - err "~/.claude/settings.local.json — не найден (запустите install.sh)" - fi - - # skills симлинк - if [ -L "$HOME/.claude/skills" ]; then - pass "~/.claude/skills — симлинк" - else - skip "~/.claude/skills — не найден" - fi - - # bashrc - if grep -q 'bash_custom' "$HOME/.bashrc" 2>/dev/null; then - pass "~/.bashrc содержит подключение bash_custom" - else - skip "~/.bashrc не содержит bash_custom" - fi -fi - -# --- 3. Битые симлинки --- -broken=$(find "$HOME" -maxdepth 3 -xtype l 2>/dev/null | grep -v '.cache\|.local/share\|node_modules\|.npm' | head -10) -if [ -n "$broken" ]; then - echo "" - echo "Битые симлинки в ~:" - while IFS= read -r link; do - err "$link → $(readlink "$link") (цель не существует)" - done <<< "$broken" -fi - -# --- 4. Секреты --- -if [ -f "$HOME/.env.secrets" ]; then - echo "" - echo "Секреты:" - pass "~/.env.secrets существует" -fi - -# --- Итого --- -total=$((ok + warn + fail)) -echo "" -echo "═══════════════════════════════════════" -echo -e "Итого: ${GREEN}$ok${NC}/${total} ✅, ${YELLOW}$warn${NC} ⚠️, ${RED}$fail${NC} ❌" - -[ "$fail" -eq 0 ] && exit 0 || exit 1 diff --git a/agents/.agents/skills/jupyter-notebook/LICENSE.txt b/agents/.agents/skills/jupyter-notebook/LICENSE.txt deleted file mode 100644 index 13e25df..0000000 --- a/agents/.agents/skills/jupyter-notebook/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf of - any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don\'t include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/agents/.agents/skills/jupyter-notebook/SKILL.md b/agents/.agents/skills/jupyter-notebook/SKILL.md deleted file mode 100644 index e1d1748..0000000 --- a/agents/.agents/skills/jupyter-notebook/SKILL.md +++ /dev/null @@ -1,107 +0,0 @@ ---- -name: "jupyter-notebook" -description: "Use when the user asks to create, scaffold, or edit Jupyter notebooks (`.ipynb`) for experiments, explorations, or tutorials; prefer the bundled templates and run the helper script `new_notebook.py` to generate a clean starting notebook." ---- - - -# Jupyter Notebook Skill - -Create clean, reproducible Jupyter notebooks for two primary modes: - -- Experiments and exploratory analysis -- Tutorials and teaching-oriented walkthroughs - -Prefer the bundled templates and the helper script for consistent structure and fewer JSON mistakes. - -## When to use -- Create a new `.ipynb` notebook from scratch. -- Convert rough notes or scripts into a structured notebook. -- Refactor an existing notebook to be more reproducible and skimmable. -- Build experiments or tutorials that will be read or re-run by other people. - -## Decision tree -- If the request is exploratory, analytical, or hypothesis-driven, choose `experiment`. -- If the request is instructional, step-by-step, or audience-specific, choose `tutorial`. -- If editing an existing notebook, treat it as a refactor: preserve intent and improve structure. - -## Skill path (set once) - -```bash -export CODEX_HOME="${CODEX_HOME:-$HOME/.codex}" -export JUPYTER_NOTEBOOK_CLI="$CODEX_HOME/skills/jupyter-notebook/scripts/new_notebook.py" -``` - -User-scoped skills install under `$CODEX_HOME/skills` (default: `~/.codex/skills`). - -## Workflow -1. Lock the intent. -Identify the notebook kind: `experiment` or `tutorial`. -Capture the objective, audience, and what "done" looks like. - -2. Scaffold from the template. -Use the helper script to avoid hand-authoring raw notebook JSON. - -```bash -uv run --python 3.12 python "$JUPYTER_NOTEBOOK_CLI" \ - --kind experiment \ - --title "Compare prompt variants" \ - --out output/jupyter-notebook/compare-prompt-variants.ipynb -``` - -```bash -uv run --python 3.12 python "$JUPYTER_NOTEBOOK_CLI" \ - --kind tutorial \ - --title "Intro to embeddings" \ - --out output/jupyter-notebook/intro-to-embeddings.ipynb -``` - -3. Fill the notebook with small, runnable steps. -Keep each code cell focused on one step. -Add short markdown cells that explain the purpose and expected result. -Avoid large, noisy outputs when a short summary works. - -4. Apply the right pattern. -For experiments, follow `references/experiment-patterns.md`. -For tutorials, follow `references/tutorial-patterns.md`. - -5. Edit safely when working with existing notebooks. -Preserve the notebook structure; avoid reordering cells unless it improves the top-to-bottom story. -Prefer targeted edits over full rewrites. -If you must edit raw JSON, review `references/notebook-structure.md` first. - -6. Validate the result. -Run the notebook top-to-bottom when the environment allows. -If execution is not possible, say so explicitly and call out how to validate locally. -Use the final pass checklist in `references/quality-checklist.md`. - -## Templates and helper script -- Templates live in `assets/experiment-template.ipynb` and `assets/tutorial-template.ipynb`. -- The helper script loads a template, updates the title cell, and writes a notebook. - -Script path: -- `$JUPYTER_NOTEBOOK_CLI` (installed default: `$CODEX_HOME/skills/jupyter-notebook/scripts/new_notebook.py`) - -## Temp and output conventions -- Use `tmp/jupyter-notebook/` for intermediate files; delete when done. -- Write final artifacts under `output/jupyter-notebook/` when working in this repo. -- Use stable, descriptive filenames (for example, `ablation-temperature.ipynb`). - -## Dependencies (install only when needed) -Prefer `uv` for dependency management. - -Optional Python packages for local notebook execution: - -```bash -uv pip install jupyterlab ipykernel -``` - -The bundled scaffold script uses only the Python standard library and does not require extra dependencies. - -## Environment -No required environment variables. - -## Reference map -- `references/experiment-patterns.md`: experiment structure and heuristics. -- `references/tutorial-patterns.md`: tutorial structure and teaching flow. -- `references/notebook-structure.md`: notebook JSON shape and safe editing rules. -- `references/quality-checklist.md`: final validation checklist. diff --git a/agents/.agents/skills/jupyter-notebook/agents/openai.yaml b/agents/.agents/skills/jupyter-notebook/agents/openai.yaml deleted file mode 100644 index 8832dea..0000000 --- a/agents/.agents/skills/jupyter-notebook/agents/openai.yaml +++ /dev/null @@ -1,6 +0,0 @@ -interface: - display_name: "Jupyter Notebooks" - short_description: "Create Jupyter notebooks for experiments and tutorials" - icon_small: "./assets/jupyter-small.svg" - icon_large: "./assets/jupyter.png" - default_prompt: "Create a Jupyter notebook for this task with clear sections, runnable cells, and concise takeaways." diff --git a/agents/.agents/skills/jupyter-notebook/assets/experiment-template.ipynb b/agents/.agents/skills/jupyter-notebook/assets/experiment-template.ipynb deleted file mode 100644 index a4a0323..0000000 --- a/agents/.agents/skills/jupyter-notebook/assets/experiment-template.ipynb +++ /dev/null @@ -1,110 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Experiment: TITLE\n", - "\n", - "Objective:\n", - "- State the question you want to answer.\n", - "- Define the success criteria.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Setup: imports and reproducibility\n", - "from __future__ import annotations\n", - "\n", - "import random\n", - "import statistics\n", - "\n", - "SEED = 7\n", - "random.seed(SEED)\n", - "SEED\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Plan\n", - "\n", - "- Hypothesis:\n", - "- Variables to sweep:\n", - "- Metrics to record:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define parameters and lightweight helpers\n", - "sample_size = 20\n", - "values = [random.random() for _ in range(sample_size)]\n", - "summary = {\n", - " \"count\": len(values),\n", - " \"mean\": statistics.fmean(values),\n", - " \"min\": min(values),\n", - " \"max\": max(values),\n", - "}\n", - "summary\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Results\n", - "\n", - "- Key observations:\n", - "- Surprises or failure modes:\n", - "- Decision: continue, pivot, or stop:\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Record findings in a minimal, copy-pasteable structure\n", - "result = {\n", - " \"seed\": SEED,\n", - " \"mean\": summary[\"mean\"],\n", - " \"range\": summary[\"max\"] - summary[\"min\"],\n", - "}\n", - "result\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Next steps\n", - "\n", - "- What to try next:\n", - "- What to document elsewhere (PRD, notes, issue):\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/agents/.agents/skills/jupyter-notebook/assets/jupyter-small.svg b/agents/.agents/skills/jupyter-notebook/assets/jupyter-small.svg deleted file mode 100644 index 472d07f..0000000 --- a/agents/.agents/skills/jupyter-notebook/assets/jupyter-small.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/agents/.agents/skills/jupyter-notebook/assets/jupyter.png b/agents/.agents/skills/jupyter-notebook/assets/jupyter.png deleted file mode 100644 index 51cdf7d3bba730eda85a26a87d1ee65c14da97f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2713 zcmV;K3TE|*P)~ebAJu^KsRWmhq|HNp<{jU1g z_o(i!A~EhEG0spXF-{Q+;ux_Yju8vu7_lIZ5ewoNu^^5S3*s2%5;KiQj~+>1U%!lu zjL71}i{<_ItJHTPhz0S10IjWU(%s#iv>Y*Z?b;H{fz=RNOxy<|g8O^vj* zeVulj&6_uiZHx%g-rg>~_wLEi(2#7ctCKqKlMh;eSO4pf*F7D-2#^Jd%D0s$<<<2v zr>0)Y7QdTzds_a7AJ(S~+aPKQ^PTerHCVoFt2m3;hhLqR%+c?r_n+bjS0?6c5yCp|&dd%{Ek zAx1m?rM_*0<;=9sicGt}mpRa197Eui|-)gS8C(b5GH)En(ulEYe+__WsJVj4-RA1yX3&A<$PI{cpxJ*%paHyeL;HVrYsf zigiJ95rfn;;Z+75yE!XAki-)2_d8zY&>N>$?yV1lWMO=u&-?!ImtMWs!Nd){`Tje} zhGL0gRgkD+sJ?-h<>(KcIMXEc{vUoDNuXkgVoeYVKGOV$lO`X<6Afy1LDh8->e0pt4gt2d$jXxHc zc1|$_LX34aE7yc++elrD1r4jxbGtGw*6+a?6Xdm*=JI5Y;8)64k&5!oA9-bK_R{%I zt5#x6ka6$%c4fm~WhR5wSAOyz^+eMaMuIvmW+qxiF(}B*#hB>C?`1j0tP$k#n>luEZetlPg-~3!Ub8jY?J{QUWIRk$#J%{rD-Xg^dkE(JeNh3X2S0{Hv% z>C;o&QW+crVS{j7#9}?iVE^EH{qe(jsa!w=&doJ(UjH%pt*@VT`aGs^>Sb#RNhQ$Q zs1Uu37D>UWXe@#X(4z3+w}w~&d-v{D-?Z8@XU?csUJ;PxL93AykMK11PL^Jye25R}dBLhsuSG8#hW+sBq4s#n2!$*P@RJ z+FJNNb?TH+F~GUu2wS#nnYN6I!7BVNP%p!O>sW&|@i(z0YDKXx`>=gbT)p1!-n1YH zWm*hyPLNdon8H(WRF19)M#kcX2*kKD?XGY)QQ?@tal>L#w%3_2B{M9Vm+-*fDiMK7 z#Fg=L;jk7}8zFkh@Y41fR;#1E$FsnPH;*^mU^e zo=5B`so@A%3Bn-8(BHQ^Gdn`A;G&pJK)>;xZo(Q<7|*iCzWE|4z*7KT=P%#!fMQmdw?In%`XZR_FF@^|%2#j+H4ml{gemF{C*E2bkdjgfMtj>A@ z%P9C~a=;>@Oqw>MW^&L(6~&L9z;a@S(RbBcCsXsEq^TS=*U9k2JSYAcOqsDE+cbPe z&UK>6MU*H|SxNxY6K2lj*?=^*L@~{*m@i8c?4!7b9@JSZF`(eL-_uP@Q%tzaFz>g8 znP4UzMR^|L%B-Z|+FUF}eLz)AYniwideFJKSe$rb$gDe=CK5A+t3qh32{Jl5Dgy%p z>i3c*OQfQrBI7=E*2cQORL@mRr?L~%2i7`2JCSigo;-OXw{PE8-+tDtS)(Rb<`vB- zs7d+xpAneEG6%~^`ri>O&EseTqk`POe_y(~x>BykN_OttsVpWN^lcArd8psSoXHNM zYVF?RV<=NS`S-lrFY8NoHX>t!@M3aHOH0P>5T&7^A(9K5jTn1kc>VhINZS!x7`Yo0 zjuAnqgwuPj0{-4+pE*tY=i!6CLXZk81WQ;ju8vu7_lIZ5ewoNu^^5S3*s2DAdc}f?~c@J Tv%g`A00000NkvXXu0mjf)PowP diff --git a/agents/.agents/skills/jupyter-notebook/assets/tutorial-template.ipynb b/agents/.agents/skills/jupyter-notebook/assets/tutorial-template.ipynb deleted file mode 100644 index 7001309..0000000 --- a/agents/.agents/skills/jupyter-notebook/assets/tutorial-template.ipynb +++ /dev/null @@ -1,107 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Tutorial: TITLE\n", - "\n", - "Audience:\n", - "- Describe who this is for.\n", - "\n", - "Prerequisites:\n", - "- List required concepts or setup.\n", - "\n", - "Learning goals:\n", - "- By the end, the reader can...\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Outline\n", - "\n", - "1. Setup\n", - "2. A minimal working example\n", - "3. Variations and pitfalls\n", - "4. Exercises\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Setup cell: keep it short and deterministic\n", - "from __future__ import annotations\n", - "\n", - "import math\n", - "import random\n", - "\n", - "SEED = 21\n", - "random.seed(SEED)\n", - "SEED\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 1 - Start with a tiny example\n", - "\n", - "Explain what the next cell does in plain language.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Minimal working example\n", - "angles = [0, math.pi / 4, math.pi / 2]\n", - "sines = [math.sin(a) for a in angles]\n", - "list(zip(angles, sines))\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Exercises\n", - "\n", - "- Try a different input.\n", - "- Predict the output before running the code.\n", - "- Note one common mistake and how to fix it.\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Exercise answer scaffold\n", - "def describe(values: list[float]) -> dict[str, float]:\n", - " return {\"min\": min(values), \"max\": max(values)}\n", - "\n", - "describe(sines)\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "name": "python", - "version": "3.12" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/agents/.agents/skills/jupyter-notebook/references/experiment-patterns.md b/agents/.agents/skills/jupyter-notebook/references/experiment-patterns.md deleted file mode 100644 index 2d5093b..0000000 --- a/agents/.agents/skills/jupyter-notebook/references/experiment-patterns.md +++ /dev/null @@ -1,10 +0,0 @@ -# Experiment Patterns - -Use this structure for exploratory and experimental work: - -- Title and objective: state the question and the success criteria. -- Setup and reproducibility: import only what you need, set a seed early, and keep configuration in one short cell. -- Plan: list hypotheses, sweeps, and metrics before running code. -- Minimal baseline: start with the smallest runnable example and confirm it runs end-to-end before adding complexity. -- Results and notes: summarize findings in markdown near the relevant code and record key metrics in a small dictionary or table-like structure. -- Next steps: decide whether to continue, pivot, or stop, and capture follow-up ideas as short bullets. diff --git a/agents/.agents/skills/jupyter-notebook/references/notebook-structure.md b/agents/.agents/skills/jupyter-notebook/references/notebook-structure.md deleted file mode 100644 index 681d36f..0000000 --- a/agents/.agents/skills/jupyter-notebook/references/notebook-structure.md +++ /dev/null @@ -1,17 +0,0 @@ -# Notebook Structure - -Jupyter notebooks are JSON documents with this high-level shape: - -- `nbformat` and `nbformat_minor` -- `metadata` -- `cells` (a list of markdown and code cells) - -When editing `.ipynb` files programmatically: - -- Preserve `nbformat` and `nbformat_minor` from the template. -- Keep `cells` as an ordered list; do not reorder unless intentional. -- For code cells, set `execution_count` to `null` when unknown. -- For code cells, set `outputs` to an empty list when scaffolding. -- For markdown cells, keep `cell_type="markdown"` and `metadata={}`. - -Prefer scaffolding from the bundled templates or `new_notebook.py` (for example, `$CODEX_HOME/skills/jupyter-notebook/scripts/new_notebook.py`) instead of hand-authoring raw notebook JSON. diff --git a/agents/.agents/skills/jupyter-notebook/references/quality-checklist.md b/agents/.agents/skills/jupyter-notebook/references/quality-checklist.md deleted file mode 100644 index 5482f28..0000000 --- a/agents/.agents/skills/jupyter-notebook/references/quality-checklist.md +++ /dev/null @@ -1,11 +0,0 @@ -# Quality Checklist - -Before delivering a notebook: - -- Run it top-to-bottom at least once (or as much as the environment allows). -- Ensure early cells set all required state; avoid hidden state from prior runs. -- Keep outputs tidy. Avoid giant outputs when a short summary works. -- Prefer small tables, key metrics, or short printouts. -- Keep the narrative skimmable. Use headings and short bullets, and avoid long paragraphs. -- Leave helpful TODOs only when necessary, and label them clearly. -- If execution is not possible, call out the risk and how to validate locally. diff --git a/agents/.agents/skills/jupyter-notebook/references/tutorial-patterns.md b/agents/.agents/skills/jupyter-notebook/references/tutorial-patterns.md deleted file mode 100644 index 2a360b0..0000000 --- a/agents/.agents/skills/jupyter-notebook/references/tutorial-patterns.md +++ /dev/null @@ -1,9 +0,0 @@ -# Tutorial Patterns - -Use this structure for teaching and walkthroughs: - -- Audience, prerequisites, and learning goals: say who it is for, list what they should already know, and state what they will be able to do by the end. -- Outline: provide a short numbered outline so readers can skim. -- Step-by-step flow: pair a short markdown explanation with a small code cell that runs on its own and a brief interpretation of the result. -- Exercises: include at least one exercise that reinforces the key concept and provide an answer scaffold in the next cell. -- Pitfalls and extensions: call out one common mistake and how to fix it, and suggest one optional extension for curious readers. diff --git a/agents/.agents/skills/jupyter-notebook/scripts/new_notebook.py b/agents/.agents/skills/jupyter-notebook/scripts/new_notebook.py deleted file mode 100644 index 0aba209..0000000 --- a/agents/.agents/skills/jupyter-notebook/scripts/new_notebook.py +++ /dev/null @@ -1,130 +0,0 @@ -from __future__ import annotations - -import argparse -import json -import re -from pathlib import Path -from typing import Any - - -def slugify(text: str) -> str: - lowered = text.strip().lower() - cleaned = re.sub(r"[^a-z0-9]+", "-", lowered) - collapsed = re.sub(r"-+", "-", cleaned).strip("-") - return collapsed or "notebook" - - -def find_repo_root(start: Path) -> Path: - for candidate in (start, *start.parents): - if (candidate / ".git").exists(): - return candidate - return start - - -def load_template(skill_dir: Path, kind: str) -> dict[str, Any]: - asset_name = "experiment-template.ipynb" if kind == "experiment" else "tutorial-template.ipynb" - template_path = skill_dir / "assets" / asset_name - if not template_path.exists(): - raise SystemExit(f"Missing template: {template_path}") - with template_path.open("r", encoding="utf-8") as f: - data = json.load(f) - if not isinstance(data, dict): - raise SystemExit(f"Unexpected template shape: {template_path}") - return data - - -def update_title(notebook: dict[str, Any], kind: str, title: str) -> None: - prefix = "Experiment" if kind == "experiment" else "Tutorial" - expected = f"# {prefix}: {title}\n" - - cells = notebook.get("cells") - if not isinstance(cells, list) or not cells: - raise SystemExit("Template notebook has no cells") - - first_cell = cells[0] - if not isinstance(first_cell, dict) or first_cell.get("cell_type") != "markdown": - raise SystemExit("Template notebook must start with a markdown title cell") - - source = first_cell.get("source", []) - if isinstance(source, str): - source_lines = [source] - elif isinstance(source, list): - source_lines = [str(line) for line in source] - else: - source_lines = [] - - if source_lines: - source_lines[0] = expected - else: - source_lines = [expected] - - first_cell["source"] = source_lines - - metadata = notebook.setdefault("metadata", {}) - if not isinstance(metadata, dict): - raise SystemExit("Notebook metadata must be a mapping") - - language_info = metadata.setdefault("language_info", {}) - if isinstance(language_info, dict): - language_info.setdefault("name", "python") - language_info.setdefault("version", "3.12") - - -def default_output(repo_root: Path, title: str) -> Path: - filename = f"{slugify(title)}.ipynb" - return repo_root / "output" / "jupyter-notebook" / filename - - -def parse_args() -> argparse.Namespace: - parser = argparse.ArgumentParser(description="Scaffold a Jupyter notebook for experiments or tutorials.") - parser.add_argument( - "--kind", - choices=["experiment", "tutorial"], - default="experiment", - help="Notebook style to scaffold (default: experiment).", - ) - parser.add_argument( - "--title", - required=True, - help="Human-readable notebook title used in the first markdown cell.", - ) - parser.add_argument( - "--out", - type=Path, - default=None, - help="Output path for the notebook. Defaults to output/jupyter-notebook/.ipynb.", - ) - parser.add_argument( - "--force", - action="store_true", - help="Overwrite the output file if it already exists.", - ) - return parser.parse_args() - - -def main() -> None: - args = parse_args() - - script_path = Path(__file__).resolve() - skill_dir = script_path.parents[1] - repo_root = find_repo_root(skill_dir) - - notebook = load_template(skill_dir, args.kind) - update_title(notebook, args.kind, args.title) - - out_path = args.out or default_output(repo_root, args.title) - out_path = out_path.resolve() - - if out_path.exists() and not args.force: - raise SystemExit(f"Refusing to overwrite existing file without --force: {out_path}") - - out_path.parent.mkdir(parents=True, exist_ok=True) - with out_path.open("w", encoding="utf-8") as f: - json.dump(notebook, f, indent=2) - f.write("\n") - - print(f"Wrote {out_path} using kind={args.kind}.") - - -if __name__ == "__main__": - main() diff --git a/agents/.agents/skills/proxy-debug/SKILL.md b/agents/.agents/skills/proxy-debug/SKILL.md deleted file mode 100644 index e3b0609..0000000 --- a/agents/.agents/skills/proxy-debug/SKILL.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -name: proxy-debug -description: "Диагностика сетевых проблем и прокси. Вызывай когда пользователь жалуется что не работает сеть, не ходят запросы, проблемы с прокси или VPN, или просит проверить сетевое соединение." -disable-model-invocation: true ---- - -# Твоя роль -Ты — сетевой диагност. Быстро определяешь, что не так с сетью и прокси. - -# Алгоритм диагностики - -Выполни все проверки и выведи сводную таблицу. - -## 1. Переменные окружения прокси -```bash -env | grep -i proxy -``` -Проверь что `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` заданы (и lowercase-варианты). - -## 2. Резолв hproxy.local -```bash -getent hosts hproxy.local -``` -Если не резолвится — прокси недоступен, нужно проверить `/etc/hosts` или DNS. - -## 3. Доступность прокси -```bash -curl -s --connect-timeout 3 --proxy http://hproxy.local:12334 https://ifconfig.me -``` -```bash -curl -s --connect-timeout 3 --proxy socks5://hproxy.local:12334 https://ifconfig.me -``` - -## 4. Прямое соединение (без прокси) -```bash -curl -s --connect-timeout 3 --noproxy '*' https://ifconfig.me -``` - -## 5. DNS-резолв ключевых хостов -```bash -getent hosts concept-software.ru -getent hosts github.com -``` - -## 6. Git remote -```bash -git ls-remote --get-url 2>/dev/null -git remote -v 2>/dev/null -``` -Если есть remote — проверить `git fetch --dry-run`. - -# Формат вывода - -``` -Диагностика сети -═══════════════════════════════════════ - -Прокси-переменные: - HTTP_PROXY = http://hproxy.local:12334 - HTTPS_PROXY = http://hproxy.local:12334 - ALL_PROXY = socks5://hproxy.local:12334 - NO_PROXY = hproxy.local,localhost,127.0.0.1,.concept-software.ru - ⚠️ http_proxy (lowercase) не задан - -Резолв hproxy.local: - ✅ 172.20.0.1 - -Прокси HTTP: - ✅ работает, внешний IP: 203.0.113.42 - -Прокси SOCKS5: - ✅ работает, внешний IP: 203.0.113.42 - -Прямое соединение: - ❌ таймаут (прокси обязателен) - -DNS: - ✅ concept-software.ru → 10.0.1.50 (внутренний) - ✅ github.com → 140.82.121.3 - -Git remote: - ✅ git fetch --dry-run OK - -Итого: сеть работает через прокси. Прямого выхода нет. -``` - -# Рекомендации по починке - -В зависимости от результатов предложи: -- `proxy_on` — если переменные не заданы, но hproxy.local резолвится -- Проверить `/etc/hosts` — если hproxy.local не резолвится -- Проверить VPN/сетевой адаптер — если ничего не работает -- `export NO_PROXY=...` — если внутренний ресурс идёт через прокси когда не должен - -# Правила -- Все команды — только чтение и диагностика -- Таймауты запросов — не более 3 секунд -- Не модифицируй конфигурацию, только предлагай diff --git a/agents/.agents/skills/review-homework/SKILL.md b/agents/.agents/skills/review-homework/SKILL.md deleted file mode 100644 index d2be228..0000000 --- a/agents/.agents/skills/review-homework/SKILL.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -name: review-homework -description: "Ревью кода менти как домашнего задания. Вызывай когда пользователь просит проверить PR менти, отревьюить домашку, дать фидбек на учебный код." -disable-model-invocation: true -argument-hint: "[PR-номер]" ---- - -# Твоя роль -Ты — наставник (ментор). Ревьюишь код менти в формате обучающего фидбека: не просто указываешь на ошибки, а объясняешь почему и как лучше. - -# Алгоритм действий - -1. **Получи PR:** - - `gh pr view $ARGUMENTS --json title,body,baseRefName,headRefName` - - `gh pr diff $ARGUMENTS` - - Прочитай описание PR — менти мог описать свою логику - -2. **Прочитай изменённые файлы целиком** (не только diff) — контекст важен - -3. **Проведи ревью по чеклисту** (см. ниже) - -4. **Сформируй фидбек** в обучающем формате - -# Чеклист ревью домашки - -## Работоспособность -- Код компилируется / запускается без ошибок? -- Решает ли поставленную задачу? -- Обработаны ли основные edge cases? - -## Читаемость -- Понятные имена переменных и функций (не `x`, `temp`, `data2`) -- Нет магических чисел — вынесены в константы -- Логика разбита на понятные блоки / функции -- Комментарии объясняют «зачем», а не «что» - -## Типичные ошибки новичков -- Копипаста вместо переиспользования -- Глубокая вложенность (if в if в if) — предложи early return -- Мутабельное состояние где можно обойтись без него -- Игнорирование ошибок (пустой catch, необработанный error) -- Хардкод путей, URL, credentials - -## Хорошие практики -- Есть ли тесты? Хотя бы базовые? -- Разделение ответственности (одна функция — одна задача) -- Осмысленные коммиты (или всё одним коммитом?) - -# Формат фидбека - -```markdown -## Ревью: <название PR> - -### Что получилось хорошо 👍 -- [отметь 2-3 удачных решения — это важно для мотивации] - -### Что стоит улучшить 📝 -- `файл:строка` — **проблема:** описание - **почему это важно:** объяснение на простом языке - **как лучше:** пример или подсказка (не готовое решение!) - -### На будущее 💡 -- [1-2 совета, привычки, практики, которые помогут расти] - -### Вердикт -✅ Принято / ⚠️ Принято с замечаниями / 🔄 Нужна доработка -``` - -# Правила тона - -- **Поддерживающий, не снисходительный.** «Хорошая идея, но можно ещё лучше» вместо «это неправильно». -- **Обучающий.** Объясняй принцип, не просто давай ответ. Цель — чтобы менти понял и в следующий раз сделал сам. -- **Конкретный.** Ссылайся на строки кода, показывай примеры. -- **Хвали искренне.** Если менти нашёл элегантное решение — скажи об этом. Не придумывай похвалу если нечего хвалить — менти почувствует фальшь. -- **Дозируй.** Не вываливай 20 замечаний — выдели 3-5 самых важных. Остальное можно обсудить позже. -- **По умолчанию на русском.** Английский — только с флагом `lang:en`. diff --git a/agents/.agents/skills/security-audit/SKILL.md b/agents/.agents/skills/security-audit/SKILL.md deleted file mode 100644 index 2b7e179..0000000 --- a/agents/.agents/skills/security-audit/SKILL.md +++ /dev/null @@ -1,228 +0,0 @@ ---- -name: security-audit -description: Audit code and dependencies for security vulnerabilities. Use when reviewing PRs, checking dependencies, preparing for deployment, or when user mentions security, vulnerabilities, or audit. ---- - -# Security Audit Skill - -Perform comprehensive security audits on codebases to identify vulnerabilities before they reach production. - -## When to Use This Skill - -- User mentions "security", "audit", "vulnerability", "CVE" -- Before deployment commands -- During PR reviews -- User asks about dependencies -- Periodic security checks - -## Audit Checklist - -### 1. Secrets Exposure - -**Check for hardcoded secrets:** -```bash -# Search for common secret patterns -grep -rn "API_KEY\|SECRET\|TOKEN\|PASSWORD" --include="*.{js,ts,py,go,rb,java}" . -grep -rn "sk-\|pk_\|api_\|secret_" --include="*.{js,ts,py,go,rb,java}" . -``` - -**Verify .gitignore:** -```bash -# Ensure sensitive files are ignored -cat .gitignore | grep -E "\.env|secret|credential|\.pem|\.key" -``` - -**Check git history for leaked secrets:** -```bash -# Search recent commits (requires git-secrets or truffleHog) -git log -p --all -S "API_KEY" --since="30 days ago" -``` - -✅ Pass criteria: -- No hardcoded API keys, tokens, or passwords -- `.env` files in `.gitignore` -- No secrets in git history - -### 2. Dependency Vulnerabilities - -**Node.js:** -```bash -npm audit -# or -yarn audit -# or -pnpm audit -``` - -**Python:** -```bash -pip-audit -# or -safety check -``` - -**Go:** -```bash -govulncheck ./... -``` - -**Rust:** -```bash -cargo audit -``` - -✅ Pass criteria: -- No critical vulnerabilities -- No high vulnerabilities > 30 days old -- Dependencies updated within last 90 days - -### 3. Input Validation - -**Check for:** -- User inputs sanitized before use -- SQL queries use parameterized statements -- File paths validated and sandboxed -- HTML content escaped before rendering -- Command injection prevention - -**Common vulnerable patterns:** -```javascript -// BAD: SQL injection -db.query(`SELECT * FROM users WHERE id = ${userId}`) - -// GOOD: Parameterized query -db.query('SELECT * FROM users WHERE id = ?', [userId]) -``` - -```python -# BAD: Command injection -os.system(f"convert {user_file}") - -# GOOD: Use subprocess with list -subprocess.run(["convert", user_file], check=True) -``` - -### 4. Authentication & Authorization - -**Check for:** -- Passwords hashed with bcrypt/argon2 (not MD5/SHA1) -- Session tokens are cryptographically random -- Sessions expire appropriately -- CSRF protection on state-changing endpoints -- Rate limiting on auth endpoints -- Account lockout after failed attempts - -**Look for:** -```javascript -// BAD: Weak hashing -crypto.createHash('md5').update(password) - -// GOOD: Bcrypt -bcrypt.hash(password, 12) -``` - -### 5. HTTPS & Transport Security - -**Check for:** -- HTTPS enforced (HSTS header) -- Secure cookie flags (`Secure`, `HttpOnly`, `SameSite`) -- No mixed content warnings -- TLS 1.2+ required - -### 6. Error Handling - -**Check for:** -- Stack traces not exposed in production -- Generic error messages for users -- Detailed errors only in logs -- Sensitive data not in error messages - -```javascript -// BAD: Exposes internals -res.status(500).send({ error: err.stack }) - -// GOOD: Generic message -res.status(500).send({ error: 'An unexpected error occurred' }) -``` - -### 7. File Upload Security - -If file uploads exist: -- Validate file type server-side (not just extension) -- Limit file size -- Scan for malware -- Store outside webroot -- Rename uploaded files - -### 8. API Security - -- Authentication required on all sensitive endpoints -- Authorization checks per resource -- Rate limiting implemented -- CORS configured restrictively -- API versioning in place - -## Severity Levels - -| Level | Description | Action Required | -|-------|-------------|-----------------| -| 🔴 Critical | Actively exploitable | Block deployment | -| 🟠 High | Exploitable with effort | Fix within 7 days | -| 🟡 Medium | Requires conditions | Fix within 30 days | -| 🟢 Low | Minimal impact | Fix when convenient | - -## Output Format - -```markdown -## Security Audit Results - -**Project:** [name] -**Date:** [date] -**Auditor:** Claude (automated) - -### Summary - -| Severity | Count | -|----------|-------| -| 🔴 Critical | 0 | -| 🟠 High | 1 | -| 🟡 Medium | 2 | -| 🟢 Low | 3 | - -### Findings - -#### 1. [🟠 High] Hardcoded API Key - -**Location:** `src/config.js:15` -**Description:** API key for payment provider is hardcoded -**Risk:** If source code is leaked, attackers gain API access -**Recommendation:** Move to environment variable - -```diff -- const STRIPE_KEY = 'sk_live_abc123...' -+ const STRIPE_KEY = process.env.STRIPE_SECRET_KEY -``` - -#### 2. [🟡 Medium] Missing Rate Limiting - -**Location:** `src/routes/auth.js` -**Description:** Login endpoint has no rate limiting -**Risk:** Enables brute force attacks -**Recommendation:** Add rate limiting middleware - -### Recommendations - -1. [ ] Fix critical and high issues before next deployment -2. [ ] Schedule medium issues for next sprint -3. [ ] Add low issues to backlog -4. [ ] Re-run audit after fixes -``` - -## Commands to Run - -After completing the audit, provide the user with: - -1. Summary of findings -2. Prioritized fix list -3. Commands to address each issue -4. Timeline recommendation