Skip to main content

clikit

Стандартная библиотека построения CLI поверх 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, 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.7.tar.gz (130.4 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.7-py3-none-any.whl (48.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: s_clikit-0.1.7.tar.gz
  • Upload date:
  • Size: 130.4 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.7.tar.gz
Algorithm Hash digest
SHA256 9314669bbfaab91dc909de5ebd323e3dd6733c0aacc5347b106af2af30e87b6d
MD5 ae12def342719c951f610e4c700fcabe
BLAKE2b-256 46eae92b3fec158891188c4b48012e942b723ed70715d13baf947a0747b51813

See more details on using hashes here.

File details

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

File metadata

  • Download URL: s_clikit-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 48.3 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.7-py3-none-any.whl
Algorithm Hash digest
SHA256 209486c20fd3f10f32dd84e3da018d792b2e754f30f011ad144161ce9e93488d
MD5 947969739fd5b7321294f1a45dd886d3
BLAKE2b-256 1b584cfed388aaaee9f6722bf7f9ddfcf59085e762b3c670e666983955f57235

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.9

2 files

0.1.8

2 files

This release

0.1.7 This release

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