Skip to main content

clikit

Стандартная библиотека построения CLI поверх s-librarykit. Новый CLI собирается за ~10 строк: единый root-app с --json/--text/--profile/--version, 4-слойный конфиг с валидацией, JSON-first вывод для агентов и скриптов, структурированные команды. Сетевой слой — транспорт, retry, секреты, пути — это зона КОРНЯ librarykit; clikit на нём построен и тянет его как зависимость, но больше НЕ фасадит (строгие зоны). Единая иерархия ошибок (errors) — общий контракт между слоями.

librarykit   ← КОРЕНЬ: errors · retry · transport · sessions · paths · config_util
   ▲
clikit       ← ЭТОТ КИТ: command_kit · config · output · scaffold + errors.
                        transport/retry/session/paths — бери из librarykit напрямую.

Установка

uv add s-clikit

Имя дистрибутива — s-clikit, имя для импорта — clikit. librarykit подтянется автоматически как зависимость.

Быстрый старт

CLI за 10 строк — build_root_app даёт root с флагами --json/--text/--profile/--version:

from clikit import build_root_app, command, AppConfig, emit_data
from librarykit.transport import RestHttpClient  # транспорт — зона librarykit

app = build_root_app(brand="acme", help="ACME CLI")

@app.command()
@command
def items():
    cfg = AppConfig.load("acme")
    client = RestHttpClient(cfg.base_url, access_token=...)
    emit_data(..., text_renderer=...)

Запуск: acme items отдаёт машинный JSON; acme items --text — человеко-читаемый вывод. Скаффолд нового проекта: clikit new <name> (см. clikit.scaffold).

clikit-проект = Skillery-навык

scaffold_cli(name, ...) (дефолт skill=True) генерит навык-ready структуру: помимо CLI-пакета — корневой SKILL.md (frontmatter name/description/version/ kind="cli"/triggers/tags) и машинный _skill_meta.toml (точка входа [[cli]]

  • runtime_dependencies на pip). Такой репо сразу публикуется в Skillery hub (POST /skills/from-git), а у потребителя skillkit авто-ставит CLI-шим и поднимает зависимости; версии — git-теги vX.Y.Z (push тега → hub-вебхук → авто-sync).

Полный стандарт и чек-лист публикации — docs/SKILL_PROJECT.md.

JSON по умолчанию

Дефолтный режим вывода — json (для AI-агентов и скриптинга): без флагов команда печатает машинный JSON Lines в stdout. Человек переключается в текст:

  • флагом --text / --plain;
  • env {BRAND}_OUTPUT=text;
  • в config.tomloutput_format = "text".

--json форсит json (перебивает --text, если переданы оба).

Слои конфига: global + project + local

AppConfig.load(brand) собирает значения по слоям (низ→верх приоритета), per-key мерж (верхний слой переопределяет только заданные ключи, не заменяет объект целиком):

defaults(модель) < global(config_dir/config.toml)
    < project(.<brand>.toml | .<brand>/config.toml — найден ВВЕРХ от cwd до .git)
    < local(*.local.toml рядом с project, gitignored)
    < ENV({BRAND}_<FIELD>) < init-kwargs
  • project-discovery: подъём от cwd до маркера .git; ищется .<brand>.toml в корне ИЛИ .<brand>/config.toml — «конфиг рядом с проектом».
  • local-оверрайд: .<brand>.local.toml — приватные правки поверх командного конфига (в .gitignore).
  • Профили (--profile / {BRAND}_PROFILEprofiles/<p>/) — на уровне global. Активный профиль разрешает clikit.config.active_profile(brand): сперва контекст исполнения (ExecutionContext), затем env. Корневой callback env не пишет — профиль едет объектом (см. «Контекст исполнения»).

AppConfig построен на pydantic-settings (типизация + fail-fast валидация). Пути по ОС (librarykit.config_util.AppPaths) — на platformdirs (%APPDATA% / ~/Library / ~/.config), ENV-override {BRAND}_HOME.

env-интерполяция секретов

Строковые значения резолвятся из окружения при load (секрет не лежит в git):

api_token = "${ACME_TOKEN}"                        # из env ACME_TOKEN
base_url  = "${ACME_HOST:-http://localhost:8000}"  # с дефолтом

Поддержаны ${VAR} и ${VAR:-default}. Подстановка команд $(...) не поддержана (поверхность атаки). Заряжать env можно load_dotenv_file или keyring (librarykit.secret_store.SecretStore).

MCP-секция

AppConfig.mcp: dict[str, McpServer] — единая форма манифеста MCP-сервера (transport/command/args/env/url/headers/enabled):

