feat(claude): install as a native plugin, skills plugin-only - #38
Closed
camjac251 wants to merge 1 commit into
Closed
feat(claude): install as a native plugin, skills plugin-only#38camjac251 wants to merge 1 commit into
camjac251 wants to merge 1 commit into
Conversation
npx goalbuddy installs GoalBuddy on Claude Code as a native plugin (claude plugin marketplace add + install --scope user), matching the Codex model. The plugin surfaces the goal-prep skill, the Scout/Judge/Worker subagents, and the /goal command from its own versioned cache. There is no loose-file fallback. When the claude CLI is unavailable or the plugin install fails, the installer writes no loose files, reports an unmanaged result, and points at /plugin. Codex loads standalone skills from ~/.agents/skills and dedupes by SKILL.md path, so a loose ~/.claude/skills/goal-prep reached through a ~/.agents/skills symlink surfaced a duplicate skill in Codex next to the plugin's goalbuddy:goal-prep. Not writing loose Claude files closes that leak. Cleanup only removes files GoalBuddy authored (content-marker guard) and only on a successful install or reset, so a user's own goal.md is never deleted and a transient failure never wipes a working setup. doctor reports plugin state from installed_plugins.json (works without the CLI) and flags loose leftovers. Updates stay the user's choice: the installer never enables marketplace auto-update or writes settings.json / known_marketplaces.json. The Codex install tolerates a failed marketplace registration: the plugin content is bundled and Codex loads from the cache dir plus the [plugins] config, so a failed `plugin marketplace add` (no codex CLI, offline, or a private or rate-limited clone) records a warning and the cache, config, and agents still install. doctor resolves the Claude plugin store from CLAUDE_CODE_PLUGIN_CACHE_DIR when that override is set, matching the claude CLI, so it reads the same files the CLI wrote.
camjac251
force-pushed
the
feat/claude-native-plugin
branch
from
July 23, 2026 22:06
4820949 to
8b3f0ee
Compare
Owner
|
Thank you for the deep investigation and for documenting the no-loose-file rationale so carefully. I am closing this version because it is now four mainline changes behind, conflicts with current The native Claude plugin direction may still be worth revisiting, but it should come back as a fresh, smaller PR against current |
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
npx goalbuddynow installs GoalBuddy on Claude Code as a native plugin (claude plugin marketplace add+claude plugin install --scope user), matching the Codex native-plugin model. The plugin surfaces the$goal-prepskill, the Scout/Judge/Worker subagents, and the/goalcommand from its own versioned cache, so a clean install no longer scatters loose files under~/.claude/{skills,agents,commands}. The installer removes any left from an earlier version./goalcommand. There is no loose-file fallback. When theclaudeCLI is not onPATH(or the plugin install fails), the installer writes no loose files, reports anunmanagedresult, and prints how to finish from inside Claude Code (/plugin marketplace add+/plugin install). It never writes a loose~/.claude/skills/goal-prep, so nothing leaks into Codex through a~/.agents/skillssymlink. It also never wipes a working install it cannot replace: any pre-existing loose files are left in place and reported, and clear only on a successful plugin install orreset. Only files GoalBuddy itself wrote are ever removed (matched by a content marker), so a user's own~/.claude/commands/goal.mdis never touched. The Codex side still succeeds in an install-everywhere run, and a failedcodex plugin marketplace add(nocodexCLI, offline, or a private or rate-limited clone) is recorded as a warning rather than aborting, so the bundled cache, config, and agents still install.npx goalbuddy updateremains the reliable cross-harness updater; users opt into auto-update in/plugin. GoalBuddy writes none of your Claude config: nothing writessettings.jsonorknown_marketplaces.json, anddoctoronly reads them.reset --target claudedelegates removal to theclaudeCLI (plugin uninstall+marketplace remove) and only cleans loose leftovers itself.doctor --target claudereports plugin state straight frominstalled_plugins.json(works with or without the CLI) and flags any loose leftovers; it resolves the plugin store fromCLAUDE_CODE_PLUGIN_CACHE_DIRwhen that override is set, matching theclaudeCLI.npm versionlifecycle hook (sync-manifest-version.mjs) stamps bothplugin.jsonversions frompackage.json, so a release keeps all three in lockstep in one commit and tag.installAll,installSkill,compatibilitySkillBody,printInstallReport), and pulled the default marketplace source into one constant.Why
Third-party marketplaces default auto-update off, so a plugin-installed Claude user could silently freeze on an old version (this happened in practice). The fix keeps the plugin self-contained and puts the update decision with the user.
Claude skills are plugin-only for a second, verified reason. Codex reads standalone skills from
~/.agents/skillsand dedupes by SKILL.md path, not by name (core-skills/src/loader.rsskill_roots_from_layer_stack_inner+root_loader.rs). A loose~/.claude/skills/goal-prepreached through a~/.agents/skillssymlink therefore surfaces a second, duplicategoal-prepin Codex alongside the plugin'sgoalbuddy:goal-prep. Refusing to write loose Claude files closes that leak.Codex cannot be made equally self-contained: Codex plugins surface skills, MCP servers, hooks, and apps, but not subagents, so the three
~/.codex/agents/*.tomlfiles must live outside the plugin (verified against codex-rs). That asymmetry is a platform requirement, not a choice.Test plan
npm run checkinternal suite passes (121 internal tests). The local-board tests fail only in the sandbox (loopback networking) and pass in CI.unmanaged), a pre-existing loose install preserved whenplugin installfails, legacy loose dirs cleaned on a successful native install, the provenance guard sparing a user's own same-named files, theagentscommand pointing at the plugin,doctorpassing without the CLI and failing when loose files are present,settings.jsonleft untouched,CLAUDE_CONFIG_DIRresolution, reset delegating to the CLI, the manifest--writestamping path, the Codex install completing whenmarketplace addfails, anddoctorresolving the plugin store fromCLAUDE_CODE_PLUGIN_CACHE_DIR.--claude-homebefore publish.Notes
claudeCLI the installer reportsunmanagedand points at/plugin. This is deliberate, to keep GoalBuddy's Claude skill from leaking into Codex via~/.agents/skills.Unreleaseduntil then; the release step runsnpm version minor, which stampspackage.jsonand bothplugin.jsonmanifests via the hook.