@bostonuniversity/buwp-local 0.6.2 β†’ 0.7.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/docs/XDEBUG.md ADDED
@@ -0,0 +1,429 @@
1
+ # Xdebug Setup Guide
2
+
3
+ Xdebug configuration depends on your [volume mapping pattern](VOLUME_MAPPINGS.md). The key principle: **pathMappings must match your volume mappings exactly**.
4
+
5
+ ## Quick Start
6
+
7
+ 1. **Enable Xdebug** in `.buwp-local.json`:
8
+ ```json
9
+ "env": {
10
+ "XDEBUG": true
11
+ }
12
+ ```
13
+
14
+ 2. **Restart environment** to apply changes:
15
+ ```bash
16
+ npx buwp-local stop
17
+ npx buwp-local start
18
+ ```
19
+
20
+ 3. **Configure pathMappings** using the pattern-specific examples below.
21
+
22
+ ---
23
+
24
+ ## Pattern A: In-Repo Development
25
+
26
+ **Scenario:** buwp-local lives inside your plugin/theme repo (like wp-env).
27
+
28
+ **Volume mapping:**
29
+ ```json
30
+ "mappings": [
31
+ {
32
+ "local": ".",
33
+ "container": "/var/www/html/wp-content/plugins/bu-navigation"
34
+ }
35
+ ]
36
+ ```
37
+
38
+ ### VSCode Configuration
39
+
40
+ Create `.vscode/launch.json` in your plugin/theme repo:
41
+
42
+ ```json
43
+ {
44
+ "version": "0.2.0",
45
+ "configurations": [
46
+ {
47
+ "name": "Listen for Xdebug (Pattern A)",
48
+ "type": "php",
49
+ "request": "launch",
50
+ "port": 9003,
51
+ "pathMappings": {
52
+ "/var/www/html/wp-content/plugins/bu-navigation": "${workspaceRoot}"
53
+ }
54
+ }
55
+ ]
56
+ }
57
+ ```
58
+
59
+ ### PHPStorm Configuration
60
+
61
+ 1. Go to **Run β†’ Edit Configurations**
62
+ 2. Add **PHP Remote Debug** configuration
63
+ 3. Set **Server** configuration:
64
+ - Host: `localhost`
65
+ - Port: `9003`
66
+ - Debugger: `Xdebug`
67
+ 4. Add **Path mapping**:
68
+ - Local: `/path/to/bu-navigation` (your repo root)
69
+ - Remote: `/var/www/html/wp-content/plugins/bu-navigation`
70
+
71
+ ### Zed Configuration
72
+
73
+ Create `.zed/tasks.json`:
74
+
75
+ ```json
76
+ {
77
+ "xdebug": {
78
+ "type": "php",
79
+ "pathMappings": {
80
+ "/var/www/html/wp-content/plugins/bu-navigation": "."
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Pattern B: Sandbox Coordination
89
+
90
+ **Scenario:** Base camp directory maps multiple plugin/theme repos.
91
+
92
+ **Volume mapping:**
93
+ ```json
94
+ "mappings": [
95
+ {
96
+ "local": "/Users/jaydub/projects/bu-navigation",
97
+ "container": "/var/www/html/wp-content/plugins/bu-navigation"
98
+ },
99
+ {
100
+ "local": "/Users/jaydub/projects/bu-slideshow",
101
+ "container": "/var/www/html/wp-content/plugins/bu-slideshow"
102
+ }
103
+ ]
104
+ ```
105
+
106
+ ### VSCode Multi-Root Workspace
107
+
108
+ Create a **workspace file** (e.g., `bu-plugins.code-workspace`) to include all repos:
109
+
110
+ ```json
111
+ {
112
+ "folders": [
113
+ { "path": "../bu-navigation" },
114
+ { "path": "../bu-slideshow" }
115
+ ],
116
+ "settings": {},
117
+ "launch": {
118
+ "version": "0.2.0",
119
+ "configurations": [
120
+ {
121
+ "name": "Listen for Xdebug (Pattern B)",
122
+ "type": "php",
123
+ "request": "launch",
124
+ "port": 9003,
125
+ "pathMappings": {
126
+ "/var/www/html/wp-content/plugins/bu-navigation": "${workspaceFolder:bu-navigation}",
127
+ "/var/www/html/wp-content/plugins/bu-slideshow": "${workspaceFolder:bu-slideshow}"
128
+ }
129
+ }
130
+ ]
131
+ }
132
+ }
133
+ ```
134
+
135
+ **Usage:**
136
+ 1. Open the `.code-workspace` file in VSCode
137
+ 2. All mapped repos will be available in the sidebar
138
+ 3. Set breakpoints in any repo
139
+ 4. Start debugging with F5
140
+
141
+ ### PHPStorm Multi-Module Setup
142
+
143
+ 1. Open PHPStorm, go to **File β†’ Project Structure**
144
+ 2. Add each repo as a **Module**
145
+ 3. Configure **Run β†’ Edit Configurations β†’ PHP Remote Debug**
146
+ 4. Add path mappings for each repo:
147
+ - `/Users/jaydub/projects/bu-navigation` β†’ `/var/www/html/wp-content/plugins/bu-navigation`
148
+ - `/Users/jaydub/projects/bu-slideshow` β†’ `/var/www/html/wp-content/plugins/bu-slideshow`
149
+
150
+ ### Zed Workspace
151
+
152
+ Zed doesn't have multi-root workspace concept. Open each repo separately and configure individually (Pattern A style for each).
153
+
154
+ ---
155
+
156
+ ## Pattern C: Monolithic Sandbox
157
+
158
+ **Scenario:** Base camp maps entire WordPress installation for complete IDE context.
159
+
160
+ **Volume mapping:**
161
+ ```json
162
+ "mappings": [
163
+ {
164
+ "local": "/Users/jaydub/wordpress-builds/bu-prod",
165
+ "container": "/var/www/html"
166
+ }
167
+ ]
168
+ ```
169
+
170
+ ### VSCode Configuration
171
+
172
+ Create `.vscode/launch.json` in your WordPress build directory:
173
+
174
+ ```json
175
+ {
176
+ "version": "0.2.0",
177
+ "configurations": [
178
+ {
179
+ "name": "Listen for Xdebug (Pattern C)",
180
+ "type": "php",
181
+ "request": "launch",
182
+ "port": 9003,
183
+ "pathMappings": {
184
+ "/var/www/html": "${workspaceRoot}"
185
+ }
186
+ }
187
+ ]
188
+ }
189
+ ```
190
+
191
+ **Advantages:**
192
+ - Single path mapping (simpler)
193
+ - Full WordPress context in IDE
194
+ - Go-to-definition works across all code
195
+ - Autocomplete for WordPress core
196
+
197
+ **Trade-offs:**
198
+ - Slower volume performance on macOS
199
+ - Larger IDE project (may be slower)
200
+ - Must manage entire WordPress build
201
+
202
+ ### PHPStorm Configuration
203
+
204
+ 1. Open the WordPress build directory as your project root
205
+ 2. Configure **PHP Remote Debug**
206
+ 3. Add single path mapping:
207
+ - Local: `/Users/jaydub/wordpress-builds/bu-prod`
208
+ - Remote: `/var/www/html`
209
+
210
+ ### Zed Configuration
211
+
212
+ Create `.zed/tasks.json` in WordPress root:
213
+
214
+ ```json
215
+ {
216
+ "xdebug": {
217
+ "type": "php",
218
+ "pathMappings": {
219
+ "/var/www/html": "."
220
+ }
221
+ }
222
+ }
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Common Setup Steps (All Patterns)
228
+
229
+ ### Install PHP Debug Extension (VSCode)
230
+
231
+ 1. Open VSCode Extensions (Cmd+Shift+X)
232
+ 2. Search for "PHP Debug"
233
+ 3. Install: https://marketplace.visualstudio.com/items?itemName=xdebug.php-debug
234
+
235
+ ### Start Debugging
236
+
237
+ 1. **Set breakpoint** in your PHP file (click left gutter)
238
+ 2. **Start debug listener** (F5 or Run β†’ Start Debugging)
239
+ 3. **Trigger code** in browser (reload page, submit form, etc.)
240
+ 4. **Debugger pauses** at breakpoint
241
+
242
+ ### Verify Xdebug is Running
243
+
244
+ ```bash
245
+ # Check Xdebug is loaded
246
+ npx buwp-local wp eval 'phpinfo();' | grep -i xdebug
247
+
248
+ # Or via shell
249
+ npx buwp-local shell
250
+ php -v # Should show "with Xdebug"
251
+ ```
252
+
253
+ ---
254
+
255
+ ## Alternative: VSCode Remote Container Debugging
256
+
257
+ An alternative to volume mapping is to use VSCode's **Dev Containers** extension to open the entire WordPress container directly in VSCode. PhpStorm also has a similar feature (Zed does not currently support this).
258
+
259
+ ### How It Works
260
+
261
+ Instead of syncing code via volume mappings, you open VSCode **inside the container** and edit/debug directly there:
262
+
263
+ 1. Start buwp-local (any pattern, even without volume mappings)
264
+ 2. Right-click the running container in VSCode Docker explorer
265
+ 3. Select "Attach Visual Studio Code"
266
+ 4. VSCode opens inside the container with full filesystem access
267
+ 5. Set breakpoints and debug the entire build
268
+
269
+ ### When to Use This
270
+
271
+ - βœ… Experimental edits (don't need to persist locally)
272
+ - βœ… Full WordPress core context needed (like Pattern C)
273
+ - βœ… Stepping through entire codebase quickly
274
+ - βœ… Learning/exploring the build
275
+
276
+ ### Setup
277
+
278
+ 1. **Install Remote Containers Extension** (if not already installed)
279
+ - Open VSCode Extensions (Cmd+Shift+X)
280
+ - Search for "Remote - Containers"
281
+ - Install: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
282
+
283
+ 2. **Start your environment**
284
+ ```bash
285
+ npx buwp-local start
286
+ ```
287
+
288
+ 3. **Open container in VSCode**
289
+ - Click **Containers** (sidebar)
290
+ - Open the buwp-local project in the Containers list
291
+ - Right-click on the WordPress container β†’ **Attach Visual Studio Code**
292
+
293
+ 4. **Install Extensions and Configure Debugging in container**
294
+ - Install PHP Debug extension inside the container VSCode
295
+ - Create `.vscode/launch.json` with pathMappings as needed (usually just `/var/www/html` to `.`)
296
+
297
+ ### Advantages vs Volume Mapping
298
+
299
+ | Aspect | Volume Mapping | Remote Container |
300
+ |--------|---|---|
301
+ | **IDE Context** | Pattern-dependent | Full codebase always |
302
+ | **Persistence** | Changes stay local | Temporary only |
303
+ | **Performance** | Fast (local) | Slower (Docker I/O) |
304
+ | **Best For** | Production code changes | Experimental debugging |
305
+
306
+ ### When NOT to Use This
307
+
308
+ - ❌ Changes you need to keep locally (use volume mapping instead)
309
+
310
+ ---
311
+
312
+ ## Troubleshooting
313
+
314
+ ### Breakpoints Not Hit
315
+
316
+ **Check pathMappings match your volume mappings:**
317
+
318
+ ```bash
319
+ # View your volume mappings
320
+ npx buwp-local config --show
321
+
322
+ # Ensure pathMappings in launch.json match exactly
323
+ ```
324
+
325
+ **Common mistakes:**
326
+ - Pattern A: Using `/var/www/html` instead of full plugin path
327
+ - Pattern B: Missing mappings for some repos
328
+ - Pattern C: Wrong workspace root
329
+
330
+ ### "Cannot Find File" Errors
331
+
332
+ **VSCode shows:** "Could not find file /var/www/html/..."
333
+
334
+ **Solution:** Your local file path doesn't match the pathMapping. Check:
335
+ 1. Is VSCode workspace root correct?
336
+ 2. Does `${workspaceRoot}` resolve to the right path?
337
+ 3. For Pattern B, are you using multi-root workspace?
338
+
339
+ ### Performance Issues
340
+
341
+ **Xdebug can slow page loads significantly.**
342
+
343
+ **Solutions:**
344
+ - Disable Xdebug when not actively debugging
345
+ - Use conditional breakpoints sparingly
346
+ - Pattern C is slower than A/B due to larger volume mapping
347
+
348
+ ### Port Already in Use
349
+
350
+ **Error:** "Port 9003 already in use"
351
+
352
+ **Solution:**
353
+ ```bash
354
+ # Find process using port 9003
355
+ lsof -i :9003
356
+
357
+ # Kill if needed
358
+ kill -9 <PID>
359
+
360
+ # Or change Xdebug port in launch.json and container config
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Advanced Configuration
366
+
367
+ ### Conditional Breakpoints
368
+
369
+ Right-click breakpoint in VSCode β†’ Edit Breakpoint β†’ Add expression:
370
+
371
+ ```php
372
+ $post_id === 123
373
+ ```
374
+
375
+ ### Step Debugging WP-CLI Commands
376
+
377
+ ```bash
378
+ # Enable Xdebug for CLI
379
+ npx buwp-local wp --allow-root eval 'xdebug_break();'
380
+
381
+ # Or set environment variable
382
+ npx buwp-local shell
383
+ export XDEBUG_SESSION=1
384
+ wp plugin list
385
+ ```
386
+
387
+ ### Remote Debugging from Browser
388
+
389
+ Install Xdebug browser extension:
390
+ - Chrome: [Xdebug Helper](https://chrome.google.com/webstore/detail/xdebug-helper)
391
+ - Firefox: [Xdebug Helper](https://addons.mozilla.org/en-US/firefox/addon/xdebug-helper-for-firefox/)
392
+
393
+ Click extension icon β†’ Enable debugging β†’ Reload page.
394
+
395
+ ---
396
+
397
+ ## Pattern-Specific Tips
398
+
399
+ ### Pattern A (In-Repo)
400
+ - βœ… Simplest pathMapping setup
401
+ - ❌ No WordPress core debugging
402
+ - πŸ’‘ Use [php-stubs/wordpress-stubs](https://github.com/php-stubs/wordpress-stubs) for autocomplete
403
+
404
+ ### Pattern B (Sandbox)
405
+ - βœ… Debug multiple repos simultaneously
406
+ - ⚠️ Requires multi-root workspace in VSCode
407
+ - πŸ’‘ Create `.code-workspace` file for team to share
408
+
409
+ ### Pattern C (Monolithic)
410
+ - βœ… Debug WordPress core, plugins, themes all together
411
+ - βœ… Full IDE context (go-to-definition everywhere)
412
+ - ⚠️ Larger project, slower performance on macOS
413
+ - πŸ’‘ Use sparse checkout to reduce repo size
414
+
415
+ ---
416
+
417
+ ## Related Documentation
418
+
419
+ - **[VOLUME_MAPPINGS.md](VOLUME_MAPPINGS.md)** - Complete guide to volume mapping patterns
420
+ - **[GETTING_STARTED.md](GETTING_STARTED.md)** - Initial setup guide
421
+ - **[COMMANDS.md](COMMANDS.md)** - CLI reference
422
+
423
+ ---
424
+
425
+ ## References
426
+
427
+ - [Xdebug Documentation](https://xdebug.org/docs/)
428
+ - [VSCode PHP Debugging](https://code.visualstudio.com/docs/languages/php)
429
+ - [PHPStorm Xdebug Guide](https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html)
@@ -85,7 +85,7 @@ function confirmDestroy(projectName) {
85
85
  console.log(chalk.yellow(`This will destroy project: ${chalk.bold(projectName)}`));
86
86
  console.log(chalk.yellow(' - Stop all containers'));
87
87
  console.log(chalk.yellow(' - Remove all containers'));
88
- console.log(chalk.yellow(' - Delete all volumes (including database data) (except maybe not, please fix)\n'));
88
+ console.log(chalk.yellow(' - Delete all volumes (including database data)\n'));
89
89
 
90
90
  rl.question(chalk.red('Are you sure you want to continue? (yes/no): '), (answer) => {
91
91
  rl.close();
@@ -9,6 +9,17 @@ import fs from 'fs';
9
9
  import os from 'os';
10
10
  import { initConfig, CONFIG_FILE_NAME } from '../config.js';
11
11
 
12
+ /**
13
+ * Container path templates for project types
14
+ * Defines where each project type maps to in the WordPress container
15
+ */
16
+ const MAPPING_TEMPLATES = {
17
+ 'plugin': '/var/www/html/wp-content/plugins/{name}',
18
+ 'mu-plugin': '/var/www/html/wp-content/mu-plugins/{name}',
19
+ 'theme': '/var/www/html/wp-content/themes/{name}',
20
+ 'sandbox': null // Sandbox has no default mapping
21
+ };
22
+
12
23
  /**
13
24
  * Detect project type from package.json or directory structure
14
25
  * @param {string} projectPath - Path to project directory
@@ -84,6 +95,7 @@ async function initCommand(options) {
84
95
  if (options.plugin) initOptions.plugin = true;
85
96
  if (options.muPlugin) initOptions.muPlugin = true;
86
97
  if (options.theme) initOptions.theme = true;
98
+ if (options.sandbox) initOptions.sandbox = true;
87
99
 
88
100
  const configPath = initConfig(projectPath, initOptions);
89
101
  console.log(chalk.green(`βœ… Created configuration file: ${configPath}\n`));
@@ -101,11 +113,26 @@ async function initCommand(options) {
101
113
  console.log(chalk.cyan(`ℹ️ Detected project type: ${detectedType}\n`));
102
114
  }
103
115
 
104
- // Determine default project type index
105
- let defaultTypeIndex = 0;
106
- if (detectedType === 'plugin') defaultTypeIndex = 0;
107
- else if (detectedType === 'mu-plugin') defaultTypeIndex = 1;
108
- else if (detectedType === 'theme') defaultTypeIndex = 2;
116
+ // Define project type choices
117
+ const projectTypeChoices = [
118
+ { title: 'Plugin', value: 'plugin', description: 'WordPress plugin development' },
119
+ { title: 'MU Plugin', value: 'mu-plugin', description: 'Must-use plugin development' },
120
+ { title: 'Theme', value: 'theme', description: 'WordPress theme development' },
121
+ { title: 'Sandbox', value: 'sandbox', description: 'Base WordPress environment (add code mappings later)' }
122
+ ];
123
+
124
+ // Determine default project type with priority: CLI flag > detected type > default
125
+ const typeFromFlag = options.plugin ? 'plugin'
126
+ : options.muPlugin ? 'mu-plugin'
127
+ : options.theme ? 'theme'
128
+ : options.sandbox ? 'sandbox'
129
+ : null;
130
+
131
+ const preferredType = typeFromFlag || detectedType || 'plugin';
132
+
133
+ const defaultTypeIndex = projectTypeChoices.findIndex(
134
+ choice => choice.value === preferredType
135
+ );
109
136
 
110
137
  const questions = [
111
138
  {
@@ -119,13 +146,7 @@ async function initCommand(options) {
119
146
  type: 'select',
120
147
  name: 'projectType',
121
148
  message: 'Project type',
122
- choices: [
123
- { title: 'Plugin', value: 'plugin', description: 'WordPress plugin development' },
124
- { title: 'MU Plugin', value: 'mu-plugin', description: 'Must-use plugin development' },
125
- { title: 'Theme', value: 'theme', description: 'WordPress theme development' },
126
- { title: 'Sandbox', value: 'sandbox', description: 'Base WordPress environment (add code mappings later)' },
127
- { title: 'Custom', value: 'custom', description: 'Custom mapping configuration' }
128
- ],
149
+ choices: projectTypeChoices,
129
150
  initial: defaultTypeIndex
130
151
  },
131
152
  {
@@ -245,31 +266,12 @@ async function initCommand(options) {
245
266
  }
246
267
  };
247
268
 
248
- // Add mapping based on project type
249
- if (answers.projectType === 'plugin') {
250
- config.mappings.push({
251
- local: './',
252
- container: `/var/www/html/wp-content/plugins/${answers.projectName}`
253
- });
254
- } else if (answers.projectType === 'mu-plugin') {
255
- config.mappings.push({
256
- local: './',
257
- container: `/var/www/html/wp-content/mu-plugins/${answers.projectName}`
258
- });
259
- } else if (answers.projectType === 'theme') {
260
- config.mappings.push({
261
- local: './',
262
- container: `/var/www/html/wp-content/themes/${answers.projectName}`
263
- });
264
- } else if (answers.projectType === 'sandbox') {
265
- // Sandbox type: no initial mappings
266
- // User can add mappings manually to config.mappings array
267
- } else {
268
- // Custom type
269
+ // Add mapping based on project type using template
270
+ const template = MAPPING_TEMPLATES[answers.projectType];
271
+ if (template) {
269
272
  config.mappings.push({
270
273
  local: './',
271
- container: '/var/www/html/wp-content/plugins/my-plugin',
272
- comment: 'Customize this mapping for your project'
274
+ container: template.replace('{name}', answers.projectName)
273
275
  });
274
276
  }
275
277
 
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Update command - Updates Docker images and recreates containers
3
+ */
4
+
5
+ import chalk from 'chalk';
6
+ import { execSync } from 'child_process';
7
+ import path from 'path';
8
+ import fs from 'fs';
9
+ import { loadConfig, loadKeychainCredentials, createSecureTempEnvFile, secureDeleteTempEnvFile, ENV_FILE_NAME } from '../config.js';
10
+
11
+ async function updateCommand(options = {}) {
12
+ console.log(chalk.blue('πŸ”„ Updating Docker images...\n'));
13
+
14
+ try {
15
+ const projectPath = process.cwd();
16
+ const composePath = path.join(projectPath, '.buwp-local', 'docker-compose.yml');
17
+ const composeDir = path.dirname(composePath);
18
+ const envFilePath = path.join(projectPath, ENV_FILE_NAME);
19
+
20
+ // Check if docker-compose.yml exists
21
+ if (!fs.existsSync(composePath)) {
22
+ console.log(chalk.yellow('⚠️ No environment found.'));
23
+ console.log(chalk.gray('Run "buwp-local start" to create an environment.\n'));
24
+ return;
25
+ }
26
+
27
+ // Load config to get project name
28
+ const config = loadConfig(projectPath);
29
+ const projectName = config.projectName || 'buwp-local';
30
+
31
+ // Check if Docker is running
32
+ try {
33
+ execSync('docker info', { stdio: 'ignore' });
34
+ } catch (err) {
35
+ console.error(chalk.red('❌ Docker is not running'));
36
+ console.log(chalk.gray('Please start Docker Desktop and try again.\n'));
37
+ process.exit(1);
38
+ }
39
+
40
+ // Determine which services to pull
41
+ const pullAll = options.all || false;
42
+ const imageFilter = pullAll ? '' : 'wordpress';
43
+
44
+ // Step 1: Pull images (WordPress only by default, or all with --all flag)
45
+ console.log(chalk.cyan(pullAll ? 'πŸ“₯ Pulling all Docker images...' : 'πŸ“₯ Pulling WordPress image...'));
46
+ try {
47
+ execSync(
48
+ `docker compose -p ${projectName} -f "${composePath}" pull ${imageFilter}`,
49
+ {
50
+ cwd: composeDir,
51
+ stdio: 'inherit'
52
+ }
53
+ );
54
+ } catch (err) {
55
+ console.error(chalk.red('\n❌ Failed to pull Docker images'));
56
+ console.log(chalk.gray('Check your Docker registry credentials and network connection.\n'));
57
+ process.exit(1);
58
+ }
59
+
60
+ // Step 2: Recreate containers with new images (preserves volumes)
61
+ // Need to pass environment variables just like start command does
62
+ console.log(chalk.cyan('\nπŸ”¨ Recreating containers with new images...'));
63
+
64
+ // Load keychain credentials and create secure temp env file if available
65
+ let tempEnvPath = null;
66
+ const finalKeychainCredentials = loadKeychainCredentials();
67
+ const keychainCredCount = Object.keys(finalKeychainCredentials).length;
68
+
69
+ if (keychainCredCount > 0) {
70
+ try {
71
+ tempEnvPath = createSecureTempEnvFile(finalKeychainCredentials, projectName);
72
+ } catch (err) {
73
+ console.warn(chalk.yellow(`⚠️ Could not load keychain credentials: ${err.message}`));
74
+ }
75
+ }
76
+
77
+ // Build env-file flags
78
+ const envFileFlag = fs.existsSync(envFilePath) ? `--env-file ${envFilePath}` : '';
79
+ const tempEnvFileFlag = tempEnvPath ? `--env-file ${tempEnvPath}` : '';
80
+
81
+ try {
82
+ execSync(
83
+ `docker compose -p ${projectName} ${tempEnvFileFlag} ${envFileFlag} -f "${composePath}" up -d --force-recreate`,
84
+ {
85
+ cwd: composeDir,
86
+ stdio: 'inherit'
87
+ }
88
+ );
89
+ } catch (err) {
90
+ console.error(chalk.red('\n❌ Failed to recreate containers'));
91
+ process.exit(1);
92
+ } finally {
93
+ // Always clean up temp env file
94
+ if (tempEnvPath) {
95
+ secureDeleteTempEnvFile(tempEnvPath);
96
+ }
97
+ }
98
+
99
+ // Success message
100
+ console.log(chalk.green('\nβœ… Update complete!\n'));
101
+ console.log(chalk.gray('Preserved:'));
102
+ console.log(chalk.gray(' βœ“ Database and WordPress data'));
103
+ console.log(chalk.gray(' βœ“ Volume mappings and configuration\n'));
104
+ console.log(chalk.cyan('Access your site at:'));
105
+ console.log(chalk.white(` https://${config.hostname}\n`));
106
+
107
+ } catch (err) {
108
+ console.error(chalk.red('\n❌ Error:'), err.message);
109
+ process.exit(1);
110
+ }
111
+ }
112
+
113
+ export default updateCommand;
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@bostonuniversity/buwp-local",
3
- "version": "0.6.2",
3
+ "version": "0.7.0",
4
4
  "description": "Local WordPress development environment for Boston University projects",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "bin": {
8
- "buwp-local": "./bin/buwp-local.js"
8
+ "buwp-local": "bin/buwp-local.js"
9
9
  },
10
10
  "scripts": {
11
11
  "test": "echo \"Error: no test specified\" && exit 1",
package/readme.md CHANGED
@@ -99,7 +99,10 @@ Your local WordPress site should now be accessible at the hostname you configure
99
99
 
100
100
  - πŸ“˜ [Getting Started Guide](docs/GETTING_STARTED.md)
101
101
  - πŸ“– [Command Reference](docs/COMMANDS.md)
102
+ - πŸ—ΊοΈ [Volume Mapping Patterns](docs/VOLUME_MAPPINGS.md) - Flexible development workflows
103
+ - πŸ› [Xdebug Setup](docs/XDEBUG.md) - Step debugging configuration
102
104
  - πŸ” [Credential Management](docs/CREDENTIALS.md)
105
+ - πŸ”„ [Migration from VM Sandboxes](docs/MIGRATION_FROM_VM.md)
103
106
  - πŸ—οΈ [Architecture](docs/ARCHITECTURE.md) (for contributors)
104
107
 
105
108
  ## Features