mise-en-scene 0.1.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.
Files changed (54) hide show
  1. package/README.md +184 -0
  2. package/dist/commands/clean.d.ts +7 -0
  3. package/dist/commands/clean.d.ts.map +1 -0
  4. package/dist/commands/clean.js +46 -0
  5. package/dist/commands/clean.js.map +1 -0
  6. package/dist/commands/export.d.ts +10 -0
  7. package/dist/commands/export.d.ts.map +1 -0
  8. package/dist/commands/export.js +27 -0
  9. package/dist/commands/export.js.map +1 -0
  10. package/dist/commands/gallery.d.ts +2 -0
  11. package/dist/commands/gallery.d.ts.map +1 -0
  12. package/dist/commands/gallery.js +22 -0
  13. package/dist/commands/gallery.js.map +1 -0
  14. package/dist/commands/init.d.ts +6 -0
  15. package/dist/commands/init.d.ts.map +1 -0
  16. package/dist/commands/init.js +82 -0
  17. package/dist/commands/init.js.map +1 -0
  18. package/dist/commands/serve.d.ts +7 -0
  19. package/dist/commands/serve.d.ts.map +1 -0
  20. package/dist/commands/serve.js +17 -0
  21. package/dist/commands/serve.js.map +1 -0
  22. package/dist/commands/stop.d.ts +6 -0
  23. package/dist/commands/stop.d.ts.map +1 -0
  24. package/dist/commands/stop.js +17 -0
  25. package/dist/commands/stop.js.map +1 -0
  26. package/dist/commands/taste.d.ts +7 -0
  27. package/dist/commands/taste.d.ts.map +1 -0
  28. package/dist/commands/taste.js +32 -0
  29. package/dist/commands/taste.js.map +1 -0
  30. package/dist/config-writer.d.ts +2 -0
  31. package/dist/config-writer.d.ts.map +1 -0
  32. package/dist/config-writer.js +32 -0
  33. package/dist/config-writer.js.map +1 -0
  34. package/dist/detect-platform.d.ts +15 -0
  35. package/dist/detect-platform.d.ts.map +1 -0
  36. package/dist/detect-platform.js +39 -0
  37. package/dist/detect-platform.js.map +1 -0
  38. package/dist/hooks-installer.d.ts +8 -0
  39. package/dist/hooks-installer.d.ts.map +1 -0
  40. package/dist/hooks-installer.js +62 -0
  41. package/dist/hooks-installer.js.map +1 -0
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +77 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/scaffold.d.ts +2 -0
  47. package/dist/scaffold.d.ts.map +1 -0
  48. package/dist/scaffold.js +37 -0
  49. package/dist/scaffold.js.map +1 -0
  50. package/dist/types.d.ts +13 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +2 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +46 -0
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # mise-en-scene
2
+
3
+ CLI bootstrap for mise en scene. One command to install and configure the full design toolkit — detects your agent environment (Claude Code, Cursor, or both), registers MCP servers, installs hooks, deploys the skill file, and scaffolds the project directory.
4
+
5
+ All dependencies ([`@mise-en-scene/server`](https://github.com/daviesayo/mise-en-scene/tree/main/packages/server), [`@mise-en-scene/taste-memory`](https://github.com/daviesayo/mise-en-scene/tree/main/packages/taste-memory)) are bundled — no separate installs needed.
6
+
7
+ ## Quick Start
8
+
9
+ ```bash
10
+ npx mise-en-scene init
11
+ ```
12
+
13
+ This single command:
14
+
15
+ 1. **Detects** Claude Code (`~/.claude/`) and Cursor (`~/.cursor/`)
16
+ 2. **Registers** both MCP servers in the platform's config
17
+ 3. **Installs** hooks (post-design SVGO optimization, post-export file opener, session-start server launcher)
18
+ 4. **Deploys** the SKILL.md to the platform's skill directory
19
+ 5. **Scaffolds** `mise-en-scene/` in your project
20
+
21
+ ## Commands
22
+
23
+ ### `init`
24
+
25
+ ```bash
26
+ mise-en-scene init [--dir <path>]
27
+ ```
28
+
29
+ Full bootstrap. Safe to run multiple times — merges configs without duplicating entries, preserves existing files.
30
+
31
+ ### `serve`
32
+
33
+ ```bash
34
+ mise-en-scene serve [--port 3333] [--dir mise-en-scene/main]
35
+ ```
36
+
37
+ Start the design preview server. Serves HTML designs with hot-reload and WebSocket feedback.
38
+
39
+ ### `stop`
40
+
41
+ ```bash
42
+ mise-en-scene stop [--port 3333]
43
+ ```
44
+
45
+ Stop the design server and shut down Puppeteer.
46
+
47
+ ### `export`
48
+
49
+ ```bash
50
+ mise-en-scene export [--format png] [--output path] [--width 1080] [-H 1080] [--quality 90]
51
+ ```
52
+
53
+ Export the current design. Requires the server to be running.
54
+
55
+ | Flag | Default | Description |
56
+ |------|---------|-------------|
57
+ | `-f, --format` | `png` | Format: `svg`, `png`, `jpg`, `pdf` |
58
+ | `-o, --output` | `mise-en-scene/exports/design.<fmt>` | Output path |
59
+ | `-w, --width` | — | Width in pixels |
60
+ | `-H, --height` | — | Height in pixels (uppercase to avoid `-h` conflict with help) |
61
+ | `-q, --quality` | `90` | JPEG quality (1-100) |
62
+
63
+ ### `gallery`
64
+
65
+ ```bash
66
+ mise-en-scene gallery
67
+ ```
68
+
69
+ Open the version gallery in your default browser. Shows all branches and versions as thumbnail cards.
70
+
71
+ ### `taste`
72
+
73
+ ```bash
74
+ mise-en-scene taste [--scope merged] [--project <name>]
75
+ ```
76
+
77
+ Print a summary of the current taste profile from the `.taste/` directory.
78
+
79
+ ### `clean`
80
+
81
+ ```bash
82
+ mise-en-scene clean [--dir <path>] [--all]
83
+ ```
84
+
85
+ Reset project state. Removes `.taste/`, clears branches and main versions, removes feedback and gallery cache. Keeps `exports/` unless `--all` is passed.
86
+
87
+ ## Platform Detection
88
+
89
+ The CLI checks for these directories in `$HOME`:
90
+
91
+ | Directory | Platform | MCP Config | Skill File |
92
+ |-----------|----------|------------|------------|
93
+ | `~/.claude/` | Claude Code | `.mcp.json` (project) | `~/.claude/skills/mise-en-scene/SKILL.md` |
94
+ | `~/.cursor/` | Cursor | `.cursor/mcp.json` (project) | `~/.cursor/rules/mise-en-scene.mdc` |
95
+
96
+ Both platforms are configured when both are detected.
97
+
98
+ ## MCP Config
99
+
100
+ The `init` command writes (or merges into) the platform's MCP config:
101
+
102
+ ```json
103
+ {
104
+ "mcpServers": {
105
+ "mise-en-scene-server": {
106
+ "command": "npx",
107
+ "args": ["@mise-en-scene/server"]
108
+ },
109
+ "mise-en-scene-taste-memory": {
110
+ "command": "npx",
111
+ "args": ["@mise-en-scene/taste-memory"]
112
+ }
113
+ }
114
+ }
115
+ ```
116
+
117
+ Existing servers in the config are preserved.
118
+
119
+ ## Hooks
120
+
121
+ Three shell scripts are installed for Claude Code hook integration:
122
+
123
+ | Hook | Trigger | Action |
124
+ |------|---------|--------|
125
+ | `post-design.sh` | After `studio_preview` | Runs SVGO optimization on the design file |
126
+ | `post-export.sh` | After `studio_export` | Opens the exported file in the system viewer |
127
+ | `session-start.sh` | Session start | Starts the design server if not already running |
128
+
129
+ All hooks read input from stdin (per the Claude Code hook protocol) and fail gracefully.
130
+
131
+ ## Project Scaffold
132
+
133
+ `init` creates this structure in your project:
134
+
135
+ ```
136
+ mise-en-scene/
137
+ ├── references/ # Drop reference images here
138
+ │ └── .gitkeep
139
+ ├── exports/ # Exported designs land here
140
+ │ └── .gitkeep
141
+ ├── main/ # Main design branch (versioned HTML)
142
+ │ └── .gitkeep
143
+ ├── branches/ # Design branches
144
+ │ └── .gitkeep
145
+ └── .taste/ # Project taste profile
146
+ ├── brief.json
147
+ ├── references.json
148
+ ├── design-system.json
149
+ ├── mood-board.json
150
+ └── decisions.json
151
+ ```
152
+
153
+ ## Programmatic Usage
154
+
155
+ ```typescript
156
+ import { detectPlatforms } from '@mise-en-scene/cli/detect-platform';
157
+ import { writeMcpConfig } from '@mise-en-scene/cli/config-writer';
158
+ import { installHooks } from '@mise-en-scene/cli/hooks-installer';
159
+ import { scaffoldProject } from '@mise-en-scene/cli/scaffold';
160
+
161
+ // Detect environment
162
+ const detection = detectPlatforms(os.homedir(), process.cwd());
163
+
164
+ // Configure each platform
165
+ for (const platform of detection.platforms) {
166
+ writeMcpConfig(platform.mcpConfig, platform.name);
167
+ installHooks({
168
+ platform: platform.name,
169
+ hooksDir: platform.hooksDir,
170
+ hooksConfigPath: '...',
171
+ });
172
+ }
173
+
174
+ // Scaffold project
175
+ scaffoldProject(process.cwd());
176
+ ```
177
+
178
+ ## Development
179
+
180
+ ```bash
181
+ npm test # Run tests (15 unit + 3 integration)
182
+ npm run build # Compile TypeScript
183
+ npm run test:watch # Watch mode
184
+ ```
@@ -0,0 +1,7 @@
1
+ interface CleanOptions {
2
+ projectDir?: string;
3
+ keepExports?: boolean;
4
+ }
5
+ export declare function clean(opts?: CleanOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=clean.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"AAGA,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDlE"}
@@ -0,0 +1,46 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ export async function clean(opts = {}) {
4
+ const projectDir = opts.projectDir ?? process.cwd();
5
+ const miseDir = path.join(projectDir, 'mise-en-scene');
6
+ if (!fs.existsSync(miseDir)) {
7
+ console.log(' No mise-en-scene directory found.');
8
+ return;
9
+ }
10
+ console.log(' ✦ Cleaning mise-en-scene project...');
11
+ const tasteDir = path.join(miseDir, '.taste');
12
+ if (fs.existsSync(tasteDir)) {
13
+ fs.rmSync(tasteDir, { recursive: true });
14
+ console.log(' ├─ Removed .taste/ ✓');
15
+ }
16
+ const branchesDir = path.join(miseDir, 'branches');
17
+ if (fs.existsSync(branchesDir)) {
18
+ fs.rmSync(branchesDir, { recursive: true });
19
+ fs.mkdirSync(branchesDir, { recursive: true });
20
+ console.log(' ├─ Cleared branches/ ✓');
21
+ }
22
+ const mainDir = path.join(miseDir, 'main');
23
+ if (fs.existsSync(mainDir)) {
24
+ const files = fs.readdirSync(mainDir).filter((f) => f.endsWith('.html'));
25
+ for (const file of files) {
26
+ fs.unlinkSync(path.join(mainDir, file));
27
+ }
28
+ console.log(` ├─ Cleared ${files.length} versions from main/ ✓`);
29
+ }
30
+ const cacheDir = path.join(miseDir, '.gallery-cache');
31
+ if (fs.existsSync(cacheDir)) {
32
+ fs.rmSync(cacheDir, { recursive: true });
33
+ console.log(' ├─ Removed .gallery-cache/ ✓');
34
+ }
35
+ const feedbackFile = path.join(miseDir, '.feedback');
36
+ if (fs.existsSync(feedbackFile)) {
37
+ fs.unlinkSync(feedbackFile);
38
+ console.log(' ├─ Removed .feedback ✓');
39
+ }
40
+ if (!opts.keepExports) {
41
+ console.log(' └─ Kept exports/ (use --all to remove)');
42
+ }
43
+ console.log('');
44
+ console.log(' ✦ Clean complete. Run init to re-scaffold.');
45
+ }
46
+ //# sourceMappingURL=clean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/commands/clean.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ interface ExportOptions {
2
+ format?: string;
3
+ output?: string;
4
+ width?: number;
5
+ height?: number;
6
+ quality?: number;
7
+ }
8
+ export declare function exportDesign(opts?: ExportOptions): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,YAAY,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B1E"}
@@ -0,0 +1,27 @@
1
+ export async function exportDesign(opts = {}) {
2
+ const format = opts.format ?? 'png';
3
+ const output = opts.output ?? `mise-en-scene/exports/design.${format}`;
4
+ console.log(` ✦ Exporting current design as ${format.toUpperCase()}...`);
5
+ console.log(` Output: ${output}`);
6
+ try {
7
+ const params = new URLSearchParams({
8
+ format,
9
+ ...(opts.width && { width: String(opts.width) }),
10
+ ...(opts.height && { height: String(opts.height) }),
11
+ ...(opts.quality && { quality: String(opts.quality) }),
12
+ output,
13
+ });
14
+ const res = await fetch(`http://localhost:3333/api/export?${params}`);
15
+ if (!res.ok) {
16
+ throw new Error(`Export failed: ${res.statusText}`);
17
+ }
18
+ const result = await res.json();
19
+ console.log(` ✓ Exported to ${result.path}`);
20
+ }
21
+ catch (err) {
22
+ console.error(` ✗ Export failed: ${err.message}`);
23
+ console.error(' Is the design server running? Try: npx mise-en-scene serve');
24
+ process.exit(1);
25
+ }
26
+ }
27
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAsB,EAAE;IACzD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,gCAAgC,MAAM,EAAE,CAAC;IAEvE,OAAO,CAAC,GAAG,CAAC,mCAAmC,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,EAAE,CAAC,CAAC;IAEnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,MAAM;YACN,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACnD,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,MAAM;SACP,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oCAAoC,MAAM,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAsB,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function gallery(): Promise<void>;
2
+ //# sourceMappingURL=gallery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gallery.d.ts","sourceRoot":"","sources":["../../src/commands/gallery.ts"],"names":[],"mappings":"AAEA,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7C"}
@@ -0,0 +1,22 @@
1
+ import { execSync } from 'child_process';
2
+ export async function gallery() {
3
+ const url = 'http://localhost:3333/gallery';
4
+ console.log(' ✦ Opening gallery...');
5
+ try {
6
+ const platform = process.platform;
7
+ if (platform === 'darwin') {
8
+ execSync(`open "${url}"`);
9
+ }
10
+ else if (platform === 'linux') {
11
+ execSync(`xdg-open "${url}"`);
12
+ }
13
+ else if (platform === 'win32') {
14
+ execSync(`start "${url}"`);
15
+ }
16
+ console.log(` ✓ Gallery opened at ${url}`);
17
+ }
18
+ catch {
19
+ console.log(` Open manually: ${url}`);
20
+ }
21
+ }
22
+ //# sourceMappingURL=gallery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gallery.js","sourceRoot":"","sources":["../../src/commands/gallery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,OAAO;IAC3B,MAAM,GAAG,GAAG,+BAA+B,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IAEtC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAClC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,QAAQ,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,QAAQ,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;QAChC,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAChC,QAAQ,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;IACzC,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface InitOptions {
2
+ projectDir?: string;
3
+ }
4
+ export declare function init(opts?: InitOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAQA,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0FhE"}
@@ -0,0 +1,82 @@
1
+ import os from 'os';
2
+ import path from 'path';
3
+ import { detectPlatforms } from '../detect-platform.js';
4
+ import { writeMcpConfig } from '../config-writer.js';
5
+ import { installHooks } from '../hooks-installer.js';
6
+ import { scaffoldProject } from '../scaffold.js';
7
+ import fs from 'fs';
8
+ export async function init(opts = {}) {
9
+ const homeDir = os.homedir();
10
+ const projectDir = opts.projectDir ?? process.cwd();
11
+ console.log('');
12
+ console.log(' ✦ mise en scène — aesthetic design studio');
13
+ console.log('');
14
+ console.log(' Detecting environment...');
15
+ const detection = detectPlatforms(homeDir, projectDir);
16
+ if (!detection.claudeCode && !detection.cursor) {
17
+ console.log(' ⚠ No supported agent detected (Claude Code or Cursor).');
18
+ console.log(' You can still use the packages manually.');
19
+ console.log('');
20
+ }
21
+ for (const platform of detection.platforms) {
22
+ console.log(` ├─ Agent: ${platform.name === 'claude-code' ? 'Claude Code' : 'Cursor'} ✓`);
23
+ }
24
+ const nodeVersion = process.version;
25
+ const major = parseInt(nodeVersion.slice(1).split('.')[0], 10);
26
+ console.log(` ├─ Node.js: ${nodeVersion} ${major >= 18 ? '✓' : '⚠ (18+ recommended)'}`);
27
+ try {
28
+ await import('puppeteer');
29
+ console.log(' └─ Puppeteer: installed ✓');
30
+ }
31
+ catch {
32
+ console.log(' └─ Puppeteer: not installed (will install on first export/screenshot)');
33
+ }
34
+ console.log('');
35
+ if (detection.platforms.length > 0) {
36
+ console.log(' Configuring MCP servers...');
37
+ for (const platform of detection.platforms) {
38
+ writeMcpConfig(platform.mcpConfig, platform.name);
39
+ console.log(` ├─ Added servers to ${path.basename(platform.mcpConfig)} ✓`);
40
+ }
41
+ console.log('');
42
+ }
43
+ if (detection.platforms.length > 0) {
44
+ console.log(' Installing skill...');
45
+ for (const platform of detection.platforms) {
46
+ fs.mkdirSync(platform.skillDir, { recursive: true });
47
+ const skillSrc = path.join(path.dirname(new URL(import.meta.url).pathname), '..', '..', '..', 'skill', 'SKILL.md');
48
+ const destFile = path.join(platform.skillDir, platform.skillFilename);
49
+ if (fs.existsSync(skillSrc)) {
50
+ fs.copyFileSync(skillSrc, destFile);
51
+ console.log(` └─ ${platform.skillFilename} → ${platform.skillDir} ✓`);
52
+ }
53
+ else {
54
+ console.log(` └─ Skill file not found at ${skillSrc} (will be available after build)`);
55
+ }
56
+ }
57
+ console.log('');
58
+ }
59
+ if (detection.platforms.length > 0) {
60
+ console.log(' Installing hooks...');
61
+ for (const platform of detection.platforms) {
62
+ const hooksConfigPath = path.join(path.dirname(platform.hooksDir.replace(/mise-en-scene$/, '')), '..', 'hooks.json');
63
+ installHooks({
64
+ platform: platform.name,
65
+ hooksDir: platform.hooksDir,
66
+ hooksConfigPath,
67
+ });
68
+ console.log(` └─ Hooks → ${platform.hooksDir} ✓`);
69
+ }
70
+ console.log('');
71
+ }
72
+ console.log(' Creating project scaffold...');
73
+ const miseDir = scaffoldProject(projectDir);
74
+ console.log(` └─ ${path.relative(projectDir, miseDir)}/`);
75
+ console.log(' ├─ references/ (drop reference images here)');
76
+ console.log(' ├─ exports/ (exported designs land here)');
77
+ console.log(' └─ .taste/ (project taste profile)');
78
+ console.log('');
79
+ console.log(' ✦ Ready. Start with: "design me a..."');
80
+ console.log('');
81
+ }
82
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ interface ServeOptions {
2
+ port?: number;
3
+ designDir?: string;
4
+ }
5
+ export declare function serve(opts?: ServeOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBlE"}
@@ -0,0 +1,17 @@
1
+ import { spawn } from 'child_process';
2
+ export async function serve(opts = {}) {
3
+ const port = opts.port ?? 3333;
4
+ const designDir = opts.designDir ?? 'mise-en-scene/main';
5
+ console.log(` ✦ Starting mise en scène server on port ${port}...`);
6
+ console.log(` Design directory: ${designDir}`);
7
+ console.log('');
8
+ const child = spawn('npx', ['@mise-en-scene/server', '--port', String(port), '--dir', designDir], {
9
+ stdio: 'inherit',
10
+ shell: true,
11
+ });
12
+ child.on('error', (err) => {
13
+ console.error(' ✗ Failed to start server:', err.message);
14
+ process.exit(1);
15
+ });
16
+ }
17
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAOtC,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAqB,EAAE;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,oBAAoB,CAAC;IAEzD,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,KAAK,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,uBAAuB,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE;QAChG,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface StopOptions {
2
+ port?: number;
3
+ }
4
+ export declare function stop(opts?: StopOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,IAAI,CAAC,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAehE"}
@@ -0,0 +1,17 @@
1
+ export async function stop(opts = {}) {
2
+ const port = opts.port ?? 3333;
3
+ console.log(` ✦ Stopping mise en scène server on port ${port}...`);
4
+ try {
5
+ const res = await fetch(`http://localhost:${port}/api/shutdown`, { method: 'POST' });
6
+ if (res.ok) {
7
+ console.log(' ✓ Server stopped');
8
+ }
9
+ else {
10
+ console.log(' ⚠ Server responded but did not shut down cleanly');
11
+ }
12
+ }
13
+ catch {
14
+ console.log(' ⚠ No server running on port ' + port);
15
+ }
16
+ }
17
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAoB,EAAE;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;IAE/B,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,KAAK,CAAC,CAAC;IAEpE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,eAAe,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACrF,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,gCAAgC,GAAG,IAAI,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ interface TasteOptions {
2
+ scope?: string;
3
+ project?: string;
4
+ }
5
+ export declare function taste(opts?: TasteOptions): Promise<void>;
6
+ export {};
7
+ //# sourceMappingURL=taste.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taste.d.ts","sourceRoot":"","sources":["../../src/commands/taste.ts"],"names":[],"mappings":"AAGA,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,KAAK,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA+BlE"}
@@ -0,0 +1,32 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ export async function taste(opts = {}) {
4
+ console.log(' ✦ Taste Profile Summary');
5
+ console.log('');
6
+ const tasteDir = path.join(process.cwd(), 'mise-en-scene', '.taste');
7
+ if (!fs.existsSync(tasteDir)) {
8
+ console.log(' No taste profile found. Run a design session first.');
9
+ return;
10
+ }
11
+ const files = ['brief.json', 'design-system.json', 'mood-board.json', 'decisions.json'];
12
+ for (const file of files) {
13
+ const filePath = path.join(tasteDir, file);
14
+ if (fs.existsSync(filePath)) {
15
+ try {
16
+ const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
17
+ if (Object.keys(data).length > 0) {
18
+ const label = file.replace('.json', '').replace(/-/g, ' ');
19
+ console.log(` ┌─ ${label}`);
20
+ const json = JSON.stringify(data);
21
+ console.log(` │ ${json.slice(0, 200)}${json.length > 200 ? '...' : ''}`);
22
+ console.log(' │');
23
+ }
24
+ }
25
+ catch {
26
+ // Skip malformed files
27
+ }
28
+ }
29
+ }
30
+ console.log(' └─ End of profile');
31
+ }
32
+ //# sourceMappingURL=taste.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taste.js","sourceRoot":"","sources":["../../src/commands/taste.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,OAAqB,EAAE;IACjD,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IACrE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QACrE,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IAExF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC5D,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBAC3D,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC;oBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAClC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB;YACzB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function writeMcpConfig(configPath: string, platform: 'claude-code' | 'cursor'): void;
2
+ //# sourceMappingURL=config-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.d.ts","sourceRoot":"","sources":["../src/config-writer.ts"],"names":[],"mappings":"AAyBA,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,aAAa,GAAG,QAAQ,GACjC,IAAI,CAiBN"}
@@ -0,0 +1,32 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ function getMiseServers() {
4
+ return {
5
+ 'mise-en-scene-server': {
6
+ command: 'npx',
7
+ args: ['@mise-en-scene/server'],
8
+ },
9
+ 'mise-en-scene-taste-memory': {
10
+ command: 'npx',
11
+ args: ['@mise-en-scene/taste-memory'],
12
+ },
13
+ };
14
+ }
15
+ export function writeMcpConfig(configPath, platform) {
16
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
17
+ let existing = { mcpServers: {} };
18
+ if (fs.existsSync(configPath)) {
19
+ try {
20
+ existing = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
21
+ if (!existing.mcpServers)
22
+ existing.mcpServers = {};
23
+ }
24
+ catch {
25
+ existing = { mcpServers: {} };
26
+ }
27
+ }
28
+ const miseServers = getMiseServers();
29
+ existing.mcpServers = { ...existing.mcpServers, ...miseServers };
30
+ fs.writeFileSync(configPath, JSON.stringify(existing, null, 2) + '\n');
31
+ }
32
+ //# sourceMappingURL=config-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-writer.js","sourceRoot":"","sources":["../src/config-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAWxB,SAAS,cAAc;IACrB,OAAO;QACL,sBAAsB,EAAE;YACtB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,CAAC,uBAAuB,CAAC;SAChC;QACD,4BAA4B,EAAE;YAC5B,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,CAAC,6BAA6B,CAAC;SACtC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,UAAkB,EAClB,QAAkC;IAElC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE5D,IAAI,QAAQ,GAAc,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC7C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5D,IAAI,CAAC,QAAQ,CAAC,UAAU;gBAAE,QAAQ,CAAC,UAAU,GAAG,EAAE,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QAChC,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,QAAQ,CAAC,UAAU,GAAG,EAAE,GAAG,QAAQ,CAAC,UAAU,EAAE,GAAG,WAAW,EAAE,CAAC;IAEjE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface PlatformInfo {
2
+ name: 'claude-code' | 'cursor';
3
+ mcpConfig: string;
4
+ globalMcpConfig: string;
5
+ hooksDir: string;
6
+ skillDir: string;
7
+ skillFilename: string;
8
+ }
9
+ export interface DetectionResult {
10
+ claudeCode: boolean;
11
+ cursor: boolean;
12
+ platforms: PlatformInfo[];
13
+ }
14
+ export declare function detectPlatforms(homeDir: string, projectDir?: string): DetectionResult;
15
+ //# sourceMappingURL=detect-platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-platform.d.ts","sourceRoot":"","sources":["../src/detect-platform.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,aAAa,GAAG,QAAQ,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,YAAY,EAAE,CAAC;CAC3B;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,eAAe,CAwCjB"}
@@ -0,0 +1,39 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ export function detectPlatforms(homeDir, projectDir) {
4
+ const claudeDir = path.join(homeDir, '.claude');
5
+ const cursorDir = path.join(homeDir, '.cursor');
6
+ const claudeCode = fs.existsSync(claudeDir);
7
+ const cursor = fs.existsSync(cursorDir);
8
+ const platforms = [];
9
+ if (claudeCode) {
10
+ platforms.push({
11
+ name: 'claude-code',
12
+ mcpConfig: projectDir
13
+ ? path.join(projectDir, '.mcp.json')
14
+ : path.join(homeDir, '.mcp.json'),
15
+ globalMcpConfig: path.join(homeDir, '.claude', 'settings.json'),
16
+ hooksDir: projectDir
17
+ ? path.join(projectDir, '.claude', 'hooks', 'mise-en-scene')
18
+ : path.join(homeDir, '.claude', 'hooks', 'mise-en-scene'),
19
+ skillDir: path.join(homeDir, '.claude', 'skills', 'mise-en-scene'),
20
+ skillFilename: 'SKILL.md',
21
+ });
22
+ }
23
+ if (cursor) {
24
+ platforms.push({
25
+ name: 'cursor',
26
+ mcpConfig: projectDir
27
+ ? path.join(projectDir, '.cursor', 'mcp.json')
28
+ : path.join(homeDir, '.cursor', 'mcp.json'),
29
+ globalMcpConfig: path.join(homeDir, '.cursor', 'mcp.json'),
30
+ hooksDir: projectDir
31
+ ? path.join(projectDir, '.cursor', 'hooks', 'mise-en-scene')
32
+ : path.join(homeDir, '.cursor', 'hooks', 'mise-en-scene'),
33
+ skillDir: path.join(homeDir, '.cursor', 'rules'),
34
+ skillFilename: 'mise-en-scene.mdc',
35
+ });
36
+ }
37
+ return { claudeCode, cursor, platforms };
38
+ }
39
+ //# sourceMappingURL=detect-platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-platform.js","sourceRoot":"","sources":["../src/detect-platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAiBxB,MAAM,UAAU,eAAe,CAC7B,OAAe,EACf,UAAmB;IAEnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAExC,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,IAAI,UAAU,EAAE,CAAC;QACf,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,aAAa;YACnB,SAAS,EAAE,UAAU;gBACnB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;gBACpC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;YACnC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC;YAC/D,QAAQ,EAAE,UAAU;gBAClB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC;gBAC5D,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC;YAC3D,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC;YAClE,aAAa,EAAE,UAAU;SAC1B,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,UAAU;gBACnB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;gBAC9C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC;YAC7C,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC;YAC1D,QAAQ,EAAE,UAAU;gBAClB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC;gBAC5D,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC;YAC3D,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC;YAChD,aAAa,EAAE,mBAAmB;SACnC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface InstallHooksOptions {
2
+ platform: 'claude-code' | 'cursor';
3
+ hooksDir: string;
4
+ hooksConfigPath: string;
5
+ }
6
+ export declare function installHooks(opts: InstallHooksOptions): void;
7
+ export {};
8
+ //# sourceMappingURL=hooks-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-installer.d.ts","sourceRoot":"","sources":["../src/hooks-installer.ts"],"names":[],"mappings":"AAIA,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,aAAa,GAAG,QAAQ,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;CACzB;AAWD,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI,CAiE5D"}
@@ -0,0 +1,62 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ const HOOK_FILES = ['post-design.sh', 'post-export.sh', 'session-start.sh'];
5
+ function getHookScriptsDir() {
6
+ return path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '..', '..', 'hooks');
7
+ }
8
+ export function installHooks(opts) {
9
+ const { hooksDir, hooksConfigPath } = opts;
10
+ fs.mkdirSync(hooksDir, { recursive: true });
11
+ const scriptsDir = getHookScriptsDir();
12
+ for (const file of HOOK_FILES) {
13
+ const srcPath = path.join(scriptsDir, file);
14
+ const destPath = path.join(hooksDir, file);
15
+ if (fs.existsSync(srcPath)) {
16
+ fs.copyFileSync(srcPath, destPath);
17
+ }
18
+ else {
19
+ // Create minimal placeholder if source doesn't exist (e.g., in tests)
20
+ fs.writeFileSync(destPath, `#!/bin/bash\n# ${file}\nexit 0\n`);
21
+ }
22
+ fs.chmodSync(destPath, 0o755);
23
+ }
24
+ fs.mkdirSync(path.dirname(hooksConfigPath), { recursive: true });
25
+ let existing = {};
26
+ if (fs.existsSync(hooksConfigPath)) {
27
+ try {
28
+ existing = JSON.parse(fs.readFileSync(hooksConfigPath, 'utf-8'));
29
+ }
30
+ catch {
31
+ existing = {};
32
+ }
33
+ }
34
+ if (!existing.hooks)
35
+ existing.hooks = {};
36
+ if (!existing.hooks.postToolUse)
37
+ existing.hooks.postToolUse = [];
38
+ const postDesignHook = {
39
+ matcher: 'studio_preview',
40
+ command: path.join(hooksDir, 'post-design.sh'),
41
+ };
42
+ const postExportHook = {
43
+ matcher: 'studio_export',
44
+ command: path.join(hooksDir, 'post-export.sh'),
45
+ };
46
+ const hasPostDesign = existing.hooks.postToolUse.some((h) => h.matcher === 'studio_preview');
47
+ if (!hasPostDesign)
48
+ existing.hooks.postToolUse.push(postDesignHook);
49
+ const hasPostExport = existing.hooks.postToolUse.some((h) => h.matcher === 'studio_export');
50
+ if (!hasPostExport)
51
+ existing.hooks.postToolUse.push(postExportHook);
52
+ if (!existing.hooks.sessionStart)
53
+ existing.hooks.sessionStart = [];
54
+ const hasSessionStart = existing.hooks.sessionStart.some((h) => h.command?.includes('session-start.sh'));
55
+ if (!hasSessionStart) {
56
+ existing.hooks.sessionStart.push({
57
+ command: path.join(hooksDir, 'session-start.sh'),
58
+ });
59
+ }
60
+ fs.writeFileSync(hooksConfigPath, JSON.stringify(existing, null, 2) + '\n');
61
+ }
62
+ //# sourceMappingURL=hooks-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-installer.js","sourceRoot":"","sources":["../src/hooks-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { init } from './commands/init.js';
4
+ import { serve } from './commands/serve.js';
5
+ import { stop } from './commands/stop.js';
6
+ import { exportDesign } from './commands/export.js';
7
+ import { gallery } from './commands/gallery.js';
8
+ import { taste } from './commands/taste.js';
9
+ import { clean } from './commands/clean.js';
10
+ const program = new Command();
11
+ program
12
+ .name('mise-en-scene')
13
+ .description('✦ mise en scène — aesthetic design studio')
14
+ .version('0.1.0'); // kept in sync with package.json by npm version
15
+ program
16
+ .command('init')
17
+ .description('Bootstrap mise en scène in the current project')
18
+ .option('-d, --dir <path>', 'Project directory', process.cwd())
19
+ .action(async (opts) => {
20
+ await init({ projectDir: opts.dir });
21
+ });
22
+ program
23
+ .command('serve')
24
+ .description('Start the design preview server')
25
+ .option('-p, --port <number>', 'Port number', '3333')
26
+ .option('-d, --dir <path>', 'Design directory', 'mise-en-scene/main')
27
+ .action(async (opts) => {
28
+ await serve({ port: parseInt(opts.port, 10), designDir: opts.dir });
29
+ });
30
+ program
31
+ .command('stop')
32
+ .description('Stop the design preview server and Puppeteer')
33
+ .option('-p, --port <number>', 'Port number', '3333')
34
+ .action(async (opts) => {
35
+ await stop({ port: parseInt(opts.port, 10) });
36
+ });
37
+ program
38
+ .command('export')
39
+ .description('Export current design')
40
+ .option('-f, --format <type>', 'Export format (svg, png, jpg, pdf)', 'png')
41
+ .option('-o, --output <path>', 'Output file path')
42
+ .option('-w, --width <pixels>', 'Width in pixels')
43
+ .option('-H, --height <pixels>', 'Height in pixels')
44
+ .option('-q, --quality <percent>', 'JPEG quality (1-100)', '90')
45
+ .action(async (opts) => {
46
+ await exportDesign({
47
+ format: opts.format,
48
+ output: opts.output,
49
+ width: opts.width ? parseInt(opts.width, 10) : undefined,
50
+ height: opts.height ? parseInt(opts.height, 10) : undefined,
51
+ quality: parseInt(opts.quality, 10),
52
+ });
53
+ });
54
+ program
55
+ .command('gallery')
56
+ .description('Open the version gallery in browser')
57
+ .action(async () => {
58
+ await gallery();
59
+ });
60
+ program
61
+ .command('taste')
62
+ .description('Show current taste profile summary')
63
+ .option('-s, --scope <scope>', 'Profile scope (user, project, merged)', 'merged')
64
+ .option('-p, --project <name>', 'Project name')
65
+ .action(async (opts) => {
66
+ await taste({ scope: opts.scope, project: opts.project });
67
+ });
68
+ program
69
+ .command('clean')
70
+ .description('Remove taste profile and branches (keeps exports)')
71
+ .option('-d, --dir <path>', 'Project directory', process.cwd())
72
+ .option('--all', 'Also remove exports')
73
+ .action(async (opts) => {
74
+ await clean({ projectDir: opts.dir, keepExports: !opts.all });
75
+ });
76
+ program.parse();
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function scaffoldProject(projectRoot: string): string;
2
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAqBA,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAsB3D"}
@@ -0,0 +1,37 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ const TASTE_FILES = [
4
+ 'brief.json',
5
+ 'references.json',
6
+ 'design-system.json',
7
+ 'mood-board.json',
8
+ 'decisions.json',
9
+ ];
10
+ const DIRS = [
11
+ 'references',
12
+ 'exports',
13
+ '.taste',
14
+ 'main',
15
+ 'branches',
16
+ ];
17
+ const GITKEEP_DIRS = ['references', 'exports', 'main', 'branches'];
18
+ export function scaffoldProject(projectRoot) {
19
+ const miseDir = path.join(projectRoot, 'mise-en-scene');
20
+ for (const dir of DIRS) {
21
+ fs.mkdirSync(path.join(miseDir, dir), { recursive: true });
22
+ }
23
+ for (const file of TASTE_FILES) {
24
+ const filePath = path.join(miseDir, '.taste', file);
25
+ if (!fs.existsSync(filePath)) {
26
+ fs.writeFileSync(filePath, '{}\n');
27
+ }
28
+ }
29
+ for (const dir of GITKEEP_DIRS) {
30
+ const gitkeep = path.join(miseDir, dir, '.gitkeep');
31
+ if (!fs.existsSync(gitkeep)) {
32
+ fs.writeFileSync(gitkeep, '');
33
+ }
34
+ }
35
+ return miseDir;
36
+ }
37
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,WAAW,GAAG;IAClB,YAAY;IACZ,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,gBAAgB;CACjB,CAAC;AAEF,MAAM,IAAI,GAAG;IACX,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,MAAM;IACN,UAAU;CACX,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AAEnE,MAAM,UAAU,eAAe,CAAC,WAAmB;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAExD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;QACpD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,13 @@
1
+ export type Platform = 'claude-code' | 'cursor' | 'both' | 'unknown';
2
+ export interface PlatformConfig {
3
+ platform: Platform;
4
+ mcpConfigPath: string;
5
+ hooksPath: string;
6
+ skillPath: string;
7
+ }
8
+ export interface InitOptions {
9
+ projectDir: string;
10
+ platform?: Platform;
11
+ port?: number;
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "mise-en-scene",
3
+ "version": "0.1.0",
4
+ "description": "CLI bootstrap for mise-en-scene design studio",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "mise-en-scene": "dist/index.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/daviesayo/mise-en-scene.git",
18
+ "directory": "packages/cli"
19
+ },
20
+ "homepage": "https://github.com/daviesayo/mise-en-scene#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/daviesayo/mise-en-scene/issues"
23
+ },
24
+ "license": "MIT",
25
+ "keywords": [
26
+ "mise-en-scene",
27
+ "design",
28
+ "mcp",
29
+ "ai",
30
+ "visual-design",
31
+ "cli"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsc",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest"
37
+ },
38
+ "dependencies": {
39
+ "@mise-en-scene/server": "0.1.0",
40
+ "@mise-en-scene/taste-memory": "0.1.0",
41
+ "commander": "^13.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "vitest": "^3.0.0"
45
+ }
46
+ }