@kisev/skills-opencode 2.0.2 → 2.0.4
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.
- package/README.md +158 -135
- package/README.ru.md +162 -173
- package/dist/agent-profiles.d.ts +4 -1
- package/dist/agent-profiles.js +13 -4
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.js +1 -1
- package/dist/cli-output.js +28 -8
- package/dist/cli.js +11 -3
- package/dist/installer.d.ts +4 -1
- package/dist/installer.js +12 -4
- package/dist/lifecycle.d.ts +11 -1
- package/dist/lifecycle.js +58 -20
- package/dist/reconcile.d.ts +6 -2
- package/dist/reconcile.js +24 -6
- package/package.json +1 -1
package/README.ru.md
CHANGED
|
@@ -2,97 +2,166 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | [Русский](README.ru.md)
|
|
4
4
|
|
|
5
|
-
`@kisev/skills-opencode` -
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
npm lifecycle. Package требует Node.js 22+ и OpenCode 1.18.29+.
|
|
5
|
+
`@kisev/skills-opencode@2.0.4` - optional OpenCode-specific слой. У portable
|
|
6
|
+
skills отдельный lifecycle: их нужно установить независимо через
|
|
7
|
+
[корневую инструкцию](../../README.ru.md).
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## Требования и ownership
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Package требует Node.js 22+ и OpenCode `>=1.18.29 <1.19.0`.
|
|
12
|
+
|
|
13
|
+
| Component | Project scope | Global scope |
|
|
14
|
+
| ------------------ | ---------------------------- | ------------------------------------------------- |
|
|
15
|
+
| npm package | project `node_modules` | `node_modules` в npm project `~/.config/opencode` |
|
|
16
|
+
| Commands | `.opencode/commands` | `~/.config/opencode/commands` |
|
|
17
|
+
| Agents | `.opencode/agents` | `~/.config/opencode/agents` |
|
|
18
|
+
| Optional wrappers | `.opencode/plugins` | `~/.config/opencode/plugins` |
|
|
19
|
+
| Ownership metadata | `.opencode/.skills-opencode` | `~/.config/opencode/.skills-opencode` |
|
|
20
|
+
|
|
21
|
+
Package и generated wrappers должны оставаться доступными после завершения
|
|
22
|
+
installer. Import, plugin loading и npm lifecycle scripts не устанавливают
|
|
23
|
+
assets или portable skills и не меняют OpenCode configuration.
|
|
24
|
+
|
|
25
|
+
## Постоянная установка package
|
|
26
|
+
|
|
27
|
+
### Project scope
|
|
28
|
+
|
|
29
|
+
Установите package в npm project репозитория и запускайте CLI из его корня:
|
|
14
30
|
|
|
15
31
|
```shell
|
|
16
|
-
|
|
32
|
+
cd /path/to/project
|
|
33
|
+
npm install --save-exact @kisev/skills-opencode@2.0.4
|
|
34
|
+
npm exec -- skills-opencode install --scope project --dry-run
|
|
17
35
|
```
|
|
18
36
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
`https://github.com/kisev/skills/tree/v2.0.0`. Package никогда не устанавливает
|
|
22
|
-
и не обновляет skills. Если команда не нашла skill, она сообщает точную команду
|
|
23
|
-
`npx skills add` для его установки.
|
|
37
|
+
Package остаётся в project `node_modules`, confirmed assets размещаются в
|
|
38
|
+
`.opencode`.
|
|
24
39
|
|
|
25
|
-
|
|
40
|
+
### Global scope
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
Используйте `~/.config/opencode` как постоянный npm project:
|
|
28
43
|
|
|
29
44
|
```shell
|
|
30
|
-
|
|
45
|
+
mkdir -p "$HOME/.config/opencode"
|
|
46
|
+
cd "$HOME/.config/opencode"
|
|
47
|
+
test -f package.json || npm init --yes
|
|
48
|
+
npm install --save-exact @kisev/skills-opencode@2.0.4
|
|
49
|
+
npm exec -- skills-opencode install --scope global --dry-run
|
|
31
50
|
```
|
|
32
51
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
52
|
+
Сохраните dependency в `package.json` и lock file этого npm project. Confirmed
|
|
53
|
+
assets размещаются в `~/.config/opencode`.
|
|
54
|
+
|
|
55
|
+
## Выбор assets
|
|
56
|
+
|
|
57
|
+
В TTY команда `install` открывает четыре группы: Skill command adapters, Package
|
|
58
|
+
command adapters, Fixed agents и Selectable plugins. Две command-группы и шесть
|
|
59
|
+
fixed agents изначально выбраны, optional plugins - нет. Skill command adapters
|
|
60
|
+
это OpenCode slash-команды, загружающие уже установленный одноимённый portable
|
|
61
|
+
skill. Package command adapters вызывают package tools. Выбор adapter не выбирает
|
|
62
|
+
и не устанавливает skill.
|
|
63
|
+
|
|
64
|
+
Вне TTY передайте все три selection group. Этот пример выбирает три commands,
|
|
65
|
+
всех fixed agents и ни одного wrapper:
|
|
39
66
|
|
|
40
67
|
```shell
|
|
41
|
-
npm exec -- skills-opencode install --scope
|
|
68
|
+
npm exec -- skills-opencode install --scope project \
|
|
69
|
+
--commands doctor,reconcile,agent-profiles \
|
|
70
|
+
--agents manager,architect,mapper,worker,review,critic \
|
|
71
|
+
--plugins none --dry-run
|
|
42
72
|
```
|
|
43
73
|
|
|
44
|
-
|
|
74
|
+
Если вне TTY передан любой selection flag, обязательны `--commands`, `--agents`
|
|
75
|
+
и `--plugins`. Точные текущие имена показывает команда:
|
|
45
76
|
|
|
46
77
|
```shell
|
|
47
|
-
npm exec -- skills-opencode
|
|
78
|
+
npm exec -- skills-opencode capabilities --json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Selectable wrappers: `rules-injector`, `rtk`, `zed-bell`.
|
|
82
|
+
|
|
83
|
+
## Активация core plugin
|
|
84
|
+
|
|
85
|
+
Installer записывает, нужна ли selection core integration, но никогда не создаёт
|
|
86
|
+
и не меняет `opencode.json`. Добавьте package в user-owned массив `plugin` для
|
|
87
|
+
того же scope, сохранив существующие entries:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"$schema": "https://opencode.ai/config.json",
|
|
92
|
+
"plugin": ["@kisev/skills-opencode"]
|
|
93
|
+
}
|
|
48
94
|
```
|
|
49
95
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
96
|
+
Для project scope храните package в project `node_modules`, а configuration - в
|
|
97
|
+
project. Для global scope храните npm project и user configuration в
|
|
98
|
+
`~/.config/opencode`. После activation или изменения assets перезапустите
|
|
99
|
+
OpenCode.
|
|
100
|
+
|
|
101
|
+
## Preview и confirm
|
|
102
|
+
|
|
103
|
+
Каждая mutation начинается с `--dry-run`. Preview показывает operations,
|
|
104
|
+
conflicts, необходимость restart, срок действия receipt, отдельные plan и
|
|
105
|
+
confirmation digests и точную confirmation command. Если reconcile показывает
|
|
106
|
+
modified managed files или ownership conflicts, он блокируется: receipt и Apply
|
|
107
|
+
command не создаются. Сначала установите или обновите текущий package,
|
|
108
|
+
примените его exact installer confirmation, затем повторите reconcile; ownership
|
|
109
|
+
conflicts нужно разрешить вручную.
|
|
53
110
|
|
|
54
111
|
```shell
|
|
55
112
|
npm exec -- skills-opencode install --scope project --dry-run
|
|
56
|
-
npm exec -- skills-opencode install --scope project --confirm <digest>
|
|
57
113
|
```
|
|
58
114
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
115
|
+
Обязательный OpenCode flow: persistent npm install, `install --dry-run`, exact
|
|
116
|
+
confirmation command из preview, добавление package в user-owned `plugin` и
|
|
117
|
+
перезапуск OpenCode. Для global-команд используйте persistent npm project в
|
|
118
|
+
`~/.config/opencode`. Перед каждым reconcile установите или обновите package и
|
|
119
|
+
примените его installer plan.
|
|
120
|
+
|
|
121
|
+
Preview имеет deterministic `plan_digest` и unique `confirmation_digest`. Новый
|
|
122
|
+
dry-run в том же scope supersede-ит любой старый unconsumed preview, включая
|
|
123
|
+
preview другой package или agent operation; старая confirmation отклоняется.
|
|
63
124
|
|
|
64
|
-
|
|
65
|
-
|
|
125
|
+
Выполните команду из preview со всеми selection flags. Receipts приватны,
|
|
126
|
+
действуют 10 минут, применяются один раз и связаны с action, scope, root и
|
|
127
|
+
текущим inventory. Apply отклоняет stale state и unsafe conflicts.
|
|
128
|
+
|
|
129
|
+
## Doctor
|
|
130
|
+
|
|
131
|
+
`doctor` читает integration facts без создания receipts, recovery journals,
|
|
132
|
+
запуска plugins или LSP servers:
|
|
66
133
|
|
|
67
134
|
```shell
|
|
68
|
-
npm exec -- skills-opencode
|
|
69
|
-
npm exec -- skills-opencode
|
|
135
|
+
npm exec -- skills-opencode doctor --scope project
|
|
136
|
+
npm exec -- skills-opencode doctor --scope project --json
|
|
70
137
|
```
|
|
71
138
|
|
|
72
|
-
|
|
139
|
+
Report содержит versions, ownership, drift, collisions, archive counts, redacted
|
|
140
|
+
configuration projections, runtime summaries и LSP facts. Raw configuration,
|
|
141
|
+
environment values, receipts, credentials и secrets не сериализуются. Exit
|
|
142
|
+
status `0` означает чистое состояние, `1` - findings, `2` - invalid input или
|
|
143
|
+
incomplete probe failure.
|
|
73
144
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
145
|
+
## Обновление
|
|
146
|
+
|
|
147
|
+
В npm project, которому принадлежит dependency, установите точную нужную version,
|
|
148
|
+
покажите и подтвердите `install` с тем же scope и нужной selection, затем
|
|
149
|
+
перезапустите OpenCode:
|
|
78
150
|
|
|
79
151
|
```shell
|
|
80
|
-
npm
|
|
81
|
-
npm exec -- skills-opencode
|
|
152
|
+
npm install --save-exact @kisev/skills-opencode@2.0.4
|
|
153
|
+
npm exec -- skills-opencode install --scope project --dry-run
|
|
82
154
|
```
|
|
83
155
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
and credentials are never serialized. Exit code `0` is clean, `1` reports
|
|
89
|
-
findings, and `2` means invalid input or an incomplete probe failure.
|
|
156
|
+
Используйте полную confirmation command из preview. Installer обновляет только
|
|
157
|
+
files с совпадающими recorded ownership и SHA-256. User-owned или modified
|
|
158
|
+
managed files остаются conflicts. Package update не сбрасывает выбранные agent
|
|
159
|
+
models, variants, additional critics или retained profile configuration.
|
|
90
160
|
|
|
91
|
-
## Reconcile
|
|
161
|
+
## Reconcile
|
|
92
162
|
|
|
93
|
-
`reconcile`
|
|
94
|
-
agents и installation metadata
|
|
95
|
-
не изменяется. Preview сохраняет private receipt с TTL и печатает digest:
|
|
163
|
+
`reconcile` классифицирует current и historical portable skills, package
|
|
164
|
+
commands, plugins, agents и installation metadata одного scope:
|
|
96
165
|
|
|
97
166
|
```shell
|
|
98
167
|
npm exec -- skills-opencode reconcile --scope project --dry-run
|
|
@@ -100,143 +169,63 @@ npm exec -- skills-opencode reconcile --scope project --confirm <digest>
|
|
|
100
169
|
npm exec -- skills-opencode reconcile --scope global --dry-run --json
|
|
101
170
|
```
|
|
102
171
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
rollback, recovery и повторный no-op reconcile. Doctor показывает archive и
|
|
108
|
-
conflicts read-only.
|
|
172
|
+
Перед reconcile сначала обновите package в принадлежащем ему npm project и
|
|
173
|
+
примените exact installer plan. Reconcile не устанавливает, не обновляет и не
|
|
174
|
+
удаляет portable skills; для них используйте только pinned
|
|
175
|
+
`npx --yes skills@1.5.23` flow.
|
|
109
176
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
"plugin": ["@kisev/skills-opencode"]
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Полностью перезапустите OpenCode после install, upgrade или uninstall: registry
|
|
120
|
-
agents и commands строится до plugin hooks.
|
|
177
|
+
Confirmed reconcile архивирует exact-owned retired assets в private
|
|
178
|
+
content-addressed XDG archive и удаляет их deployed copies. Modified, user-owned,
|
|
179
|
+
unknown, symlink, unsafe и ambiguous entries остаются без изменений как findings
|
|
180
|
+
или conflicts. Worktrees и runtime state сохраняются. Archive доступен для
|
|
181
|
+
просмотра через `doctor`; команд restore или purge нет.
|
|
121
182
|
|
|
122
183
|
## Управление agents
|
|
123
184
|
|
|
124
|
-
|
|
125
|
-
токены. Fixed roles `manager`, `architect`, `mapper`, `worker`, `review` и
|
|
126
|
-
стандартный `critic` всегда сохраняют имена и canonical prompts/permissions.
|
|
127
|
-
Меняются только `model` и `variant`:
|
|
185
|
+
Direct CLI управляет models fixed agents и additional critics без LLM call:
|
|
128
186
|
|
|
129
187
|
```shell
|
|
130
188
|
npm exec -- skills-opencode agent list --scope global
|
|
131
189
|
npm exec -- skills-opencode agent configure manager --scope global --dry-run
|
|
132
|
-
npm exec -- skills-opencode agent model-set worker --scope global
|
|
133
|
-
|
|
190
|
+
npm exec -- skills-opencode agent model-set worker --scope global --model openai/gpt-5 --variant high --dry-run
|
|
191
|
+
npm exec -- skills-opencode critic add security --scope global --model anthropic/claude-sonnet-4-6 --dry-run
|
|
134
192
|
npm exec -- skills-opencode agent reconcile --scope global --dry-run
|
|
135
193
|
```
|
|
136
194
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
перед выбором; доступны `keep`, `change`, `clear variant`, `back` и `cancel`.
|
|
141
|
-
Wizard не вызывает LLM, OpenCode Question или refresh catalog. Если catalog
|
|
142
|
-
недоступен, он завершается без записи и печатает инструкцию для exact
|
|
143
|
-
`--model <provider/model>` с optional `--variant`. Для модели без variants
|
|
144
|
-
дополнительный selector не показывается.
|
|
195
|
+
Fixed roles сохраняют имена, prompts и permissions; меняются только model и
|
|
196
|
+
variant. Additional critics используют `critic-<safe-suffix>`. Каждая mutation
|
|
197
|
+
использует тот же contract preview и one-time confirmation.
|
|
145
198
|
|
|
146
|
-
|
|
147
|
-
roles нельзя удалить или переименовать:
|
|
199
|
+
## Uninstall
|
|
148
200
|
|
|
149
|
-
|
|
150
|
-
npm exec -- skills-opencode critic add security --scope global \
|
|
151
|
-
--model anthropic/claude-sonnet-4-6 --dry-run
|
|
152
|
-
npm exec -- skills-opencode critic remove security --scope global --dry-run
|
|
153
|
-
```
|
|
201
|
+
Package должен оставаться доступным до удаления его assets:
|
|
154
202
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
machine-readable result добавьте `--json`; поле `requires_restart` сообщает о
|
|
160
|
-
необходимости полностью перезапустить OpenCode.
|
|
161
|
-
|
|
162
|
-
В global scope profile configuration хранится в
|
|
163
|
-
`~/.config/opencode/.skills-opencode/agent-profiles.json`, а semantic deployment
|
|
164
|
-
manifest - рядом в `agent-profiles.manifest.json`. Для project scope те же файлы
|
|
165
|
-
находятся под `.opencode/.skills-opencode/`. Configuration хранит выбранные
|
|
166
|
-
model/variant и additional critics; package update её не сбрасывает. Manifest
|
|
167
|
-
хранит package version, exact critic pool и hashes canonical configuration и
|
|
168
|
-
rendered files.
|
|
169
|
-
|
|
170
|
-
Inventory различает `package-owned`, `managed`, `user-owned`, `drift` и exact-name
|
|
171
|
-
`collision`. User-owned и неизвестные agents не изменяются. Collision блокирует
|
|
172
|
-
apply; drift исправляется только явным `agent reconcile`. Все mutations проходят
|
|
173
|
-
под lifecycle lock, повторно проверяют inventory, используют journaled
|
|
174
|
-
all-or-rollback transaction и выполняют final validation. После прерывания
|
|
175
|
-
следующая mutation безопасно восстанавливает before-images и требует свежий plan.
|
|
176
|
-
|
|
177
|
-
## Upgrade и uninstall
|
|
178
|
-
|
|
179
|
-
После обновления npm package снова выполните dry-run и подтвердите новый digest.
|
|
180
|
-
Installer обновляет только files с совпадающим managed SHA-256.
|
|
181
|
-
|
|
182
|
-
При первом upgrade с `1.0.0` installer передаёт ownership шести fixed agents из
|
|
183
|
-
generic manifest в profile domain только при точном совпадении package/version,
|
|
184
|
-
manifest records и SHA-256 каждого файла. Любое отличие остаётся конфликтом.
|
|
185
|
-
Commands и plugins продолжают принадлежать generic installer. Uninstall удаляет
|
|
186
|
-
неизменённые deployments, но сохраняет profile configuration для последующей
|
|
187
|
-
установки.
|
|
203
|
+
1. Покажите preview и подтвердите удаление package-owned assets.
|
|
204
|
+
2. Удалите `@kisev/skills-opencode` из user-owned массива `plugin`.
|
|
205
|
+
3. Удалите dependency из того же npm project.
|
|
206
|
+
4. Перезапустите OpenCode.
|
|
188
207
|
|
|
189
208
|
```shell
|
|
190
|
-
npm exec -- skills-opencode uninstall --scope
|
|
191
|
-
npm exec -- skills-opencode uninstall --scope
|
|
209
|
+
npm exec -- skills-opencode uninstall --scope project --dry-run
|
|
210
|
+
npm exec -- skills-opencode uninstall --scope project --confirm <digest>
|
|
211
|
+
npm uninstall @kisev/skills-opencode
|
|
192
212
|
```
|
|
193
213
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Package экспортирует core OpenCode plugin и independent plugin factories
|
|
200
|
-
`rules-injector`, `rtk`, `zed-bell`. Retired plugin APIs и internal lifecycle
|
|
201
|
-
implementations public surface не входят:
|
|
202
|
-
|
|
203
|
-
Background Attempts создают workspace только через единый managed worktree
|
|
204
|
-
owner. Records используют private current-only state, marker и repository
|
|
205
|
-
fingerprint; release перепроверяет регистрацию, fingerprint и чистый status и
|
|
206
|
-
возвращает `blocked` без удаления при расхождении. Scheduler принимает строгий
|
|
207
|
-
five-field cron, не воспроизводит missed slots и пишет receipts `started`,
|
|
208
|
-
`completed`, `failed` или `overrun`.
|
|
209
|
-
|
|
210
|
-
`rules-injector` fail-soft применяет ограниченный budget и пропускает native
|
|
211
|
-
project/global rules. `rtk` fail-open сжимает большой bash output и добавляет
|
|
212
|
-
подсказку для edit error, но не содержит ownership guard.
|
|
213
|
-
|
|
214
|
-
## Routing этапа 18
|
|
215
|
-
|
|
216
|
-
`doit` владеет полным lifecycle evidence -> plan -> confirmation -> execution ->
|
|
217
|
-
checks -> report; `manager` только адаптирует его к OpenCode. Tool `route` имеет
|
|
218
|
-
четыре назначения: exploration -> `mapper`, architecture -> `architect`,
|
|
219
|
-
implementation -> `worker`, review -> `review` или один `critic`. Documentation и
|
|
220
|
-
quick остаются у `doit`.
|
|
221
|
-
|
|
222
|
-
Inventory берётся только из resolved host config. Caller не может подменить agents,
|
|
223
|
-
capabilities, tools, models или availability. Versioned receipts, cards и
|
|
224
|
-
mapper/worker/review/critic reports проверяются на реальных Task dispatch/result
|
|
225
|
-
hooks. Card связывает paths, checks, явные VCS operations и отдельные confirmations
|
|
226
|
-
для execution, publication и history rewrite.
|
|
214
|
+
Для global scope выполните тот же flow из `~/.config/opencode` с
|
|
215
|
+
`--scope global`. Uninstall архивирует exact manifest-owned assets и сохраняет
|
|
216
|
+
modified files как conflicts вместе с worktrees, runtime state и retained
|
|
217
|
+
profile configuration. Он не удаляет portable skills и не меняет
|
|
218
|
+
`opencode.json`. Команд restore или purge для archive нет.
|
|
227
219
|
|
|
228
220
|
## Границы
|
|
229
221
|
|
|
230
|
-
Portable skills
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
Package распространяется по лицензии MIT. Полные инструкции по portable skills,
|
|
242
|
-
upgrade и security boundaries находятся в корневом README репозитория.
|
|
222
|
+
- Portable skills и package assets устанавливаются, обновляются и удаляются
|
|
223
|
+
независимо.
|
|
224
|
+
- Commands, соответствующие skills, являются thin adapters; portable skill
|
|
225
|
+
остаётся authoritative и устанавливается отдельно.
|
|
226
|
+
- Package tools: `capabilities`, `route`, `doctor`, `agent_profiles`, `reconcile`;
|
|
227
|
+
у `route` нет slash command.
|
|
228
|
+
- Installer владеет только files с доказанными manifests и exact hashes.
|
|
229
|
+
- Package распространяется по лицензии MIT. Текущий inventory и checks описаны в
|
|
230
|
+
[инвентаре миграции](../../docs/ru/migration-inventory.md) и
|
|
231
|
+
[документе проверки](../../docs/ru/verification.md).
|
package/dist/agent-profiles.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LifecycleError, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
|
|
1
|
+
import { LifecycleError, type SupersededPlan, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
|
|
2
2
|
export { type Scope as AgentProfileScope } from "./lifecycle.js";
|
|
3
3
|
export declare const FIXED_AGENT_ROLES: readonly ["manager", "architect", "mapper", "worker", "review", "critic"];
|
|
4
4
|
export type FixedAgentRole = (typeof FIXED_AGENT_ROLES)[number];
|
|
@@ -70,6 +70,9 @@ export type AgentProfilePlan = {
|
|
|
70
70
|
root: string;
|
|
71
71
|
operations: AgentProfileOperation[];
|
|
72
72
|
critic_pool: string[];
|
|
73
|
+
plan_digest: string;
|
|
74
|
+
confirmation_digest?: string;
|
|
75
|
+
superseded_plan?: SupersededPlan;
|
|
73
76
|
digest: string;
|
|
74
77
|
receipt_expires_at?: string;
|
|
75
78
|
requires_restart: boolean;
|
package/dist/agent-profiles.js
CHANGED
|
@@ -520,9 +520,11 @@ export async function buildAgentProfilePlan(request, scope, cwd = process.cwd(),
|
|
|
520
520
|
critic_pool: desired?.critic_pool ?? finalManifest?.critic_pool ?? [],
|
|
521
521
|
requires_restart: mutations.some((item) => item.path.startsWith("agents/")),
|
|
522
522
|
};
|
|
523
|
+
const planDigest = planDigestBase(base, inventoryDigest, request);
|
|
523
524
|
const plan = {
|
|
524
525
|
...base,
|
|
525
|
-
|
|
526
|
+
plan_digest: planDigest,
|
|
527
|
+
digest: planDigest,
|
|
526
528
|
};
|
|
527
529
|
return {
|
|
528
530
|
plan,
|
|
@@ -639,8 +641,15 @@ export async function previewAgentProfileChange(request, scope, cwd = process.cw
|
|
|
639
641
|
if (await recoverTransaction(deploymentRoot(scope, cwd, home), stateRoot))
|
|
640
642
|
throw new AgentProfileError("recovered_transaction", "Recovered an interrupted transaction; request a fresh plan");
|
|
641
643
|
const built = await buildAgentProfilePlan(request, scope, cwd, home);
|
|
642
|
-
const receipt = await saveReceipt(stateRoot, `agent:${request.action}`, scope, built.plan.root, { request,
|
|
643
|
-
return {
|
|
644
|
+
const receipt = await saveReceipt(stateRoot, `agent:${request.action}`, scope, built.plan.root, { request, plan_digest: built.plan.digest }, Date.now(), built.plan.digest);
|
|
645
|
+
return {
|
|
646
|
+
...built.plan,
|
|
647
|
+
plan_digest: built.plan.digest,
|
|
648
|
+
confirmation_digest: receipt.digest,
|
|
649
|
+
digest: receipt.digest,
|
|
650
|
+
receipt_expires_at: receipt.expires_at,
|
|
651
|
+
...(receipt.superseded_plan ? { superseded_plan: receipt.superseded_plan } : {}),
|
|
652
|
+
};
|
|
644
653
|
});
|
|
645
654
|
}
|
|
646
655
|
export async function applyAgentProfileChange(request, scope, confirmationDigest, cwd = process.cwd(), home = homedir(), options = {}) {
|
|
@@ -658,7 +667,7 @@ export async function applyAgentProfileChange(request, scope, confirmationDigest
|
|
|
658
667
|
if (stable(receipt.request) !== stable(request))
|
|
659
668
|
throw new AgentProfileError("confirmation_unknown", "Saved confirmation belongs to a different request");
|
|
660
669
|
const built = await buildAgentProfilePlan(request, scope, cwd, home);
|
|
661
|
-
if (built.plan.digest !== receipt.
|
|
670
|
+
if (built.plan.digest !== receipt.plan_digest)
|
|
662
671
|
throw new AgentProfileError("stale_plan", "Agent inventory changed after preview");
|
|
663
672
|
if (built.plan.operations.some((item) => item.operation === "conflict" && item.reason.includes("collision")))
|
|
664
673
|
throw new AgentProfileError("collision", "Exact-name user-owned collision blocks apply");
|
package/dist/catalog.d.ts
CHANGED
|
@@ -4,5 +4,5 @@ export declare const CATALOG: {
|
|
|
4
4
|
readonly agents: readonly ["manager", "architect", "mapper", "worker", "review", "critic"];
|
|
5
5
|
readonly package_commands: readonly ["capabilities", "doctor", "reconcile", "agent-profiles"];
|
|
6
6
|
readonly tools: readonly ["capabilities", "route", "doctor", "agent_profiles", "reconcile"];
|
|
7
|
-
readonly version: "2.0.
|
|
7
|
+
readonly version: "2.0.4";
|
|
8
8
|
};
|
package/dist/catalog.js
CHANGED
|
@@ -34,5 +34,5 @@ export const CATALOG = {
|
|
|
34
34
|
agents: ["manager", "architect", "mapper", "worker", "review", "critic"],
|
|
35
35
|
package_commands: ["capabilities", "doctor", "reconcile", "agent-profiles"],
|
|
36
36
|
tools: ["capabilities", "route", "doctor", "agent_profiles", "reconcile"],
|
|
37
|
-
version: "2.0.
|
|
37
|
+
version: "2.0.4",
|
|
38
38
|
};
|
package/dist/cli-output.js
CHANGED
|
@@ -119,9 +119,16 @@ export function renderPlan(plan, options) {
|
|
|
119
119
|
? `Restart required: ${plan.requires_restart ? "yes" : "no"}`
|
|
120
120
|
: `Restart after apply: ${plan.requires_restart ? "yes" : "no"}`);
|
|
121
121
|
if (!options.applied) {
|
|
122
|
+
if (plan.superseded_plan)
|
|
123
|
+
lines.push("", "Superseded plan:", ` kind: ${terminalSafe(plan.superseded_plan.kind)}`, ` confirmation: ${terminalSafe(plan.superseded_plan.confirmation_digest)}`, ` created: ${terminalSafe(plan.superseded_plan.created_at)}`, ` expires: ${terminalSafe(plan.superseded_plan.expires_at)}`);
|
|
122
124
|
if (plan.receipt_expires_at)
|
|
123
125
|
lines.push(`Confirmation expires: ${plan.receipt_expires_at}`);
|
|
124
|
-
|
|
126
|
+
if ("plan_digest" in plan)
|
|
127
|
+
lines.push(`Plan digest: ${plan.plan_digest}`);
|
|
128
|
+
if (plan.confirmation_digest ?? plan.digest) {
|
|
129
|
+
lines.push(`Confirmation digest: ${plan.confirmation_digest ?? plan.digest}`);
|
|
130
|
+
lines.push(`Digest: ${plan.confirmation_digest ?? plan.digest}`);
|
|
131
|
+
}
|
|
125
132
|
if (options.confirmationCommand)
|
|
126
133
|
lines.push("", "Apply:", ` ${options.confirmationCommand}`);
|
|
127
134
|
}
|
|
@@ -179,15 +186,28 @@ export function renderReconcile(plan, options) {
|
|
|
179
186
|
if (plan.retired.length)
|
|
180
187
|
lines.push("", "Retired:", ...plan.retired.slice(0, 20).map((entry) => ` ${terminalSafe(entry.path)}`));
|
|
181
188
|
if (plan.conflicts.length)
|
|
182
|
-
lines.push("", "Conflicts:", ...plan.conflicts
|
|
183
|
-
|
|
184
|
-
|
|
189
|
+
lines.push("", "Conflicts:", ...plan.conflicts.map((entry) => ` ${terminalSafe(entry.path)} (${terminalSafe(entry.reason)})`));
|
|
190
|
+
if (plan.modified_managed.length)
|
|
191
|
+
lines.push("", "Modified managed:", ...plan.modified_managed.map((entry) => ` ${terminalSafe(entry.path)} (${terminalSafe(entry.reason)})`));
|
|
185
192
|
if (!options.applied) {
|
|
186
|
-
|
|
187
|
-
if (
|
|
188
|
-
lines.push(
|
|
189
|
-
|
|
193
|
+
const blocked = plan.modified_managed.length > 0 || plan.conflicts.length > 0;
|
|
194
|
+
if (blocked) {
|
|
195
|
+
lines.push("", "Blocked:");
|
|
196
|
+
if (plan.modified_managed.length)
|
|
197
|
+
lines.push(` Update managed assets first: ${shellCommand(["install", "--scope", plan.scope, "--dry-run"])}`, " Apply the exact confirmation command from that installer preview, then build a new reconcile preview.");
|
|
198
|
+
if (plan.conflicts.length)
|
|
199
|
+
lines.push(" Manually resolve every ownership conflict listed above before reconciling.");
|
|
200
|
+
}
|
|
201
|
+
else if (options.confirmationCommand) {
|
|
202
|
+
if (plan.superseded_plan)
|
|
203
|
+
lines.push("", "Superseded plan:", ` kind: ${terminalSafe(plan.superseded_plan.kind)}`, ` confirmation: ${terminalSafe(plan.superseded_plan.confirmation_digest)}`, ` created: ${terminalSafe(plan.superseded_plan.created_at)}`, ` expires: ${terminalSafe(plan.superseded_plan.expires_at)}`);
|
|
204
|
+
lines.push("", `Plan digest: ${plan.plan_digest}`);
|
|
205
|
+
if (plan.receipt_expires_at)
|
|
206
|
+
lines.push(`Confirmation expires: ${plan.receipt_expires_at}`);
|
|
207
|
+
if (plan.confirmation_digest ?? plan.digest)
|
|
208
|
+
lines.push(`Confirmation digest: ${plan.confirmation_digest ?? plan.digest}`, `Digest: ${plan.confirmation_digest ?? plan.digest}`);
|
|
190
209
|
lines.push("", "Apply:", ` ${options.confirmationCommand}`);
|
|
210
|
+
}
|
|
191
211
|
}
|
|
192
212
|
return `${lines.join("\n")}\n`;
|
|
193
213
|
}
|
package/dist/cli.js
CHANGED
|
@@ -100,6 +100,14 @@ function help() {
|
|
|
100
100
|
async function interactiveInstallerSelection() {
|
|
101
101
|
if (!process.stdin.isTTY || !process.stderr.isTTY)
|
|
102
102
|
throw new InstallerError("terminal_required", "install requires explicit selection flags outside a terminal");
|
|
103
|
+
process.stderr.write([
|
|
104
|
+
"Portable skills are installed separately through npx skills.",
|
|
105
|
+
"This installer does not install, update, or remove portable skills.",
|
|
106
|
+
"Skill command adapters are OpenCode slash commands that load an already-installed skill with the same name.",
|
|
107
|
+
"Package command adapters invoke package tools.",
|
|
108
|
+
"Selecting a command adapter does not select or install its skill.",
|
|
109
|
+
"\n",
|
|
110
|
+
].join("\n"));
|
|
103
111
|
const group = async (label, names, initial) => {
|
|
104
112
|
const choices = ["Select all", "Select none", ...names];
|
|
105
113
|
const selected = await selectOption(label, choices, process.stdin, process.stderr, initial);
|
|
@@ -112,8 +120,8 @@ async function interactiveInstallerSelection() {
|
|
|
112
120
|
return [names[selected - 2]];
|
|
113
121
|
};
|
|
114
122
|
const commands = [
|
|
115
|
-
...(await group("Skill
|
|
116
|
-
...(await group("Package
|
|
123
|
+
...(await group("Skill command adapters", SKILL_COMMANDS, 0)),
|
|
124
|
+
...(await group("Package command adapters", PACKAGE_COMMANDS, 0)),
|
|
117
125
|
];
|
|
118
126
|
const agents = await group("Fixed agents", defaultSelection().agents, 0);
|
|
119
127
|
const plugins = await group("Selectable plugins (none selected by default)", SELECTABLE_PLUGINS, 1);
|
|
@@ -345,7 +353,7 @@ async function run(arguments_) {
|
|
|
345
353
|
if (options.json)
|
|
346
354
|
process.stdout.write(`${JSON.stringify({ status: "ok", applied: false, plan }, null, 2)}\n`);
|
|
347
355
|
else
|
|
348
|
-
process.stdout.write(renderReconcile(plan, { applied: false, confirmationCommand: shellCommand(["reconcile", "--scope", options.scope, "--confirm", plan.digest]) }));
|
|
356
|
+
process.stdout.write(renderReconcile(plan, { applied: false, confirmationCommand: plan.confirmable ? shellCommand(["reconcile", "--scope", options.scope, "--confirm", plan.confirmation_digest ?? plan.digest]) : undefined }));
|
|
349
357
|
}
|
|
350
358
|
else {
|
|
351
359
|
const applied = await applyReconcile(options.scope, options.confirm);
|
package/dist/installer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LifecycleError, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
|
|
1
|
+
import { LifecycleError, type SupersededPlan, type FileMutation, type Scope, type TransactionOptions } from "./lifecycle.js";
|
|
2
2
|
import { CATALOG } from "./catalog.js";
|
|
3
3
|
import { type FixedAgentRole } from "./agent-profiles.js";
|
|
4
4
|
export type { Scope } from "./lifecycle.js";
|
|
@@ -25,6 +25,9 @@ export type Plan = {
|
|
|
25
25
|
package_version: string;
|
|
26
26
|
selection: InstallerSelection;
|
|
27
27
|
operations: PlanItem[];
|
|
28
|
+
plan_digest: string;
|
|
29
|
+
confirmation_digest?: string;
|
|
30
|
+
superseded_plan?: SupersededPlan;
|
|
28
31
|
digest: string;
|
|
29
32
|
receipt_expires_at?: string;
|
|
30
33
|
requires_restart: boolean;
|