* fix(upgrade): refresh installer-written agent surfaces after a binary upgrade codegraph upgrade swapped the binary but never revisited what earlier installs wrote into CLAUDE.md / AGENTS.md / GEMINI.md and the agent configs, so sections written by a pre-1.0 installer kept teaching agents a multi-tool surface (including tools that no longer exist) months of releases later. The install path already self-heals everything it owns, but nothing ever called it on upgrade. - codegraph install --refresh: non-interactive sweep that re-runs install() for already-configured targets only — never a first install; permissions and prompt-hook choices are preserved. - codegraph upgrade spawns it via the freshly-installed binary after a successful swap (the still-running old process would only rewrite its own stale template). Gated on PATH resolution and the CODEGRAPH_NO_INSTALL_REFRESH=1 kill-switch; never fatal to the upgrade. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(installer): clarify refresh change reporting --------- Co-authored-by: xuing <np2v9bvbbs@privaterelay.appleid.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Colby McHenry <me@colbymchenry.com>
This commit is contained in:
co-authored by
Claude Fable 5
xuing
Colby McHenry
parent
63eb488ed4
commit
386bff0f84
@@ -2193,12 +2193,14 @@ program
|
||||
.option('-y, --yes', 'Non-interactive: defaults to --location=global --target=auto, auto-allow on')
|
||||
.option('--no-permissions', 'Skip writing the auto-allow permissions list (Claude Code only)')
|
||||
.option('--print-config <id>', 'Print MCP config snippet for the named agent and exit (no file writes)')
|
||||
.option('--refresh', 'Rewrite what previous installs configured, for already-configured agents only (never adds new ones). Run automatically by `codegraph upgrade`')
|
||||
.action(async (opts: {
|
||||
target?: string;
|
||||
location?: string;
|
||||
yes?: boolean;
|
||||
permissions?: boolean;
|
||||
printConfig?: string;
|
||||
refresh?: boolean;
|
||||
}) => {
|
||||
if (opts.printConfig) {
|
||||
const { getTarget, listTargetIds } = await import('../installer/targets/registry');
|
||||
@@ -2213,6 +2215,37 @@ program
|
||||
return;
|
||||
}
|
||||
|
||||
// --refresh: non-interactive sweep that re-writes what previous
|
||||
// installs configured (instructions section, MCP entry, legacy-hook
|
||||
// cleanups) for already-configured agents, so those surfaces match
|
||||
// THIS binary's templates. Skips everything else — never a first
|
||||
// install, never touches permissions or the prompt hook. Sweeps both
|
||||
// locations unless --location narrows it.
|
||||
if (opts.refresh) {
|
||||
const { refreshTargets } = await import('../installer');
|
||||
const { ALL_TARGETS } = await import('../installer/targets/registry');
|
||||
if (opts.location && opts.location !== 'global' && opts.location !== 'local') {
|
||||
error(`--location must be "global" or "local" (got "${opts.location}").`);
|
||||
process.exit(1);
|
||||
}
|
||||
const locs: Array<'global' | 'local'> = opts.location
|
||||
? [opts.location as 'global' | 'local']
|
||||
: ['global', 'local'];
|
||||
let changed = 0;
|
||||
for (const loc of locs) {
|
||||
for (const report of refreshTargets(ALL_TARGETS, loc)) {
|
||||
for (const p of report.changedPaths) {
|
||||
changed += 1;
|
||||
console.log(` ${report.displayName}: refreshed ${p}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed === 0) {
|
||||
console.log('All configured agent surfaces are already current.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const { runInstallerWithOptions } = await import('../installer');
|
||||
if (opts.location && opts.location !== 'global' && opts.location !== 'local') {
|
||||
error(`--location must be "global" or "local" (got "${opts.location}").`);
|
||||
|
||||
Reference in New Issue
Block a user