lshed 0.8.0 → 0.12.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 +35 -0
- package/README.md +62 -5
- package/dist/cli.js +251 -189
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.0 — 2026-09-04
|
|
4
|
+
|
|
5
|
+
MCP servers follow the shed into the other agents.
|
|
6
|
+
|
|
7
|
+
- `restore --agent codex|gemini|copilot|cursor` now writes the profile's MCP servers too: Codex into `config.toml` (`[mcp_servers.*]`), Gemini into `settings.json`, Copilot into `mcp-config.json`, Cursor into `mcp.json`. The shed keeps Claude Code's shape; each target gets its own (`httpUrl`, `type: local` + `tools`, `${env:VAR}`, `env_vars` / `bearer_token_env_var`).
|
|
8
|
+
- Secrets stay out of Codex and Cursor config files, which take variable names or `${env:VAR}`. Gemini and Copilot take values, filled from your shell at `restore` like settings keys.
|
|
9
|
+
- Codex's `config.toml` is edited one table at a time. Comments, ordering and unrelated tables are left untouched.
|
|
10
|
+
- `lshed init --agent gemini` (or any of the others) reads that tool's MCP servers into the shed, masked the same way as Claude Code's. `diff` and `save` work across the translation.
|
|
11
|
+
|
|
12
|
+
— 2026-09-04
|
|
13
|
+
|
|
14
|
+
One shed, several agents.
|
|
15
|
+
|
|
16
|
+
- `--agent codex|gemini|copilot|cursor|agents` restores the same shed into another tool's config root. They all read `skills/<name>/SKILL.md` the way Claude Code does, and `~/.agents/skills/` is the shared location every one of them also reads. Codex gets `AGENTS.md`, Gemini `GEMINI.md`, Copilot `copilot-instructions.md`, each with the profile's instruction fragments concatenated; Cursor and `~/.agents` have no user-level instructions file and skip that category.
|
|
17
|
+
- Parts the target does not understand are announced and skipped instead of failing: MCP servers, settings keys and Claude Code agents/commands stay Claude-only, and Claude plugin packages are not installed elsewhere. Each agent root keeps its own state, profile and `--link` choice.
|
|
18
|
+
- `lshed init --agent codex` builds a shed from a Codex machine; a shed made by one agent restores into any other. The shed's `agent:` field is now only the default for `--agent`; `$LSHED_AGENT` also works.
|
|
19
|
+
- `lshed status` names the agent next to the root.
|
|
20
|
+
|
|
21
|
+
— 2026-09-04
|
|
22
|
+
|
|
23
|
+
Link instead of copy, on the machines where you edit.
|
|
24
|
+
|
|
25
|
+
- `lshed restore --link` places skills, agents, commands and instruction fragments as links into the shed. Edits in `~/.claude` land in the shed directly; `diff` and `save` have nothing to do and `lshed sync` is the whole loop. MCP entries, settings keys and the generated `CLAUDE.md` are still written as before.
|
|
26
|
+
- The choice is per machine and remembered in `state.json`: later bare `lshed restore` calls keep linking, `lshed status` shows `배치 link`, and `restore --no-link` goes back to copies. Other machines keep copying.
|
|
27
|
+
- Turning a copy into a link backs the copy up only if it differs from the shed (an unsaved edit); turning a link back into a copy backs up nothing. Switching profiles removes the links and never touches the shed behind them.
|
|
28
|
+
- Windows: directories become junctions and need no permission. Single-file parts need Developer Mode for a link; without it the file is copied, the log says so, and it behaves like any other copy.
|
|
29
|
+
|
|
30
|
+
— 2026-09-04
|
|
31
|
+
|
|
32
|
+
Profiles can build on each other.
|
|
33
|
+
|
|
34
|
+
- `extends: default` (or `extends: [a, b]`) inside a profile pulls in everything the parent lists, then adds the profile's own parts. The parent's parts come first and duplicates appear once, so instructions fragments keep a predictable order in `CLAUDE.md`. Inheritance only adds; for less than the parent, list what you want instead of extending.
|
|
35
|
+
- A parent that does not exist, or profiles that extend each other in a cycle, is a `lshed.yaml` error reported before anything is touched.
|
|
36
|
+
- Everything that reads a profile sees the resolved one: `restore`, package installs, `lshed list` (a part counts as used by profiles that inherit it), the `add` hint, and `restore <profile> --pick` (inherited parts start checked).
|
|
37
|
+
|
|
3
38
|
## 0.8.0 — 2026-09-04
|
|
4
39
|
|
|
5
40
|
Pick what a machine gets instead of writing a profile by hand.
|
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ lshed exists for those five cases. It keeps the shed as a plain directory in git
|
|
|
39
39
|
| **Profiles** | named recipes — `research`, `work`, `minimal` — that pick a subset of parts; write them in `lshed.yaml`, or let `restore --pick` build one from a checklist |
|
|
40
40
|
| **Managed set** | lshed remembers what it placed, so switching profiles or restoring onto an existing machine removes only its own files and never touches yours |
|
|
41
41
|
|
|
42
|
-
The trade: you edit in `~/.claude` and run `lshed save` to copy changes into the shed, and lshed has to know Claude Code's layout, which the plain repository does not. If none of the five cases applies to you, the `.gitignore` wins.
|
|
42
|
+
The trade: you edit in `~/.claude` and run `lshed save` to copy changes into the shed (or use `restore --link` on machines where you edit a lot, and skip the copy step), and lshed has to know Claude Code's layout, which the plain repository does not. If none of the five cases applies to you, the `.gitignore` wins.
|
|
43
43
|
|
|
44
44
|
Currently supports **Claude Code** (`~/.claude`). Other agents plug in through an adapter.
|
|
45
45
|
|
|
@@ -245,6 +245,63 @@ Switching removes only what the previous profile placed (`-`), keeps what both u
|
|
|
245
245
|
|
|
246
246
|
Instructions fragments are ordered. `restore` writes a `CLAUDE.md` that `@`-imports each fragment, so editing a fragment in the shed shows up on the next `restore` and there is nothing to merge.
|
|
247
247
|
|
|
248
|
+
### Other agents, same shed
|
|
249
|
+
|
|
250
|
+
Codex, Gemini CLI, Copilot CLI and Cursor all read skills from `<their config dir>/skills/<name>/SKILL.md`, the same layout Claude Code uses, and all of them also read the shared `~/.agents/skills/`. So one shed can serve them all. Pick the target with `--agent`:
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
lshed restore --agent agents # ~/.agents/skills: every tool that follows the convention reads it
|
|
254
|
+
lshed restore --agent codex # ~/.codex/skills + ~/.codex/AGENTS.md
|
|
255
|
+
lshed restore --agent gemini --link # ~/.gemini/skills + ~/.gemini/GEMINI.md, as links
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
| `--agent` | root | skills | instructions file | MCP servers |
|
|
259
|
+
|---|---|---|---|---|
|
|
260
|
+
| `claude-code` (default) | `~/.claude` or `$CLAUDE_CONFIG_DIR` | yes, plus agents, commands, settings | `CLAUDE.md`, `@`-imports fragments | `~/.claude.json` |
|
|
261
|
+
| `codex` | `~/.codex` or `$CODEX_HOME` | yes | `AGENTS.md`, fragments concatenated | `config.toml` `[mcp_servers.*]` |
|
|
262
|
+
| `gemini` | `~/.gemini` | yes | `GEMINI.md`, concatenated | `settings.json` |
|
|
263
|
+
| `copilot` | `~/.copilot` or `$COPILOT_HOME` | yes | `copilot-instructions.md`, concatenated | `mcp-config.json` |
|
|
264
|
+
| `cursor` | `~/.cursor` | yes | none (Cursor's user rules live in its settings UI) | `mcp.json` |
|
|
265
|
+
| `agents` | `~/.agents` | yes | none | none |
|
|
266
|
+
|
|
267
|
+
MCP entries are stored in the shed in Claude Code's shape and translated on the way out: Gemini gets `httpUrl` and no `type`, Copilot gets `type: local` and `tools: ["*"]`, Cursor gets `${env:VAR}` placeholders and Codex gets `env_vars` / `bearer_token_env_var` / `env_http_headers` with the variable *names*, so for those two the secret values never touch the config file. Gemini and Copilot do not expand placeholders, so lshed fills them from your shell at `restore`. Codex's `config.toml` is edited table by table; your comments and other settings stay as they are. `lshed init --agent gemini` reads the same files back into the shed shape, secrets masked.
|
|
268
|
+
|
|
269
|
+
Each agent root keeps its own `lshed/state.json`, so restoring into `~/.codex` never touches what lshed placed in `~/.claude`, and each can use a different profile or `--link` choice. Parts the target does not understand are announced and skipped: a profile with settings keys restores into Codex without them, with a line saying `codex 은 settings 를 다루지 않아 건너뜁니다`. Claude plugin packages are skipped the same way; `github:`/`git:` packages are cloned into every agent root that restores the profile, so give the other agents a profile without them if that is not what you want. `lshed init --agent codex` works too, and a shed made from Codex restores into Claude Code with `CLAUDE.md` generated from the same fragments. The shed's `agent:` is only a default for `--agent` (`$LSHED_AGENT` also works).
|
|
270
|
+
|
|
271
|
+
### Links instead of copies
|
|
272
|
+
|
|
273
|
+
On the machine where you do most of your editing, `restore --link` places skills, agents, commands and instruction fragments as links into the shed instead of copies. Edits in `~/.claude` land in the shed directly, `diff` has nothing to report, and `save` has nothing to do; `lshed sync` is the whole loop.
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
$ lshed restore --link
|
|
277
|
+
~ skills/add-drivers (link)
|
|
278
|
+
~ agents/reviewer.md (link)
|
|
279
|
+
~ lshed/instructions/main.md (link)
|
|
280
|
+
= CLAUDE.md
|
|
281
|
+
|
|
282
|
+
프로필 "default" 적용 (link): 배치 4, 제거 0
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The choice is per machine and remembered: later `lshed restore` calls on that machine keep linking, `lshed status` shows `배치 link`, and `restore --no-link` goes back to copies. Other machines are not affected. MCP entries and settings keys are JSON values, not files, so they are always written. Switching profiles removes the links, never the shed behind them. On Windows, directories become junctions with no special permission; single-file parts (agents, commands, fragments) need Developer Mode for a link, and without it lshed copies the file, says so, and treats it like any other copy (`save` still works for it).
|
|
286
|
+
|
|
287
|
+
A profile can build on another one with `extends`, so a machine-specific profile lists only what is different:
|
|
288
|
+
|
|
289
|
+
```yaml
|
|
290
|
+
profiles:
|
|
291
|
+
default:
|
|
292
|
+
skills: [add-drivers, domain-modeling]
|
|
293
|
+
instructions: [main]
|
|
294
|
+
laptop:
|
|
295
|
+
extends: default # everything in default, plus:
|
|
296
|
+
packages: [gstack]
|
|
297
|
+
mcp: [notion]
|
|
298
|
+
lab:
|
|
299
|
+
extends: [default] # a list works too, applied in order
|
|
300
|
+
instructions: [lab-rules] # comes after default's `main`
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Inheritance only adds. The parent's parts come first, then the profile's own, and instructions keep that order in the generated `CLAUDE.md`. To get *less* than the parent, do not extend it; list what you want. A missing parent or a cycle is reported as a `lshed.yaml` error before anything is touched, and `lshed list` counts a part as used by every profile that inherits it.
|
|
304
|
+
|
|
248
305
|
### Adding things later
|
|
249
306
|
|
|
250
307
|
Write a new skill, add an MCP server with `claude mcp add`, clone a toolkit into `~/.claude/skills/`. Then:
|
|
@@ -410,7 +467,7 @@ $ lshed add
|
|
|
410
467
|
```
|
|
411
468
|
lshed init [--shed <dir>] [--profile <name>] [--exclude <id...>]
|
|
412
469
|
lshed add [keys...] [--all] put things that appeared since init into the shed
|
|
413
|
-
lshed restore [profile] [--pick] [--dry-run] [--no-backup] [--yes]
|
|
470
|
+
lshed restore [profile] [--pick] [--link | --no-link] [--dry-run] [--no-backup] [--yes] (--agent <name> to target another tool)
|
|
414
471
|
lshed status applied profile, drift, packages, missing env, new things
|
|
415
472
|
lshed diff files (or JSON keys) that differ between local and shed
|
|
416
473
|
lshed save [ids...] copy local edits back into the shed
|
|
@@ -423,13 +480,13 @@ lshed prune [--yes] drop everything no profile uses
|
|
|
423
480
|
|
|
424
481
|
Keys are `category/id`, or just `id` when unambiguous: `skills/paper-review`, `mcp/exa`, `packages/gstack`.
|
|
425
482
|
|
|
426
|
-
Global options: `--shed <dir>` (or `LSHED_HOME`; after the first restore lshed remembers it), `--root <dir>` (agent config root, default `~/.claude` or `
|
|
483
|
+
Global options: `--shed <dir>` (or `LSHED_HOME`; after the first restore lshed remembers it), `--agent <name>` (or `LSHED_AGENT`; default is the shed's `agent:`, then `claude-code`), `--root <dir>` (agent config root, default is the agent's own, e.g. `~/.claude` or `~/.codex`).
|
|
427
484
|
|
|
428
485
|
### What `restore` does
|
|
429
486
|
|
|
430
487
|
0. Installs any package in the profile that is missing, at the version in `lshed.lock`.
|
|
431
488
|
1. Removes paths that the **previous** profile placed and the new one doesn't need.
|
|
432
|
-
2. Copies every part of the new profile into place; writes MCP entries into `~/.claude.json` and settings keys into `settings.json`.
|
|
489
|
+
2. Copies every part of the new profile into place (or links it into the shed, with `--link` or on a machine that used it before); writes MCP entries into `~/.claude.json` and settings keys into `settings.json`.
|
|
433
490
|
3. Regenerates the instructions file.
|
|
434
491
|
|
|
435
492
|
Anything it overwrites or removes is backed up first under `~/.claude/lshed/backups/<timestamp>/`, unless you pass `--no-backup`. Files lshed never placed are left alone. `--dry-run` prints the plan and writes nothing.
|
|
@@ -447,7 +504,7 @@ On a conflict it aborts the rebase, leaves the shed clean with your commit intac
|
|
|
447
504
|
|
|
448
505
|
### Ownership
|
|
449
506
|
|
|
450
|
-
The shed is the source of truth for authored parts: `save` copies local edits back for `file:` components. Packages are owned by their upstream: `update` pulls them, `save` ignores them.
|
|
507
|
+
The shed is the source of truth for authored parts: `save` copies local edits back for `file:` components, and a linked part is the shed. Packages are owned by their upstream: `update` pulls them, `save` ignores them.
|
|
451
508
|
|
|
452
509
|
## Where things live
|
|
453
510
|
|