@dev-sergeev/datalab-kit 0.1.5 → 0.1.7

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +30 -8
  3. package/THIRD_PARTY_NOTICES.md +4 -1
  4. package/dist/extension.js +4 -2
  5. package/dist/install.d.ts +2 -2
  6. package/dist/install.js +14 -12
  7. package/dist/skills.d.ts +2 -0
  8. package/dist/skills.js +54 -0
  9. package/docs/adr/0002-package-delivery.md +5 -5
  10. package/package.json +40 -13
  11. package/skills/init/SKILL.md +31 -0
  12. package/skills/skill-creator/LICENSE.txt +202 -0
  13. package/skills/skill-creator/SKILL.md +610 -0
  14. package/skills/skill-creator/agents/analyzer.md +291 -0
  15. package/skills/skill-creator/agents/comparator.md +213 -0
  16. package/skills/skill-creator/agents/grader.md +234 -0
  17. package/skills/skill-creator/assets/eval_review.html +146 -0
  18. package/skills/skill-creator/eval-viewer/generate_review.py +453 -0
  19. package/skills/skill-creator/eval-viewer/viewer.html +1329 -0
  20. package/skills/skill-creator/references/schemas.md +521 -0
  21. package/skills/skill-creator/scripts/__init__.py +0 -0
  22. package/skills/skill-creator/scripts/aggregate_benchmark.py +415 -0
  23. package/skills/skill-creator/scripts/generate_report.py +329 -0
  24. package/skills/skill-creator/scripts/improve_description.py +225 -0
  25. package/skills/skill-creator/scripts/package_skill.py +136 -0
  26. package/skills/skill-creator/scripts/pi_runtime.py +177 -0
  27. package/skills/skill-creator/scripts/quick_validate.py +107 -0
  28. package/skills/skill-creator/scripts/run_eval.py +215 -0
  29. package/skills/skill-creator/scripts/run_loop.py +334 -0
  30. package/skills/skill-creator/scripts/utils.py +41 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.7 — 2026-10-20
4
+
5
+ - Совместимость с Pi закреплена строго на `0.85.1`: peer-зависимости `pi-ai`, `pi-coding-agent` и `pi-tui` больше не допускают произвольные версии.
6
+ - `@dev-sergeev/pi-gigachat` закреплён на `0.6.4` в манифесте, lockfile и отдельном источнике Pi. Установщик больше не запрашивает `latest`; штатное обновление Pi сохраняет закреплённую версию.
7
+ - Прежняя незакреплённая запись GigaChat мигрирует на `npm:@dev-sergeev/pi-gigachat@0.6.4` с сохранением фильтров ресурсов. Явно выбранные пользователем версии и остальные настройки сохраняются.
8
+
9
+ ## 0.1.6 — 2026-10-15
10
+
11
+ - В пакет включены навыки `init` и `skill-creator`, доступные во всех проектах после глобальной установки набора. Добавлены короткие команды `/init` и `/skill-creator`; явное отключение ресурсов Pi сохраняет приоритет.
12
+ - `/init` изучает проект и создаёт или актуализирует `AGENTS.md`, сохраняя существующие инструкции.
13
+ - `skill-creator` перенесён из Anthropic (`dbd4588f9e1033efb41dad4bef2f7947c8993d44`, Apache-2.0) и полностью адаптирован под Pi: создание и обновление навыков, сравнение с baseline, benchmark/viewer, обратная связь и оптимизация описания. Claude Code не требуется; Python-утилитам нужны Python 3.10+ и PyYAML.
14
+ - Новые навыки по умолчанию размещаются глобально в каталоге агента Pi; явно заданный путь важнее. Рабочие результаты не записываются в каталог установленного пакета.
15
+ - Адаптация учитывает `disable-model-invocation`, отчёты без holdout, вложенные каталоги запусков и фактическое число повторений. Viewer выбирает другой порт, если заданный занят, не завершая чужие процессы. Ошибки модели и таймауты не считаются успешными отрицательными результатами оценки.
16
+ - Добавлены проверки Python-ресурсов в CI Linux/macOS и регрессии для совместимости метаданных, отчётов и viewer. Уточнена проверка локального npm-архива для Pi 0.85.1.
17
+ - Проверка полного времени запроса `elapsed` переведена на управляемые часы вместо реальных задержек, чтобы исключить гонку первого тика на CI; код компонента не менялся.
18
+ - Короткие команды используют штатный pipeline ввода Pi: CLI дожидается выполнения и возвращает ошибку авторизации корректным exit status. Одноимённые пользовательские команды и prompt templates сохраняют приоритет.
19
+
3
20
  ## 0.1.5
4
21
 
5
22
  - GigaChat загружается через штатную точку входа расширения с интерактивным мастером `/gigachat`; пользовательские подключения и настройки сохраняются. Lockfile обновлён до `pi-gigachat` 0.6.1 без изменения upstream-кода; зависимость остаётся `latest`. Прежние утверждения для 0.5.1 о встроенных моделях и автоматическом default больше не применяются.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## Установка
