synap 0.5.0 → 0.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "synap",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "A CLI for externalizing your working memory",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -1835,10 +1835,11 @@ async function main() {
1835
1835
  skillResult = { ...skillResult, ...(await skillInstaller.install()) };
1836
1836
  if (skillResult.installed) {
1837
1837
  console.log(` ${chalk.green('✓')} Skill installed at ~/.claude/skills/synap-assistant/`);
1838
+ if (skillResult.backupFile) {
1839
+ console.log(` ${chalk.yellow('•')} Your modifications backed up to ${skillResult.backupFile}`);
1840
+ }
1838
1841
  } else if (skillResult.skipped) {
1839
1842
  console.log(` ${chalk.yellow('•')} Skill already up to date`);
1840
- } else if (skillResult.needsForce) {
1841
- console.log(` ${chalk.yellow('•')} Skill modified. Use ${chalk.cyan('synap install-skill --force')}`);
1842
1843
  }
1843
1844
  } catch (err) {
1844
1845
  console.log(` ${chalk.red('✗')} Skill install failed: ${err.message}`);
@@ -2040,7 +2041,6 @@ async function main() {
2040
2041
  .command('install-skill')
2041
2042
  .description('Install Claude Code skill')
2042
2043
  .option('--uninstall', 'Remove the skill')
2043
- .option('--force', 'Override ownership check')
2044
2044
  .action(async (options) => {
2045
2045
  const skillInstaller = require('./skill-installer');
2046
2046
 
@@ -2048,13 +2048,14 @@ async function main() {
2048
2048
  await skillInstaller.uninstall();
2049
2049
  console.log(chalk.green('Skill uninstalled'));
2050
2050
  } else {
2051
- const result = await skillInstaller.install({ force: options.force });
2051
+ const result = await skillInstaller.install();
2052
2052
  if (result.installed) {
2053
2053
  console.log(chalk.green('Skill installed to ~/.claude/skills/synap-assistant/'));
2054
+ if (result.backupFile) {
2055
+ console.log(chalk.yellow(`Your modifications were backed up to ${result.backupFile}`));
2056
+ }
2054
2057
  } else if (result.skipped) {
2055
2058
  console.log(chalk.yellow('Skill already up to date'));
2056
- } else if (result.needsForce) {
2057
- console.log(chalk.yellow('Skill was modified by user. Use --force to overwrite.'));
2058
2059
  }
2059
2060
  }
2060
2061
  });
@@ -116,6 +116,8 @@ async function install(options = {}) {
116
116
  fs.mkdirSync(TARGET_SKILL_DIR, { recursive: true });
117
117
  }
118
118
 
119
+ let backupFile = null;
120
+
119
121
  // Check if target exists
120
122
  if (fs.existsSync(TARGET_SKILL_FILE)) {
121
123
  const targetContent = fs.readFileSync(TARGET_SKILL_FILE, 'utf8');
@@ -124,32 +126,33 @@ async function install(options = {}) {
124
126
  const canonicalTargetHash = getHash(canonicalTarget);
125
127
  const targetMatchesSource = canonicalTargetHash === sourceHash;
126
128
 
127
- if (targetSource !== SKILL_SOURCE && !options.force) {
128
- return { installed: false, needsForce: true };
129
+ // Already up to date
130
+ if (targetMatchesSource && targetContent === normalizedSourceContent) {
131
+ return { installed: false, skipped: true };
129
132
  }
130
133
 
131
- if (targetSource === SKILL_SOURCE && !options.force) {
132
- if (targetMatchesSource && targetContent === normalizedSourceContent) {
133
- return { installed: false, skipped: true };
134
- }
135
-
136
- if (targetHash) {
137
- if (targetHash !== canonicalTargetHash) {
138
- return { installed: false, needsForce: true };
139
- }
140
- } else if (!targetMatchesSource) {
141
- return { installed: false, needsForce: true };
134
+ // Check if user modified the file (hash mismatch or different source)
135
+ const userModified = targetSource !== SKILL_SOURCE ||
136
+ (targetHash && targetHash !== canonicalTargetHash) ||
137
+ (!targetHash && !targetMatchesSource);
138
+
139
+ if (userModified) {
140
+ // Create timestamped backup
141
+ const timestamp = new Date().toISOString().slice(0, 10).replace(/-/g, '');
142
+ backupFile = `${TARGET_SKILL_FILE}.backup.${timestamp}`;
143
+ // If backup already exists today, add time
144
+ if (fs.existsSync(backupFile)) {
145
+ const time = new Date().toISOString().slice(11, 16).replace(':', '');
146
+ backupFile = `${TARGET_SKILL_FILE}.backup.${timestamp}-${time}`;
142
147
  }
148
+ fs.writeFileSync(backupFile, targetContent);
143
149
  }
144
-
145
- const backupFile = TARGET_SKILL_FILE + '.backup';
146
- fs.writeFileSync(backupFile, targetContent);
147
150
  }
148
151
 
149
152
  // Install
150
153
  fs.writeFileSync(TARGET_SKILL_FILE, normalizedSourceContent);
151
154
 
152
- return { installed: true };
155
+ return { installed: true, backupFile };
153
156
  }
154
157
 
155
158
  /**