#!/usr/bin/env python3 """Конфигурация дома агента (agent-home-kit): один файл kit.json вместо литералов в коде. Корень дома ищется так: 1. переменная окружения HOME_KIT_ROOT; 2. каталог над bin/, где лежит этот файл (дом развёрнут install.sh). В корне обязан лежать kit.json (образец — kit.example.json). python3 bin/kit.py show напечатать действующую конфигурацию python3 bin/kit.py check проверить, что каталоги дома на месте """ from __future__ import annotations import json import os import sys from pathlib import Path DEFAULTS = { "agent_name": "Agent", # имя агента в текстах кадра "agent_slug": "agent", # латиница: owner во frontmatter, метки "coord_project": "", # проект окна-координатора (ступень dispatch только ему) "canon_prefix": "home:", # как агент ссылается на свои файлы в текстах (у Дистилла — dcc:) "unit_prefix": "agent-", # префикс systemd-юнитов, если дом их заводит "host_id": "local", # имя этой машины в таблице узлов "nodes": {"local": {"ssh": "", "max_runs": 1}}, # пул узлов для витков dispatch.py "runner": "", # команда запуска витка по ТЗ: {tz} {label} {home}; пусто — dispatch launch печатает команду "lint_cmd": "", # линтер ступени: команда, читающая stdin, rc=0 — чисто; пусто — без линтера "density_cmd": "", # прибор плотности кадра, тот же контракт; пусто — без него } def root() -> Path: env = os.environ.get("HOME_KIT_ROOT") return Path(env).resolve() if env else Path(__file__).resolve().parent.parent def load() -> dict: r = root() f = r / "kit.json" cfg = dict(DEFAULTS) if f.exists(): cfg.update(json.loads(f.read_text(encoding="utf-8"))) cfg["root"] = str(r) return cfg CFG = load() HOME = Path(CFG["root"]) AGENT = CFG["agent_name"] BIN = HOME / "bin" def cli(rel: str) -> str: """Строка вызова инструмента дома для подсказок в кадре: python3 <корень>/bin/.""" return f"python3 {BIN / rel}" if __name__ == "__main__": a = sys.argv[1:] or ["show"] if a[0] == "show": print(json.dumps(CFG, ensure_ascii=False, indent=2)) elif a[0] == "check": need = ["kit.json", "wake/ladder.json", "state", "tasks/dispatch", "journal/letters"] miss = [p for p in need if not (HOME / p).exists()] print("дом в порядке: " + str(HOME) if not miss else "нет: " + ", ".join(miss)) sys.exit(1 if miss else 0) else: print(__doc__)