buildwright 0.0.3 → 0.0.4

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": "buildwright",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Agent-first autonomous development workflow. Ship code you don't read.",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -46,11 +46,15 @@ function init() {
46
46
  const stat = fs.statSync(fs.realpathSync(src));
47
47
 
48
48
  if (stat.isDirectory()) {
49
- console.log(` Copying ${entry}/`);
50
- copyDir(src, dest);
49
+ console.log(` Copying ${entry}/ (adding new files only)`);
50
+ copyDir(src, dest, { skipExisting: true });
51
51
  } else {
52
- console.log(` Copying ${entry}`);
53
- fs.copyFileSync(fs.realpathSync(src), dest);
52
+ if (fs.existsSync(dest)) {
53
+ console.log(` Skipping ${entry} (already exists)`);
54
+ } else {
55
+ console.log(` Copying ${entry}`);
56
+ fs.copyFileSync(fs.realpathSync(src), dest);
57
+ }
54
58
  }
55
59
  }
56
60
 
@@ -62,6 +62,26 @@ async function downloadAndExtract() {
62
62
  return { tmpDir, extractedRoot };
63
63
  }
64
64
 
65
+ /**
66
+ * Copy files from src to dest, but only files that exist in src.
67
+ * Files in dest that have no counterpart in src are left untouched.
68
+ */
69
+ function copyUpstreamOnly(src, dest) {
70
+ for (const entry of fs.readdirSync(src)) {
71
+ const srcEntry = path.join(src, entry);
72
+ const destEntry = path.join(dest, entry);
73
+ const stat = fs.statSync(srcEntry);
74
+ if (stat.isDirectory()) {
75
+ fs.mkdirSync(destEntry, { recursive: true });
76
+ copyUpstreamOnly(srcEntry, destEntry);
77
+ } else {
78
+ if (!fs.existsSync(destEntry)) {
79
+ fs.copyFileSync(srcEntry, destEntry); // only new files
80
+ }
81
+ }
82
+ }
83
+ }
84
+
65
85
  async function update() {
66
86
  const cwd = process.cwd();
67
87
 
@@ -86,7 +106,8 @@ async function update() {
86
106
  throw new Error('Downloaded archive is missing .buildwright/ directory');
87
107
  }
88
108
 
89
- // Update only the specified directories
109
+ // Update only the specified directories — overwrite upstream files only,
110
+ // never delete files the user added that don't exist in the upstream source.
90
111
  for (const dir of UPDATE_DIRS) {
91
112
  const src = path.join(srcBuildwright, dir);
92
113
  const dest = path.join(cwd, '.buildwright', dir);
@@ -94,17 +115,18 @@ async function update() {
94
115
  console.log(` ${YELLOW}Skipping ${dir}/ (not found in latest release)${RESET}`);
95
116
  continue;
96
117
  }
97
- console.log(` Updating .buildwright/${dir}/`);
98
- // Remove old and replace
99
- fs.rmSync(dest, { recursive: true, force: true });
100
- copyDir(src, dest);
118
+ console.log(` Updating .buildwright/${dir}/ (adding new files only)`);
119
+ fs.mkdirSync(dest, { recursive: true });
120
+ // Copy only files that exist in upstream — preserves user-added files
121
+ copyUpstreamOnly(src, dest);
101
122
  }
102
123
 
103
- // Also update CLAUDE.md if it exists in the download
124
+ // Also add CLAUDE.md if it doesn't already exist locally
104
125
  const srcClaude = path.join(extractedRoot, 'CLAUDE.md');
105
- if (fs.existsSync(srcClaude)) {
106
- console.log(` Updating CLAUDE.md`);
107
- fs.copyFileSync(srcClaude, path.join(cwd, 'CLAUDE.md'));
126
+ const destClaude = path.join(cwd, 'CLAUDE.md');
127
+ if (fs.existsSync(srcClaude) && !fs.existsSync(destClaude)) {
128
+ console.log(` Adding CLAUDE.md`);
129
+ fs.copyFileSync(srcClaude, destClaude);
108
130
  }
109
131
 
110
132
  console.log('');
@@ -118,8 +140,8 @@ async function update() {
118
140
 
119
141
  console.log('');
120
142
  console.log(`${GREEN}${BOLD}Update complete!${RESET}`);
121
- console.log('commands, agents, and claws are now up to date.');
122
- console.log('Your steering docs (.buildwright/steering/) are unchanged.\n');
143
+ console.log('commands, agents, and claws: new files added. Existing files unchanged.');
144
+ console.log('Your custom files and steering docs are unchanged.\n');
123
145
 
124
146
  } catch (err) {
125
147
  console.error(`\nUpdate failed: ${err.message}`);
@@ -10,9 +10,11 @@ const path = require('path');
10
10
  * @param {string} dest - Destination directory path
11
11
  * @param {object} [opts]
12
12
  * @param {string[]} [opts.skip] - Relative paths (from src) to skip
13
+ * @param {boolean} [opts.skipExisting] - Skip files that already exist at dest
13
14
  */
14
15
  function copyDir(src, dest, opts = {}) {
15
16
  const skip = opts.skip || [];
17
+ const skipExisting = opts.skipExisting || false;
16
18
  const entries = fs.readdirSync(src, { withFileTypes: true });
17
19
  fs.mkdirSync(dest, { recursive: true });
18
20
 
@@ -32,7 +34,11 @@ function copyDir(src, dest, opts = {}) {
32
34
  if (stat.isDirectory()) {
33
35
  copyDir(realSrcPath, destPath, opts);
34
36
  } else {
35
- fs.copyFileSync(realSrcPath, destPath);
37
+ if (skipExisting && fs.existsSync(destPath)) {
38
+ // leave existing file untouched
39
+ } else {
40
+ fs.copyFileSync(realSrcPath, destPath);
41
+ }
36
42
  }
37
43
  }
38
44
  }