[mcp.skills-hub]
transport = "stdio"
command = "skills-hub-mcp"
args = ["--stdio"]
env = { TOKEN = "${SH_TOKEN}" }

$schema для редактора

AppConfig.json_schema() отдаёт JSON Schema модели. Команда для CLI — make_schema_command(MyConfig):

from clikit import make_schema_command, AppConfig
app.command(name="schema")(make_schema_command(MyConfig))   # `acme schema` печатает схему

Контекст исполнения (ExecutionContext)

Контекст запуска — ЯВНЫЙ объект в ContextVar, а не процессное окружение. Корневой callback собирает его один раз (единственное место чтения env) и ставит на всё исполнение команды:

from clikit import build_root_app, current_context

app = build_root_app("acme", redact_output=True)   # + флаг --unsafe-show-secrets

@app.command()
def whoami():
    ctx = current_context()          # profile / tenant / home_dir / proxy /
    ...                              # output_mode / reveal_secrets / trace_id

Зачем: os.environ — процессный носитель, поэтому два тенанта в одном процессе делили профиль, {BRAND}_HOME и прокси, а запись env из-под await уводила сессию чужого аккаунта. ContextVar скоупится по asyncio-task и треду.

  • Env читается ТОЛЬКО в build_context(brand, ...) ({BRAND}_PROFILE, {BRAND}_TENANT, {BRAND}_HOME, {BRAND}_PROXY/ALL_PROXY, {BRAND}_UNSAFE_SHOW_SECRETS, {BRAND}_TRACE_ID); явный аргумент старше env.
  • Свой контекст (сервер, тесты, пул воркеров) — use_context(ctx) / set_context / reset_context.
  • Маскировка секретов — свойство контекста: redact_output=True включает редакцию для ВСЕХ команд (emit_data/emit_table зовут redact сами), а --unsafe-show-secrets её снимает. Monkey-patch emit_data и процессный global _REVEAL у потребителей больше не нужны.
  • Профиль потребители читают через clikit.config.active_profile(brand) (контекст → env). Тем, кто ещё берёт его из os.environ напрямую, доступен временный опт-ин build_root_app(..., legacy_profile_env=True).

Публичный API

Зона clikit (clikit.__all__): CliError, AuthRequired, SessionExpired, RateLimited, NotImplementedYet, ValidationError, init_output_mode, is_json, console, emit_data, emit_message, emit_error, redact, AppConfig, McpServer, AdapterConfig, validate_adapters_installed, AdapterProbe, set_adapter_probe, get_adapter_probe, load_dotenv_file, interpolate_env, discover_project_config, active_profile, ExecutionContext, build_context, current_context, has_context, set_context, reset_context, use_context, context_for, build_root_app, command, async_command, gated, make_schema_command, scaffold_cli.

Депрекейт (строгие зоны): HttpClient / ApiError / RefreshCallback, RetryPolicy / DEFAULT_RETRY, SecretStore, AppPaths / atomic_write_text / chmod_600 / slugify ещё доступны из clikit (back-compat), но кидают DeprecationWarning. Бери их канон напрямую из librarykit.transport / librarykit.retry / librarykit.secret_store / librarykit.config_util.

Разработка

uv sync --extra dev
uv run --extra dev pytest -q
uv run --extra dev ruff check clikit

Лицензия

MIT © 2026 Dmitry.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

s_clikit-0.1.8.tar.gz (133.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

s_clikit-0.1.8-py3-none-any.whl (49.7 kB view details)

Uploaded Python 3

File details

Details for the file s_clikit-0.1.8.tar.gz.

File metadata

  • Download URL: s_clikit-0.1.8.tar.gz
  • Upload date:
  • Size: 133.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for s_clikit-0.1.8.tar.gz
Algorithm Hash digest
SHA256 cfaac0b5bd94dd422c3eaf3e6185d42787957a0b416e1c3e11b330ab0947d909
MD5 e8c5f499044341d53eff2546ddf44d72
BLAKE2b-256 224df2a72b9bec6038f499681b0122c9c9210db63948f096b98cfe396ef55139

See more details on using hashes here.

File details

Details for the file s_clikit-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: s_clikit-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 49.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for s_clikit-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 7ff193838e5393bd0f736b77cfeee38d1d7859d056f294bcbecc1620b5aaf6fb
MD5 100edd9884516658efa5ce38d6ecd0e9
BLAKE2b-256 d140a65deadb6a9ac9ecbfd218d33b22512625f3777388ae6bd7797f5917ad0c

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.9

2 files

This release

0.1.8 This release

2 files

0.1.7

2 files

0.1.6

2 files

0.1.5

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page