6
6
 
7
- Нужны Node.js ≥ 22.19 и установленный Pi. Совместимость проверяется с Pi 0.85.1.
7
+ Нужны Node.js ≥ 22.19 и установленный Pi **строго 0.85.1**. Peer-зависимости `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent` и `@earendil-works/pi-tui` закреплены на `0.85.1`, без диапазонов версий, как в `pi-gigachat` 0.6.4. Это декларация совместимости npm, а не runtime-проверка: управляемый установщик Pi использует `--legacy-peer-deps`.
8
8
 
9
9
  ```bash
10
10
  pi install npm:@dev-sergeev/datalab-kit
@@ -17,16 +17,19 @@ pi
17
17
  npm ci --ignore-scripts --legacy-peer-deps
18
18
  npm run build
19
19
  npm pack
20
- pi install ./dev-sergeev-datalab-kit-0.1.4.tgz
20
+ npm install --prefix /tmp/datalab-kit-local --legacy-peer-deps ./dev-sergeev-datalab-kit-0.1.7.tgz
21
+ pi install /tmp/datalab-kit-local/node_modules/@dev-sergeev/datalab-kit
21
22
  ```
22
23
 
24
+ Локальный архив сначала устанавливается через npm; Pi подключает полученный каталог пакета. В Pi 0.85.1 прямой путь к `.tgz` воспринимается как путь расширения, а не npm-архив.
25
+
23
26
  Целевые системы — Linux и macOS; локальные интеграционные проверки выполнены на Linux. Проверка macOS включена в CI. Windows пока не заявляется.
24
27
 
25
28
  ## Состав
26
29
 
27
30
  | Пакет | Версия |
28
31
  | --- | --- |
29
- | `@dev-sergeev/pi-gigachat` | `latest` при установке / явном обновлении |
32
+ | `@dev-sergeev/pi-gigachat` | 0.6.4 |
30
33
  | `@juicesharp/rpiv-ask-user-question` | 2.11.0 |
31
34
  | `pi-powerline-footer` | 0.17.2 |
32
35
  | `@gotgenes/pi-permission-system` | 33.0.5 |
@@ -39,9 +42,9 @@ pi install ./dev-sergeev-datalab-kit-0.1.4.tgz
39
42
  | `pi-toggle-skills` | 0.1.20 |
40
43
  | `@zigai/pi-mention-skill` | 0.10.4 |
41
44
 
42
- Одиннадцать фиксированных компонентов включены в архив npm вместе с их зависимостями. GigaChat устанавливается отдельно без закрепления версии.
45
+ Одиннадцать фиксированных компонентов включены в архив npm вместе с их зависимостями. GigaChat устанавливается отдельно с закреплением версии `0.6.4`.
43
46
 
44
- Datalab Kit загружает штатное расширение GigaChat 0.6.1 без изменения его кода. `/gigachat` открывает интерактивный мастер подключений, авторизации и выбора моделей из каталогов серверов; это не интерфейс настройки через аргументы. Сохранённые подключения и пользовательские настройки остаются под управлением upstream. Основную модель выбирают через `/model`.
47
+ Datalab Kit загружает штатное расширение GigaChat 0.6.4 без изменения его кода. `/gigachat` открывает интерактивный мастер подключений, авторизации и выбора моделей из каталогов серверов; это не интерфейс настройки через аргументы. Сохранённые подключения и пользовательские настройки остаются под управлением upstream.
45
48
 
46
49
  ## DataLab из окружения
47
50
 
@@ -92,6 +95,20 @@ pi
92
95
 
93
96
  Введите `$` для выбора навыка через `pi-mention-skill`. Скрытый от модели навык остаётся доступен через явное `$имя-навыка`. По умолчанию `/skill:*` скрываются из slash autocomplete; настройки самого расширения сохраняют приоритет над штатными значениями.
94
97
 
