@noemuch/bridge-ds 2.1.0 → 2.2.0

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/lib/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const path = require('path');
2
- const { scaffold } = require('./scaffold');
2
+ const { scaffold, update } = require('./scaffold');
3
3
  const { checkMcp, setupMcp } = require('./mcp-setup');
4
4
 
5
5
  // ── Branding ──────────────────────────────────────────────
@@ -113,6 +113,35 @@ async function cmdInit() {
113
113
  print('');
114
114
  }
115
115
 
116
+ async function cmdUpdate() {
117
+ banner();
118
+ header('Updating Bridge DS skill files');
119
+
120
+ const cwd = process.cwd();
121
+
122
+ step(1, 2, 'Updating skill files');
123
+ const spinner = new Spinner('Updating SKILL.md, actions, rules, schemas, templates...').start();
124
+ const result = update(cwd);
125
+
126
+ if (result.error) {
127
+ spinner.stop();
128
+ error(result.error);
129
+ process.exit(1);
130
+ }
131
+
132
+ spinner.stop(`${result.updated.length} files updated`);
133
+
134
+ for (const f of result.updated) {
135
+ muted(f);
136
+ }
137
+
138
+ step(2, 2, 'Done!');
139
+ print('');
140
+ success('Skill files updated. Your knowledge base (registries, guides) was preserved.');
141
+ info('No need to re-run /design-workflow setup.');
142
+ print('');
143
+ }
144
+
116
145
  function cmdHelp() {
117
146
  banner();
118
147
  print(`${C.bold} Commands:${C.reset}`);
@@ -120,13 +149,17 @@ function cmdHelp() {
120
149
  print(` ${C.orange}init${C.reset} Initialize Bridge DS in current project`);
121
150
  print(` Scaffolds skills, commands, and specs directories`);
122
151
  print('');
152
+ print(` ${C.orange}update${C.reset} Update skill files to latest version`);
153
+ print(` Preserves your knowledge base (registries, guides)`);
154
+ print('');
123
155
  print(` ${C.orange}help${C.reset} Show this help message`);
124
156
  print(` ${C.orange}version${C.reset} Show version`);
125
157
  print('');
126
158
  print(`${C.bold} Usage:${C.reset}`);
127
159
  print('');
128
- print(` ${C.dim}npx bridge-ds init${C.reset} # Initialize in current project`);
129
- print(` ${C.dim}bridge-ds help${C.reset} # Show help`);
160
+ print(` ${C.dim}npx @noemuch/bridge-ds init${C.reset} # Initialize in current project`);
161
+ print(` ${C.dim}npx @noemuch/bridge-ds update${C.reset} # Update skill files only`);
162
+ print(` ${C.dim}bridge-ds help${C.reset} # Show help`);
130
163
  print('');
131
164
  print(`${C.bold} After init:${C.reset}`);
132
165
  print('');
@@ -152,6 +185,9 @@ async function run(args) {
152
185
  case 'init':
153
186
  await cmdInit();
154
187
  break;
188
+ case 'update':
189
+ await cmdUpdate();
190
+ break;
155
191
  case 'help':
156
192
  case '--help':
157
193
  case '-h':
package/lib/scaffold.js CHANGED
@@ -3,8 +3,9 @@ const path = require('path');
3
3
 
4
4
  /**
5
5
  * Recursively copy a directory, preserving structure.
6
+ * @param {string[]} skipDirs - directory names to skip (e.g., ['registries', 'guides', 'ui-references'])
6
7
  */
7
- function copyDir(src, dest) {
8
+ function copyDir(src, dest, skipDirs = []) {
8
9
  const created = [];
9
10
  if (!fs.existsSync(dest)) {
10
11
  fs.mkdirSync(dest, { recursive: true });
@@ -13,7 +14,8 @@ function copyDir(src, dest) {
13
14
  const srcPath = path.join(src, entry.name);
14
15
  const destPath = path.join(dest, entry.name);
15
16
  if (entry.isDirectory()) {
16
- created.push(...copyDir(srcPath, destPath));
17
+ if (skipDirs.includes(entry.name)) continue;
18
+ created.push(...copyDir(srcPath, destPath, skipDirs));
17
19
  } else {
18
20
  fs.copyFileSync(srcPath, destPath);
19
21
  created.push(destPath);
@@ -117,4 +119,37 @@ function scaffold(projectDir) {
117
119
  return { created };
118
120
  }
119
121
 
120
- module.exports = { scaffold };
122
+ /**
123
+ * Update only the skill files (SKILL.md, actions, rules, schemas, templates).
124
+ * Preserves all user-generated data (registries, guides, ui-references, specs).
125
+ * Returns { updated: string[] } with relative paths of updated files.
126
+ */
127
+ function update(projectDir) {
128
+ const updated = [];
129
+ const pkgRoot = path.resolve(__dirname, '..');
130
+
131
+ const skillsSrc = path.join(pkgRoot, 'skills', 'design-workflow');
132
+ const skillsDest = path.join(projectDir, '.claude', 'skills', 'design-workflow');
133
+
134
+ if (!fs.existsSync(skillsDest)) {
135
+ return { updated: [], error: 'Bridge DS not initialized. Run: npx @noemuch/bridge-ds init' };
136
+ }
137
+
138
+ // Copy skill files, skipping user-generated KB data
139
+ const userDataDirs = ['registries', 'guides', 'ui-references'];
140
+ const files = copyDir(skillsSrc, skillsDest, userDataDirs);
141
+ updated.push(...files.map(f => path.relative(projectDir, f)));
142
+
143
+ // Update command file
144
+ const cmdSrc = path.join(pkgRoot, 'commands', 'design-workflow.md');
145
+ const cmdDest = path.join(projectDir, '.claude', 'commands', 'design-workflow.md');
146
+ if (fs.existsSync(cmdSrc)) {
147
+ fs.mkdirSync(path.dirname(cmdDest), { recursive: true });
148
+ fs.copyFileSync(cmdSrc, cmdDest);
149
+ updated.push(path.relative(projectDir, cmdDest));
150
+ }
151
+
152
+ return { updated };
153
+ }
154
+
155
+ module.exports = { scaffold, update };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noemuch/bridge-ds",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "AI-powered design generation in Figma — 100% design system compliant. Connects Claude Code to Figma via MCP for spec-first, token-bound, component-native design.",
5
5
  "main": "lib/cli.js",
6
6
  "bin": {