s-agentskit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- s_agentskit-0.1.0/.gitignore +47 -0
- s_agentskit-0.1.0/.gitlab-ci.yml +31 -0
- s_agentskit-0.1.0/AGENTS.md +45 -0
- s_agentskit-0.1.0/LICENSE +21 -0
- s_agentskit-0.1.0/PKG-INFO +92 -0
- s_agentskit-0.1.0/README.md +78 -0
- s_agentskit-0.1.0/agentskit/__init__.py +65 -0
- s_agentskit-0.1.0/agentskit/cli.py +139 -0
- s_agentskit-0.1.0/agentskit/data/agents.json +149 -0
- s_agentskit-0.1.0/agentskit/detect.py +55 -0
- s_agentskit-0.1.0/agentskit/inject.py +84 -0
- s_agentskit-0.1.0/agentskit/markers.py +23 -0
- s_agentskit-0.1.0/agentskit/onboard.py +104 -0
- s_agentskit-0.1.0/agentskit/spec.py +151 -0
- s_agentskit-0.1.0/agentskit/targets.py +94 -0
- s_agentskit-0.1.0/pyproject.toml +59 -0
- s_agentskit-0.1.0/tests/test_inject.py +96 -0
- s_agentskit-0.1.0/tests/test_onboard_cli.py +97 -0
- s_agentskit-0.1.0/tests/test_spec_targets_detect.py +109 -0
- s_agentskit-0.1.0/uv.lock +778 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# === atlas universal gitignore ===
|
|
2
|
+
|
|
3
|
+
# OS / IDE
|
|
4
|
+
.DS_Store
|
|
5
|
+
Thumbs.db
|
|
6
|
+
.vscode/
|
|
7
|
+
.idea/
|
|
8
|
+
*.swp
|
|
9
|
+
*.swo
|
|
10
|
+
|
|
11
|
+
# Sensitive
|
|
12
|
+
.env
|
|
13
|
+
.env.local
|
|
14
|
+
*.key
|
|
15
|
+
*.pem
|
|
16
|
+
secrets/
|
|
17
|
+
private/
|
|
18
|
+
|
|
19
|
+
# Python
|
|
20
|
+
__pycache__/
|
|
21
|
+
*.py[cod]
|
|
22
|
+
.venv/
|
|
23
|
+
venv/
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.ruff_cache/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
|
|
28
|
+
# Node / JS
|
|
29
|
+
node_modules/
|
|
30
|
+
.next/
|
|
31
|
+
dist/
|
|
32
|
+
build/
|
|
33
|
+
|
|
34
|
+
# Temporary / large
|
|
35
|
+
*.log
|
|
36
|
+
*.tmp
|
|
37
|
+
nul
|
|
38
|
+
NUL
|
|
39
|
+
*.zip
|
|
40
|
+
*.rar
|
|
41
|
+
*.7z
|
|
42
|
+
|
|
43
|
+
# Media (selectively unignore via !path/*.ext if needed for fixtures)
|
|
44
|
+
*.mp4
|
|
45
|
+
*.mov
|
|
46
|
+
*.avi
|
|
47
|
+
*.mkv
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Автопубликация на PyPI по семвер-тегу vX.Y.Z через Trusted Publishing (OIDC).
|
|
2
|
+
# Токены НИГДЕ не хранятся: GitLab выдаёт короткоживущий OIDC-токен (PYPI_ID_TOKEN),
|
|
3
|
+
# он одноразово обменивается на PyPI API-токен. Издатель настраивается на pypi.org:
|
|
4
|
+
# Manage -> Publishing -> GitLab (namespace=S-kits, project=agentskit,
|
|
5
|
+
# top-level pipeline file=.gitlab-ci.yml, environment — пусто).
|
|
6
|
+
# Запускается ТОЛЬКО на тег vX.Y.Z (обычный push на main ничего не публикует).
|
|
7
|
+
stages: [publish]
|
|
8
|
+
|
|
9
|
+
publish-pypi:
|
|
10
|
+
stage: publish
|
|
11
|
+
image: ghcr.io/astral-sh/uv:python3.12-bookworm
|
|
12
|
+
rules:
|
|
13
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
|
|
14
|
+
id_tokens:
|
|
15
|
+
PYPI_ID_TOKEN:
|
|
16
|
+
aud: pypi
|
|
17
|
+
script:
|
|
18
|
+
- uv build
|
|
19
|
+
# обмен GitLab OIDC -> одноразовый PyPI API-токен (Trusted Publishing):
|
|
20
|
+
- |
|
|
21
|
+
export UV_PUBLISH_TOKEN=$(python3 - <<'PY'
|
|
22
|
+
import json, os, urllib.request
|
|
23
|
+
req = urllib.request.Request(
|
|
24
|
+
"https://pypi.org/_/oidc/mint-token",
|
|
25
|
+
data=json.dumps({"token": os.environ["PYPI_ID_TOKEN"]}).encode(),
|
|
26
|
+
headers={"Content-Type": "application/json"},
|
|
27
|
+
)
|
|
28
|
+
print(json.load(urllib.request.urlopen(req))["token"])
|
|
29
|
+
PY
|
|
30
|
+
)
|
|
31
|
+
- uv publish
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# AGENTS.md — agentskit
|
|
2
|
+
|
|
3
|
+
> Контекст для AI-ассистентов (Claude Code, ChatGPT, Cursor и т.п.), работающих
|
|
4
|
+
> над этим проектом.
|
|
5
|
+
|
|
6
|
+
## Что это
|
|
7
|
+
|
|
8
|
+
(заполнить one-line)
|
|
9
|
+
|
|
10
|
+
## Atlas
|
|
11
|
+
|
|
12
|
+
Проект зарегистрирован в Atlas-БД (Atlas). Карточка:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
atlas projects get agentskit
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Любые изменения метаданных (приоритет, статус, теги) — через atlas CLI:
|
|
19
|
+
|
|
20
|
+
- `atlas projects update agentskit --priority P0` — поменять приоритет
|
|
21
|
+
- `atlas add-tags agentskit -t domain:<slug>` — добавить тег
|
|
22
|
+
- `atlas projects move agentskit --to-type <type>` — конвертировать тип
|
|
23
|
+
|
|
24
|
+
## Тип / Статус (на момент создания)
|
|
25
|
+
|
|
26
|
+
- type=`shared-infrastructure`, status=`experiment`, priority=`P2`
|
|
27
|
+
|
|
28
|
+
## Правила работы
|
|
29
|
+
|
|
30
|
+
- Все исходные тексты, документы, код проекта — в этом репо.
|
|
31
|
+
- Чувствительные данные (`.env`, токены, ключи) — игнорируются `.gitignore`.
|
|
32
|
+
- AI-ассистенту разрешено: читать, генерировать, редактировать в этом репо.
|
|
33
|
+
|
|
34
|
+
## Канонические команды
|
|
35
|
+
|
|
36
|
+
- `atlas projects get agentskit` — карточка проекта
|
|
37
|
+
- `atlas task list --project agentskit` — задачи проекта (когда W7
|
|
38
|
+
волна будет реализована)
|
|
39
|
+
|
|
40
|
+
<!-- atlas:usage:start -->
|
|
41
|
+
## Управление проектом — через Atlas
|
|
42
|
+
|
|
43
|
+
Этот проект ведётся в Atlas (личная PM-система портфеля). Для задач/проектов/эпиков/бэкапов
|
|
44
|
+
используй CLI `atlas` и вызывай навык `atlas` — вся логика и роутинг внутри навыка.
|
|
45
|
+
<!-- atlas:usage:end -->
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dmitry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: s-agentskit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-агенты как сущности: автономный онбординг инструкций (идемпотентные managed-блоки в .claude/.cursor/.codex/.gemini/.github/…) поверх единого реестра агентов-данных. Тонкий слой на clikit.
|
|
5
|
+
Author: Dmitry
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Requires-Dist: s-clikit
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: pytest>=8.3; extra == 'dev'
|
|
12
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# agentskit
|
|
16
|
+
|
|
17
|
+
**AI-агенты как сущности: автономный онбординг инструкций.** Переиспользуемый
|
|
18
|
+
слой (dist `s-agentskit` / import `agentskit`) поверх `clikit`. Делает любой
|
|
19
|
+
навык/инструмент **автономным онбордером**: он сам прописывает свои инструкции
|
|
20
|
+
(managed-блок) в конфиг-файлы любого AI-агента — `.claude` / `.cursor` / `.codex`
|
|
21
|
+
/ `.gemini` / `.github` / … — идемпотентно и аддитивно (чужой текст не затирается).
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
agentskit (реестр агентов = данные) → onboard(namespace, body) → managed-блок в N агентов
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Зачем
|
|
28
|
+
|
|
29
|
+
Знание «где живёт каждый AI-агент» (его config-папка и memory-файл) не должно
|
|
30
|
+
дублироваться в каждом инструменте. agentskit держит **единый реестр агентов как
|
|
31
|
+
ДАННЫЕ** (`data/agents.json`, 18 агентов) — потребитель приносит только контент
|
|
32
|
+
(тело инструкции + свой namespace), а механизм (детект, инъекция, резолв
|
|
33
|
+
global/project) общий.
|
|
34
|
+
|
|
35
|
+
> Роль «агент-как-адаптер» (драйв агента из комбайна gateway/bublictr) — зона
|
|
36
|
+
> **adapterkit**, не этого кита. agentskit отвечает только за онбординг.
|
|
37
|
+
|
|
38
|
+
## Установка
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install s-agentskit # import agentskit (dist-имя ≠ import-имя)
|
|
42
|
+
# dev: uv sync --extra dev
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Библиотека (основной способ)
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from agentskit import onboard, resolve_agent_keys
|
|
49
|
+
|
|
50
|
+
onboard(
|
|
51
|
+
namespace="atlas", # маркеры <!-- ATLAS:BEGIN/END -->
|
|
52
|
+
body="## Работай в Atlas\n- atlas task …",
|
|
53
|
+
scope="all", # global | repo | all
|
|
54
|
+
agents=resolve_agent_keys("claude,gemini"), # или None — все существующие файлы
|
|
55
|
+
create=True,
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Идемпотентно: повторный вызов с тем же `body` → `unchanged`. Несколько плагинов
|
|
60
|
+
(разные `namespace`) сосуществуют в одном `CLAUDE.md` без коллизий.
|
|
61
|
+
|
|
62
|
+
## CLI
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
agentskit agents # весь реестр агентов
|
|
66
|
+
agentskit detect # какие агенты есть в проекте/$HOME
|
|
67
|
+
agentskit onboard -n mytool --body-file INSTRUCTIONS.md --agents claude,cursor --create
|
|
68
|
+
agentskit uninstall -n mytool --agents all
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Публичный API
|
|
72
|
+
|
|
73
|
+
`onboard` / `uninstall` · `detect_agents` / `list_agents` · `resolve_agent_keys`
|
|
74
|
+
· `resolve_targets` · `inject_managed_block` / `has_managed_block` /
|
|
75
|
+
`strip_managed_block` / `managed_block` · `begin_marker` / `end_marker` ·
|
|
76
|
+
`AgentSpec` / `SkillLayout` / `register_agent_spec` / `agent_registry`.
|
|
77
|
+
|
|
78
|
+
## Расширение реестра
|
|
79
|
+
|
|
80
|
+
Добавить агента без правки кита: запись в `data/agents.json`, либо
|
|
81
|
+
`register_agent_spec(AgentSpec(...))`, либо entry-points группа
|
|
82
|
+
`agentskit.agent_specs` во внешнем пакете.
|
|
83
|
+
|
|
84
|
+
## Режимы
|
|
85
|
+
|
|
86
|
+
- **reference** (MVP): managed-блок-указатель в memory-файл агента (`CLAUDE.md` и т.п.).
|
|
87
|
+
- **full** (фаза 2): материализация контента целиком в per-agent layout (как
|
|
88
|
+
`uipro`-инсталлеры).
|
|
89
|
+
|
|
90
|
+
## Лицензия
|
|
91
|
+
|
|
92
|
+
[MIT](LICENSE).
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# agentskit
|
|
2
|
+
|
|
3
|
+
**AI-агенты как сущности: автономный онбординг инструкций.** Переиспользуемый
|
|
4
|
+
слой (dist `s-agentskit` / import `agentskit`) поверх `clikit`. Делает любой
|
|
5
|
+
навык/инструмент **автономным онбордером**: он сам прописывает свои инструкции
|
|
6
|
+
(managed-блок) в конфиг-файлы любого AI-агента — `.claude` / `.cursor` / `.codex`
|
|
7
|
+
/ `.gemini` / `.github` / … — идемпотентно и аддитивно (чужой текст не затирается).
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
agentskit (реестр агентов = данные) → onboard(namespace, body) → managed-блок в N агентов
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Зачем
|
|
14
|
+
|
|
15
|
+
Знание «где живёт каждый AI-агент» (его config-папка и memory-файл) не должно
|
|
16
|
+
дублироваться в каждом инструменте. agentskit держит **единый реестр агентов как
|
|
17
|
+
ДАННЫЕ** (`data/agents.json`, 18 агентов) — потребитель приносит только контент
|
|
18
|
+
(тело инструкции + свой namespace), а механизм (детект, инъекция, резолв
|
|
19
|
+
global/project) общий.
|
|
20
|
+
|
|
21
|
+
> Роль «агент-как-адаптер» (драйв агента из комбайна gateway/bublictr) — зона
|
|
22
|
+
> **adapterkit**, не этого кита. agentskit отвечает только за онбординг.
|
|
23
|
+
|
|
24
|
+
## Установка
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pip install s-agentskit # import agentskit (dist-имя ≠ import-имя)
|
|
28
|
+
# dev: uv sync --extra dev
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Библиотека (основной способ)
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from agentskit import onboard, resolve_agent_keys
|
|
35
|
+
|
|
36
|
+
onboard(
|
|
37
|
+
namespace="atlas", # маркеры <!-- ATLAS:BEGIN/END -->
|
|
38
|
+
body="## Работай в Atlas\n- atlas task …",
|
|
39
|
+
scope="all", # global | repo | all
|
|
40
|
+
agents=resolve_agent_keys("claude,gemini"), # или None — все существующие файлы
|
|
41
|
+
create=True,
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Идемпотентно: повторный вызов с тем же `body` → `unchanged`. Несколько плагинов
|
|
46
|
+
(разные `namespace`) сосуществуют в одном `CLAUDE.md` без коллизий.
|
|
47
|
+
|
|
48
|
+
## CLI
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
agentskit agents # весь реестр агентов
|
|
52
|
+
agentskit detect # какие агенты есть в проекте/$HOME
|
|
53
|
+
agentskit onboard -n mytool --body-file INSTRUCTIONS.md --agents claude,cursor --create
|
|
54
|
+
agentskit uninstall -n mytool --agents all
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Публичный API
|
|
58
|
+
|
|
59
|
+
`onboard` / `uninstall` · `detect_agents` / `list_agents` · `resolve_agent_keys`
|
|
60
|
+
· `resolve_targets` · `inject_managed_block` / `has_managed_block` /
|
|
61
|
+
`strip_managed_block` / `managed_block` · `begin_marker` / `end_marker` ·
|
|
62
|
+
`AgentSpec` / `SkillLayout` / `register_agent_spec` / `agent_registry`.
|
|
63
|
+
|
|
64
|
+
## Расширение реестра
|
|
65
|
+
|
|
66
|
+
Добавить агента без правки кита: запись в `data/agents.json`, либо
|
|
67
|
+
`register_agent_spec(AgentSpec(...))`, либо entry-points группа
|
|
68
|
+
`agentskit.agent_specs` во внешнем пакете.
|
|
69
|
+
|
|
70
|
+
## Режимы
|
|
71
|
+
|
|
72
|
+
- **reference** (MVP): managed-блок-указатель в memory-файл агента (`CLAUDE.md` и т.п.).
|
|
73
|
+
- **full** (фаза 2): материализация контента целиком в per-agent layout (как
|
|
74
|
+
`uipro`-инсталлеры).
|
|
75
|
+
|
|
76
|
+
## Лицензия
|
|
77
|
+
|
|
78
|
+
[MIT](LICENSE).
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""agentskit — AI-агенты как сущности: автономный онбординг инструкций.
|
|
2
|
+
|
|
3
|
+
Переиспользуемый слой поверх ``librarykit``. Делает любой навык/инструмент
|
|
4
|
+
**автономным онбордером**: сам прописывает свои инструкции (managed-блок) в
|
|
5
|
+
конфиг-файлы любого AI-агента (``.claude``/``.cursor``/``.codex``/``.gemini``/
|
|
6
|
+
``.github``/…) идемпотентно и аддитивно — чужой текст не затирается.
|
|
7
|
+
|
|
8
|
+
Механизм generic: реестр агент→файл как ДАННЫЕ (``data/agents.json``), детект по
|
|
9
|
+
ФС, инъекция managed-блока между параметризуемыми маркерами, резолв global/project.
|
|
10
|
+
Контент (тело инструкции + namespace) приносит потребитель — это НЕ код кита.
|
|
11
|
+
|
|
12
|
+
Роль «агент-как-адаптер» (драйв агента из комбайна) — зона ``adapterkit``, не
|
|
13
|
+
этого кита (agentskit отвечает только за онбординг-данные и инъекцию).
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
__version__ = "0.1.0"
|
|
18
|
+
|
|
19
|
+
from .detect import DetectedAgent, detect_agents
|
|
20
|
+
from .inject import (
|
|
21
|
+
has_managed_block,
|
|
22
|
+
inject_managed_block,
|
|
23
|
+
managed_block,
|
|
24
|
+
strip_managed_block,
|
|
25
|
+
)
|
|
26
|
+
from .markers import begin_marker, end_marker
|
|
27
|
+
from .onboard import ApplyResult, onboard, uninstall
|
|
28
|
+
from .spec import (
|
|
29
|
+
AgentSpec,
|
|
30
|
+
SkillLayout,
|
|
31
|
+
agent_registry,
|
|
32
|
+
get_agent_spec,
|
|
33
|
+
list_agents,
|
|
34
|
+
register_agent_spec,
|
|
35
|
+
resolve_agent_keys,
|
|
36
|
+
)
|
|
37
|
+
from .targets import Target, global_path_for, resolve_targets
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
"__version__",
|
|
41
|
+
# инъекция / маркеры
|
|
42
|
+
"begin_marker",
|
|
43
|
+
"end_marker",
|
|
44
|
+
"managed_block",
|
|
45
|
+
"has_managed_block",
|
|
46
|
+
"inject_managed_block",
|
|
47
|
+
"strip_managed_block",
|
|
48
|
+
# реестр агентов (данные)
|
|
49
|
+
"AgentSpec",
|
|
50
|
+
"SkillLayout",
|
|
51
|
+
"agent_registry",
|
|
52
|
+
"get_agent_spec",
|
|
53
|
+
"list_agents",
|
|
54
|
+
"register_agent_spec",
|
|
55
|
+
"resolve_agent_keys",
|
|
56
|
+
# детект / резолв целей / онбординг
|
|
57
|
+
"DetectedAgent",
|
|
58
|
+
"detect_agents",
|
|
59
|
+
"Target",
|
|
60
|
+
"global_path_for",
|
|
61
|
+
"resolve_targets",
|
|
62
|
+
"ApplyResult",
|
|
63
|
+
"onboard",
|
|
64
|
+
"uninstall",
|
|
65
|
+
]
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"""CLI кита: ``agentskit detect / agents / onboard / uninstall`` (на clikit).
|
|
2
|
+
|
|
3
|
+
Кит — прежде всего библиотека (потребитель зовёт ``agentskit.onboard(...)``), но
|
|
4
|
+
даёт тонкий автономный CLI для самостоятельного использования и для раздачи как
|
|
5
|
+
tooling-навык. json-by-default (clikit); ``--text`` — человекочитаемо.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import typer
|
|
13
|
+
from clikit import CliError, build_root_app, command, emit_data
|
|
14
|
+
|
|
15
|
+
from . import __version__
|
|
16
|
+
from .detect import detect_agents
|
|
17
|
+
from .onboard import onboard as _onboard
|
|
18
|
+
from .onboard import uninstall as _uninstall
|
|
19
|
+
from .spec import list_agents, resolve_agent_keys
|
|
20
|
+
|
|
21
|
+
app = build_root_app(
|
|
22
|
+
"agentskit",
|
|
23
|
+
version=__version__,
|
|
24
|
+
help="AI-агенты как сущности: онбординг инструкций в агентские файлы (--json по умолчанию).",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _keys(agents: str) -> list[str] | None:
|
|
29
|
+
if not agents.strip():
|
|
30
|
+
return None
|
|
31
|
+
try:
|
|
32
|
+
return resolve_agent_keys(agents)
|
|
33
|
+
except ValueError as exc:
|
|
34
|
+
raise CliError("bad_agents", str(exc)) from exc
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@app.command("agents")
|
|
38
|
+
@command
|
|
39
|
+
def agents_cmd() -> None:
|
|
40
|
+
"""Весь канонический реестр агентов (ключ/label/config_dir/файлы)."""
|
|
41
|
+
data = [
|
|
42
|
+
{
|
|
43
|
+
"key": s.key,
|
|
44
|
+
"label": s.label,
|
|
45
|
+
"config_dir": s.config_dir,
|
|
46
|
+
"repo_file": s.repo_file,
|
|
47
|
+
"global": list(s.global_subpath) if s.global_subpath else None,
|
|
48
|
+
"aliases": list(s.aliases),
|
|
49
|
+
}
|
|
50
|
+
for s in list_agents()
|
|
51
|
+
]
|
|
52
|
+
emit_data(data, text_renderer=lambda rows: [
|
|
53
|
+
print(f"{r['key']:<12} {r['config_dir']:<10} "
|
|
54
|
+
f"{r['repo_file'] or '—':<28} {r['label']}") for r in rows
|
|
55
|
+
])
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@app.command("detect")
|
|
59
|
+
@command
|
|
60
|
+
def detect_cmd(
|
|
61
|
+
glob: bool = typer.Option(False, "--global", help="Считать и $HOME-агентов."),
|
|
62
|
+
include_absent: bool = typer.Option(False, "--all", help="Показать и ненайденных."),
|
|
63
|
+
) -> None:
|
|
64
|
+
"""Какие AI-агенты присутствуют (config-папка в cwd и/или $HOME)."""
|
|
65
|
+
found = detect_agents(include_absent=include_absent)
|
|
66
|
+
data = [{"key": d.key, "label": d.label, "present": d.present, "scope": d.scope}
|
|
67
|
+
for d in found]
|
|
68
|
+
emit_data(data, text_renderer=lambda rows: (
|
|
69
|
+
[print(f"{r['key']:<12} {r['scope']:<8} {r['label']}") for r in rows]
|
|
70
|
+
or [print("агентов не найдено — трактуй как 'all'")] if not rows else None
|
|
71
|
+
))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@app.command("onboard")
|
|
75
|
+
@command
|
|
76
|
+
def onboard_cmd(
|
|
77
|
+
namespace: str = typer.Option(..., "--namespace", "-n", help="namespace плагина"),
|
|
78
|
+
body_file: str | None = typer.Option(None, "--body-file", help="Файл с телом (markdown)."),
|
|
79
|
+
body: str | None = typer.Option(None, "--body", help="Тело инструкции строкой ('-' — stdin)."),
|
|
80
|
+
scope: str = typer.Option("all", "--scope", help="global | repo | all."),
|
|
81
|
+
agents: str = typer.Option("", "--agents", help="CSV ключей/алиасов или 'all'."),
|
|
82
|
+
create: bool = typer.Option(False, "--create", help="Создать файлы выбранных агентов."),
|
|
83
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Показать, что изменится, без записи."),
|
|
84
|
+
) -> None:
|
|
85
|
+
"""Прописать managed-блок плагина в выбранных AI-агентов (reference-режим)."""
|
|
86
|
+
if scope not in ("global", "repo", "all"):
|
|
87
|
+
raise CliError("bad_scope", f"--scope: global|repo|all, не '{scope}'.")
|
|
88
|
+
text = _read_body(body, body_file)
|
|
89
|
+
results = _onboard(
|
|
90
|
+
namespace=namespace, body=text, scope=scope, agents=_keys(agents),
|
|
91
|
+
create=create, dry_run=dry_run,
|
|
92
|
+
)
|
|
93
|
+
emit_data(
|
|
94
|
+
[{"path": r.path, "action": r.action, "agent": r.agent_key, "reason": r.reason}
|
|
95
|
+
for r in results],
|
|
96
|
+
text_renderer=lambda rows: [
|
|
97
|
+
print(f" {r['action']:<12} {r['agent']:<10} {r['path']}"
|
|
98
|
+
+ (f" ({r['reason']})" if r['reason'] else "")) for r in rows
|
|
99
|
+
] or [print("целей нет")],
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@app.command("uninstall")
|
|
104
|
+
@command
|
|
105
|
+
def uninstall_cmd(
|
|
106
|
+
namespace: str = typer.Option(..., "--namespace", "-n", help="namespace плагина."),
|
|
107
|
+
scope: str = typer.Option("all", "--scope", help="global | repo | all."),
|
|
108
|
+
agents: str = typer.Option("", "--agents", help="CSV ключей/алиасов или 'all'."),
|
|
109
|
+
dry_run: bool = typer.Option(False, "--dry-run", help="Показать без записи."),
|
|
110
|
+
) -> None:
|
|
111
|
+
"""Снять managed-блок плагина (чужие блоки не трогаются)."""
|
|
112
|
+
results = _uninstall(
|
|
113
|
+
namespace=namespace, scope=scope, agents=_keys(agents), dry_run=dry_run,
|
|
114
|
+
)
|
|
115
|
+
emit_data(
|
|
116
|
+
[{"path": r.path, "action": r.action, "agent": r.agent_key, "reason": r.reason}
|
|
117
|
+
for r in results],
|
|
118
|
+
text_renderer=lambda rows: [
|
|
119
|
+
print(f" {r['action']:<12} {r['agent']:<10} {r['path']}") for r in rows
|
|
120
|
+
] or [print("целей нет")],
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _read_body(body: str | None, body_file: str | None) -> str:
|
|
125
|
+
if body_file:
|
|
126
|
+
return Path(body_file).read_text(encoding="utf-8")
|
|
127
|
+
if body == "-":
|
|
128
|
+
return sys.stdin.read()
|
|
129
|
+
if body is not None:
|
|
130
|
+
return body
|
|
131
|
+
raise CliError("no_body", "Нужно --body '<текст>' / --body - (stdin) / --body-file <md>.")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def main() -> None:
|
|
135
|
+
app()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
if __name__ == "__main__":
|
|
139
|
+
main()
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_schema": "agentskit.agents/1 — реестр AI-агентов как ДАННЫЕ (не код). config_dir → детект; repo_file/global_subpath → reference-инъекция; skill_layout → full-материализация (фаза 2). Источник канона папок: ui-ux-pro-max AI_FOLDERS + global-память Atlas.",
|
|
3
|
+
"agents": {
|
|
4
|
+
"claude": {
|
|
5
|
+
"label": "Claude Code",
|
|
6
|
+
"config_dir": ".claude",
|
|
7
|
+
"repo_file": "CLAUDE.md",
|
|
8
|
+
"global_subpath": [".claude", "CLAUDE.md"],
|
|
9
|
+
"aliases": ["claude-code", "claudecode"],
|
|
10
|
+
"skill_layout": {"subdir": ["skills", "{skill}"], "filename": "SKILL.md", "install_type": "full", "frontmatter": true}
|
|
11
|
+
},
|
|
12
|
+
"codex": {
|
|
13
|
+
"label": "Codex / AGENTS.md",
|
|
14
|
+
"config_dir": ".codex",
|
|
15
|
+
"repo_file": "AGENTS.md",
|
|
16
|
+
"global_subpath": [".codex", "AGENTS.md"],
|
|
17
|
+
"aliases": ["agents", "agents.md"],
|
|
18
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
19
|
+
},
|
|
20
|
+
"gemini": {
|
|
21
|
+
"label": "Gemini CLI",
|
|
22
|
+
"config_dir": ".gemini",
|
|
23
|
+
"repo_file": "GEMINI.md",
|
|
24
|
+
"global_subpath": [".gemini", "GEMINI.md"],
|
|
25
|
+
"aliases": ["gemini-cli"],
|
|
26
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
27
|
+
},
|
|
28
|
+
"cursor": {
|
|
29
|
+
"label": "Cursor",
|
|
30
|
+
"config_dir": ".cursor",
|
|
31
|
+
"repo_file": ".cursorrules",
|
|
32
|
+
"global_subpath": null,
|
|
33
|
+
"aliases": [],
|
|
34
|
+
"skill_layout": {"subdir": [".shared"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
35
|
+
},
|
|
36
|
+
"copilot": {
|
|
37
|
+
"label": "GitHub Copilot",
|
|
38
|
+
"config_dir": ".github",
|
|
39
|
+
"repo_file": ".github/copilot-instructions.md",
|
|
40
|
+
"global_subpath": null,
|
|
41
|
+
"aliases": ["copilot-instructions"],
|
|
42
|
+
"skill_layout": {"subdir": ["prompts"], "filename": "{skill}.prompt.md", "install_type": "full", "frontmatter": true}
|
|
43
|
+
},
|
|
44
|
+
"windsurf": {
|
|
45
|
+
"label": "Windsurf",
|
|
46
|
+
"config_dir": ".windsurf",
|
|
47
|
+
"repo_file": ".windsurfrules",
|
|
48
|
+
"global_subpath": null,
|
|
49
|
+
"aliases": [],
|
|
50
|
+
"skill_layout": {"subdir": ["rules"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
51
|
+
},
|
|
52
|
+
"antigravity": {
|
|
53
|
+
"label": "Antigravity",
|
|
54
|
+
"config_dir": ".agents",
|
|
55
|
+
"repo_file": "AGENTS.md",
|
|
56
|
+
"global_subpath": null,
|
|
57
|
+
"aliases": ["agent"],
|
|
58
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
59
|
+
},
|
|
60
|
+
"kiro": {
|
|
61
|
+
"label": "Kiro",
|
|
62
|
+
"config_dir": ".kiro",
|
|
63
|
+
"repo_file": null,
|
|
64
|
+
"global_subpath": null,
|
|
65
|
+
"aliases": [],
|
|
66
|
+
"skill_layout": {"subdir": ["steering"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
67
|
+
},
|
|
68
|
+
"roocode": {
|
|
69
|
+
"label": "Roo Code",
|
|
70
|
+
"config_dir": ".roo",
|
|
71
|
+
"repo_file": null,
|
|
72
|
+
"global_subpath": null,
|
|
73
|
+
"aliases": ["roo"],
|
|
74
|
+
"skill_layout": {"subdir": ["rules"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
75
|
+
},
|
|
76
|
+
"qoder": {
|
|
77
|
+
"label": "Qoder",
|
|
78
|
+
"config_dir": ".qoder",
|
|
79
|
+
"repo_file": null,
|
|
80
|
+
"global_subpath": null,
|
|
81
|
+
"aliases": [],
|
|
82
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
83
|
+
},
|
|
84
|
+
"trae": {
|
|
85
|
+
"label": "Trae",
|
|
86
|
+
"config_dir": ".trae",
|
|
87
|
+
"repo_file": null,
|
|
88
|
+
"global_subpath": null,
|
|
89
|
+
"aliases": [],
|
|
90
|
+
"skill_layout": {"subdir": ["rules"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
91
|
+
},
|
|
92
|
+
"opencode": {
|
|
93
|
+
"label": "OpenCode",
|
|
94
|
+
"config_dir": ".opencode",
|
|
95
|
+
"repo_file": null,
|
|
96
|
+
"global_subpath": null,
|
|
97
|
+
"aliases": [],
|
|
98
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
99
|
+
},
|
|
100
|
+
"continue": {
|
|
101
|
+
"label": "Continue",
|
|
102
|
+
"config_dir": ".continue",
|
|
103
|
+
"repo_file": null,
|
|
104
|
+
"global_subpath": null,
|
|
105
|
+
"aliases": [],
|
|
106
|
+
"skill_layout": {"subdir": ["rules"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
107
|
+
},
|
|
108
|
+
"codebuddy": {
|
|
109
|
+
"label": "CodeBuddy",
|
|
110
|
+
"config_dir": ".codebuddy",
|
|
111
|
+
"repo_file": null,
|
|
112
|
+
"global_subpath": null,
|
|
113
|
+
"aliases": [],
|
|
114
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
115
|
+
},
|
|
116
|
+
"droid": {
|
|
117
|
+
"label": "Factory Droid",
|
|
118
|
+
"config_dir": ".factory",
|
|
119
|
+
"repo_file": null,
|
|
120
|
+
"global_subpath": null,
|
|
121
|
+
"aliases": ["factory"],
|
|
122
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
123
|
+
},
|
|
124
|
+
"kilocode": {
|
|
125
|
+
"label": "Kilo Code",
|
|
126
|
+
"config_dir": ".kilocode",
|
|
127
|
+
"repo_file": null,
|
|
128
|
+
"global_subpath": null,
|
|
129
|
+
"aliases": ["kilo"],
|
|
130
|
+
"skill_layout": {"subdir": ["rules"], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
131
|
+
},
|
|
132
|
+
"warp": {
|
|
133
|
+
"label": "Warp",
|
|
134
|
+
"config_dir": ".warp",
|
|
135
|
+
"repo_file": null,
|
|
136
|
+
"global_subpath": null,
|
|
137
|
+
"aliases": [],
|
|
138
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
139
|
+
},
|
|
140
|
+
"augment": {
|
|
141
|
+
"label": "Augment",
|
|
142
|
+
"config_dir": ".augment",
|
|
143
|
+
"repo_file": null,
|
|
144
|
+
"global_subpath": null,
|
|
145
|
+
"aliases": [],
|
|
146
|
+
"skill_layout": {"subdir": [], "filename": "{skill}.md", "install_type": "full", "frontmatter": false}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|