Skip to content

Installer: doctor's fixes keep --source, and doctor says when --source did not move a home - #39

Open
J0UH wants to merge 2 commits into
chhoumann:mainfrom
J0UH:fix/installer-source
Open

J0UH wants to merge 2 commits into
chhoumann:mainfrom
J0UH:fix/installer-source

Conversation

@J0UH

@J0UH J0UH commented Oct 21, 2026

Copy link
Copy Markdown

Two installer problems show up when a run passes --source for a fork.

1. Doctor's fixes drop the run's --source

Every fix doctor printed was npx -y github:chhoumann/t3-pstack install, whatever --source the run had. On a home with no marketplace, following it adds chhoumann/t3-pstack instead of the source the user named.

Before, on main (7a38564), in a throwaway HOME:

$ node tools/install.mjs doctor --source J0UH/t3-pstack --claude-home ~/.claude-new
Claude Code  ~/.claude-new  (--claude-home)
  FAIL  installed: the home does not exist
        fix: rerun `npx -y github:chhoumann/t3-pstack install`

After:

Claude Code  ~/.claude-new  (--claude-home)
  FAIL  installed: the home does not exist
        fix: rerun `npx -y github:J0UH/t3-pstack install --source J0UH/t3-pstack`

installHint(source) replaces the INSTALL_HINT constant, and every fix in install.mjs, both doctors, marketplaceCheck and doctorSheet uses it. With no --source, or --source chhoumann/t3-pstack, the text is unchanged. A GitHub --source also names that repository as the package to run. install.mjs already treats "this package" as "the marketplace's own repo", and each home is checked against the installer's version, which for a fork is the fork's. A local or non-GitHub --source keeps github:chhoumann/t3-pstack and adds --source <arg>.

The install gates in installClaude, installCodex and trustHooks now call a new trustedOnly(sources, trusted) instead of reading marketplaceCheck(...).ok. They never showed the fix text. The condition is the same: at least one source, and every source trusted.

2. --source never moves a home that is already on chhoumann/t3-pstack

The installer trusts both chhoumann/t3-pstack and the run's --source, and adds a marketplace only to a home that has none. So a home installed earlier from chhoumann/t3-pstack stays on it under install --source J0UH/t3-pstack. The report's first line says "from J0UH/t3-pstack" and every check passes.

Before, on a real Claude Code home installed with no --source:

$ node tools/install.mjs install --source J0UH/t3-pstack
t3-pstack 2.0.0-rc.15 from J0UH/t3-pstack
...
Claude Code  ~/.claude  (default)
  ok    marketplace: chhoumann/t3-pstack
  ok    installed: 2.0.0-rc.15

I didn't make the run switch the source. Every run also covers the default homes, so install --source ./t3-pstack --claude-home /tmp/x would move ~/.claude and ~/.codex to the local checkout, and the next plain update would then refuse them as a local --source from an earlier run. That is the case the trust rule exists to catch. Switching in place would also uninstall and reinstall the plugin as a side effect of a flag.

Instead, the marketplace check warns when a home's sources are all trusted but none is this run's --source, and prints the commands that move it. A warning doesn't fail the run, so a test run with a local --source still exits 0. The install still converges the home on the source it has. After:

Claude Code  ~/.claude  (default)
  warn  marketplace: chhoumann/t3-pstack, not --source J0UH/t3-pstack
        fix: to install from J0UH/t3-pstack, remove it with `CLAUDE_CONFIG_DIR=~/.claude claude plugin marketplace remove t3-pstack`, then rerun `npx -y github:J0UH/t3-pstack install --source J0UH/t3-pstack`
...
Codex  ~/.codex  (default)
  warn  marketplace: https://github.com/chhoumann/t3-pstack.git, not --source J0UH/t3-pstack
        fix: to install from J0UH/t3-pstack, remove it with `CODEX_HOME=~/.codex codex plugin marketplace remove t3-pstack`, then rerun `npx -y github:J0UH/t3-pstack install --source J0UH/t3-pstack`

Following both fixes with Claude Code 2.1.304 and codex-cli 0.163.0 moves both homes, and every check passes:

Claude Code  ~/.claude  (default)
  - added the t3-pstack marketplace from J0UH/t3-pstack
  - installed 2.0.0-rc.15
  - turned on marketplace auto-update
  ok    marketplace: J0UH/t3-pstack
...
Codex  ~/.codex  (default)
  - added the t3-pstack marketplace from J0UH/t3-pstack
  ok    marketplace: https://github.com/J0UH/t3-pstack.git
  ok    installed: 2.0.0-rc.15
  ok    enabled: yes
  ok    session-start hook trusted: t3-pstack@t3-pstack:hooks/codex-hooks.json:session_start:0:0 trusted

4 changes. Every check passes, 1 warning.

claude plugin marketplace remove also uninstalls the plugin and clears the extraKnownMarketplaces entry the installer wrote, so the rerun adds the new source cleanly. codex plugin marketplace remove leaves the installed copy in place. Here the version matched, so the Codex home kept it, and its next update comes from the new marketplace.

The README's install paragraph and the header comment in tools/install.mjs now say that a run never switches a home's source.

Tests

Two tests in tests/install.test.mjs. Both failed on main before the fix:

  • --source > is in every fix doctor prints, and a GitHub --source runs that repository's installer: runs tools/install.mjs doctor with a fork source and with a local source, and checks every failing check doctorClaude returns for a home with no marketplace.
  • --source > leaves a home on chhoumann/t3-pstack where it is, and doctor warns with the commands that switch it: install still runs on that home, and the marketplace check is a warning with the commands above.
$ bun tools/generate.mjs --check
ok: 17 generated files current
ok: skill frontmatter, links, plugin layout, agent frontmatter, Codex marketplace, and hooks pass their checks

$ GIT_CONFIG_GLOBAL=/dev/null bun test tests/ --timeout 30000
 552 pass
 46 skip
 0 fail
Ran 598 tests across 20 files.

$ T3_PSTACK_E2E=1 GIT_CONFIG_GLOBAL=/dev/null bun test tests/install-e2e.test.mjs --timeout 300000
 12 pass
 0 fail
Ran 12 tests across 1 file. [209.01s]

I didn't bump VERSION or add a CHANGES.md entry, so the release is yours. The installer runs from main through npx, so the fix takes effect without a release.

J0UH added 2 commits October 21, 2026 10:53
Every fix doctor printed was `npx -y github:chhoumann/t3-pstack
install`, whatever --source the run had. Following it on a home with
no marketplace added chhoumann/t3-pstack instead of the source the user
named. The fixes now carry the run's --source. A GitHub --source also
names that repository as the installer to run, since the installer's
version is what each home converges on, and a fork's marketplace has
the fork's version.

The install gates now ask trustedOnly() instead of reading
marketplaceCheck's ok, so they don't build a fix text they never show.
The installer trusts chhoumann/t3-pstack and the run's --source, and it
adds a marketplace only to a home that has none. So a home already on
chhoumann/t3-pstack stayed there under `install --source owner/fork`,
while the report's first line said "from owner/fork" and every check
passed.

Switching the home in place would also move the default homes to a
local checkout on a test run with `--source ./t3-pstack`, and the next
plain `update` would then refuse them. So the run still leaves the
home's source alone, and the marketplace check warns that the home is
not on --source, with the remove command and the rerun that move it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant