From a4b7deac3eaa5586a2682322507b4280b33ffaf4 Mon Sep 17 00:00:00 2001 From: Jiayuan Zhang Date: Sun, 15 Feb 2026 14:15:31 +0800 Subject: [PATCH] fix(skills): preserve all user files during bundled skill upgrades Instead of only protecting .env files, use cpSync with force:true to overlay bundle files onto the existing directory. This preserves any user-created files (credentials.json, token.json, etc.) that don't exist in the bundle, rather than deleting and re-copying the entire directory. Co-Authored-By: Claude Opus 4.6 --- packages/core/src/agent/skills/loader.ts | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/packages/core/src/agent/skills/loader.ts b/packages/core/src/agent/skills/loader.ts index fed8006d..2cca9fb0 100644 --- a/packages/core/src/agent/skills/loader.ts +++ b/packages/core/src/agent/skills/loader.ts @@ -198,8 +198,8 @@ export function initializeManagedSkills(): void { // Check if skill exists in managed if (!existsSync(dest)) { - // Skill doesn't exist, copy it (skip .env files - those are user-specific) - cpSync(src, dest, { recursive: true, dereference: true, filter: (s) => !s.endsWith("/.env") }); + // Skill doesn't exist, copy it as-is + cpSync(src, dest, { recursive: true, dereference: true }); continue; } @@ -214,21 +214,9 @@ export function initializeManagedSkills(): void { // Update if bundled version is higher if (compareVersions(bundledVersion, managedVersion) > 0) { - // Preserve user's .env file across upgrades - const envPath = join(dest, ".env"); - let savedEnv: string | null = null; - if (existsSync(envPath)) { - try { savedEnv = readFileSync(envPath, "utf-8"); } catch { /* ignore */ } - } - - // Remove old and copy new (skip .env from bundle) - rmSync(dest, { recursive: true }); - cpSync(src, dest, { recursive: true, dereference: true, filter: (s) => !s.endsWith("/.env") }); - - // Restore user's .env - if (savedEnv !== null) { - writeFileSync(envPath, savedEnv, "utf-8"); - } + // Overwrite only files that exist in the bundle, preserving + // user-created files (e.g. .env, credentials.json, token.json) + cpSync(src, dest, { recursive: true, dereference: true, force: true }); } }