lshed 0.16.1 → 0.17.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
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.0 — 2026-09-09
4
+
5
+ - A Codex, Gemini, Copilot, Cursor or Antigravity user who followed the quick start without `--agent` got two quiet failures: `init` scanned a `~/.claude` that did not exist and wrote a shed with zero parts, and after `restore --agent codex` on another machine, `status`, `diff` and `save` without flags looked at `~/.claude` again and reported nothing applied. Now `init` refuses to scan a root that is not there and names the agent folders it did find (`Found here: codex (~/.codex). Try: lshed init --agent codex`), and when neither `--agent`, `LSHED_AGENT` nor a shed says which agent, lshed uses the one agent on the machine that has lshed state; Claude Code keeps precedence when it has state, and with several candidates the command asks you to say which. The README's quick start and loop are written for any agent, and the smoke suite walks them on a home folder that has only `~/.codex`.
6
+ - New `lshed check`: the failure that makes no noise is an agent that does not read what lshed placed, and until now only the developer's `scripts/vm/probe.sh` could tell. `check` puts a throwaway skill holding a random passphrase into the agent's skills folder, asks the agent's own CLI for it non-interactively (the same invocations the probe verified: `claude -p`, `codex exec --ephemeral`, `gemini -p --output-format json`, `copilot -p -s`, `agent -p`, `agy -p`), and removes the skill again, whatever happens. ✔ means location and format are right; ✘ prints every answer the agent gave and the end of its stderr, which is what a bug report needs. `--agent agents` asks every installed CLI. It refuses to touch an existing `lshed-check` skill, runs the CLI from an empty temporary directory so no project config interferes, and costs one or two small model calls.
7
+ - `lshed --help` ends with two lines pointing at `check` and `report`, and `restore` adds one line, `If any of the above is not what you expected: lshed report`, only when it printed a notice (a skipped category or package, a copy instead of a link, an install it did not run, a variable that is not set). A clean restore prints nothing extra.
8
+
3
9
  ## 0.16.1 — 2026-09-09
4
10
 
5
11
  - `lshed report --open` on Windows went through `cmd /c start`, which cuts the URL at its first `&` and expands `%…%` sequences, so the issue form would have opened without the summary. It now hands PowerShell an encoded command, which parses nothing. On Linux without `xdg-open` (WSL, most servers) `wslview` is tried next, and `lshed report --url` prints the prefilled link for a machine with no browser at all. On Windows the report also hides the profile folder when a path spells it with an 8.3 short name (`C:\Users\RUNNER~1\…` for `runneradmin`, which is how `TEMP` usually reads), by treating any `<drive>:\Users\<name>` on the home drive as `~`. The smoke suite, which CI runs on Ubuntu, macOS and Windows, now runs `report` and checks that no user directory appears in its output in any spelling.
package/README.ko.md CHANGED
@@ -63,9 +63,11 @@ macOS와 Linux에서는 먼저 `chmod +x`가 필요합니다. 서명하지 않
63
63
 
64
64
  ## 빠른 시작
65
65
 
66
+ 지원하는 어느 에이전트든 같은 절차입니다. `--agent` 로 도구를 고르고, 없으면 Claude Code 로 봅니다. 그 도구의 폴더가 기기에 없으면 `init` 은 빈 창고를 만드는 대신 어떤 도구를 찾았는지 알려 줍니다. 창고가 에이전트를 기억하므로 나머지 명령에는 플래그가 필요 없습니다.
67
+
66
68
  ```bash
67
69
  # 1. 이미 설정이 있는 기기에서
68
- lshed init --shed ~/lshed
70
+ lshed init --shed ~/lshed # Claude Code 기준. 다른 도구는 --agent codex|gemini|copilot|cursor|agy
69
71
  cd ~/lshed && git init && git remote add origin <비공개 저장소>
70
72
  lshed sync # commit + push
71
73
 
@@ -73,13 +75,16 @@ lshed sync # commit + push
73
75
 
74
76
  # 3. 다른 기기에서
75
77
  git clone <비공개 저장소> ~/lshed
76
- lshed restore research --shed ~/lshed # --shed 는 처음 한 번만
78
+ lshed restore default --shed ~/lshed # 또는 2 에서 만든 프로필. --shed 는 처음 한 번만
77
79
  lshed restore --pick --shed ~/lshed # 또는 카테고리별로 이 기기에 둘 것을 체크
80
+ lshed check # 선택: 놓인 것을 에이전트가 읽는지 물어본다
78
81
  ```