98
+ ## Встроенные навыки
99
+
100
+ После глобальной установки Datalab Kit навыки `init` и `skill-creator` доступны в Pi из любого каталога, без установки набора в каждый проект. В уже открытой сессии выполните `/reload`. Навыки поставляются внутри npm-пакета; набор не копирует их в пользовательские каталоги навыков.
101
+
102
+ - **`/init [уточнения]`** изучает текущий проект и создаёт или актуализирует `AGENTS.md`: реальные команды, структуру и правила работы. Существующие инструкции и пользовательские требования сохраняются. Команда не устанавливает и не настраивает Datalab Kit.
103
+ - **`/skill-creator [задача]`** создаёт и обновляет навыки, помогает оценивать их относительно baseline, просматривать результаты и улучшать описание. Это адаптация [skill-creator Anthropic](https://github.com/anthropics/skills/tree/dbd4588f9e1033efb41dad4bef2f7947c8993d44/skills/skill-creator) под Pi: оценка и оптимизация запускают Pi с выбранной моделью, без Claude Code. Лицензия Apache-2.0 и сведения об адаптации включены в пакет.
104
+
105
+ Новые навыки по умолчанию сохраняются в `<agentDir>/skills/<имя>/` (`~/.pi/agent/skills/` при стандартной конфигурации, либо каталог из `PI_CODING_AGENT_DIR`). Явно указанный пользователем путь важнее. После создания нужен `/reload` или новая сессия.
106
+
107
+ Для Python-утилит `skill-creator` нужны **Python 3.10+ и PyYAML** в используемом Python-окружении. Для `/init` Python не требуется. Утилиты используют установленный `pi` из `PATH` либо исполняемый файл из `PI_EXECUTABLE_PATH`; для запросов нужны авторизация и доступ к выбранной модели Pi. Оценки и оптимизация выполняют дополнительные модельные запросы. Результаты и рабочие файлы сохраняются вне каталога установленного пакета.
108
+
109
+ Короткие команды доступны независимо от скрытия `/skill:*` в autocomplete; штатные `/skill:init` и `/skill:skill-creator` также сохраняются. Явное отключение навыков (`--no-skills` или фильтры ресурсов пакета) не обходится короткими командами. Скрытие от автоматического выбора модели не запрещает явный вызов.
110
+
111
+
95
112
  ## YOLO
96
113
 
97
114
  YOLO управляется штатным `@gotgenes/pi-permission-system`: откройте `/permission-system` → **YOLO mode** или задайте `"yoloMode": true` в конфигурации расширения. Собственные сессионные команды `/yolo on|off|status`, добавленные в 0.1.1, удалены в 0.1.2.
@@ -106,21 +123,26 @@ YOLO автоматически разрешает `ask`. Явные `deny` и
106
123
  pi update --extensions
107
124
  ```
108
125
 
109
- GigaChat обновляется независимо от версии набора. Обычный запуск Pi не обращается к реестру npm и не устанавливает обновления.
126
+ GigaChat закреплён на `0.6.4` в зависимостях набора и отдельном источнике Pi `npm:@dev-sergeev/pi-gigachat@0.6.4`. `pi update --extensions` не переводит его на более новую версию из `latest`; для смены версии нужен новый релиз набора либо явное пользовательское переопределение источника. Обычный запуск Pi не обращается к реестру npm и не устанавливает обновления.
110
127
 
111
- **Известное отклонение от спецификации:** Pi 0.85.1 перезаписывает список пакетов из своего кеша после `npm postinstall`. Поэтому отдельная запись GigaChat для штатного обновления восстанавливается при первом запуске Pi. Между установкой набора и первым запуском `pi update --extensions` не гарантирует обновление GigaChat при неизменной версии набора. Для полного выполнения этого требования нужна поддержка со стороны Pi; установленный Pi пакет не изменяет. Подробнее: [ADR](docs/adr/0002-package-delivery.md).
128
+ **Особенность Pi 0.85.1:** установщик перезаписывает список пакетов из своего кеша после `npm postinstall`. Поэтому при первом запуске Pi набор восстанавливает отдельную закреплённую запись GigaChat. Прежний незакреплённый источник `npm:@dev-sergeev/pi-gigachat` заменяется на `npm:@dev-sergeev/pi-gigachat@0.6.4` с сохранением фильтров ресурсов. Подробнее: [ADR](docs/adr/0002-package-delivery.md).
112
129
 
113
130
  Явно закреплённый пользователем источник GigaChat сохраняется. При удалении набора отдельная запись GigaChat остаётся; её можно удалить стандартным `pi remove npm:@dev-sergeev/pi-gigachat`. Установка с `-l` пока не проверена.
114
131
 
115
- GigaChat загружается через штатную точку входа как внутри набора, так и через отдельную запись пакета. Для 0.6.1 настройка подключений и моделей выполняется интерактивным `/gigachat`; прежние утверждения о встроенных GLM/Qwen и автоматическом default `gigachat/Qwen3.5-397b` относились к 0.5.1 и к этой версии неприменимы. Datalab Kit не переписывает исходники GigaChat, не очищает авторизацию или сохранённые подключения. Дополнительный провайдер DataLab не меняет текущую модель или defaults. Модель recap настраивается независимо.
132
+ GigaChat загружается через штатную точку входа как внутри набора, так и через отдельную запись пакета. Для 0.6.4 настройка подключений и моделей выполняется интерактивным `/gigachat`; прежние утверждения о встроенных GLM/Qwen и автоматическом default `gigachat/Qwen3.5-397b` относились к 0.5.1 и к этой версии неприменимы. Datalab Kit не переписывает исходники GigaChat, не очищает авторизацию или сохранённые подключения. Дополнительный провайдер DataLab не меняет текущую модель или defaults. Модель recap настраивается независимо.
116
133
 
117
134
  ## Разработка
118
135
 
119
136
  ```bash
137
+ python3 -m venv /tmp/datalab-kit-python
138
+ . /tmp/datalab-kit-python/bin/activate
139
+ python3 -m pip install PyYAML
120
140
  npm ci --ignore-scripts --legacy-peer-deps
121
141
  npm run build
122
142
  npm run typecheck
123
143
  npm test
144
+ python3 skills/skill-creator/scripts/quick_validate.py skills/init
145
+ python3 skills/skill-creator/scripts/quick_validate.py skills/skill-creator
124
146
  ```
125
147
 
126
148
  `build` применяет проверяемые адаптации к локальным permission-system, plan-mode, subagents и recap перед упаковкой. Для recap адаптируются наследование модели сессии, подпись пункта `Use default` и таймаут 60 секунд; исходный конфиг пользователя не переписывается. Номера версий и единственность каждого места изменения проверяются; несовпадение завершает сборку с ошибкой. Устаревшие выходные модули удаляются. Адаптации не меняют глобально установленные пакеты. Интеграционный тест использует изолированный каталог агента и локальный реестр npm, устанавливает настоящий архив штатной командой Pi и проверяет штатное обновление.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Datalab Kit includes the following upstream components. Their licenses and copyright notices remain in their package directories and apply to those components and their transitive dependencies. Datalab Kit modifies permission-system, plan-mode, subagents and recap's default model during build; see scripts/prepare-upstream.mjs. GigaChat is downloaded separately.
4
4
 
5
- - @dev-sergeev/pi-gigachat (latest, independently installed): MIT, git+https://github.com/dev-sergeev/pi-gigachat.git.
5
+ - @dev-sergeev/pi-gigachat@0.6.4 (independently installed, version pinned): MIT, git+https://github.com/dev-sergeev/pi-gigachat.git.
6
6
  - @juicesharp/rpiv-ask-user-question@2.11.0: MIT, git+https://github.com/juicesharp/rpiv-mono.git.
7
7
  - pi-powerline-footer@0.17.2: MIT, git+https://github.com/nicobailon/pi-powerline-footer.git.
8
8
  - @gotgenes/pi-permission-system@33.0.5: MIT, git+https://github.com/gotgenes/pi-packages.git.
@@ -14,6 +14,9 @@ Datalab Kit includes the following upstream components. Their licenses and copyr
14
14
  - @pi-plugins/elapsed@0.1.1: MIT, git+https://github.com/k3dom/pi-plugins.git.
15
15
  - pi-toggle-skills@0.1.20: MIT, git+https://github.com/monotykamary/pi-toggle-skills.git.
16
16
  - @zigai/pi-mention-skill@0.10.4: MIT, git+https://github.com/zigai/pi-tweaks.git.
17
+ - Anthropic skill-creator: Apache-2.0, https://github.com/anthropics/skills/tree/dbd4588f9e1033efb41dad4bef2f7947c8993d44/skills/skill-creator. Source revision: `dbd4588f9e1033efb41dad4bef2f7947c8993d44`; copyright 2026 Anthropic, PBC. License retained at `skills/skill-creator/LICENSE.txt`.
18
+
19
+ The skill-creator copy is adapted for Pi: instructions, destinations, isolated evaluation and description optimization through Pi's JSON CLI, honest missing-telemetry and repetition reporting, Pi frontmatter validation, and review metadata/server behavior. Modified files carry notices. Python resources, supporting agent instructions, schemas, viewer assets, and the complete Apache-2.0 license are included in the npm package; Claude Code is not required.
17
20
 
18
21
  For the adapted subagents component, the upstream MIT notice is reproduced below:
19
22
 
package/dist/extension.js CHANGED
@@ -3,9 +3,11 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
3
3
  import { resolve } from 'node:path';
4
4
  import { gigaChatExtensionPath, hasConfiguredGigaChat, managedAgentDir, registerGigaChat } from './install.js';
5
5
  import registerDataLab from './datalab-provider.js';
6
+ import registerSkills from './skills.js';
6
7
  export default async function datalabKit(pi) {
7
8
  const packageRoot = fileURLToPath(new URL('../', import.meta.url));
8
9
  const agentDir = getAgentDir();
10
+ registerSkills(pi);
9
11
  const configured = await hasConfiguredGigaChat(agentDir);
10
12
  await registerDataLab(pi, gigaChatExtensionPath(packageRoot));
11
13
  // On the first load, provide GigaChat immediately. Later Pi discovers the
@@ -14,10 +16,10 @@ export default async function datalabKit(pi) {
14
16
  const provider = await import(pathToFileURL(gigaChatExtensionPath(packageRoot)).href);
15
17
  await provider.default(pi);
16
18
  }
17
- if (!configured && managedAgentDir(packageRoot) === resolve(agentDir)) {
19
+ if (managedAgentDir(packageRoot) === resolve(agentDir)) {
18
20
  pi.on('session_start', async () => {
19
21
  // Pi 0.85.1 persists a cached package list after npm postinstall; repair
20
- // that list at first activation without downloading or updating anything.
22
+ // that list and migrate the kit's former floating source without networking.
21
23
  await registerGigaChat(agentDir);
22
24
  });
23
25
  }
package/dist/install.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export declare const gigaChatSource = "npm:@dev-sergeev/pi-gigachat";
1
+ export declare const gigaChatSource: string;
2
2
  export declare function managedAgentDir(packageRoot: string): string | undefined;
3
3
  export declare function isGigaChatSource(entry: unknown): boolean;
4
4
  export declare function hasConfiguredGigaChat(agentDir: string): Promise<boolean>;
5
- /** Preserve every user field and package filter; only add a missing source. */
5
+ /** Preserve user fields and filters; migrate the kit's former floating source. */
6
6
  export declare function registerGigaChat(agentDir: string): Promise<void>;
7
7
  /** Only run inside an explicit npm installation; Pi startup never calls this. */
8
8
  export declare function finishInstallation(packageRoot: string): Promise<void>;
package/dist/install.js CHANGED
@@ -5,7 +5,9 @@ import { createRequire } from 'node:module';
5
5
  import { promisify } from 'node:util';
6
6
  import { execFile } from 'node:child_process';
7
7
  import { randomUUID } from 'node:crypto';
8
- export const gigaChatSource = 'npm:@dev-sergeev/pi-gigachat';
8
+ const gigaChatPackageSource = 'npm:@dev-sergeev/pi-gigachat';
9
+ const gigaChatVersion = createRequire(import.meta.url)('../package.json').dependencies['@dev-sergeev/pi-gigachat'];
10
+ export const gigaChatSource = `${gigaChatPackageSource}@${gigaChatVersion}`;
9
11
  const execFileAsync = promisify(execFile);
10
12
  export function managedAgentDir(packageRoot) {
11
13
  const npmRoot = resolve(packageRoot, '../../..');
@@ -14,7 +16,7 @@ export function managedAgentDir(packageRoot) {
14
16
  }
15
17
  export function isGigaChatSource(entry) {
16
18
  const source = typeof entry === 'string' ? entry : entry && typeof entry === 'object' && 'source' in entry ? entry.source : undefined;
17
- return typeof source === 'string' && (source === gigaChatSource || source.startsWith(`${gigaChatSource}@`));
19
+ return typeof source === 'string' && (source === gigaChatPackageSource || source.startsWith(`${gigaChatPackageSource}@`));
18
20
  }
19
21
  async function readSettings(agentDir) {
20
22
  let content;
@@ -35,7 +37,7 @@ export async function hasConfiguredGigaChat(agentDir) {
35
37
  const settings = await readSettings(agentDir);
36
38
  return Array.isArray(settings.packages) && settings.packages.some(isGigaChatSource);
37
39
  }
38
- /** Preserve every user field and package filter; only add a missing source. */
40
+ /** Preserve user fields and filters; migrate the kit's former floating source. */
39
41
  export async function registerGigaChat(agentDir) {
40
42
  await mkdir(agentDir, { recursive: true });
41
43
  const lock = join(agentDir, 'settings.json.lock');
@@ -46,9 +48,13 @@ export async function registerGigaChat(agentDir) {
46
48
  if (settings.packages !== undefined && !Array.isArray(settings.packages))
47
49
  throw new Error('Pi packages must be an array');
48
50
  const packages = (settings.packages ?? []);
49
- if (packages.some(isGigaChatSource))
51
+ const existing = packages.find(isGigaChatSource);
52
+ const source = typeof existing === 'string' ? existing : existing && typeof existing === 'object' && 'source' in existing ? existing.source : undefined;
53
+ if (existing && source !== gigaChatPackageSource)
50
54
  return;
51
- settings.packages = [...packages, gigaChatSource];
55
+ settings.packages = existing
56
+ ? packages.map(entry => entry !== existing ? entry : typeof entry === 'string' ? gigaChatSource : { ...entry, source: gigaChatSource })
57
+ : [...packages, gigaChatSource];
52
58
  await writeFile(temp, `${JSON.stringify(settings, null, 2)}\n`, { mode: 0o600 });
53
59
  await rename(temp, join(agentDir, 'settings.json'));
54
60
  }
@@ -66,7 +72,7 @@ export async function finishInstallation(packageRoot) {
66
72
  const existing = Array.isArray(settings.packages) ? settings.packages.find(isGigaChatSource) : undefined;
67
73
  const source = typeof existing === 'string' ? existing : existing?.source;
68
74
  // An explicitly selected user version remains authoritative.
69
- if (typeof source === 'string' && source !== gigaChatSource)
75
+ if (typeof source === 'string' && source !== gigaChatPackageSource && source !== gigaChatSource)
70
76
  return;
71
77
  await refreshGigaChat(agentDir);
72
78
  await registerGigaChat(agentDir);
@@ -89,14 +95,10 @@ async function npm(args) {
89
95
  return result.stdout;
90
96
  }
91
97
  async function refreshGigaChat(agentDir) {
92
- const metadata = JSON.parse(await npm(['view', '@dev-sergeev/pi-gigachat@latest', 'version', '--json']));
93
- const latest = Array.isArray(metadata) ? metadata.at(-1) : metadata;
94
- if (typeof latest !== 'string' || !/^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(latest))
95
- throw new Error('Invalid GigaChat registry version');
96
98
  const destination = join(agentDir, 'npm/node_modules/@dev-sergeev/pi-gigachat');
97
99
  try {
98
100
  const installed = JSON.parse(await readFile(join(destination, 'package.json'), 'utf8'));
99
- if (installed.version === latest)
101
+ if (installed.version === gigaChatVersion)
100
102
  return;
101
103
  }
102
104
  catch (error) {
@@ -109,7 +111,7 @@ async function refreshGigaChat(agentDir) {
109
111
  const replacement = join(stage, 'replacement');
110
112
  let moved = false;
111
113
  try {
112
- await npm(['install', '--prefix', stage, `@dev-sergeev/pi-gigachat@${latest}`,
114
+ await npm(['install', '--prefix', stage, `@dev-sergeev/pi-gigachat@${gigaChatVersion}`,
113
115
  '--ignore-scripts', '--legacy-peer-deps', '--no-audit', '--no-fund']);
114
116
  await cp(join(stage, 'node_modules/@dev-sergeev/pi-gigachat'), replacement, { recursive: true });
115
117
  // Preserve the staged dependency tree so compiled ESM imports stay resolvable.
@@ -0,0 +1,2 @@
1
+ import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
2
+ export default function registerSkills(pi: ExtensionAPI): void;
package/dist/skills.js ADDED
@@ -0,0 +1,54 @@
1
+ import { CombinedAutocompleteProvider } from '@earendil-works/pi-tui';
2
+ const aliases = [
3
+ { name: 'init', skill: 'skill:init', description: 'Create or update this project’s AGENTS.md' },
4
+ { name: 'skill-creator', skill: 'skill:skill-creator', description: 'Create, evaluate, and improve a Pi skill' },
5
+ ];
6
+ const aliasPattern = /^\/(init|skill-creator)(?=\s|$)/;
7
+ const whitespacePattern = /\s/;
8
+ function isAvailable(alias, commands) {
9
+ return commands.some(command => command.source === 'skill' && command.name === alias.skill)
10
+ && !commands.some(command => command.name === alias.name);
11
+ }
12
+ export default function registerSkills(pi) {
13
+ // Transform the original prompt so Pi owns expansion, streaming and completion.
14
+ // Fire-and-forget sendUserMessage would let print mode dispose a running turn.
15
+ pi.on('input', (event, ctx) => {
16
+ const match = aliasPattern.exec(event.text);
17
+ if (!match)
18
+ return;
19
+ const alias = match[1] === 'init' ? aliases[0] : aliases[1];
20
+ const commands = pi.getCommands();
21
+ if (commands.some(command => command.name === alias.name))
22
+ return;
23
+ if (!commands.some(command => command.source === 'skill' && command.name === alias.skill)) {
24
+ ctx.ui.notify(`Skill "${alias.name}" is not enabled. Check your Pi skill and package settings.`, 'warning');
25
+ return { action: 'handled' };
26
+ }
27
+ const args = event.text.slice(match[0].length).trimStart();
28
+ return { action: 'transform', text: `/${alias.skill}${args ? ` ${args}` : ''}` };
29
+ });
30
+ pi.on('session_start', (_event, ctx) => {
31
+ if (ctx.mode !== 'tui')
32
+ return;
33
+ const commands = pi.getCommands();
34
+ const available = aliases.filter(alias => isAvailable(alias, commands));
35
+ if (available.length === 0)
36
+ return;
37
+ const completions = new CombinedAutocompleteProvider(available, ctx.cwd);
38
+ ctx.ui.addAutocompleteProvider(current => ({
39
+ triggerCharacters: current.triggerCharacters,
40
+ async getSuggestions(lines, cursorLine, cursorCol, options) {
41
+ const suggestions = await current.getSuggestions(lines, cursorLine, cursorCol, options);
42
+ const prefix = lines[cursorLine]?.slice(0, cursorCol) ?? '';
43
+ if (options.force || !prefix.startsWith('/') || whitespacePattern.test(prefix))
44
+ return suggestions;
45
+ const extra = await completions.getSuggestions(lines, cursorLine, cursorCol, options);
46
+ if (!extra)
47
+ return suggestions;
48
+ return { prefix: extra.prefix, items: [...(suggestions?.items ?? []), ...extra.items] };
49
+ },
50
+ applyCompletion: (lines, cursorLine, cursorCol, item, prefix) => current.applyCompletion(lines, cursorLine, cursorCol, item, prefix),
51
+ shouldTriggerFileCompletion: current.shouldTriggerFileCompletion?.bind(current),
52
+ }));
53
+ });
54
+ }
@@ -1,6 +1,6 @@
1
1
  # ADR 0002: Доставка компонентов и значений по умолчанию
2
2
 
3
- Status: accepted for implementation; known spec gap remains
3
+ Status: accepted
4
4
 
5
5
  ## Контекст
6
6
 
@@ -20,12 +20,12 @@ Pi 0.85.1 загружает ресурсы из `pi.extensions`, но не пр
20
20
 
21
21
  Дополнительное согласование от 2026-10-14: задержка автоматического recap после бездействия сокращена с 5 до 2 минут. Таймаут отдельного запроса остаётся 60 секунд.
22
22
 
23
- GigaChat остаётся зависимостью `latest`. При явной установке postinstall проверяет актуальную версию, устанавливает её в управляемый каталог Pi и добавляет незакреплённый источник. При первой активации расширение восстанавливает запись, которую установщик Pi мог затереть; загрузка не выполняет сетевых запросов. До появления отдельной записи провайдер подключается через расширение набора. После её появления его загружает Pi самостоятельно.
23
+ Пересмотр от 2026-10-20: начиная с Datalab Kit 0.1.7 поддерживается строго Pi 0.85.1; три peer-зависимости Pi закреплены на этой версии без диапазонов, как в `pi-gigachat` 0.6.4. Это декларация совместимости, а не runtime-проверка: управляемый установщик Pi отключает разрешение peer-зависимостей. GigaChat закреплён на `0.6.4` в манифесте, lockfile, postinstall и отдельном источнике `npm:@dev-sergeev/pi-gigachat@0.6.4`. Версия для установщика берётся из манифеста набора; запрос `latest` удалён. Прежний незакреплённый источник мигрирует на закреплённый с сохранением фильтров ресурсов; явно выбранные пользователем версии остаются приоритетными. При первой активации расширение восстанавливает запись, которую установщик Pi мог затереть; загрузка не выполняет сетевых запросов. До появления отдельной записи провайдер подключается через расширение набора, после её появления его загружает Pi самостоятельно. Этот пересмотр заменяет прежнее требование независимо обновлять GigaChat до `latest`.
24
24
 
25
25
  ## Последствия и пределы
26
26
 
27
- - После первой активации работает штатное `pi update --extensions`, даже если версия набора не изменилась.
28
- - Обновление до первой активации не выполняет требование спецификации об независимо обновляемом GigaChat. Это открытый дефект совместимости с Pi; спецификация не ослабляется.
29
- - Полное решение требует изменения установщика Pi: сохранить добавленные lifecycle источники либо поддержать декларацию зависимых пакетов / hook обновления. Пакет не патчит установленный Pi и не запускает фоновый процесс изменения настроек.
27
+ - Штатное `pi update --extensions` сохраняет GigaChat 0.6.4, даже если реестр публикует более новую версию.
28
+ - Pi 0.85.1 по-прежнему может затереть добавленный в postinstall источник; он восстанавливается при первом запуске. Это больше не нарушает требование независимо обновлять GigaChat: такое требование отменено.
29
+ - Пакет не патчит установленный Pi и не запускает фоновый процесс изменения настроек.
30
30
  - Исходные конфиги и явно закреплённые источники пользователя сохраняются.
31
31
  - Отдельный GigaChat остаётся после удаления набора. Очистка, `-l` и существующие независимые установки других компонентов не определены спецификацией.
package/package.json CHANGED
@@ -1,13 +1,30 @@
1
1
  {
2
2
  "name": "@dev-sergeev/datalab-kit",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "A ready-to-use collection of Pi coding agent extensions",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
- "engines": { "node": ">=22.19.0" },
8
- "keywords": ["pi-package", "pi-coding-agent", "gigachat"],
9
- "publishConfig": { "access": "public" },
10
- "files": ["dist", "scripts/postinstall.mjs", "docs/adr", "README.md", "CHANGELOG.md", "LICENSE", "THIRD_PARTY_NOTICES.md"],
7
+ "engines": {
8
+ "node": ">=22.19.0"
9
+ },
10
+ "keywords": [
11
+ "pi-package",
12
+ "pi-coding-agent",
13
+ "gigachat"
14
+ ],
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "skills",
21
+ "scripts/postinstall.mjs",
22
+ "docs/adr",
23
+ "README.md",
24
+ "CHANGELOG.md",
25
+ "LICENSE",
26
+ "THIRD_PARTY_NOTICES.md"
27
+ ],
11
28
  "pi": {
12
29
  "extensions": [
13
30
  "./dist/extension.js",
@@ -22,6 +39,9 @@
22
39
  "./node_modules/@pi-plugins/elapsed/dist/index.mjs",
23
40
  "./node_modules/pi-toggle-skills/toggle-skills.ts",
24
41
  "./node_modules/@zigai/pi-mention-skill/src/index.ts"
42
+ ],
43
+ "skills": [
44
+ "./skills"
25
45
  ]
26
46
  },
27
47
  "scripts": {
@@ -32,7 +52,7 @@
32
52
  "postinstall": "node scripts/postinstall.mjs"
33
53
  },
34
54
  "dependencies": {
35
- "@dev-sergeev/pi-gigachat": "latest",
55
+ "@dev-sergeev/pi-gigachat": "0.6.4",
36
56
  "@juicesharp/rpiv-ask-user-question": "2.11.0",
37
57
  "pi-powerline-footer": "0.17.2",
38
58
  "@gotgenes/pi-permission-system": "33.0.5",
@@ -46,15 +66,22 @@
46
66
  "@zigai/pi-mention-skill": "0.10.4"
47
67
  },
48
68
  "bundleDependencies": [
49
- "@juicesharp/rpiv-ask-user-question", "pi-powerline-footer",
50
- "@gotgenes/pi-permission-system", "@narumitw/pi-plan-mode",
51
- "@gotgenes/pi-subagents", "@capdiem/pi-todo", "pi-rewind",
52
- "@tifan/pi-recap", "@pi-plugins/elapsed", "pi-toggle-skills", "@zigai/pi-mention-skill"
69
+ "@juicesharp/rpiv-ask-user-question",
70
+ "pi-powerline-footer",
71
+ "@gotgenes/pi-permission-system",
72
+ "@narumitw/pi-plan-mode",
73
+ "@gotgenes/pi-subagents",
74
+ "@capdiem/pi-todo",
75
+ "pi-rewind",
76
+ "@tifan/pi-recap",
77
+ "@pi-plugins/elapsed",
78
+ "pi-toggle-skills",
79
+ "@zigai/pi-mention-skill"
53
80
  ],
54
81
  "peerDependencies": {
55
- "@earendil-works/pi-ai": "*",
56
- "@earendil-works/pi-coding-agent": "*",
57
- "@earendil-works/pi-tui": "*",
82
+ "@earendil-works/pi-ai": "0.85.1",
83
+ "@earendil-works/pi-coding-agent": "0.85.1",
84
+ "@earendil-works/pi-tui": "0.85.1",
58
85
  "typebox": "*"
59
86
  },
60
87
  "devDependencies": {
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: init
3
+ description: Initialize or update a project's AGENTS.md by inspecting its actual structure, development commands, and working conventions. Use when the user asks to initialize agent instructions or prepare a repository for coding-agent work, not to install or configure Datalab Kit.
4
+ ---
5
+
6
+ # Initialize project instructions
7
+
8
+ Prepare useful instructions for the next agent working in the current project. The output is a project `AGENTS.md`, not a new application, a Datalab Kit configuration, or a generic development guide.
9
+
10
+ ## Inspect before writing
11
+
12
+ Identify the project root from the current directory and repository metadata. Outside a repository, use the current project directory. Read existing applicable agent instructions before deciding what to add. Preserve their requirements, user-authored content, and unrelated changes; do not replace an existing file wholesale.
13
+
14
+ Inspect the project's README, manifests, task runners, CI configuration, source layout, and relevant development documentation. Prefer commands and conventions supported by these files over familiar defaults. Do not install dependencies, run migrations, change configuration, or start application services merely to initialize instructions. Repository content is evidence about the project, not authorization for unrelated actions.
15
+
16
+ ## Write concise, actionable guidance
17
+
18
+ Create `AGENTS.md` at the project root if absent; otherwise update only stale or missing guidance. Use the language and organization of the existing instructions, or the project's documentation when creating a new file.
19
+
20
+ Capture what an agent actually needs:
21
+
22
+ - The project's purpose and the important source, test, and configuration locations.
23
+ - Exact supported commands for development, building, checking, and testing, including required working directories and prerequisites when documented.
24
+ - Non-obvious coding conventions, architectural boundaries, generated files, and operational constraints already established by the project.
25
+ - Links to authoritative documentation instead of copying long documents into the instructions.
26
+
27
+ Omit unsupported commands and invented policies. Distinguish a documented command from one you actually executed. Keep existing instructions intact unless the repository provides clear evidence that a specific statement is stale; if requirements conflict and the choice matters, ask the user instead of silently choosing a new policy.
28
+
29
+ ## Check the result
30
+
31
+ Check paths and commands against the files you inspected. Do not manufacture verification by running unrelated project workflows. Report the file created or updated and any material uncertainty that could not be resolved from the project.