lshed 0.17.2 → 0.17.3

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,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.17.3 — 2026-09-11
4
+
5
+ - Fix: a failed `restore --yes` reported success whenever its output went through a pipe. `lshed restore prof --yes | head` (or into a pager you quit, or `| tee log` in CI) made the reader close first, stdout raised `EPIPE`, and the handler answered with `process.exit(0)` — which hard-set the status to 0 and threw away the `exit 1` that 0.17.2 had just made meaningful. lshed now drops the writes and keeps going, so the command finishes its work and exits with the code it earned.
6
+ - Fix: `lshed check` could hang past its `--timeout` and never come back. It waited for the child's `close` event, which only arrives once every pipe is closed — and on Windows `kill()` ends `cmd.exe` alone, leaving the `claude.cmd` → node grandchild alive with lshed's pipes in hand. A CLI that ignores the kill signal did the same thing on any OS. `ask` now kills the whole process tree on Windows (`taskkill /T`), and after the process ends it waits out a short grace period and then settles regardless, releasing the pipes. This also matters for what a hang left behind: `check`'s cleanup never ran, so the throwaway `lshed-check` skill stayed in the skills folder and every later `check` refused to start with `already exists`.
7
+ - Fix: 0.17.2 stopped an `install:` command from aborting a restore, but the package installers themselves — `git clone`, `claude plugin install`, `claude plugin marketplace add` — still threw, and they run *before* the placement loop. So an unreachable git host, a missing `claude` CLI or a force-pushed lock commit still ended a restore with no part placed and no profile recorded: the exact symptom the last release set out to remove, reached through a different door. A package that cannot be set up is now reported under its own name (`! package failed: …`), the restore places everything that does not depend on it, records the profile, lists the failures at the end, and exits 1.
8
+ - Fix: the `DEP0190` deprecation warning was still printed by `lshed report` on Windows and Node ≥ 22.9. The last release converted the two `spawn` sites it had seen fail by hand but missed `toolVersion`'s `execFile`, which also passes an argument array together with `shell: true`. All three now go through one `invocation()` helper, so there is a single place to get this right rather than a pattern to remember at each call site.
9
+ - `lshed check` now survives a cleanup it cannot finish. On Windows a CLI that leaves a child behind keeps lshed's temporary working directory open, and `rmdir` answered `EBUSY` — from inside the `finally`, so the error replaced the whole result and the `(timed out)` line and every attempt excerpt were lost. Removal is retried briefly, the skill folder is removed even when the temporary folder is stuck, and anything still left is reported as its own line (`! could not remove … — something still has it open.`) under a result that is otherwise intact.
10
+ - Fix: the Windows command line lshed builds escaped arguments for the executable's own parser but not for the `cmd.exe` that reads the line first. An argument holding `&`, `|`, `<`, `>`, `^`, `(` or `)` was passed through bare whenever it had no spaces, and an argument holding a double quote broke the quote parity `cmd` counts, so a metacharacter after it became a live operator. Arguments are now quoted whenever either parser would care, inner quotes are written `""` (which both parsers read as a literal quote), and a newline — which nothing can quote away from `cmd` — is refused. A round-trip test spawns a real child process and compares the arguments it received, so Windows CI checks the shell path end to end for the first time; the smoke suite adds the failed install and the closed pipe.
11
+
3
12
  ## 0.17.2 — 2026-09-09
4
13
 
5
14
  - Fix: `restore --yes` stopped at the first `install:` command that failed, before any part was placed and before the profile was recorded. The fifth Windows pass hit it: gstack's `./setup` is an sh script, cmd.exe answered `'.' is not recognized`, and the run ended with exit 1, nine parts unplaced and no state written. A failing command now prints `! install failed: …` under the package, the restore goes on to place everything and record the profile, the failed commands are listed at the end (`N install commands failed. Everything else was placed.`), and `restore` and `update` exit 1 so a script still notices.
package/README.ko.md CHANGED
@@ -548,6 +548,7 @@ lshed report [--open | --url] 이슈에 붙여 넣을 이 설
548
548
 
549
549
  - 테스트, CLI 스모크, 단독 실행파일이 push마다 **Ubuntu, macOS, Windows**(Node 20, 22)에서 돕니다. Windows는 `--link`에 junction을, 플러그인 설치에 `claude.cmd`를 씁니다. 스모크에는 한글 이름 스킬이 들어 있어, macOS의 파일 이름 정규화 차이나 Windows의 코드페이지 문제는 사용자 기기가 아니라 CI에서 먼저 실패합니다.
550
550
  - 개발자 모드가 꺼진 실제 Windows 11 PC(PowerShell 7과 cmd.exe, Node 24, 공백과 한글이 든 경로)에서도 npm 으로 설치한 lshed 0.15.1 로 같은 절차가 통과했습니다. `init`, 이미 설정이 있는 기기로의 `restore`, `--link`(스킬은 junction, 단일 파일은 안내와 함께 복사), `add`/`diff`/`save`, 프로필 전환, `codex`·`agents` 대상, 원격 없는 `sync`, 스모크까지입니다. 같은 PC 에서 두 차례 더 확인했습니다. 0.15.2 는 거기서 만든 창고가 WSL 안에서 `/home/…/` 경로로 복원되고 옛 창고가 `save` 한 번으로 정규화되는 것을, 0.15.3 은 링크 모드가 복사로 놓았던 파일 부품을 `=` 로 안정시키고 창고가 바뀔 때만 다시 복사하는 것을 확인했습니다.