79
82
 
83
+ 다른 기기가 다른 에이전트를 쓰면 거기서 `restore` 에 `--agent` 를 붙이세요. 스킬·지침 파일·MCP 서버는 그대로 옮겨지고 나머지는 알리고 건너뜁니다([자세히](#다른-에이전트도-같은-창고로)).
84
+
80
85
  ## 사용법
81
86
 
82
- ### 첫날: 가진 것을 창고에 담기
87
+ ### 초기화: 가진 것을 창고에 담기
83
88
 
84
89
  ```
85
90
  $ lshed init --shed ~/lshed --exclude _gstack-command connect-chrome
@@ -98,7 +103,7 @@ scan: /home/me/.claude → shed: /home/me/lshed
98
103
  lshed.yaml written: /home/me/lshed/lshed.yaml (4 parts, 3 packages, 53 generated skipped, 2 excluded, profile "default")
99
104
  ```
100
105
 
101
- `init`은 에이전트 루트를 읽기만 하고, 쓰는 곳은 창고와 `~/.claude/lshed/`뿐입니다. 발견한 것을 [세 종류](#세-종류의-것)로 나눕니다. 직접 만든 것은 복사(`+`), 설치한 것은 출처와 버전만 적은 패키지(`≡`), 설치기가 만든 파일은 건너뜀(`·`)입니다. 설치기가 심볼릭 링크 없이 만든 별칭은 직접 만든 것처럼 보이므로 `--exclude`로 빼세요. 그 선택은 매니페스트의 `exclude:`에 남습니다.
106
+ `init`은 에이전트 루트(여기서는 `~/.claude`, `--agent` 를 주면 `~/.codex`, `~/.gemini` 등)를 읽기만 하고, 쓰는 곳은 창고와 `<루트>/lshed/`뿐입니다. 발견한 것을 [세 종류](#세-종류의-것)로 나눕니다. 직접 만든 것은 복사(`+`), 설치한 것은 출처와 버전만 적은 패키지(`≡`), 설치기가 만든 파일은 건너뜀(`·`)입니다. 설치기가 심볼릭 링크 없이 만든 별칭은 직접 만든 것처럼 보이므로 `--exclude`로 빼세요. 그 선택은 매니페스트의 `exclude:`에 남습니다.
102
107
 
103
108
  그다음 `lshed.yaml`을 여세요. 전부를 담은 `default` 프로필 하나가 있습니다. clone 뒤 설치 단계가 필요한 git 패키지에는 `install:`을 적고, 창고를 git 저장소로 만듭니다.
104
109
 
@@ -107,18 +112,18 @@ cd ~/lshed && git init && git remote add origin git@github.com:me/harness.git
107
112
  lshed sync
108
113
  ```
109
114
 
110
- ### 매일: 편집, 저장, 동기화
115
+ ### 반복: 편집, 저장, 동기화
111
116
 
112
- 스킬은 에이전트가 읽는 자리인 `~/.claude`에서 편집합니다. 창고는 저절로 바뀌지 않습니다.
117
+ 스킬은 에이전트가 읽는 자리, 곧 그 도구의 폴더(`~/.claude`, `~/.codex`, `~/.gemini` 등)에서 편집합니다. 창고는 저절로 바뀌지 않습니다.
113
118
 
114
119
  ```
115
120
  lshed status # 적용된 프로필, 드리프트, 새로 생긴 것
116
- lshed diff # ~/.claude 와 창고의 파일 차이
121
+ lshed diff # 에이전트 폴더와 창고의 파일 차이
117
122
  lshed save # 로컬 편집을 창고로 (또는: lshed save skills/add-drivers)
118
123
  lshed sync # 창고 커밋, pull, push
119
124
  ```
120
125
 
121
- `~/.claude`에서 창고로 가는 길은 `save`뿐이고, 창고가 소유한 부품(`file:` 출처)에만 동작합니다. `sync`는 저장하지 않은 편집이 있으면 경고해서, 기기보다 뒤처진 창고를 push하지 않게 합니다.
126
+ 이 명령들에는 `--agent` 가 필요 없습니다. lshed 상태가 있는 에이전트가 하나뿐인 기기에서는 그것을 찾고, 여럿이면 어느 것인지 물어봅니다. 에이전트 폴더에서 창고로 가는 길은 `save`뿐이고, 창고가 소유한 부품(`file:` 출처)에만 동작합니다. `sync`는 저장하지 않은 편집이 있으면 경고해서, 기기보다 뒤처진 창고를 push하지 않게 합니다.
122
127
 
123
128
  ### 이미 설정이 있는 기기
124
129
 
@@ -474,6 +479,7 @@ lshed list [--unused] 창고의 내용과 그것을
474
479
  lshed remove <key> 창고에서 부품이나 패키지 삭제
475
480
  lshed prune [--yes] 어느 프로필도 안 쓰는 것 전부 삭제
476
481
  lshed scan 루트를 읽기만 하고 나열
482
+ lshed check [--attempts <n>] [--timeout <s>] 방금 놓은 스킬을 에이전트 CLI 가 읽는지 물어본다 (작은 모델 호출 한두 번)
477
483
  lshed report [--open | --url] 이슈에 붙여 넣을 이 설정의 요약, --open 은 GitHub 이슈 폼에 채워서 열고 --url 은 그 링크만 찍는다
478
484
  ```
479
485
 
@@ -535,7 +541,7 @@ lshed report [--open | --url] 이슈에 붙여 넣을 이 설
535
541
  - 개발하는 Linux 기기에서는 CI 너머까지 전체 명령을 돌려 봅니다. `install:`이 있는 git·GitHub 패키지의 `restore`와 `update`, 충돌까지 포함한 실제 원격과의 `sync`, `remove`/`prune`, 모든 `--agent` 대상, 환경변수 기본값, 실제 터미널을 거친 `restore --pick`, 컴파일된 Linux 바이너리까지입니다.
536
542
  - 다른 에이전트는 문서만이 아니라 도구 자체로 확인합니다. `scripts/vm/probe.sh`는 임시 창고를 도구의 실제 루트에 복원한 뒤, 스킬에 든 암호어, 지침 파일에 든 코드워드, `--link` 링크를 거친 같은 스킬을 비대화형으로 물어봅니다. Codex 0.153.4와 Antigravity CLI 1.1.27은 모든 검사를 통과했고(마지막 실행 2026-09-09, lshed 0.15.5), Gemini CLI·Copilot CLI·Cursor는 아직 파일 배치와 형식까지만 확인했습니다. 자세한 내용과 새 VM에서 전부 돌리는 cloud-init 파일은 `scripts/vm/README.md`에 있습니다.
537
543
  - 개발하는 기기에서는 실제 창고 하나를 매일 씁니다. Claude Code, Codex, Antigravity가 모두 `--link`로 그 창고를 읽고, 셋 다 `status`에 드리프트가 없습니다.
538
- - 위는 전부 한 사람의 기기입니다. 여기 없는 도구 버전이나 OS 에서 lshed 가 잘 돌았다면 [검증 보고](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=verified.yml)를 남겨 주세요. 2분이면 되고, 이 절의 한 줄이 됩니다. 안 돌았다면 `lshed report` 가 [버그 보고](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=bug.yml)에 필요한 것을 찍어 줍니다. 버전, 에이전트와 루트, 적용 프로필, 창고에 든 것의 이름까지이고 값이나 시크릿은 없으며 홈 디렉터리는 `~` 로 나옵니다. 명령이 실패한 직후에는 그 요약을 채운 폼을 열지 물어봅니다. lshed 가 스스로 보내는 것은 없고, `LSHED_REPORT=0` 이면 묻지 않습니다.
544
+ - 위는 전부 한 사람의 기기입니다. 여기 없는 도구 버전이나 OS 에서 lshed 가 잘 돌았다면 [검증 보고](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=verified.yml)를 남겨 주세요. 2분이면 되고, 이 절의 한 줄이 됩니다. 안 돌았다면 `lshed report` 가 [버그 보고](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=bug.yml)에 필요한 것을 찍어 줍니다. 버전, 에이전트와 루트, 적용 프로필, 창고에 든 것의 이름까지이고 값이나 시크릿은 없으며 홈 디렉터리는 `~` 로 나옵니다. 명령이 실패한 직후에는 그 요약을 채운 폼을 열지 물어봅니다. lshed 가 스스로 보내는 것은 없고, `LSHED_REPORT=0` 이면 묻지 않습니다. 소리 없이 실패하는 경우, 즉 에이전트가 놓인 것을 그냥 안 읽는 경우는 `lshed check` 가 에이전트에게 직접 물어봅니다.
539
545
 
540
546
  ## 아직 범위 밖
541
547
 
@@ -545,6 +551,7 @@ lshed report [--open | --url] 이슈에 붙여 넣을 이 설
545
551
 
546
552
  ## 문제 해결
547
553
 
554
+ - **restore 는 다 놓았다는데 에이전트가 못 본다** — `lshed check`. 임의 암호어가 든 임시 스킬을 에이전트의 스킬 폴더에 놓고, 사용자가 하듯 그 CLI 에 비대화형으로 암호어를 물은 뒤(`claude -p`, `codex exec`, `gemini -p`, `copilot -p`, `agent -p`, `agy -p`) 스킬을 치웁니다. ✔ 면 위치와 형식은 맞고 문제는 다른 데 있는 것이고, ✘ 면 에이전트의 실제 답이 찍히는데 그것이 버그 보고에 딱 필요한 것입니다. 작은 모델 호출 한두 번이 들고, 그 CLI 가 이 기기에 있어야 합니다.
548
555
  - **다른 문제가 생겼다** — `lshed report` 가 버그 보고에 필요한 요약을 찍습니다(비밀은 없지만 직접 확인하세요). `lshed report --open` 은 그것을 새 이슈 폼에 채워 엽니다(브라우저가 없는 기기에서는 `--url` 이 링크만 찍습니다). 명령이 실패한 직후에도 같은 것을 묻는데, 아니오라고 하거나 `LSHED_REPORT=0` 을 두면 아무 일도 없습니다.
549
556
  - **"Shed location unknown. Pass --shed <dir> or set LSHED_HOME."** (창고 위치를 모름) — `--shed <dir>`를 주거나 `LSHED_HOME`을 설정하세요. `restore`가 한 번 성공하면 기억합니다.
550
557
  - **restore가 내 `CLAUDE.md`를 바꿨다** — `~/.claude/lshed/backups/<시각>/CLAUDE.md`에 있습니다. 내용을 창고의 조각으로 옮기고 그 조각을 프로필에 넣으세요.
package/README.md CHANGED
@@ -63,9 +63,11 @@ On macOS and Linux, `chmod +x` it first. The binaries are unsigned, so macOS war
63
63
 
64
64
  ## Quick start
65
65
 
66
+ Works the same for every supported agent. `--agent` names the tool; without it lshed assumes Claude Code, and if that tool's folder is not on the machine `init` says which ones it found instead of writing an empty shed. The shed remembers the agent, so the other commands do not need the flag.
67
+
66
68
  ```bash
67
69
  # 1. On the machine that already has your setup
68
- lshed init --shed ~/lshed
70
+ lshed init --shed ~/lshed # Claude Code; for another tool: --agent codex|gemini|copilot|cursor|agy
69
71
  cd ~/lshed && git init && git remote add origin <your private repo>
70
72
  lshed sync # commit + push
71
73
 
@@ -73,13 +75,16 @@ lshed sync # commit + push
73
75
 
74
76
  # 3. On any other machine
75
77
  git clone <your private repo> ~/lshed
76
- lshed restore research --shed ~/lshed # --shed only needed the first time
78
+ lshed restore default --shed ~/lshed # or a profile you added in step 2; --shed only the first time
77
79
  lshed restore --pick --shed ~/lshed # or tick what this machine gets, category by category
80
+ lshed check # optional: ask the agent whether it reads what was placed
78
81
  ```
79
82
 
83
+ If the other machine runs a different agent, add `--agent` to `restore` there; skills, the instructions file and MCP servers carry over, the rest is announced and skipped ([details](#other-agents-same-shed)).
84
+
80
85
  ## How to use it
81
86
 
82
- ### Day one: put what you have into a shed
87
+ ### Setup: put what you have into a shed
83
88
 
84
89
  ```
85
90
  $ lshed init --shed ~/lshed --exclude _gstack-command connect-chrome
@@ -98,7 +103,7 @@ scan: /home/me/.claude → shed: /home/me/lshed
98
103
  lshed.yaml written: /home/me/lshed/lshed.yaml (4 parts, 3 packages, 53 generated skipped, 2 excluded, profile "default")
99
104
  ```
100
105
 
101
- `init` reads your agent root and writes only to the shed and `~/.claude/lshed/`. It sorts everything into [three kinds](#three-kinds-of-things): authored parts are copied (`+`), things you installed become packages recorded by source and version (`≡`), and files an installer generated are skipped (`·`). Aliases an installer created without symlinks look authored; leave them out with `--exclude`, and lshed remembers that under `exclude:` in the manifest.
106
+ `init` reads your agent root (`~/.claude` here; `~/.codex`, `~/.gemini`, … with `--agent`) and writes only to the shed and `<root>/lshed/`. It sorts everything into [three kinds](#three-kinds-of-things): authored parts are copied (`+`), things you installed become packages recorded by source and version (`≡`), and files an installer generated are skipped (`·`). Aliases an installer created without symlinks look authored; leave them out with `--exclude`, and lshed remembers that under `exclude:` in the manifest.
102
107
 
103
108
  Then open `lshed.yaml`. It has one profile, `default`, listing everything. Fill in `install:` for git packages that need a post-clone step, and make it a git repo:
104
109
 
@@ -107,18 +112,18 @@ cd ~/lshed && git init && git remote add origin git@github.com:me/harness.git
107
112
  lshed sync
108
113
  ```
109
114
 
110
- ### Every day: edit, save, sync
115
+ ### The loop: edit, save, sync
111
116
 
112
- You edit skills where the agent reads them, in `~/.claude`. The shed does not change by itself.
117
+ You edit skills where the agent reads them, in its own folder (`~/.claude`, `~/.codex`, `~/.gemini`, …). The shed does not change by itself.
113
118
 
114
119
  ```
115
120
  lshed status # what profile is applied, what drifted, what is new
116
- lshed diff # file-level differences between ~/.claude and the shed
121
+ lshed diff # file-level differences between the agent folder and the shed
117
122
  lshed save # copy local edits into the shed (or: lshed save skills/add-drivers)
118
123
  lshed sync # commit the shed, pull, push
119
124
  ```
120
125
 
121
- `save` is the only path from `~/.claude` to the shed, and it only works for parts the shed owns (`file:` sources). `sync` warns if you have unsaved edits so you do not push a shed that is behind your machine.
126
+ None of these need `--agent`: on a machine where only one agent has lshed state, they find it; where several do, they ask you to say which. `save` is the only path from the agent folder to the shed, and it only works for parts the shed owns (`file:` sources). `sync` warns if you have unsaved edits so you do not push a shed that is behind your machine.
122
127
 
123
128
  ### A machine that already has a setup
124
129
 
@@ -474,6 +479,7 @@ lshed list [--unused] what is in the shed, and which p
474
479
  lshed remove <key> drop a component or package from the shed
475
480
  lshed prune [--yes] drop everything no profile uses
476
481
  lshed scan list what the agent root holds, without writing anything
482
+ lshed check [--attempts <n>] [--timeout <s>] ask the agent's CLI whether it reads a skill lshed just placed (one or two small model calls)
477
483
  lshed report [--open | --url] summary of this setup to paste into an issue; --open prefills one on GitHub, --url prints that link
478
484
  ```
479
485
 
@@ -535,7 +541,7 @@ The shed is the source of truth for authored parts: `save` copies local edits ba
535
541
  - On the Linux development machine the whole command set is exercised beyond CI: git and GitHub packages with `install:` through `restore` and `update`, `sync` against a real remote including a conflict, `remove`/`prune`, every `--agent` target, the environment-variable defaults, `restore --pick` through a real terminal, and the compiled Linux binary.
536
542
  - The other agents are checked against the tools themselves, not just their docs. `scripts/vm/probe.sh` restores a throwaway shed into a tool's real root and asks the tool, non-interactively, for a passphrase kept in a skill, a codeword kept in the instructions file, and the same skill again through a `--link` symlink. Codex 0.153.4 and Antigravity CLI 1.1.27 pass every check (last run 2026-09-09 with lshed 0.15.5); Gemini CLI, Copilot CLI and Cursor are verified for file placement and format so far. `scripts/vm/README.md` has the details and a cloud-init file for running the whole thing on a fresh VM.
537
543
  - One real shed is in daily use on the machine this is developed on: Claude Code, Codex and Antigravity all read it through `--link`, and `status` reports no drift for any of the three.
538
- - Everything above is one person's machines. If lshed works for you on a tool version or an OS not listed here, a [verification report](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=verified.yml) takes two minutes and becomes a line in this section. If it does not work, `lshed report` prints what a [bug report](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=bug.yml) needs: versions, the agent and its root, the applied profile and the names of what the shed holds. No values, no secrets, and your home directory shows as `~`. After a failed command lshed asks whether to open that form with the summary filled in; it never sends anything by itself, and `LSHED_REPORT=0` turns the question off.
544
+ - Everything above is one person's machines. If lshed works for you on a tool version or an OS not listed here, a [verification report](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=verified.yml) takes two minutes and becomes a line in this section. If it does not work, `lshed report` prints what a [bug report](https://github.com/LeeSongHeon-LSH/lshed/issues/new?template=bug.yml) needs: versions, the agent and its root, the applied profile and the names of what the shed holds. No values, no secrets, and your home directory shows as `~`. After a failed command lshed asks whether to open that form with the summary filled in; it never sends anything by itself, and `LSHED_REPORT=0` turns the question off. For the failure that makes no noise, an agent that simply does not read what was placed, `lshed check` asks the agent itself.
539
545
 
540
546
  ## Not in scope (yet)
541
547
 
@@ -545,6 +551,7 @@ The shed is the source of truth for authored parts: `save` copies local edits ba
545
551
 
546
552
  ## Troubleshooting
547
553
 
554
+ - **restore said everything is in place, but the agent does not see it** — `lshed check`. It puts a throwaway skill holding a random passphrase into the agent's skills folder, asks the agent's CLI for the passphrase the way a user would (`claude -p`, `codex exec`, `gemini -p`, `copilot -p`, `agent -p`, `agy -p`), and removes the skill. A ✔ means the location and format are right and the problem is elsewhere; a ✘ shows the agent's actual answer and is exactly what a bug report needs. It costs one or two small model calls and needs that CLI on this machine.
548
555
  - **Something else went wrong** — `lshed report` prints the summary a bug report needs (nothing secret; check it yourself), `lshed report --open` puts it into a new issue form (`--url` prints the link instead, for a machine without a browser). The same question is asked right after a failed command; answer no, or set `LSHED_REPORT=0`, and nothing happens.
549
556
  - **"Shed location unknown. Pass --shed <dir> or set LSHED_HOME."** — do one of those. After one successful `restore`, lshed remembers it.
550
557
  - **restore replaced my `CLAUDE.md`** — it is in `~/.claude/lshed/backups/<timestamp>/CLAUDE.md`. Move its content into a fragment in the shed and add that fragment to your profile.