lshed 0.17.3 → 0.17.5
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 +20 -0
- package/README.ko.md +156 -147
- package/README.md +139 -131
- package/dist/cli.js +172 -169
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.5 — 2026-09-18
|
|
4
|
+
|
|
5
|
+
- README reorganized for the reader who wants to use lshed, not for the record of how it was built: install and quick start first, a shorter "Why not just git?", the walkthrough, then a reference section (commands, manifest, kinds, MCP, settings, what `restore` and `sync` do, where things live), trust, troubleshooting. The per-pass verification history, tool versions and what each pass found moved to `docs/VERIFICATION.md`, with a five-row summary table left in the README; adapter internals (which MCP field each tool gets, which Claude Code version a behaviour was checked against) were cut from the README. The Korean README follows the same structure.
|
|
6
|
+
- `lshed check --agent cursor` (and the probe) now pass `--trust` to Cursor's `agent -p`. Without it Cursor prints a "Workspace Trust Required" notice for the temporary folder the question is asked from and gives no answer, so the check reported the skill as not read when the tool had simply not looked. Found on the first Cursor run with a key (agent 2026.09.15): every placement check had passed and every answer was empty.
|
|
7
|
+
- `restore --fresh-only` and `restore --agent installed`, for a bootstrap that runs on every start of a container or shell. `--fresh-only` leaves a root that already has lshed state alone — one line saying which profile is applied there and when, exit 0 — so the entrypoint no longer has to know where each agent keeps its `state.json`. `--agent installed` restores into every agent whose CLI is on `PATH` (claude, codex, gemini, copilot, agent for Cursor, agy), one after another and each with its own state, and exits 1 at the end if any of them failed; it needs `--shed` or `LSHED_HOME`, since a fresh machine has nothing to remember the shed from, and refuses `--pick` and `--root`. The agent-box container's init script went from a per-agent loop with hard-coded state paths to one command.
|
|
8
|
+
- `status` no longer counts `~/.claude/skills/synced` as a part outside the shed. Claude Code 2.1 creates that folder itself, one bucket per account, for the skills it syncs from claude.ai — a single `claude -p` on a fresh machine is enough to make it appear — so every restored machine showed `outside 1: skills/synced → lshed add`, and following the hint would have copied the account's skills into the shed. The folder is now skipped in the scan, like a hidden directory; `init`, `add` and `status` all read the same scan. Found by running a fresh-machine test in a container.
|
|
9
|
+
- The VM probe now runs in a local container as well. `scripts/vm/Dockerfile.probe` bakes the runbook's image (Node 22, Codex, Gemini CLI, Copilot CLI, Cursor CLI, Antigravity CLI, and lshed from the checkout) with the unchanged `install-tools.sh`, and `scripts/vm/probe-docker.sh build` / `probe-docker.sh <target>...` runs `probe.sh` in it, passing through whichever agent keys the environment holds and falling back to the model-free run when there are none. The tools that were waiting for a cloud VM (Gemini, Copilot, Cursor) can now be checked on any machine with Docker; the first run (2026-09-18, Gemini CLI 0.60.0, Copilot CLI 1.0.86, Cursor agent 2026.09.15) passed every placement, format, link and cleanup check for all three, and `gemini mcp list` accepted the `settings.json` lshed wrote. With free-tier keys the same day, Gemini and Cursor answered every model question on the first attempt; only Copilot's questions still wait for a token. A `probe` workflow (weekly and on demand) builds that image on a GitHub runner and runs the six Linux targets, model-free unless the keys are set as repository secrets, so a change to an adapter or an MCP form is checked against the tools' own parsers instead of only against lshed's tests. One probe fix on the way: `gemini mcp list` is now run with `GEMINI_CLI_TRUST_WORKSPACE=true`, as the questions already were, because Gemini suppresses user-level servers in an untrusted folder and the probe's scratch folder is one.
|
|
10
|
+
- Windows: an argument holding a `%` is now refused instead of being passed through. `cmd.exe` expands `%VAR%` even inside double quotes and then reads the result again, and there is no way to spell a literal `%` on a command line it parses — so 0.17.3's quoting wrapped it and hoped. Nothing lshed sends that way can legitimately contain one (a package id is letters, digits and `._@-`; the check prompt is fixed), while a shed's plugin source is free text, so refusing costs nothing and closes the last gap in the shell work.
|
|
11
|
+
- `lshed check` clears the temporary folders it could not remove before. On Windows a CLI that leaves a child behind keeps its working directory open for that child's lifetime, so the removal fails at the time and the folder stays; the next check now sweeps any `lshed-check-*` older than an hour out of the temp directory before it starts. The age cut leaves a check that is running right now alone, and the message about a folder that is still held says it will be cleared later rather than asking for it to be removed by hand.
|
|
12
|
+
- The package tests get the timeout the git-heavy blocks in `sync.test.ts` already use. They run on real repositories — the fixture clones a bare remote for every test, and each test adds its own clones, commits and pushes — and `windows-latest` on Node 20 went past the 5s default on a test that had taken 2.4s a run earlier. No behaviour changed; this only stops a slow runner from reading as a failure.
|
|
13
|
+
|
|
14
|
+
## 0.17.4 — 2026-09-11
|
|
15
|
+
|
|
16
|
+
- An `install:` command that failed left no trace once the restore finished. The parts were placed, the profile was recorded, and the one mention of the failure scrolled past — `lshed status` then showed the machine as `packages 1 in sync`, `drift none`, exactly like a machine where everything worked. The failing package ids are now kept in the machine's state, `status` prints them under the package they belong to (`! gstack install: failed at the last restore → fix it, then lshed restore default --yes`), and `lshed report` names them. A later restore that succeeds clears the record.
|
|
17
|
+
- `lshed update` stopped at the first package it could not pull. Everything after it was left at its old revision, and because the lock is written after the loop, the packages that *had* been updated were not recorded either — the working tree moved and the lock still pointed at the previous commit. A package that cannot be updated is now reported and skipped, the rest are pulled, and the lock is written for them.
|
|
18
|
+
- A failing git command said only `Command failed: git clone --quiet -- <url> <dir>`, which is the command, not the reason. The message now carries git's own `fatal:` line (`git clone failed: repository '…' does not exist`), picked out of stderr rather than taken from the end of it, since `git pull` appends two lines of generic advice after the real error.
|
|
19
|
+
- The end of a failed restore said `Everything else was placed.` — including after `lshed update`, which places nothing. Each command now ends that sentence its own way.
|
|
20
|
+
- The `--yes` help said plugin installs "always run", which is not true under `--dry-run`. It now says what the flag gates and that `--dry-run` runs nothing at all.
|
|
21
|
+
- `lshed check` no longer retries a removal it cannot finish. 0.17.3 assumed the lock on its temporary folder was momentary and retried for a second and a half; the sixth Windows pass measured that retry succeeding zero times out of three, because what holds the folder is an orphaned grandchild of the CLI that keeps it for its own lifetime. Every failed check paid the delay for nothing. The leftover is reported as before.
|
|
22
|
+
|
|
3
23
|
## 0.17.3 — 2026-09-11
|
|
4
24
|
|
|
5
25
|
- 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.
|