551
+ - 같은 PC 에서 다섯 번째로(Windows PowerShell 5.1, Node 24, git 2.55, npm 으로 설치한 lshed 0.17.1) 빈 상태부터 다시 걸었습니다. private 창고를 HTTPS 로 clone 하고 `restore default` 를 돌리자 모든 패키지가 락에 적힌 리비전으로 왔고(Linux 기기에서 올린 gstack 업데이트가 같은 커밋으로 도착), `status` 는 아홉 패키지 모두 in sync, `lshed check` 는 첫 시도에 Claude Code 가 암호어를 돌려줬으며, `report` 는 홈 디렉터리를 `~` 로 가렸습니다. 이 검증이 `restore --yes` 가 첫 `install:` 실패(gstack 의 `./setup` 은 cmd.exe 에서 시작조차 못 함)에서 아무것도 놓지 않고 멈추는 것을 찾았고, 0.17.2 가 고친 뒤 같은 PC 에서 확인했습니다. 실패는 찍히고, 부품 아홉은 놓이고, 실패한 명령은 끝에 목록으로 나옵니다.
551
552
  - 개발하는 Linux 기기에서는 CI 너머까지 전체 명령을 돌려 봅니다. `install:`이 있는 git·GitHub 패키지의 `restore`와 `update`, 충돌까지 포함한 실제 원격과의 `sync`, `remove`/`prune`, 모든 `--agent` 대상, 환경변수 기본값, 실제 터미널을 거친 `restore --pick`, 컴파일된 Linux 바이너리까지입니다.
552
553
  - 다른 에이전트는 문서만이 아니라 도구 자체로 확인합니다. `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`에 있습니다.
553
554
  - 개발하는 기기에서는 실제 창고 하나를 매일 씁니다. Claude Code, Codex, Antigravity가 모두 `--link`로 그 창고를 읽고, 셋 다 `status`에 드리프트가 없습니다.
package/README.md CHANGED
@@ -548,6 +548,8 @@ A shed is executable, not just data. `restore` places files into your agent's co
548
548
 
549
549
  - Tests, a CLI smoke run and the standalone binaries run on every push on **Ubuntu, macOS and Windows** (Node 20 and 22). Windows uses junctions for `--link` and `claude.cmd` for plugin installs. The smoke run includes a skill with a Korean name, so a filename-normalization difference on macOS or a code-page problem on Windows would fail there, not on a user's machine.
550
550
  - On a real Windows 11 PC without Developer Mode (PowerShell 7 and cmd.exe, Node 24, paths with spaces and Korean) the same walk passed with lshed 0.15.1 from npm: `init`, `restore` next to an existing setup, `--link` (junctions for skills, copies with a notice for single files), `add`/`diff`/`save`, a profile switch, the `codex` and `agents` targets, `sync` without a remote, and the smoke suite. Two follow-up passes on the same PC confirmed 0.15.2 (a shed made there restores with `/home/…/` paths inside WSL, an older shed is normalized by one `save`) and 0.15.3 (link mode settles on `=` for the file parts it had to copy, and re-copies them only when the shed changes).
551
+ - A fifth pass on the same PC (Windows PowerShell 5.1, Node 24, git 2.55, lshed 0.17.1 from npm) started from nothing: a private shed cloned over HTTPS, `restore default` fetched every package at the revision in the lock (a gstack update made on the Linux machine arrived at the same commit), `status` reported all nine packages in sync, `lshed check` got the passphrase back from Claude Code on the first attempt, and `report` showed the home directory as `~`. The pass found that `restore --yes` stopped at the first failing `install:` (gstack's `./setup` cannot start under cmd.exe) before placing anything; 0.17.2 fixed that and the same PC confirmed the fix: the failure is printed, the nine parts are placed, and the failed command is listed at the end.
552
+ - A sixth pass on the same PC (Windows PowerShell, Node 24, lshed 0.17.3 built from source) checked what the 0.17.2 review had turned up: nine arguments holding `&`, `|`, `(`, `^`, a quote and a trailing backslash came back from a real child process through `cmd.exe` unchanged, `lshed report` printed no `DEP0190` warning even under `--throw-deprecation`, `check` got the passphrase back on the first attempt and left no skill behind, a package whose clone cannot succeed no longer stops the restore, and `check` against a CLI that leaves a child holding the pipes returned in 2.2 seconds instead of hanging. It found that the cleanup after such a run hit `EBUSY` from inside a `finally` and replaced the whole result with that error; the fix in this release retries, keeps the result, and names whatever is left over.
551
553
  - 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.
552
554
  - 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.
553
555
  - 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.