claude-use 0.2.9 → 0.3.2

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/README.md CHANGED
@@ -49,7 +49,7 @@ scoop bucket add claude-use https://github.com/ExaDev/scoop-claude-use
49
49
  scoop install claude-use
50
50
  ```
51
51
 
52
- Every channel installs `claude-use` alone — none of them install a `claude` command; `claude-use shim enable` is the one explicit action that does, on any of them. The GitHub Release binary, Homebrew, and Scoop all ship the self-contained Node SEA build (no Node.js installation required) — macOS arm64, both Linux architectures, and both Windows architectures are all targets Node core itself tests and verifies `--build-sea` against upstream; the GitHub Release binary for macOS x64 is published best-effort, since Node core does not test or verify single-executable-application support on that target and the resulting binary genuinely crashes there (see [Build (Node SEA)](#build-node-sea) below). **Homebrew on macOS x64 is the one exception**: rather than installing that broken binary, the formula depends on Homebrew's own `node` and installs the same plain bundle the npm channel publishes — a real, working `claude-use`, not a best-effort one. npm ships the plain bundle everywhere, running under whatever Node ≥ 22.12 you already have.
52
+ Every channel installs `claude-use` alone — none of them install a `claude` command; `claude-use shim enable` is the one explicit action that does, on any of them. The GitHub Release binary and Scoop ship the self-contained Node SEA build (no Node.js installation required) — macOS arm64, both Linux architectures, and both Windows architectures are all targets Node core itself tests and verifies `--build-sea` against upstream; the raw GitHub Release binary for macOS x64 is published best-effort, since Node core does not test or verify single-executable-application support on that target and the resulting binary genuinely crashes there (see [Build (Node SEA)](#build-node-sea) below). **Homebrew and `install.sh` both work around this on macOS x64 specifically**: rather than installing that broken binary, they depend on (or check for) Node and install the same plain bundle the npm channel publishes — a real, working `claude-use`, not a best-effort one. npm ships the plain bundle everywhere, running under whatever Node ≥ 22.12 you already have.
53
53
 
54
54
  ## Quick start
55
55
 
@@ -519,6 +519,18 @@ The resolver closes this by treating every materialised directory as a two-way s
519
519
 
520
520
  The reverse direction matters just as much: a directory materialised because of a split whose cause later disappears (a profile edit removes the entry override that split it, say) collapses back into a single plain symlink on the next resync, rather than being left behind as permanent local scaffolding. This is the same "compare against prior farm state, update only what changed" logic that makes every resync fast in the common case, applied to the one case where a subtree's resolved shape needs to get simpler, not just different.
521
521
 
522
+ ### Automated releases (semantic-release)
523
+
524
+ Every push to `main` (never a tag push — the `semantic-release` job's own `if:` checks `github.ref == 'refs/heads/main'` specifically) runs [semantic-release](https://github.com/semantic-release/semantic-release) after `check` passes. It analyses every commit since the last `vX.Y.Z` tag using the `conventionalcommits` preset — the same convention this project's own commitlint config already enforces — and decides whether a release is warranted at all: a `feat:` commit bumps minor, `fix:`/`perf:` bump patch, a `BREAKING CHANGE:` footer bumps major, and anything else (`chore:`, `docs:`, `ci:`, `test:`) triggers no release on its own. If a release is warranted, it creates and pushes the next tag itself — exactly the step that used to be a manual `git tag`/`git push` earlier in this project's life.
525
+
526
+ `.releaserc.json` configures five plugins, in this order: `@semantic-release/commit-analyzer` and `@semantic-release/release-notes-generator` (both `conventionalcommits`-preset, deciding the version and generating notes text), `@semantic-release/changelog` (writes `CHANGELOG.md`), `@semantic-release/npm` with **`npmPublish: false`** (bumps `package.json`'s version field and stages it, but never touches the npm registry), `@semantic-release/git` (commits `CHANGELOG.md` + `package.json` with a `chore(release): X.Y.Z [skip ci]` message and pushes it to `main`), and `@semantic-release/exec` (see below). `@semantic-release/github` is not loaded at all. This split is deliberate: semantic-release owns only the version *decision*, the tag, and the changelog — actual npm publishing (this project's own OIDC trusted-publishing job, below), GitHub Release creation (with this project's own multi-platform asset list and release-notes body, not semantic-release's generic one), and the Homebrew/Scoop tap updates all remain this project's existing tag-triggered jobs, completely unchanged. The `[skip ci]` marker on the changelog commit stops it from re-triggering `check`/`semantic-release` on `main`.
527
+
528
+ One accepted quirk worth knowing rather than being surprised by: semantic-release creates the release tag pointing at the commit that already existed (the actual code change being released) *before* running `@semantic-release/git`'s commit step — so the changelog/version-bump commit lands on `main` **after** the tag, not folded into it. This means checking out a given `vX.Y.Z` tag shows the *previous* version in `package.json` until the next release's tag moves past this commit. This is standard, widely-accepted semantic-release behaviour, not a bug — and harmless here specifically because every job downstream (`publish-npm`'s `npm pkg set version="${GITHUB_REF_NAME#v}"`, every build/verify job's own version assertions) already derives the version from the **tag name** (`GITHUB_REF_NAME`) directly, never from `package.json`'s committed value at that commit.
529
+
530
+ **Branch/tag protection had to be disabled for this to work.** `main`'s branch-protection ruleset previously required every push go through a reviewed PR, and a separate ruleset blocked tag creation/deletion outright — both only bypassable by the Admin repository role. semantic-release's own git operations run as the workflow's default `GITHUB_TOKEN`, which doesn't hold that role, so both rulesets were disabled (not deleted — the rule definitions are preserved and can be re-enabled with a single API call or via the repo's Rules settings page) rather than routing around them with a separate bypass credential.
531
+
532
+ **The tag push itself does not trigger the build/publish/verify pipeline below — GitHub Actions never lets a `GITHUB_TOKEN`-authenticated push start a new workflow run, to prevent recursive loops.** This turned out to hold for an SSH deploy key registered on the repository too, not just the default token — confirmed empirically rather than assumed, since most write-ups of this restriction only discuss `GITHUB_TOKEN` and imply any other credential is exempt. `workflow_dispatch` (and `repository_dispatch`) are explicitly exempt, though, so `@semantic-release/exec`'s `successCmd` re-dispatches this same workflow directly against the new tag: `gh workflow run ci.yml --ref ${nextRelease.gitTag}`. The `success` step only fires once semantic-release has actually created a release, so a push with nothing to release skips it entirely rather than dispatching a pointless run. The `semantic-release` job's `permissions: actions: write` is what lets its own `GITHUB_TOKEN` call the dispatch API — `contents: write` covers the tag/commit push, same as before.
533
+
522
534
  ### Build (Node SEA)
523
535
 
524
536
  `scripts/build.mts` bundles `src/cli.ts` to a single CJS file with esbuild, writes a `sea-config.json` next to it, then invokes the now-stable single command `node --build-sea=sea-config.json` — this one step handles the bundle copy, signature removal, blob injection, and re-signing that used to require chaining `--experimental-sea-config` with a separate `postject` invocation, and `postject` is not a dependency of this project. On macOS the resulting binary is re-signed with an ad-hoc signature (`codesign --sign -`) afterwards, since blob injection invalidates the original one. `--build-sea` requires Node ≥ v25.5.0, the version it stabilised in; the build script checks the running Node version up front and refuses with a clear error rather than failing deep inside the SEA step if it's older.
@@ -529,7 +541,9 @@ macOS SEA support is tested and verified upstream on **arm64 only** — x64 is e
529
541
 
530
542
  **Root cause, confirmed rather than assumed.** Reproduced locally under Rosetta with 100% fidelity to CI: `lldb` shows `EXC_BAD_ACCESS` inside `__cxx_global_var_init`, invoked by `dyld` while running C++ static initializers — before `main()` ever executes, with `rdi` (the faulting access) holding the literal value `0x2`. A trivial one-line `console.log(...)` script built through the exact same `--build-sea` + ad-hoc-codesign steps crashes identically, which rules out anything in claude-use's own bundle, build script, or code — this is `--build-sea` itself misbehaving on x64 macOS. This is a known, tracked, and deliberately unfixed upstream limitation: [nodejs/node#62893](https://github.com/nodejs/node/issues/62893) reproduces the identical crash and was closed as documentation-only ([nodejs/node#63181](https://github.com/nodejs/node/pull/63181)), with a Node core maintainer stating SEA on x64 macOS "is not supported and skipped in the tests... until someone volunteers to implement support for it." The deeper investigation thread ([nodejs/node#59553](https://github.com/nodejs/node/issues/59553)) floats an unconfirmed theory — that `postject`'s LIEF-based Mach-O binary injection corrupts the executable such that `dyld` misidentifies a segment as an oversized (>4GB) thread-local-storage region — but that thread closed stale, unfixed, with the same maintainer concluding it's "unlikely that anyone would invest time in fixing it for macOS" given x64 macOS's Tier 2 deprioritisation upstream. There is no available workaround (no alternate `codesign` invocation, `sea-config.json` option, or Node flag) — the fault is inside `--build-sea`'s own binary-injection step, before any code this project controls runs at all.
531
543
 
532
- **Homebrew works around this by not using the SEA binary at all on this one architecture.** Since there's no fix available for the binary itself, `update-tap`'s generated formula gives macOS x64 a genuinely different install path: `on_intel do ... depends_on "node" end` nested under `on_macos`, pointing at the npm registry tarball (`https://registry.npmjs.org/claude-use/-/claude-use-<version>.tgz`) instead of the GitHub Release SEA asset, and `def install` branches on `OS.mac? && Hardware::CPU.intel?` to run `system "npm", "install", *std_npm_args` (Homebrew's own documented Node-formula pattern — see the [Formula Cookbook](https://docs.brew.sh/Formula-Cookbook) and [Language-Specific Formulae](https://docs.brew.sh/Language-Specific-Formulae) docs) followed by `bin.install_symlink libexec.glob("bin/*")`, rather than downloading and `bin.install`-ing a binary. `depends_on "node"` inside an `on_intel` block is legal precisely because it's a metadata declaration Homebrew resolves at build-spec time, not runtime logic — the actual branch deciding *which* install steps run lives in `def install` using `OS.mac?`/`Hardware::CPU.intel?`, exactly as the Cookbook prescribes. This means `brew install ExaDev/claude-use/claude-use` gives macOS x64 users a genuinely working `claude-use` (the same code the npm channel already publishes and verifies), unlike the raw GitHub Release binary and `install.sh` on that architecture, which still ship the best-effort, currently-broken SEA binary described above.
544
+ **Homebrew works around this by not using the SEA binary at all on this one architecture.** Since there's no fix available for the binary itself, `update-tap`'s generated formula gives macOS x64 a genuinely different install path: `on_intel do ... depends_on "node" end` nested under `on_macos`, pointing at the npm registry tarball (`https://registry.npmjs.org/claude-use/-/claude-use-<version>.tgz`) instead of the GitHub Release SEA asset, and `def install` branches on `OS.mac? && Hardware::CPU.intel?` to run `system "npm", "install", *std_npm_args` (Homebrew's own documented Node-formula pattern — see the [Formula Cookbook](https://docs.brew.sh/Formula-Cookbook) and [Language-Specific Formulae](https://docs.brew.sh/Language-Specific-Formulae) docs) followed by `bin.install_symlink libexec.glob("bin/*")`, rather than downloading and `bin.install`-ing a binary. `depends_on "node"` inside an `on_intel` block is legal precisely because it's a metadata declaration Homebrew resolves at build-spec time, not runtime logic — the actual branch deciding *which* install steps run lives in `def install` using `OS.mac?`/`Hardware::CPU.intel?`, exactly as the Cookbook prescribes. This means `brew install ExaDev/claude-use/claude-use` gives macOS x64 users a genuinely working `claude-use` (the same code the npm channel already publishes and verifies), unlike the raw GitHub Release binary on that architecture, which still ships the best-effort, currently-broken SEA binary described above.
545
+
546
+ **`install.sh` takes the same workaround**, since it can express the equivalent of `depends_on "node"` itself (a POSIX shell script, unlike a Homebrew formula, has no package manager underneath it to declare dependencies to): on macOS x64 specifically, it checks for `npm` on `PATH` before anything else, and — if present — installs into a scratch npm prefix and copies the resulting `bin/claude-use` script into place, exactly matching where the binary-download path would have put it, rather than downloading the broken SEA asset at all. If `npm` isn't available, it exits with a clear error pointing at installing Node.js first or using Homebrew instead (which resolves this automatically via its own `node` dependency), rather than silently installing something broken.
533
547
 
534
548
  Windows and Linux carry no such carve-out — Node's own SEA documentation tests both regularly across every architecture it supports on those platforms (x64 and arm64 alike), so CI builds and verifies all four of those binaries as fully supported release artefacts, same as macOS arm64.
535
549
 
package/dist/cli.cjs CHANGED
@@ -221857,7 +221857,7 @@ var categories_default_default = {
221857
221857
  // package.json
221858
221858
  var package_default = {
221859
221859
  name: "claude-use",
221860
- version: "0.2.9",
221860
+ version: "0.3.2",
221861
221861
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
221862
221862
  license: "Apache-2.0",
221863
221863
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -221904,14 +221904,20 @@ var package_default = {
221904
221904
  "@commitlint/cli": "^21.2.1",
221905
221905
  "@commitlint/config-conventional": "^21.2.0",
221906
221906
  "@eslint/js": "^10.0.1",
221907
+ "@semantic-release/changelog": "^7.0.0",
221908
+ "@semantic-release/exec": "^7.1.0",
221909
+ "@semantic-release/git": "^11.0.1",
221910
+ "@semantic-release/npm": "^13.1.5",
221907
221911
  "@types/node": "^26.1.2",
221908
221912
  "@types/picomatch": "^4.0.3",
221913
+ "conventional-changelog-conventionalcommits": "^10.2.1",
221909
221914
  esbuild: "^0.28.1",
221910
221915
  eslint: "^10.8.0",
221911
221916
  globals: "^17.8.0",
221912
221917
  husky: "^9.1.7",
221913
221918
  jiti: "^2.7.0",
221914
221919
  "lint-staged": "^17.3.0",
221920
+ "semantic-release": "^25.0.8",
221915
221921
  typescript: "^6.0.3",
221916
221922
  "typescript-eslint": "^8.65.0",
221917
221923
  vitest: "^4.1.10"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-use",
3
- "version": "0.2.9",
3
+ "version": "0.3.2",
4
4
  "description": "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Joseph Mearman <joseph@mearman.co.uk>",
@@ -47,14 +47,20 @@
47
47
  "@commitlint/cli": "^21.2.1",
48
48
  "@commitlint/config-conventional": "^21.2.0",
49
49
  "@eslint/js": "^10.0.1",
50
+ "@semantic-release/changelog": "^7.0.0",
51
+ "@semantic-release/exec": "^7.1.0",
52
+ "@semantic-release/git": "^11.0.1",
53
+ "@semantic-release/npm": "^13.1.5",
50
54
  "@types/node": "^26.1.2",
51
55
  "@types/picomatch": "^4.0.3",
56
+ "conventional-changelog-conventionalcommits": "^10.2.1",
52
57
  "esbuild": "^0.28.1",
53
58
  "eslint": "^10.8.0",
54
59
  "globals": "^17.8.0",
55
60
  "husky": "^9.1.7",
56
61
  "jiti": "^2.7.0",
57
62
  "lint-staged": "^17.3.0",
63
+ "semantic-release": "^25.0.8",
58
64
  "typescript": "^6.0.3",
59
65
  "typescript-eslint": "^8.65.0",
60
66
  "vitest": "^4.1.10"