@klhapp/skillmux 0.4.5 → 0.6.0

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/CHANGELOG.md CHANGED
@@ -5,6 +5,53 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.6.0](https://github.com/klhq/skillmux/compare/v0.5.0...v0.6.0) (2026-07-24)
9
+
10
+
11
+ ### Added
12
+
13
+ * **cli:** add line-oriented selection prompts ([b8579a4](https://github.com/klhq/skillmux/commit/b8579a47513a722c76d8826b80ca08155f2229f6))
14
+ * **init:** add guided client and project setup ([c426502](https://github.com/klhq/skillmux/commit/c426502693755185a7d83f3c4b8c2b6b502bbb90))
15
+ * **init:** detect installed clients for setup ([0c529f3](https://github.com/klhq/skillmux/commit/0c529f310de8bc96d18ddb6b25174d375478d9fa))
16
+ * **init:** launch guided client setup in terminals ([9bd15ac](https://github.com/klhq/skillmux/commit/9bd15acfbad088732ad6d92927f0e16a2f57f44d))
17
+ * **project:** add direct project management commands ([132e8af](https://github.com/klhq/skillmux/commit/132e8af0124ee75163161df16af83dc774b773a8))
18
+ * **project:** add direct project management commands ([f36e2b3](https://github.com/klhq/skillmux/commit/f36e2b356f5f170c887734367cebb838acacc2e4))
19
+ * **project:** add project init command ([3cf8ecc](https://github.com/klhq/skillmux/commit/3cf8ecc94fb16f0f8ed807976e36935e09918a4e))
20
+ * **project:** harden project setup planning ([faff0e1](https://github.com/klhq/skillmux/commit/faff0e14a6d0a6268da3e01a33553efd9ede7d58))
21
+ * **project:** upsert project setup state ([7a92e03](https://github.com/klhq/skillmux/commit/7a92e03e281b517dff45d11eef5714d0512fd952))
22
+ * **setup:** guide machine and project choices ([2ef1010](https://github.com/klhq/skillmux/commit/2ef1010e8cb0d42b20a6f60980e7be0e28bf1e5f))
23
+ * **target:** add advanced target management commands ([bde2069](https://github.com/klhq/skillmux/commit/bde206981bcb93c0b1be317ef7f1c8d6f6ece34c))
24
+ * **target:** add advanced target management commands ([9e6a993](https://github.com/klhq/skillmux/commit/9e6a993643865b2134be05ba7306c671023f38ff))
25
+
26
+
27
+ ### Fixed
28
+
29
+ * **cli:** keep guided init interactive and legacy-safe ([f6ae405](https://github.com/klhq/skillmux/commit/f6ae40564ed26b19ac464847b455d840d78daa93))
30
+ * **project:** validate guided project inputs ([0bed954](https://github.com/klhq/skillmux/commit/0bed9543897e83860038d83620a7c3638540ca95))
31
+ * **setup:** report client target prerequisites ([62fd8b8](https://github.com/klhq/skillmux/commit/62fd8b80444a37c8bcde403be95d8224b9776b0b))
32
+
33
+ ## [0.5.0](https://github.com/klhq/skillmux/compare/v0.4.5...v0.5.0) (2026-07-24)
34
+
35
+
36
+ ### Added
37
+
38
+ * **init:** add named client registry ([e14dc26](https://github.com/klhq/skillmux/commit/e14dc261c51f7235cd7ee2223f49a0ec87668922))
39
+ * **init:** add safe client-aware setup planner ([4a199b7](https://github.com/klhq/skillmux/commit/4a199b76c52819601a5935a7e6ac478aeddce5ca))
40
+ * **init:** add shared setup bootstrap planner ([83ef8de](https://github.com/klhq/skillmux/commit/83ef8de67a1ff8a13de992e26ad5eedb4487509c))
41
+ * **init:** add transactional setup planning ([6fc6f5e](https://github.com/klhq/skillmux/commit/6fc6f5e8d991a6b411c78016f5d0659486daf4d0))
42
+ * **init:** classify and preflight skill surfaces ([b760e93](https://github.com/klhq/skillmux/commit/b760e939a66b49372642109daff6e753d9b99b8b))
43
+ * **init:** harden target setup and host scoping ([8941f59](https://github.com/klhq/skillmux/commit/8941f598b52f73fe204c0705efb2b857b2f3c658))
44
+ * **init:** manage client instruction blocks ([256c7a7](https://github.com/klhq/skillmux/commit/256c7a7f690e14a0e4ea5340536d762dab853bcc))
45
+ * **init:** preflight and commit setup atomically ([9307780](https://github.com/klhq/skillmux/commit/93077809fca4949b1384213a7d8d444cd0da88eb))
46
+ * **sync:** scope manifest targets by host ([1441dea](https://github.com/klhq/skillmux/commit/1441deac95e70df9d97b798cb514f6e7722e24eb))
47
+ * **sync:** track ownership with versioned markers ([ad415b1](https://github.com/klhq/skillmux/commit/ad415b1a5cd8cf5351e6497c42640b624048d001))
48
+
49
+
50
+ ### Fixed
51
+
52
+ * **init:** harden no-op plans and symlink checks ([137e050](https://github.com/klhq/skillmux/commit/137e05086e4f6b2d01cfdf6d5e8843f21bc1ae54))
53
+ * **init:** preserve existing setup on reinitialization ([0c1bea9](https://github.com/klhq/skillmux/commit/0c1bea92c1d600679663c853f15bcc5a246109ff))
54
+
8
55
  ## [0.4.5](https://github.com/klhq/skillmux/compare/v0.4.4...v0.4.5) (2026-07-24)
9
56
 
10
57
 
package/README.md CHANGED
@@ -186,23 +186,98 @@ bun run src/cli.ts serve
186
186
 
187
187
  Optional — skip this if `resolve_skill` alone is enough (most setups). Use it once you want a small set of skills loaded *statically* in every agent that reads from a given directory, instead of routed on demand — see [Tiers](#tiers-routed-vs-pinned).
188
188
 
189
- ### 1. Discover surfaces and adopt one
189
+ Run `skillmux init` with no arguments in a terminal for guided setup. It checks
190
+ the vault, preselects clients with concrete filesystem evidence, asks for core
191
+ skills, shows one review, and applies after one confirmation. The wizard uses
192
+ line-oriented prompts and does not take over the terminal screen.
193
+
194
+ ### 1. Check the plan
195
+
196
+ ```sh
197
+ skillmux init --client claude-code --client codex --core csv-formatter --dry-run
198
+ ```
199
+
200
+ `--client` names the tool you use. Skillmux maps it to the correct user-level
201
+ skill directory and merges clients that share one directory. Gemini CLI,
202
+ OpenCode, GitHub Copilot, and Windsurf share `~/.agents/skills`. Claude Code
203
+ uses `~/.claude/skills`; Codex uses `$CODEX_HOME/skills` or
204
+ `~/.codex/skills`.
205
+
206
+ Supported clients are `claude-code`, `codex`, `gemini-cli`, `opencode`,
207
+ `github-copilot`, `windsurf`, `antigravity`, `goose`, `hermes`, and
208
+ `skillmux-mcp`. Goose, Hermes, and Skillmux MCP report the manual registration
209
+ work they need instead of inventing a target directory.
210
+
211
+ The dry run prints target classification, config changes, instruction-file
212
+ changes, readiness, and core pins. It does not prompt or write.
213
+
214
+ ### 2. Apply the plan
215
+
216
+ ```sh
217
+ skillmux init --client claude-code --client codex --core csv-formatter --yes
218
+ ```
219
+
220
+ Skillmux writes `skillmux.toml`, adds host-scoped targets, adopts each selected
221
+ directory, and installs one managed discovery block for each client with a
222
+ known safe durable instruction file. Other clients report manual setup.
223
+ Existing manifest entries and instruction text stay intact.
224
+ Explicit flags keep the command deterministic. Without `--yes`, an interactive
225
+ terminal reviews the plan before applying; a pipe or CI job must pass `--yes`.
226
+ Use `--no-instructions` to leave instruction files untouched or `--no-sync` to
227
+ save setup for a later `skillmux sync`.
228
+
229
+ Use direct targets when you want paths rather than clients:
230
+
231
+ ```sh
232
+ skillmux init --target agent-skills --yes
233
+ skillmux init --target claude-code --yes
234
+ skillmux init --target codex --yes
235
+ skillmux init --target custom --path /srv/my-agent/skills --yes
236
+ ```
237
+
238
+ The old `agents` and `claude` target names still work and print a deprecation
239
+ warning. Skillmux keeps those names in an existing manifest.
240
+
241
+ If a target points at the whole vault, Skillmux classifies it as `full-vault`
242
+ and refuses managed-pin adoption. Review the visibility change before
243
+ converting it:
244
+
245
+ ```sh
246
+ skillmux init --client claude-code --migrate-full-vault \
247
+ --core csv-formatter --dry-run
248
+ skillmux init --client claude-code --migrate-full-vault \
249
+ --core csv-formatter --yes
250
+ ```
251
+
252
+ After conversion and `skillmux sync`, the client sees the selected core pins
253
+ instead of every vault skill.
254
+
255
+ ### 3. Set up project-scoped skills
256
+
257
+ From a project directory:
190
258
 
191
259
  ```sh
192
- skillmux init
260
+ skillmux project init
193
261
  ```
194
262
 
195
- Lists candidate surfaces (default: `~/.claude/skills`, `~/.agents/skills`) with their dir/symlink status and skill count. Nothing is written until you pass `--target`:
263
+ The guided flow detects the Git root, suggests a project-group name, asks which
264
+ configured clients should receive the group, and accepts project skill IDs.
265
+ For automation:
196
266
 
197
267
  ```sh
198
- skillmux init --target claude --yes
268
+ skillmux project init ~/code/skillmux --name skillmux \
269
+ --client claude-code --client codex \
270
+ --skill sdd-tdd --skill code-context --yes
199
271
  ```
200
272
 
201
- This writes `skillmux.toml` at the vault root and marks `~/.claude/skills` as skillmux-owned — a `.skillmux` marker file that `sync` requires before it will touch the directory.
273
+ Re-running the command adds missing paths, skills, and target attachments
274
+ without duplicating existing entries. Project setup runs `sync` unless
275
+ `--no-sync` is supplied.
202
276
 
203
- ### 2. Pick which skills are pinned
277
+ ### 4. Add or remove pins later
204
278
 
205
- `init` always starts `[core]` empty there's no heuristic yet for which skills belong there. Pin with the CLI instead of hand-editing `skillmux.toml`:
279
+ `--core` seeds only the skill IDs you name. Without it, `init` preserves
280
+ existing core pins and makes no guesses. Add another pin with:
206
281
 
207
282
  ```sh
208
283
  skillmux manifest pin csv-formatter --core
@@ -218,12 +293,13 @@ skills = ["csv-formatter"]
218
293
 
219
294
  [targets.claude]
220
295
  dir = "/Users/you/.claude/skills"
296
+ host = "workhorse" # optional; sync skips this target on every other hostname
221
297
  project_groups = []
222
298
  ```
223
299
 
224
300
  Full manifest schema, including `[project.<group>]` pins scoped to one or more local paths and machine-local overlay vaults via `local_vault_paths`, is in [`docs/configuration.md`](docs/configuration.md#tiers-and-the-manifest).
225
301
 
226
- ### 3. Materialize
302
+ ### 4. Materialize
227
303
 
228
304
  ```sh
229
305
  skillmux sync
@@ -240,7 +316,7 @@ skillmux sync --restore-monolith # undo: replace a target dir with one symlink
240
316
 
241
317
  `--restore-monolith` drops the `.skillmux` marker along with the per-skill symlinks — re-adopt with `skillmux init --target <name> --yes` before that target can be `sync`'d again.
242
318
 
243
- ### 4. See what's actually getting used
319
+ ### 5. See what's actually getting used
244
320
 
245
321
  `skillmux report` reads the same audit log `resolve_skill` writes to (see [Guarantees](#guarantees)) — useful for deciding what belongs in `[core]` versus staying routed:
246
322
 
@@ -4,6 +4,25 @@ Skillmux defaults to FTS5 plus local GTE-small semantic retrieval. Most users ne
4
4
 
5
5
  For detailed CLI command reference, target resolution, policy calibration, and automation envelopes, see [`docs/cli.md`](cli.md).
6
6
 
7
+ ## Machine config bootstrap
8
+
9
+ Create `~/.config/skillmux/config.toml` from a populated vault:
10
+
11
+ ```sh
12
+ skillmux config init --vault ~/skills --yes
13
+ ```
14
+
15
+ The command writes:
16
+
17
+ ```toml
18
+ vault_path = "/home/you/skills"
19
+ ```
20
+
21
+ It validates that the path resolves to a directory with at least one
22
+ `SKILL.md`, preserves an existing config byte-for-byte, and leaves
23
+ `local_vault_paths` unset. `skillmux init --vault ~/skills --yes` uses the
24
+ same bootstrap when the machine config does not exist.
25
+
7
26
  ## Local mode
8
27
 
9
28
  ```toml
@@ -88,17 +107,18 @@ skills = ["csv-formatter"] # pinned into every [targets.*] dir; capped
88
107
  paths = ["/Users/you/code/repo1"] # only synced for paths that exist locally
89
108
  skills = ["pdf-extractor"] # must not overlap [core]
90
109
 
91
- [targets.claude]
110
+ [targets.claude-code]
92
111
  dir = "/Users/you/.claude/skills"
112
+ host = "workhorse" # optional; init adds the current hostname
93
113
  project_groups = ["repo1"] # which [project.*] groups materialize into this target — [] means none
94
114
  ```
95
115
 
96
116
  - `[core].skills` — symlinked into every `[targets.*]` dir on `sync`. Capped at 25 skills; `sync` fails if a listed skill id isn't actually in the vault.
97
117
  - `[project.<group>].skills` — symlinked only into `<path>/<relative path from $HOME to the target dir>`, for each `paths` entry, and only for targets whose `project_groups` names that group. `paths` entries must resolve under `$HOME` (that's how the pin path is derived). A skill can't appear in both `[core]` and the same `[project.*]` group.
98
118
  - `[project.<group>].paths` can list the same project's checkout on more than one machine (e.g. `["/home/alice/code/repo1", "/Users/alice/code/repo1"]`) — `sync` silently skips any entry that doesn't exist on the machine it's running on (see below), so one shared manifest can span machines with different checkout locations without needing per-machine manifests.
99
- - `[targets.<name>]` — one entry per adopted surface. `skillmux init --target <name> --yes` writes these; hand-editing is fine as long as `sync` is still allowed to own the directory (see below). `project_groups` is an explicit list, not a boolean — a target only receives the specific groups it names, never every group in the manifest.
119
+ - `[targets.<name>]` — one entry per adopted surface. `skillmux init --target <name> --yes` writes these and scopes newly added targets to the current hostname. Hand-editing is fine as long as `sync` is still allowed to own the directory (see below). An optional `host` limits the target to an exact machine-hostname match; omit it for a global, backward-compatible target. A host mismatch is reported and skipped before any target filesystem operation. `project_groups` is an explicit list, not a boolean — a target only receives the specific groups it names, never every group in the manifest.
100
120
 
101
- **Pin/unpin without hand-editing.** `skillmux manifest pin`/`unpin` mutate `[core]`/`[project.*]` for you, validating with the same rules `sync`/`doctor` enforce (skill must resolve from `vault_path`, no duplicate pins, `[core]` stays under the 25-skill cap) before writing anything:
121
+ **Pin/unpin without hand-editing.** `skillmux manifest pin`/`unpin` mutate `[core]`/`[project.*]` for you, validating with the same rules `sync` enforces (skill must resolve from `vault_path`, no duplicate pins, `[core]` stays under the 25-skill cap) before writing anything:
102
122
 
103
123
  ```sh
104
124
  skillmux manifest pin csv-formatter --core # add to [core]
@@ -114,13 +134,31 @@ skillmux manifest unpin pdf-extractor --project repo1 # r
114
134
  >
115
135
  > **Breaking change:** `[project.<group>].repos` has been renamed to `paths` — it was never required to be a git repository, just a local directory, and the old name collided in meaning with `skillmux install <repo>`'s unrelated git-source `repo` concept. A manifest still using `repos` fails to parse with an error pointing at `paths`; migrate by renaming the key (values are unchanged).
116
136
 
117
- Every `[core]`/`[project.*]` skill_id must resolve from the canonical `vault_path` — pinning a skill that only exists in a `local_vault_paths` entry (see below) fails `sync`/`doctor` with a distinct error, since the manifest is meant to be portable across machines and a machine-local override wouldn't exist elsewhere.
137
+ Every `[core]`/`[project.*]` skill_id must resolve from the canonical `vault_path` — pinning a skill that only exists in a `local_vault_paths` entry (see below) fails `sync` with a distinct error, since the manifest is meant to be portable across machines and a machine-local override wouldn't exist elsewhere. `doctor` does not validate the manifest yet.
118
138
 
119
139
  ### Ownership marker
120
140
 
121
- Every directory `sync` manages gets a `.skillmux` marker file (`{"managed_by": "skillmux", "role": "target", "target": "<name>", "created_at": ...}`). `sync` refuses to touch a directory that exists but has no marker — run `skillmux init --target <name> --yes` first, which either creates the directory fresh or adopts an existing one in place (contents untouched). This is also why `sync --restore-monolith` (which deletes the marker and replaces the whole directory with one symlink straight to the vault) requires re-running `init` before that target can be `sync`'d again.
122
-
123
- The same `.skillmux` marker filename and JSON shape is also used for `local_vault_paths` entries (see below), distinguished by `role: "local_vault"` with a `vault_path` field instead of `target`. Markers written before this `role` field existed have no `role` key at all — they're read back as `role: "target"`, so nothing already on disk needs migrating.
141
+ Every directory `sync` manages gets a versioned `.skillmux` marker. A target
142
+ marker records `schema_version: 1`, `managed_by: "skillmux"`, `role:
143
+ "target"`, its target name, `vault_path`, `created_at`, and
144
+ `managed_entries`. The last field is the exact list of directory entries
145
+ Skillmux created. Sync removes only those tracked entries, preserves unrelated
146
+ content, and rejects a desired skill that collides with an unmanaged entry
147
+ before changing anything.
148
+
149
+ `sync` refuses to touch a directory that exists but has no marker — run
150
+ `skillmux init --target <name> --yes` first, which either creates the
151
+ directory fresh or adopts an existing one in place (contents untouched).
152
+ `sync --restore-monolith` likewise refuses a `local_vault` marker or any
153
+ unmanaged target content before replacing a target directory with a symlink
154
+ to the vault.
155
+
156
+ The same `.skillmux` filename is used for `local_vault_paths` entries (see
157
+ below), distinguished by `role: "local_vault"` and never accepted as target
158
+ ownership. Legacy unversioned markers are read for compatibility. An empty
159
+ legacy target is upgraded safely on its next sync; one containing untracked
160
+ entries is rejected with a migration diagnostic because their ownership
161
+ cannot be inferred.
124
162
 
125
163
  ### Local vault overlays
126
164
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klhapp/skillmux",
3
- "version": "0.4.5",
3
+ "version": "0.6.0",
4
4
  "description": "Local read-only MCP server routing natural-language task queries to skills in a SKILL.md vault, with zero-loss delivery",
5
5
  "type": "module",
6
6
  "private": false,