whiteport-design-studio 0.2.0 → 0.2.1

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,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "whiteport-design-studio",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "description": "Whiteport Design Studio - Strategic design methodology for AI-powered workflows",
6
6
  "keywords": [
7
7
  "design",
@@ -0,0 +1,85 @@
1
+ # Project Info: {{project_name}}
2
+
3
+ **Created:** {{date}}
4
+ **Project Type:** {{project_type}}
5
+ **Design Experience:** {{design_experience}}
6
+ **Status:** In progress
7
+
8
+ ---
9
+
10
+ ## Team
11
+
12
+ **Project Lead:** {{user_name}}
13
+ **Communication Language:** {{communication_language}}
14
+ **Document Output Language:** {{document_output_language}}
15
+
16
+ ---
17
+
18
+ ## Project Configuration
19
+
20
+ **Output Folder:** `{{output_folder}}/`
21
+ **WDS System Folder:** `{{wds_folder}}/`
22
+
23
+ Configuration stored in: `{{wds_folder}}/config.yaml`
24
+
25
+ ---
26
+
27
+ ## Quick Navigation
28
+
29
+ **Product Brief (Phase 1):**
30
+ - [01 — Product Brief](01-product-brief.md)
31
+ - [02 — Content Language](02-content-language.md)
32
+ - [03 — Visual Direction](03-visual-direction.md)
33
+ - [04 — Platform Requirements](04-platform-requirements.md)
34
+
35
+ **Trigger Map (Phase 2):**
36
+ - [00 — Trigger Map Overview](../B-Trigger-Map/00-trigger-map.md)
37
+
38
+ **UX Scenarios (Phase 4):**
39
+ - [UX Scenarios Guide](../C-UX-Scenarios/ux-scenarios-guide.md)
40
+
41
+ **Design System (Phase 7):**
42
+ - [00 — Design System Overview](../D-Design-System/00-design-system.md)
43
+
44
+ ---
45
+
46
+ ## Project Timeline
47
+
48
+ | Phase | Status | Completed |
49
+ |-------|--------|-----------|
50
+ | 1 — Product Brief | Not started | — |
51
+ | 2 — Trigger Map | Not started | — |
52
+ | 3 — Platform Requirements | Not started | — |
53
+ | 4 — UX Design | Not started | — |
54
+ | 5 — Design System | Not started | — |
55
+ | 6 — Design Deliveries | Not started | — |
56
+ | 7 — Testing | Not started | — |
57
+
58
+ ---
59
+
60
+ ## Technical Stack
61
+
62
+ **Frontend:** TBD
63
+ **Backend:** TBD
64
+ **Hosting:** TBD
65
+ **Languages:** {{document_output_language}}
66
+
67
+ ---
68
+
69
+ ## WDS Agents
70
+
71
+ To activate agents, tell Claude:
72
+
73
+ ```
74
+ Read and activate the agent in `{{wds_folder}}/agents/[agent-name].md`
75
+ ```
76
+
77
+ **Available:**
78
+ - **Mimir** — Orchestrator & Guide
79
+ - **Saga** — Product Brief & Trigger Mapping
80
+ - **Idunn** — Platform Requirements & Design Deliveries
81
+ - **Freya** — UX Design, Design System & Testing
82
+
83
+ ---
84
+
85
+ *Generated by Whiteport Design Studio installer*
@@ -103,14 +103,23 @@ class Installer {
103
103
 
104
104
  // Step 4: Create docs folder structure
105
105
  const docsSpinner = ora('Creating project folders...').start();
106
+ let detectedOutputFolder = 'docs';
106
107
  try {
107
- await this.createDocsFolders(projectDir);
108
- docsSpinner.succeed('Project folders created');
108
+ detectedOutputFolder = await this.createDocsFolders(projectDir);
109
+ docsSpinner.succeed(`Project folders created in ${detectedOutputFolder}/`);
109
110
  } catch (error) {
110
111
  docsSpinner.fail('Failed to create project folders');
111
112
  throw error;
112
113
  }
113
114
 
115
+ // Update config.yaml with detected output folder (if different from default)
116
+ if (detectedOutputFolder !== 'docs') {
117
+ const configPath = path.join(wdsDir, 'config.yaml');
118
+ let configContent = await fs.readFile(configPath, 'utf8');
119
+ configContent = configContent.replace(/output_folder:\s*docs/, `output_folder: ${detectedOutputFolder}`);
120
+ await fs.writeFile(configPath, configContent, 'utf8');
121
+ }
122
+
114
123
  // Step 5: Set up IDEs
115
124
  const ideList = ides || (config.ide ? [config.ide] : []);
116
125
  const ideSpinner = ora(`Setting up ${ideList.length} IDE(s)...`).start();
@@ -234,9 +243,30 @@ class Installer {
234
243
 
235
244
  /**
236
245
  * Create the WDS docs folder structure
246
+ * FIXED: Detects existing folders, doesn't overwrite files
237
247
  */
238
248
  async createDocsFolders(projectDir) {
239
- const docsPath = path.join(projectDir, 'docs');
249
+ // Check if user already has a deliverables folder with WDS content
250
+ const possibleFolders = ['design-process', 'docs', 'deliverables', 'wds-deliverables'];
251
+ let existingFolder = null;
252
+
253
+ for (const folderName of possibleFolders) {
254
+ const folderPath = path.join(projectDir, folderName);
255
+ if (await fs.pathExists(folderPath)) {
256
+ // Check if it has WDS structure (A-Product-Brief, B-Trigger-Map, etc.)
257
+ const hasProductBrief = await fs.pathExists(path.join(folderPath, 'A-Product-Brief'));
258
+ const hasTriggerMap = await fs.pathExists(path.join(folderPath, 'B-Trigger-Map'));
259
+ if (hasProductBrief || hasTriggerMap) {
260
+ existingFolder = folderName;
261
+ break;
262
+ }
263
+ }
264
+ }
265
+
266
+ // Use existing folder if found, otherwise default to 'docs'
267
+ const outputFolder = existingFolder || 'docs';
268
+ const docsPath = path.join(projectDir, outputFolder);
269
+
240
270
  const folders = [
241
271
  'A-Product-Brief',
242
272
  'B-Trigger-Map',
@@ -250,14 +280,121 @@ class Installer {
250
280
 
251
281
  for (const folder of folders) {
252
282
  const folderPath = path.join(docsPath, folder);
253
- await fs.ensureDir(folderPath);
254
283
 
255
- // Add .gitkeep to preserve empty directories
256
- const gitkeepPath = path.join(folderPath, '.gitkeep');
257
- if (!(await fs.pathExists(gitkeepPath))) {
258
- await fs.writeFile(gitkeepPath, '# This file ensures the directory is tracked by git\n');
284
+ // Only create folder if it doesn't exist
285
+ if (!(await fs.pathExists(folderPath))) {
286
+ await fs.ensureDir(folderPath);
287
+
288
+ // Add .gitkeep to preserve empty directories (only if folder is empty)
289
+ const gitkeepPath = path.join(folderPath, '.gitkeep');
290
+ const existingFiles = await fs.readdir(folderPath);
291
+ if (existingFiles.length === 0) {
292
+ await fs.writeFile(gitkeepPath, '# This file ensures the directory is tracked by git\n');
293
+ }
259
294
  }
260
295
  }
296
+
297
+ // Create 00 guide files in each folder (if they don't exist)
298
+ await this.createFolderGuides(docsPath, config);
299
+
300
+ // Return the detected/used folder name so config.yaml can be updated
301
+ return outputFolder;
302
+ }
303
+
304
+ /**
305
+ * Create 00 guide files in each folder from templates
306
+ */
307
+ async createFolderGuides(docsPath, config) {
308
+ const templateDir = path.join(this.srcDir, 'workflows', '0-project-setup', 'templates', 'folder-guides');
309
+
310
+ // Mapping: template filename → destination folder & filename
311
+ const guides = [
312
+ { template: '00-product-brief.template.md', folder: 'A-Product-Brief', filename: '00-product-brief.md' },
313
+ { template: '00-trigger-map.template.md', folder: 'B-Trigger-Map', filename: '00-trigger-map.md' },
314
+ { template: '00-ux-scenarios.template.md', folder: 'C-UX-Scenarios', filename: '00-ux-scenarios.md' },
315
+ { template: '00-design-system.template.md', folder: 'D-Design-System', filename: '00-design-system.md' },
316
+ ];
317
+
318
+ // Common placeholder replacements
319
+ const replacements = {
320
+ '{{project_name}}': config.project_name || 'Untitled Project',
321
+ '{{date}}': new Date().toISOString().split('T')[0],
322
+ '{{project_type}}': config.project_type || 'digital_product',
323
+ '{{design_experience}}': config.design_experience || 'intermediate',
324
+ '{{user_name}}': config.user_name || 'Designer',
325
+ '{{communication_language}}': config.communication_language || 'en',
326
+ '{{document_output_language}}': config.document_output_language || 'en',
327
+ '{{output_folder}}': path.relative(config.projectDir, docsPath) || 'docs',
328
+ '{{wds_folder}}': config.wdsFolder || '_wds',
329
+ };
330
+
331
+ // Create each folder guide
332
+ for (const guide of guides) {
333
+ const templatePath = path.join(templateDir, guide.template);
334
+ const destPath = path.join(docsPath, guide.folder, guide.filename);
335
+
336
+ // Skip if file exists (never overwrite) or template doesn't exist
337
+ if (await fs.pathExists(destPath)) continue;
338
+ if (!(await fs.pathExists(templatePath))) continue;
339
+
340
+ // Read template
341
+ let content = await fs.readFile(templatePath, 'utf8');
342
+
343
+ // Replace all placeholders
344
+ for (const [placeholder, value] of Object.entries(replacements)) {
345
+ content = content.split(placeholder).join(value);
346
+ }
347
+
348
+ // Write file
349
+ await fs.writeFile(destPath, content, 'utf8');
350
+ }
351
+
352
+ // Also create 00-project-info.md in A-Product-Brief (project settings home)
353
+ await this.createProjectInfoFile(docsPath, config);
354
+ }
355
+
356
+ /**
357
+ * Create 00-project-info.md in A-Product-Brief from template
358
+ */
359
+ async createProjectInfoFile(docsPath, config) {
360
+ const productBriefPath = path.join(docsPath, 'A-Product-Brief');
361
+ const projectInfoPath = path.join(productBriefPath, '00-project-info.md');
362
+
363
+ // Only create if it doesn't exist (never overwrite)
364
+ if (await fs.pathExists(projectInfoPath)) {
365
+ return;
366
+ }
367
+
368
+ const templatePath = path.join(this.srcDir, 'workflows', '1-project-brief', 'templates', '00-project-info.template.md');
369
+
370
+ // Check if template exists
371
+ if (!(await fs.pathExists(templatePath))) {
372
+ // Skip if template not found (backward compatibility)
373
+ return;
374
+ }
375
+
376
+ // Read template
377
+ let template = await fs.readFile(templatePath, 'utf8');
378
+
379
+ // Replace placeholders
380
+ const replacements = {
381
+ '{{project_name}}': config.project_name || 'Untitled Project',
382
+ '{{date}}': new Date().toISOString().split('T')[0],
383
+ '{{project_type}}': config.project_type || 'digital_product',
384
+ '{{design_experience}}': config.design_experience || 'intermediate',
385
+ '{{user_name}}': config.user_name || 'Designer',
386
+ '{{communication_language}}': config.communication_language || 'en',
387
+ '{{document_output_language}}': config.document_output_language || 'en',
388
+ '{{output_folder}}': path.relative(config.projectDir, docsPath) || 'docs',
389
+ '{{wds_folder}}': config.wdsFolder || '_wds',
390
+ };
391
+
392
+ for (const [placeholder, value] of Object.entries(replacements)) {
393
+ template = template.split(placeholder).join(value);
394
+ }
395
+
396
+ // Write the file
397
+ await fs.writeFile(projectInfoPath, template, 'utf8');
261
398
  }
262
399
  }
263
400