skill-flow 1.0.2 → 1.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 +62 -23
- package/README.zh.md +63 -25
- package/dist/cli.js +13 -39
- package/dist/cli.js.map +1 -1
- package/dist/domain/types.d.ts +12 -1
- package/dist/services/doctor-service.js +1 -1
- package/dist/services/doctor-service.js.map +1 -1
- package/dist/services/skill-flow.d.ts +16 -13
- package/dist/services/skill-flow.js +158 -5
- package/dist/services/skill-flow.js.map +1 -1
- package/dist/services/source-service.d.ts +11 -1
- package/dist/services/source-service.js +60 -18
- package/dist/services/source-service.js.map +1 -1
- package/dist/services/workflow-service.d.ts +2 -2
- package/dist/services/workflow-service.js +17 -4
- package/dist/services/workflow-service.js.map +1 -1
- package/dist/services/workspace-bootstrap-service.d.ts +25 -0
- package/dist/services/workspace-bootstrap-service.js +148 -0
- package/dist/services/workspace-bootstrap-service.js.map +1 -0
- package/dist/state/store.js +1 -0
- package/dist/state/store.js.map +1 -1
- package/dist/tests/skill-flow.test.js +1458 -0
- package/dist/tests/skill-flow.test.js.map +1 -1
- package/dist/tui/config-app.d.ts +3 -0
- package/dist/tui/config-app.js +61 -1
- package/dist/tui/config-app.js.map +1 -1
- package/dist/tui/find-app.d.ts +1 -1
- package/dist/tui/find-app.js +36 -4
- package/dist/tui/find-app.js.map +1 -1
- package/dist/utils/format.js +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/naming.d.ts +1 -0
- package/dist/utils/naming.js +7 -1
- package/dist/utils/naming.js.map +1 -1
- package/dist/utils/source-id.js +4 -0
- package/dist/utils/source-id.js.map +1 -1
- package/package.json +10 -1
- package/.gstack/browse-network.log +0 -1
- package/.gstack/browse.json +0 -7
- package/.gstack/qa-reports/base-branch.txt +0 -1
- package/.gstack/qa-reports/qa-report-skill-flow-cli-2026-03-22.md +0 -159
- package/.gstack/qa-reports/qa-report-skill-manager-2026-03-22.md +0 -60
- package/docs/DESIGN.md +0 -407
- package/docs/PRD/PRD-1.0.0.md +0 -1862
- package/docs/PRD/renew/PRD-0.0.0.md +0 -26
- package/docs/PRD/renew/PRD-0.0.1.md +0 -408
- package/docs/PRD/renew/PRD-0.0.2.md +0 -705
- package/docs/PRD/renew/PRD-0.0.3.md +0 -740
- package/docs/PRD/renew/PRD-0.0.4.md +0 -1494
- package/docs/README.md +0 -242
- package/docs/plan/PLAN_v1.0.0.md +0 -663
- package/docs/plan/PLAN_v1.0.1.md +0 -845
- package/docs/refrences/README.md +0 -9
- package/docs/refrences/agent-skill-paths.md +0 -274
- package/docs/refrences/config-state-reconciliation.md +0 -199
- package/docs/refrences/naming-dedupe-warning-rules.md +0 -482
- package/img/img-1.jpg +0 -0
package/docs/refrences/README.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
# References
|
|
2
|
-
|
|
3
|
-
This directory stores external path and compatibility references that guide
|
|
4
|
-
future `skill-flow` target support.
|
|
5
|
-
|
|
6
|
-
- [agent-skill-paths.md](/Users/Vint/仓库/03%20Project/skill-flow/docs/refrences/agent-skill-paths.md)
|
|
7
|
-
Current implementation paths and broader ecosystem path references.
|
|
8
|
-
- [config-state-reconciliation.md](/Users/Vint/仓库/03%20Project/skill-manager/docs/refrences/config-state-reconciliation.md)
|
|
9
|
-
Config, manifest, lock, and disk-state reconciliation rules.
|
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
# Agent Skill Paths Reference
|
|
2
|
-
|
|
3
|
-
Last updated: 2026-03-22
|
|
4
|
-
|
|
5
|
-
This file separates two things:
|
|
6
|
-
|
|
7
|
-
1. Current `skill-flow` implementation behavior
|
|
8
|
-
2. Broader ecosystem path references for future support work
|
|
9
|
-
|
|
10
|
-
The goal is to keep implementation truth and compatibility research in one
|
|
11
|
-
place without mixing them up.
|
|
12
|
-
|
|
13
|
-
## Current Skill Flow Support
|
|
14
|
-
|
|
15
|
-
These are the target roots that the current code can detect and project into.
|
|
16
|
-
Targets with missing directories are hidden from the `config` TUI.
|
|
17
|
-
|
|
18
|
-
| Target | Default detection roots | Env override | Strategy |
|
|
19
|
-
| --- | --- | --- | --- |
|
|
20
|
-
| Claude Code | `~/.claude/skills` | `SKILL_MANAGER_TARGET_CLAUDE_CODE` | `symlink` |
|
|
21
|
-
| OpenAI Codex | `~/.codex/.agents/skills`, `~/.agents/skills` | `SKILL_MANAGER_TARGET_CODEX` | `symlink` |
|
|
22
|
-
| Cursor | `~/.cursor/skills` | `SKILL_MANAGER_TARGET_CURSOR` | `symlink` |
|
|
23
|
-
| GitHub Copilot | `~/.copilot/skills` | `SKILL_MANAGER_TARGET_GITHUB_COPILOT` | `symlink` |
|
|
24
|
-
| Gemini CLI | `~/.gemini/skills` | `SKILL_MANAGER_TARGET_GEMINI_CLI` | `symlink` |
|
|
25
|
-
| OpenCode | `~/.config/opencode/skills`, `~/.opencode/skills` | `SKILL_MANAGER_TARGET_OPENCODE` | `symlink` |
|
|
26
|
-
| OpenClaw | `~/.openclaw/skills` | `SKILL_MANAGER_TARGET_OPENCLAW` | `copy` |
|
|
27
|
-
| Pi | `~/.pi/agent/skills` | `SKILL_MANAGER_TARGET_PI` | `symlink` |
|
|
28
|
-
| Windsurf | `~/.codeium/windsurf/skills` | `SKILL_MANAGER_TARGET_WINDSURF` | `symlink` |
|
|
29
|
-
| Roo Code | `~/.roo/skills` | `SKILL_MANAGER_TARGET_ROO_CODE` | `symlink` |
|
|
30
|
-
| Cline | `~/.cline/skills` | `SKILL_MANAGER_TARGET_CLINE` | `symlink` |
|
|
31
|
-
| Amp | `~/.config/agents/skills`, `~/.config/amp/skills` | `SKILL_MANAGER_TARGET_AMP` | `symlink` |
|
|
32
|
-
| Kiro | `~/.kiro/skills` | `SKILL_MANAGER_TARGET_KIRO` | `symlink` |
|
|
33
|
-
|
|
34
|
-
Notes:
|
|
35
|
-
|
|
36
|
-
- Current v1 implementation projects into target roots only. It does not yet
|
|
37
|
-
model per-agent project skill roots, compatibility reads, or instruction
|
|
38
|
-
files such as `AGENTS.md`, `CLAUDE.md`, or `GEMINI.md`.
|
|
39
|
-
- Hidden target behavior is intentional: if no detected root exists, the target
|
|
40
|
-
should not appear in `config`.
|
|
41
|
-
- Shared compatibility roots such as `~/.agents/skills` and `~/.claude/skills`
|
|
42
|
-
are not reused across multiple new targets yet. This avoids multi-target
|
|
43
|
-
projection collisions onto the same physical directory.
|
|
44
|
-
|
|
45
|
-
## Ecosystem Path References
|
|
46
|
-
|
|
47
|
-
These references are for future compatibility and target-expansion work. They
|
|
48
|
-
should not be read as "already implemented".
|
|
49
|
-
|
|
50
|
-
### Ecosystem Default Path Matrix
|
|
51
|
-
|
|
52
|
-
This matrix is broader than current `skill-flow` support. It is a planning and compatibility reference, not an implementation promise.
|
|
53
|
-
|
|
54
|
-
| Tool | Global Path | Project Path | Default |
|
|
55
|
-
| --- | --- | --- | :---: |
|
|
56
|
-
| Claude Code | `~/.claude/skills/` | `.claude/skills/` | enabled |
|
|
57
|
-
| Codex | `~/.codex/skills/` | `.codex/skills/` | enabled |
|
|
58
|
-
| OpenClaw | `~/.openclaw/skills/` | `.openclaw/skills/` | enabled |
|
|
59
|
-
| Agents (generic) | `~/.agents/skills/` | `.agents/skills/` | enabled |
|
|
60
|
-
| Cursor | `~/.cursor/rules/` | `.cursor/rules/` | enabled |
|
|
61
|
-
| Windsurf | `~/.windsurf/rules/` | `.windsurf/rules/` | enabled |
|
|
62
|
-
| Cline | `~/Documents/Cline/Rules/` | `.clinerules/` | enabled |
|
|
63
|
-
| Roo Code | `~/.roo/rules/` | `.roo/rules/` | enabled |
|
|
64
|
-
| Continue | `~/.continue/rules/` | `.continue/rules/` | enabled |
|
|
65
|
-
| GitHub Copilot | `~/.github/instructions/` | `.github/instructions/` | enabled |
|
|
66
|
-
| Aider | `~/.aider/skills/` | `.aider/skills/` | enabled |
|
|
67
|
-
| OpenCode | `~/.config/opencode/skills/` | `.opencode/skills/` | enabled |
|
|
68
|
-
| Zed | `~/.config/zed/prompt_overrides/` | `.zed/rules/` | enabled |
|
|
69
|
-
| Augment | `~/.augment/rules/` | `.augment/rules/` | enabled |
|
|
70
|
-
| Amp | `~/.amp/skills/` | `.amp/skills/` | enabled |
|
|
71
|
-
|
|
72
|
-
### 1. Claude Code
|
|
73
|
-
|
|
74
|
-
Skills:
|
|
75
|
-
|
|
76
|
-
- Personal skills: `~/.claude/skills/<skill-name>/SKILL.md`
|
|
77
|
-
- Project skills: `<repo>/.claude/skills/<skill-name>/SKILL.md`
|
|
78
|
-
|
|
79
|
-
Instructions and rules:
|
|
80
|
-
|
|
81
|
-
- User instructions: `~/.claude/CLAUDE.md`
|
|
82
|
-
- Project instructions: `<repo>/CLAUDE.md`
|
|
83
|
-
- Project hidden instructions: `<repo>/.claude/CLAUDE.md`
|
|
84
|
-
- Rules: `<repo>/.claude/rules/*.md`
|
|
85
|
-
|
|
86
|
-
### 2. OpenAI Codex
|
|
87
|
-
|
|
88
|
-
Skills:
|
|
89
|
-
|
|
90
|
-
- Current official user skills: `$HOME/.agents/skills`
|
|
91
|
-
- Project skills: upward scan from current directory for `.agents/skills`
|
|
92
|
-
- System skills: `/etc/codex/skills`
|
|
93
|
-
|
|
94
|
-
Notes:
|
|
95
|
-
|
|
96
|
-
- `~/.codex/` is primarily a config directory now, for example
|
|
97
|
-
`~/.codex/config.toml`.
|
|
98
|
-
- `~/.codex/` should not be treated as the official primary skills root going
|
|
99
|
-
forward.
|
|
100
|
-
|
|
101
|
-
### 3. Cursor
|
|
102
|
-
|
|
103
|
-
Skills:
|
|
104
|
-
|
|
105
|
-
- Global skills: `~/.cursor/skills/`
|
|
106
|
-
- Project skills: `<repo>/.cursor/skills/`
|
|
107
|
-
|
|
108
|
-
Compatibility reads:
|
|
109
|
-
|
|
110
|
-
- `.agents/skills/`
|
|
111
|
-
- `.claude/skills/`
|
|
112
|
-
- `.codex/skills/`
|
|
113
|
-
- Their corresponding home-directory versions
|
|
114
|
-
|
|
115
|
-
Rules and notes:
|
|
116
|
-
|
|
117
|
-
- Rules: `<repo>/.cursor/rules/`
|
|
118
|
-
- Cursor skills entered editor and CLI support on `2026-01-22`
|
|
119
|
-
|
|
120
|
-
### 4. OpenCode
|
|
121
|
-
|
|
122
|
-
Skills:
|
|
123
|
-
|
|
124
|
-
- Global skills: `~/.config/opencode/skills/<name>/SKILL.md`
|
|
125
|
-
- Project skills: `<repo>/.opencode/skills/<name>/SKILL.md`
|
|
126
|
-
|
|
127
|
-
Compatibility reads:
|
|
128
|
-
|
|
129
|
-
- `.claude/skills`
|
|
130
|
-
- `~/.claude/skills`
|
|
131
|
-
- `.agents/skills`
|
|
132
|
-
- `~/.agents/skills`
|
|
133
|
-
|
|
134
|
-
Instructions and rules:
|
|
135
|
-
|
|
136
|
-
- Long-term instructions: `AGENTS.md`
|
|
137
|
-
- Global instructions: `~/.config/opencode/AGENTS.md`
|
|
138
|
-
- Also reads `.cursor/rules/*.md` as one instruction source
|
|
139
|
-
|
|
140
|
-
### 5. Pi
|
|
141
|
-
|
|
142
|
-
Skills:
|
|
143
|
-
|
|
144
|
-
- Global skills: `~/.pi/agent/skills/`
|
|
145
|
-
- Also supports: `~/.agents/skills/`
|
|
146
|
-
- Project skills: `<repo>/.pi/skills/`
|
|
147
|
-
- Also scans current directory and ancestors for `.agents/skills/`
|
|
148
|
-
|
|
149
|
-
Compatibility reads:
|
|
150
|
-
|
|
151
|
-
- `~/.claude/skills`
|
|
152
|
-
- `~/.codex/skills`
|
|
153
|
-
|
|
154
|
-
### 6. GitHub Copilot
|
|
155
|
-
|
|
156
|
-
Skills:
|
|
157
|
-
|
|
158
|
-
- Project skills: `.github/skills/`
|
|
159
|
-
- Project compatibility skills: `.claude/skills/`
|
|
160
|
-
- User skills: `~/.copilot/skills/`
|
|
161
|
-
- User compatibility skills: `~/.claude/skills/`
|
|
162
|
-
|
|
163
|
-
Notes:
|
|
164
|
-
|
|
165
|
-
- Another official description also lists `.agents/skills/` in the wider
|
|
166
|
-
priority order.
|
|
167
|
-
- This covers VS Code agent mode and Copilot coding agent usage.
|
|
168
|
-
|
|
169
|
-
### 7. Gemini CLI
|
|
170
|
-
|
|
171
|
-
Skills:
|
|
172
|
-
|
|
173
|
-
- Workspace skills: `<repo>/.gemini/skills/`
|
|
174
|
-
- Workspace alias: `<repo>/.agents/skills/`
|
|
175
|
-
- User skills: `~/.gemini/skills/`
|
|
176
|
-
- User alias: `~/.agents/skills/`
|
|
177
|
-
|
|
178
|
-
Instructions and extensions:
|
|
179
|
-
|
|
180
|
-
- User instructions: `~/.gemini/GEMINI.md`
|
|
181
|
-
- Workspace instructions: upward scan for `GEMINI.md`
|
|
182
|
-
- Extensions: `~/.gemini/extensions/`
|
|
183
|
-
|
|
184
|
-
### 8. Windsurf
|
|
185
|
-
|
|
186
|
-
Skills:
|
|
187
|
-
|
|
188
|
-
- Workspace skills: `<repo>/.windsurf/skills/<skill-name>/SKILL.md`
|
|
189
|
-
- User skills: `~/.codeium/windsurf/skills/<skill-name>/SKILL.md`
|
|
190
|
-
- System skills on macOS:
|
|
191
|
-
`/Library/Application Support/Windsurf/skills/`
|
|
192
|
-
|
|
193
|
-
Instructions, rules, workflows, memories:
|
|
194
|
-
|
|
195
|
-
- Long-term instructions: `AGENTS.md`
|
|
196
|
-
- Global rules: `global_rules.md`
|
|
197
|
-
- Project rules: `<repo>/.windsurf/rules/`
|
|
198
|
-
- Project workflows: `<repo>/.windsurf/workflows/`
|
|
199
|
-
- Generated memories: `~/.codeium/windsurf/memories/`
|
|
200
|
-
|
|
201
|
-
### 9. Roo Code
|
|
202
|
-
|
|
203
|
-
Skills:
|
|
204
|
-
|
|
205
|
-
- Project skills: `<repo>/.roo/skills/`
|
|
206
|
-
- Global skills: `~/.roo/skills/`
|
|
207
|
-
|
|
208
|
-
Rules and commands:
|
|
209
|
-
|
|
210
|
-
- Project rules: `<repo>/.roo/rules/`
|
|
211
|
-
- Global rules: `~/.roo/rules/`
|
|
212
|
-
- Mode-specific rules: `rules-{modeSlug}`
|
|
213
|
-
- Project commands: `<repo>/.roo/commands/`
|
|
214
|
-
- Global commands: `~/.roo/commands/`
|
|
215
|
-
|
|
216
|
-
### 10. Cline
|
|
217
|
-
|
|
218
|
-
Skills:
|
|
219
|
-
|
|
220
|
-
- Project skills: `<repo>/.cline/skills/`
|
|
221
|
-
- Global skills: `~/.cline/skills/`
|
|
222
|
-
|
|
223
|
-
Compatibility reads:
|
|
224
|
-
|
|
225
|
-
- Project compatibility skills: `.clinerules/skills/`
|
|
226
|
-
- Project compatibility skills: `.claude/skills/`
|
|
227
|
-
|
|
228
|
-
Rules, workflows, local data:
|
|
229
|
-
|
|
230
|
-
- Project rules: `.clinerules/`
|
|
231
|
-
- Global rules on macOS: `~/Documents/Cline/Rules`
|
|
232
|
-
- Project workflows: `<repo>/.clinerules/workflows/`
|
|
233
|
-
- Global workflows on macOS: `~/Documents/Cline/Workflows`
|
|
234
|
-
- Local data and config: `~/.cline/data/`
|
|
235
|
-
|
|
236
|
-
### 11. Amp
|
|
237
|
-
|
|
238
|
-
Skills:
|
|
239
|
-
|
|
240
|
-
- Project skills: `<repo>/.agents/skills/`
|
|
241
|
-
- User skills: `~/.config/agents/skills/`
|
|
242
|
-
|
|
243
|
-
Compatibility reads:
|
|
244
|
-
|
|
245
|
-
- `~/.config/amp/skills/`
|
|
246
|
-
- `.claude/skills/`
|
|
247
|
-
- `~/.claude/skills/`
|
|
248
|
-
|
|
249
|
-
Instructions:
|
|
250
|
-
|
|
251
|
-
- Long-term instructions: `AGENTS.md`
|
|
252
|
-
- User `AGENTS` locations:
|
|
253
|
-
- `~/.config/amp/AGENTS.md`
|
|
254
|
-
- `~/.config/AGENTS.md`
|
|
255
|
-
|
|
256
|
-
### 12. Kiro
|
|
257
|
-
|
|
258
|
-
Skills:
|
|
259
|
-
|
|
260
|
-
- Global skills: `~/.kiro/skills/`
|
|
261
|
-
- Project skills: `<repo>/.kiro/skills/`
|
|
262
|
-
|
|
263
|
-
## Suggested Follow-up Optimization Areas
|
|
264
|
-
|
|
265
|
-
These references imply a few near-term architecture changes:
|
|
266
|
-
|
|
267
|
-
- Split target support into:
|
|
268
|
-
- projection targets
|
|
269
|
-
- project-level compatibility readers
|
|
270
|
-
- instruction/rules readers
|
|
271
|
-
- Distinguish official roots from compatibility aliases
|
|
272
|
-
- Model user-level, project-level, and system-level roots explicitly
|
|
273
|
-
- Add reference-backed tests for detection precedence and hidden-target behavior
|
|
274
|
-
- Document which roots are used for read, write, or compatibility-only behavior
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
# Config State Reconciliation
|
|
2
|
-
|
|
3
|
-
Last updated: 2026-03-22
|
|
4
|
-
|
|
5
|
-
This document explains how `skill-flow` maps config state to persisted state,
|
|
6
|
-
why state could look inconsistent before, and what the current normalization
|
|
7
|
-
rules are.
|
|
8
|
-
|
|
9
|
-
## Four State Layers
|
|
10
|
-
|
|
11
|
-
`skill-flow` currently has four relevant state layers:
|
|
12
|
-
|
|
13
|
-
1. TUI draft state
|
|
14
|
-
2. `manifest.json`
|
|
15
|
-
3. `lock.json`
|
|
16
|
-
4. Target disk state
|
|
17
|
-
|
|
18
|
-
They are related, but they do not serve the same purpose.
|
|
19
|
-
|
|
20
|
-
## Layer Responsibilities
|
|
21
|
-
|
|
22
|
-
### 1. TUI draft state
|
|
23
|
-
|
|
24
|
-
The config UI uses this shape:
|
|
25
|
-
|
|
26
|
-
- `enabledTargets: DeploymentTargetName[]`
|
|
27
|
-
- `selectedLeafIds: string[]`
|
|
28
|
-
|
|
29
|
-
This is the editing model used by `ConfigApp`.
|
|
30
|
-
|
|
31
|
-
Important constraint:
|
|
32
|
-
|
|
33
|
-
- the TUI has one shared selected skill set per workflow group
|
|
34
|
-
- it does not model different `leafIds` per target
|
|
35
|
-
|
|
36
|
-
So from the UI's perspective, a workflow group means:
|
|
37
|
-
|
|
38
|
-
- these targets are enabled
|
|
39
|
-
- these skills are selected for all enabled targets
|
|
40
|
-
|
|
41
|
-
### 2. `manifest.json`
|
|
42
|
-
|
|
43
|
-
`manifest.json` stores user intent.
|
|
44
|
-
|
|
45
|
-
Relevant structure:
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"bindings": {
|
|
50
|
-
"<sourceId>": {
|
|
51
|
-
"targets": {
|
|
52
|
-
"<target>": {
|
|
53
|
-
"enabled": true,
|
|
54
|
-
"leafIds": ["<sourceId>:browse"]
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Even though `manifest` stores `leafIds` per target, current config behavior
|
|
63
|
-
expects all enabled targets for one source to share the same `leafIds`.
|
|
64
|
-
|
|
65
|
-
That means the persisted manifest shape is more expressive than the TUI model.
|
|
66
|
-
|
|
67
|
-
### 3. `lock.json`
|
|
68
|
-
|
|
69
|
-
`lock.json` stores actual scanned and applied state.
|
|
70
|
-
|
|
71
|
-
It contains:
|
|
72
|
-
|
|
73
|
-
- `sources`: checked out source snapshots
|
|
74
|
-
- `leafInventory`: currently discovered valid skills
|
|
75
|
-
- `deployments`: saved projections to targets
|
|
76
|
-
|
|
77
|
-
This file is not the source of user intent. It is the source of actual known
|
|
78
|
-
inventory and deployment state.
|
|
79
|
-
|
|
80
|
-
### 4. Target disk state
|
|
81
|
-
|
|
82
|
-
This is the real directory or symlink on each target root.
|
|
83
|
-
|
|
84
|
-
Planner and doctor logic compare disk state against `lock.json`.
|
|
85
|
-
|
|
86
|
-
Disk state is the final truth for whether a projection exists right now.
|
|
87
|
-
|
|
88
|
-
## Main Read/Write Flow
|
|
89
|
-
|
|
90
|
-
### Config open
|
|
91
|
-
|
|
92
|
-
When `skill-flow config` starts:
|
|
93
|
-
|
|
94
|
-
1. `getConfigData()` forces inventory reconciliation
|
|
95
|
-
2. `manifest` and `lock` are loaded
|
|
96
|
-
3. bindings are normalized into the same model the TUI uses
|
|
97
|
-
4. summaries are derived from normalized data
|
|
98
|
-
|
|
99
|
-
This makes config rendering depend on one consistent state model.
|
|
100
|
-
|
|
101
|
-
### Preview
|
|
102
|
-
|
|
103
|
-
When the user changes selection in the TUI:
|
|
104
|
-
|
|
105
|
-
1. the draft stays in memory only
|
|
106
|
-
2. `previewDraft()` loads `manifest` and `lock`
|
|
107
|
-
3. bindings are normalized first
|
|
108
|
-
4. the draft is applied to an in-memory manifest copy
|
|
109
|
-
5. a deployment plan is calculated
|
|
110
|
-
|
|
111
|
-
Preview does not write filesystem state.
|
|
112
|
-
|
|
113
|
-
### Save
|
|
114
|
-
|
|
115
|
-
When the user saves:
|
|
116
|
-
|
|
117
|
-
1. `applyDraft()` reconciles inventory for the source
|
|
118
|
-
2. `manifest` and `lock` are loaded
|
|
119
|
-
3. bindings are normalized first
|
|
120
|
-
4. the current draft is written into manifest intent
|
|
121
|
-
5. planner computes actions
|
|
122
|
-
6. applier updates target disk state and `lock.deployments`
|
|
123
|
-
7. normalized manifest and updated lock are written back
|
|
124
|
-
|
|
125
|
-
## Why State Could Look Wrong Before
|
|
126
|
-
|
|
127
|
-
The main mismatch was this:
|
|
128
|
-
|
|
129
|
-
- TUI draft model: one shared `selectedLeafIds`
|
|
130
|
-
- persisted manifest model: separate `leafIds` per target
|
|
131
|
-
|
|
132
|
-
If persisted data ever contained different `leafIds` for different enabled
|
|
133
|
-
targets, config had no exact way to represent that state.
|
|
134
|
-
|
|
135
|
-
Typical bad outcome:
|
|
136
|
-
|
|
137
|
-
1. persisted `manifest` had target A and target B enabled
|
|
138
|
-
2. target A had one skill selected
|
|
139
|
-
3. target B had another skill selected
|
|
140
|
-
4. config loaded that into one shared draft
|
|
141
|
-
5. after save or refresh, the visible state looked different from what the
|
|
142
|
-
user expected
|
|
143
|
-
|
|
144
|
-
That is not a rendering bug by itself. It is a state-model mismatch.
|
|
145
|
-
|
|
146
|
-
## Current Normalization Rule
|
|
147
|
-
|
|
148
|
-
Before config-related reads and writes, bindings are normalized per source:
|
|
149
|
-
|
|
150
|
-
1. collect all enabled targets
|
|
151
|
-
2. union all `leafIds` across those enabled targets
|
|
152
|
-
3. drop any `leafId` not present in current `lock.leafInventory`
|
|
153
|
-
4. write the same final `leafIds` back to every enabled target
|
|
154
|
-
|
|
155
|
-
So for current behavior, this:
|
|
156
|
-
|
|
157
|
-
```json
|
|
158
|
-
{
|
|
159
|
-
"claude-code": { "enabled": true, "leafIds": ["group:browse"] },
|
|
160
|
-
"codex": { "enabled": true, "leafIds": ["group:review"] }
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
is normalized to:
|
|
165
|
-
|
|
166
|
-
```json
|
|
167
|
-
{
|
|
168
|
-
"claude-code": { "enabled": true, "leafIds": ["group:browse", "group:review"] },
|
|
169
|
-
"codex": { "enabled": true, "leafIds": ["group:browse", "group:review"] }
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
This matches the only state shape the current TUI can represent.
|
|
174
|
-
|
|
175
|
-
## Relationship With Inventory Reconciliation
|
|
176
|
-
|
|
177
|
-
`reconcileInventory()` may remove stale `leafIds` from bindings when those
|
|
178
|
-
skills are no longer present in `lock.leafInventory`.
|
|
179
|
-
|
|
180
|
-
That behavior is expected and necessary.
|
|
181
|
-
|
|
182
|
-
The important part is ordering:
|
|
183
|
-
|
|
184
|
-
- reconcile inventory first
|
|
185
|
-
- normalize bindings second
|
|
186
|
-
- render or save third
|
|
187
|
-
|
|
188
|
-
Without that ordering, config can show stale selections or write back an
|
|
189
|
-
incompatible state shape.
|
|
190
|
-
|
|
191
|
-
## Current Invariant
|
|
192
|
-
|
|
193
|
-
For the current config implementation, one workflow group should satisfy this
|
|
194
|
-
invariant:
|
|
195
|
-
|
|
196
|
-
- every enabled target under the same source has the same `leafIds`
|
|
197
|
-
|
|
198
|
-
If product requirements later need per-target skill selection, the TUI state
|
|
199
|
-
model must change first. Until then, normalization is the correct behavior.
|