visual-ai-staging 0.0.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/cli.js ADDED
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+
3
+ const http = require('http');
4
+ const fs = require('fs');
5
+ const path = require('path');
6
+ const url = require('url');
7
+
8
+ const args = process.argv.slice(2);
9
+ const command = args[0];
10
+
11
+ if (command === '--version' || command === '-v') {
12
+ try {
13
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8'));
14
+ console.log(pkg.version);
15
+ } catch (err) {
16
+ console.error('Error reading package.json:', err.message);
17
+ process.exit(1);
18
+ }
19
+ process.exit(0);
20
+ }
21
+
22
+ if (command === '--help' || command === '-h' || !command) {
23
+ console.log(`
24
+ Usage: vais [options] [command]
25
+
26
+ Options:
27
+ -v, --version Output the version number
28
+ -h, --help Output usage information
29
+
30
+ Commands:
31
+ dev Start the Visual AI Staging native development server
32
+ `);
33
+ process.exit(0);
34
+ }
35
+
36
+ if (command === 'dev') {
37
+ const port = 3000;
38
+ const resolvedBase = path.resolve(__dirname);
39
+
40
+ const server = http.createServer((req, res) => {
41
+ const parsedUrl = url.parse(req.url, true);
42
+ const pathname = parsedUrl.pathname;
43
+
44
+ // Handle POST /api/save-audio?filename=<encoded_filename>
45
+ if (req.method === 'POST' && pathname === '/api/save-audio') {
46
+ const rawFilename = parsedUrl.query.filename || '';
47
+ const filename = path.basename(rawFilename);
48
+ const wavPattern = /^[a-zA-Z0-9_\-\.]+\.wav$/;
49
+
50
+ if (!wavPattern.test(filename)) {
51
+ res.statusCode = 400;
52
+ res.setHeader('Content-Type', 'application/json');
53
+ res.end(JSON.stringify({ success: false, error: 'Invalid filename. Must match ^[a-zA-Z0-9_\\-\\.]+\\.wav$' }));
54
+ return;
55
+ }
56
+
57
+ const targetDir = path.join(resolvedBase, '.ai-staging', 'audio');
58
+ try {
59
+ fs.mkdirSync(targetDir, { recursive: true });
60
+ } catch (err) {
61
+ res.statusCode = 500;
62
+ res.setHeader('Content-Type', 'application/json');
63
+ res.end(JSON.stringify({ success: false, error: 'Failed to create audio storage directory' }));
64
+ return;
65
+ }
66
+
67
+ const targetPath = path.join(targetDir, filename);
68
+ const writeStream = fs.createWriteStream(targetPath);
69
+
70
+ req.pipe(writeStream);
71
+
72
+ writeStream.on('finish', () => {
73
+ res.statusCode = 200;
74
+ res.setHeader('Content-Type', 'application/json');
75
+ res.end(JSON.stringify({ success: true, path: targetPath }));
76
+ });
77
+
78
+ writeStream.on('error', (err) => {
79
+ res.statusCode = 500;
80
+ res.setHeader('Content-Type', 'application/json');
81
+ res.end(JSON.stringify({ success: false, error: err.message }));
82
+ });
83
+ return;
84
+ }
85
+
86
+ // Handle POST /api/save-feedback
87
+ if (req.method === 'POST' && pathname === '/api/save-feedback') {
88
+ let body = '';
89
+ req.on('data', chunk => {
90
+ body += chunk.toString();
91
+ });
92
+
93
+ req.on('end', () => {
94
+ try {
95
+ const payload = JSON.parse(body);
96
+ const rawFilename = payload.filename || '';
97
+ const filename = path.basename(rawFilename);
98
+ const mdPattern = /^[a-zA-Z0-9_\-\.]+\.md$/;
99
+
100
+ if (!mdPattern.test(filename)) {
101
+ res.statusCode = 400;
102
+ res.setHeader('Content-Type', 'application/json');
103
+ res.end(JSON.stringify({ success: false, error: 'Invalid filename. Must match ^[a-zA-Z0-9_\\-\\.]+\\.md$' }));
104
+ return;
105
+ }
106
+
107
+ const targetDir = path.join(resolvedBase, '.ai-staging', 'feedback');
108
+ try {
109
+ fs.mkdirSync(targetDir, { recursive: true });
110
+ } catch (err) {
111
+ res.statusCode = 500;
112
+ res.setHeader('Content-Type', 'application/json');
113
+ res.end(JSON.stringify({ success: false, error: 'Failed to create feedback storage directory' }));
114
+ return;
115
+ }
116
+
117
+ const targetPath = path.join(targetDir, filename);
118
+ fs.writeFileSync(targetPath, payload.content || '');
119
+
120
+ res.statusCode = 200;
121
+ res.setHeader('Content-Type', 'application/json');
122
+ res.end(JSON.stringify({ success: true, path: targetPath }));
123
+ } catch (err) {
124
+ res.statusCode = 400;
125
+ res.setHeader('Content-Type', 'application/json');
126
+ res.end(JSON.stringify({ success: false, error: 'Malformed JSON payload' }));
127
+ }
128
+ });
129
+ return;
130
+ }
131
+
132
+ // Handle static files serving (GET)
133
+ if (req.method === 'GET') {
134
+ let relativePath = pathname;
135
+ if (relativePath === '/') {
136
+ relativePath = '/index.html';
137
+ }
138
+
139
+ const resolvedPath = path.resolve(path.join(resolvedBase, relativePath));
140
+
141
+ // Path traversal security check
142
+ if (!resolvedPath.startsWith(resolvedBase)) {
143
+ res.statusCode = 403;
144
+ res.setHeader('Content-Type', 'text/plain');
145
+ res.end('403 Forbidden: Path traversal detected.');
146
+ return;
147
+ }
148
+
149
+ fs.stat(resolvedPath, (err, stats) => {
150
+ if (err || !stats.isFile()) {
151
+ res.statusCode = 404;
152
+ res.setHeader('Content-Type', 'text/plain');
153
+ res.end('404 Not Found');
154
+ return;
155
+ }
156
+
157
+ const ext = path.extname(resolvedPath).toLowerCase();
158
+ const mimeTypes = {
159
+ '.html': 'text/html',
160
+ '.css': 'text/css',
161
+ '.js': 'application/javascript',
162
+ '.png': 'image/png',
163
+ '.jpg': 'image/jpeg',
164
+ '.gif': 'image/gif',
165
+ '.svg': 'image/svg+xml',
166
+ '.wav': 'audio/wav',
167
+ '.md': 'text/markdown',
168
+ '.json': 'application/json',
169
+ '.txt': 'text/plain'
170
+ };
171
+
172
+ const contentType = mimeTypes[ext] || 'application/octet-stream';
173
+ res.statusCode = 200;
174
+ res.setHeader('Content-Type', contentType);
175
+ fs.createReadStream(resolvedPath).pipe(res);
176
+ });
177
+ return;
178
+ }
179
+
180
+ // Method not supported fallback
181
+ res.statusCode = 405;
182
+ res.setHeader('Content-Type', 'text/plain');
183
+ res.end('405 Method Not Allowed');
184
+ });
185
+
186
+ server.listen(port, () => {
187
+ console.log(`Visual AI Staging Dev Server running at http://localhost:${port}/`);
188
+ });
189
+ } else {
190
+ console.error(`Unknown command: ${command}`);
191
+ console.error('Run "vais --help" for usage.');
192
+ process.exit(1);
193
+ }
package/index.html ADDED
@@ -0,0 +1,430 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Visual AI Staging Companion - R1 Sandbox</title>
7
+ <link rel="stylesheet" href="styles.css">
8
+ </head>
9
+ <body>
10
+ <!-- Header Toolbar -->
11
+ <header class="app-header">
12
+ <div class="header-logo">
13
+ <span class="logo-icon">โœจ</span>
14
+ <h1>Visual AI Staging <span class="badge">Companion</span></h1>
15
+ </div>
16
+ <div class="toolbar-modes">
17
+ <button id="btn-inspect" class="toolbar-btn">
18
+ <span class="btn-icon">๐Ÿ”</span> Inspection Mode
19
+ </button>
20
+ <button id="btn-drawing" class="toolbar-btn">
21
+ <span class="btn-icon">๐Ÿ“</span> Free-Zone Drawing
22
+ </button>
23
+ </div>
24
+ <div class="header-meta">
25
+ <span class="status-indicator active"></span>
26
+ <span class="status-text">Local Dev Node Connected</span>
27
+ </div>
28
+ </header>
29
+
30
+ <!-- Split Layout Container -->
31
+ <main class="app-layout">
32
+ <!-- Left Column: DOM Mock Page Container -->
33
+ <section class="mock-page-container">
34
+ <div class="panel-header">
35
+ <span class="panel-title">DOM Mock Page (Sandbox Target)</span>
36
+ <div class="viewport-controls">
37
+ <span class="size-pill">100% Desktop Viewport</span>
38
+ </div>
39
+ </div>
40
+
41
+ <!-- Realistic Mock Page Content -->
42
+ <div id="mock-page">
43
+ <!-- Transparent Drawing Overlay -->
44
+ <svg id="canvas-overlay"></svg>
45
+
46
+ <!-- Hero Section -->
47
+ <header class="mock-hero">
48
+ <nav class="mock-nav">
49
+ <div class="mock-logo">QuantumLabs</div>
50
+ <div class="mock-nav-links">
51
+ <a href="#" class="mock-nav-link">Features</a>
52
+ <a href="#" class="mock-nav-link">Pricing</a>
53
+ <a href="#" class="mock-nav-link">Docs</a>
54
+ </div>
55
+ </nav>
56
+
57
+ <div class="mock-hero-content">
58
+ <h1 class="mock-title">Engineered for the Autonomous Web</h1>
59
+ <p class="mock-subtitle">Instantly bridge the gap between human designers and agentic software. Build, staging, and compile prompts visually.</p>
60
+ <div class="mock-actions">
61
+ <button class="mock-btn mock-btn-primary">Launch Sandbox</button>
62
+ <button class="mock-btn mock-btn-secondary">Read Blueprint</button>
63
+ </div>
64
+ </div>
65
+ </header>
66
+
67
+ <!-- Features Grid -->
68
+ <section class="mock-features">
69
+ <h2 class="section-title">Core Capabilities</h2>
70
+ <div class="features-grid">
71
+ <div class="feature-card">
72
+ <div class="feature-icon">๐Ÿ›ก๏ธ</div>
73
+ <h3>Dynamic Sandbox</h3>
74
+ <p>Manipulate computed element layouts in hot memory before staging. Test border radii and spacing tokens.</p>
75
+ <button class="mock-card-btn">Explore</button>
76
+ </div>
77
+
78
+ <div class="feature-card">
79
+ <div class="feature-icon">โšก</div>
80
+ <h3>Token Mapping</h3>
81
+ <p>Auto-approximate manual pixels to standard spacing and border design variables instantly.</p>
82
+ <button class="mock-card-btn">Explore</button>
83
+ </div>
84
+
85
+ <div class="feature-card">
86
+ <div class="feature-icon">๐ŸŽ™๏ธ</div>
87
+ <h3>Multimodal Log</h3>
88
+ <p>Record voice comments and overlay badges on selected nodes for high-context agent execution.</p>
89
+ <button class="mock-card-btn">Explore</button>
90
+ </div>
91
+ </div>
92
+ </section>
93
+
94
+ <!-- Text Detail Card Section -->
95
+ <section class="mock-text-section">
96
+ <div class="text-detail-card">
97
+ <h4>System Architecture Note</h4>
98
+ <p>Our hybrid communication framework routes WebSocket packages directly to the Tauri companion app on localhost. This guarantees that your changes remain local, private, and extremely secure while preserving layout reactiveness.</p>
99
+ </div>
100
+ </section>
101
+
102
+ <!-- Images Grid -->
103
+ <section class="mock-images-section">
104
+ <h2 class="section-title">Staging Presets</h2>
105
+ <div class="images-grid">
106
+ <div class="mock-image-card">
107
+ <div class="mock-img-placeholder img-grad-1">
108
+ <span class="img-badge">UI Layout</span>
109
+ </div>
110
+ <div class="img-details">
111
+ <h5>Flexible Grid Templates</h5>
112
+ <p>Curated design variables ready for compile.</p>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="mock-image-card">
117
+ <div class="mock-img-placeholder img-grad-2">
118
+ <span class="img-badge">Component</span>
119
+ </div>
120
+ <div class="img-details">
121
+ <h5>Navigation Overlays</h5>
122
+ <p>Polished menus and floating panels.</p>
123
+ </div>
124
+ </div>
125
+ </div>
126
+ </section>
127
+ </div>
128
+ </section>
129
+
130
+ <!-- Right Column: Lateral Staging Panel -->
131
+ <aside id="main-staging-panel" class="staging-panel glass-panel">
132
+ <!-- Section 1: Selected Element Metadata -->
133
+ <section class="staging-section element-meta-section">
134
+ <div class="meta-section-header">
135
+ <h3 class="section-heading">Selected Element</h3>
136
+ <button id="btn-undock-panel" class="meta-action-btn" title="Undock panel (Pop-out)">
137
+ <span>โ†—๏ธ</span> Undock
138
+ </button>
139
+ </div>
140
+ <div id="meta-container" class="meta-empty">
141
+ No element selected. Toggle Inspection Mode and click an element inside the mock page to begin.
142
+ </div>
143
+ <div id="meta-details" class="hidden">
144
+ <div class="meta-row">
145
+ <span class="meta-label">Tag Name:</span>
146
+ <span id="meta-tag" class="meta-value tag-value">div</span>
147
+ </div>
148
+ <div class="meta-row">
149
+ <span class="meta-label">Class List:</span>
150
+ <span id="meta-classes" class="meta-value class-value">.hero-content</span>
151
+ </div>
152
+ <div class="meta-row">
153
+ <span class="meta-label">CSS Selector:</span>
154
+ <span id="meta-selector" class="meta-value selector-value">#mock-page > header > div</span>
155
+ </div>
156
+ <div class="meta-row">
157
+ <span class="meta-label">UI Component Type:</span>
158
+ <span id="meta-ui-type" class="meta-value ui-type-value">โš™๏ธ Generic Element</span>
159
+ </div>
160
+
161
+ <!-- Contenedor del รrbol de Jerarquรญa DOM -->
162
+ <div class="hierarchy-header-title">DOM Hierarchy Tree</div>
163
+ <div id="hierarchy-tree-container" class="hierarchy-tree-container"></div>
164
+ </div>
165
+ </section>
166
+
167
+ <!-- Section 2: Visual Sandbox Sliders -->
168
+ <section class="staging-section properties-section">
169
+ <h3 class="section-heading">Visual Sandbox</h3>
170
+ <div class="properties-controls">
171
+ <!-- Padding Slider -->
172
+ <div class="control-group">
173
+ <div class="control-header">
174
+ <label for="slider-padding">Padding</label>
175
+ <div class="val-wrapper">
176
+ <span id="val-padding" class="control-num">0px</span>
177
+ <span id="token-padding" class="token-badge hidden">--spacing-xs</span>
178
+ </div>
179
+ </div>
180
+ <input type="range" id="slider-padding" min="0" max="100" value="0" class="slider">
181
+ </div>
182
+
183
+ <!-- Margin Slider -->
184
+ <div class="control-group">
185
+ <div class="control-header">
186
+ <label for="slider-margin">Margin</label>
187
+ <div class="val-wrapper">
188
+ <span id="val-margin" class="control-num">0px</span>
189
+ <span id="token-margin" class="token-badge hidden">--spacing-xs</span>
190
+ </div>
191
+ </div>
192
+ <input type="range" id="slider-margin" min="0" max="100" value="0" class="slider">
193
+ </div>
194
+
195
+ <!-- Width Slider -->
196
+ <div class="control-group">
197
+ <div class="control-header">
198
+ <label for="slider-width">Width</label>
199
+ <div class="val-wrapper">
200
+ <span id="val-width" class="control-num">auto</span>
201
+ </div>
202
+ </div>
203
+ <input type="range" id="slider-width" min="50" max="1000" value="300" class="slider">
204
+ </div>
205
+
206
+ <!-- Height Slider -->
207
+ <div class="control-group">
208
+ <div class="control-header">
209
+ <label for="slider-height">Height</label>
210
+ <div class="val-wrapper">
211
+ <span id="val-height" class="control-num">auto</span>
212
+ </div>
213
+ </div>
214
+ <input type="range" id="slider-height" min="10" max="800" value="100" class="slider">
215
+ </div>
216
+
217
+ <!-- Border Radius Slider -->
218
+ <div class="control-group">
219
+ <div class="control-header">
220
+ <label for="slider-borderRadius">Border Radius</label>
221
+ <div class="val-wrapper">
222
+ <span id="val-borderRadius" class="control-num">0px</span>
223
+ <span id="token-borderRadius" class="token-badge hidden">--border-radius-sm</span>
224
+ </div>
225
+ </div>
226
+ <input type="range" id="slider-borderRadius" min="0" max="100" value="0" class="slider">
227
+ </div>
228
+
229
+ <!-- Font Size Slider -->
230
+ <div class="control-group">
231
+ <div class="control-header">
232
+ <label for="slider-fontSize">Font Size</label>
233
+ <div class="val-wrapper">
234
+ <span id="val-fontSize" class="control-num">16px</span>
235
+ </div>
236
+ </div>
237
+ <input type="range" id="slider-fontSize" min="8" max="72" value="16" class="slider">
238
+ </div>
239
+
240
+ <!-- Text Content Input -->
241
+ <div class="control-group text-content-group">
242
+ <div class="control-header">
243
+ <label for="input-textContent">Text Content</label>
244
+ </div>
245
+ <input type="text" id="input-textContent" class="text-input" placeholder="Edit text content...">
246
+ </div>
247
+ </div>
248
+ </section>
249
+
250
+ <!-- Section 3: Color Sliders -->
251
+ <section class="staging-section colors-section">
252
+ <h3 class="section-heading">Color Staging</h3>
253
+
254
+ <!-- Background Color -->
255
+ <div class="color-control-box">
256
+ <div class="color-title">Background Color</div>
257
+ <div class="hsl-sliders">
258
+ <div class="slider-row">
259
+ <span class="hsl-label">H</span>
260
+ <input type="range" id="bg-h" min="0" max="360" value="220" class="slider color-h-slider">
261
+ <span id="bg-h-val" class="hsl-val">220</span>
262
+ </div>
263
+ <div class="slider-row">
264
+ <span class="hsl-label">S</span>
265
+ <input type="range" id="bg-s" min="0" max="100" value="15" class="slider">
266
+ <span id="bg-s-val" class="hsl-val">15%</span>
267
+ </div>
268
+ <div class="slider-row">
269
+ <span class="hsl-label">L</span>
270
+ <input type="range" id="bg-l" min="0" max="100" value="10" class="slider">
271
+ <span id="bg-l-val" class="hsl-val">10%</span>
272
+ </div>
273
+ </div>
274
+ <div class="color-palette-repr">
275
+ <div id="bg-preview" class="color-preview-swatch"></div>
276
+ <span id="bg-hsl-string" class="hsl-string">hsl(220, 15%, 10%)</span>
277
+ </div>
278
+ </div>
279
+
280
+ <!-- Text Color -->
281
+ <div class="color-control-box">
282
+ <div class="color-title">Text Color</div>
283
+ <div class="hsl-sliders">
284
+ <div class="slider-row">
285
+ <span class="hsl-label">H</span>
286
+ <input type="range" id="text-h" min="0" max="360" value="220" class="slider color-h-slider">
287
+ <span id="text-h-val" class="hsl-val">220</span>
288
+ </div>
289
+ <div class="slider-row">
290
+ <span class="hsl-label">S</span>
291
+ <input type="range" id="text-s" min="0" max="100" value="10" class="slider">
292
+ <span id="text-s-val" class="hsl-val">10%</span>
293
+ </div>
294
+ <div class="slider-row">
295
+ <span class="hsl-label">L</span>
296
+ <input type="range" id="text-l" min="0" max="100" value="95" class="slider">
297
+ <span id="text-l-val" class="hsl-val">95%</span>
298
+ </div>
299
+ </div>
300
+ <div class="color-palette-repr">
301
+ <div id="text-preview" class="color-preview-swatch"></div>
302
+ <span id="text-hsl-string" class="hsl-string">hsl(220, 10%, 95%)</span>
303
+ </div>
304
+ </div>
305
+ </section>
306
+
307
+ <!-- Section 3.5: Voice Annotation -->
308
+ <section class="staging-section voice-annotation-section">
309
+ <h3 class="section-heading">Voice Annotation</h3>
310
+ <div class="voice-controls-box">
311
+ <div class="voice-actions">
312
+ <button id="btn-voice-record" class="voice-btn record-btn" disabled>
313
+ <span class="voice-icon">๐ŸŽค</span> <span id="record-btn-text">Record Voice Note</span>
314
+ </button>
315
+ <button id="btn-voice-delete" class="voice-btn delete-btn hidden" title="Delete voice note">
316
+ ๐Ÿ—‘๏ธ
317
+ </button>
318
+ </div>
319
+
320
+ <div id="voice-status-container" class="voice-status hidden">
321
+ <span class="pulse-indicator"></span>
322
+ <span id="voice-timer">00:00</span>
323
+ <span class="status-label">Recording...</span>
324
+ </div>
325
+
326
+ <div id="voice-audio-player-container" class="audio-player-container hidden">
327
+ <audio id="voice-audio-player" controls></audio>
328
+ </div>
329
+ </div>
330
+ </section>
331
+
332
+ <!-- Section 4: Staged Changes List -->
333
+ <section class="staging-section changes-section">
334
+ <h3 class="section-heading">Staged Changes</h3>
335
+ <div id="staged-changes-list" class="changes-list">
336
+ <div class="no-changes">No staged changes yet. Select an element and adjust properties.</div>
337
+ </div>
338
+ </section>
339
+ </aside>
340
+ </main>
341
+
342
+ <!-- Floating Action Button (FAB) -->
343
+ <div class="fab-wrapper">
344
+ <button class="fab" id="fab-trigger">
345
+ <span class="fab-status-dot"></span>
346
+ <span class="fab-label">Companion Status</span>
347
+ <span class="fab-icon">โšก</span>
348
+ </button>
349
+ <div id="fab-menu" class="fab-menu hidden">
350
+ <div class="fab-menu-header">
351
+ <h4>Staging Quick Actions</h4>
352
+ </div>
353
+ <div class="fab-menu-items">
354
+ <button id="fab-btn-inspect">
355
+ <span class="item-icon">๐Ÿ”</span> Toggle Inspector Mode
356
+ </button>
357
+ <button id="fab-btn-clear">
358
+ <span class="item-icon">๐Ÿงน</span> Clear Staged Changes
359
+ </button>
360
+ <button id="fab-btn-copy">
361
+ <span class="item-icon">๐Ÿ“‹</span> Copy AI Recipe Prompt
362
+ </button>
363
+ </div>
364
+ </div>
365
+ </div>
366
+
367
+ <!-- Bounding Box Annotation Modal -->
368
+ <div id="drawing-modal" class="modal-overlay hidden">
369
+ <div class="modal-content glass-panel">
370
+ <div class="modal-header">
371
+ <h4>Configure Bounding Box Insertion</h4>
372
+ <button id="btn-close-modal" class="modal-close-btn">&times;</button>
373
+ </div>
374
+ <div class="modal-body">
375
+ <div class="form-group">
376
+ <label>Resolved Parent Container Selector</label>
377
+ <div id="modal-resolved-selector" class="resolved-selector-display"></div>
378
+ </div>
379
+
380
+ <div class="form-group">
381
+ <label for="modal-template-select">Quick Template Preset</label>
382
+ <select id="modal-template-select" class="modal-select">
383
+ <optgroup label="Layout & Containers">
384
+ <option value="Header / Navigation Bar">๐Ÿงญ Header / Navbar (Navigation Bar)</option>
385
+ <option value="Hero Section">๐Ÿš€ Hero Section (Intro Banner)</option>
386
+ <option value="Container / Card">๐Ÿ“ฆ Container / Card (Widget)</option>
387
+ <option value="Grid / Flex Layout">๐ŸŽ›๏ธ Grid / Flex Container</option>
388
+ <option value="Footer">๐Ÿ Footer (Page End)</option>
389
+ </optgroup>
390
+ <optgroup label="Interactives & Forms">
391
+ <option value="Button (Primary/Secondary)">๐Ÿ”˜ Button (Call to Action)</option>
392
+ <option value="Formulario (Form)">๐Ÿ“ Complete Form</option>
393
+ <option value="Input Field / Input Group">โœ๏ธ Input (Text Field)</option>
394
+ <option value="Search Bar">๐Ÿ” Search Bar (Search Box)</option>
395
+ <option value="Toggle / Selector">โŒฅ Toggle / Checkbox</option>
396
+ </optgroup>
397
+ <optgroup label="Media & Contents">
398
+ <option value="Image Placeholder">๐Ÿ–ผ๏ธ Image Placeholder (Photo)</option>
399
+ <option value="Carousel Slider">๐ŸŽก Carousel / Slider</option>
400
+ <option value="Video Player">๐ŸŽฅ Video Player</option>
401
+ <option value="Avatar / Profile Badge">๐Ÿ‘ค Avatar (User Profile)</option>
402
+ </optgroup>
403
+ <optgroup label="WebApp Components">
404
+ <option value="Modal / Dialog Box">๐Ÿ’ฌ Modal / Pop-up Dialog</option>
405
+ <option value="Tabs Container">๐Ÿ“‘ Tabs Container</option>
406
+ <option value="Accordion / FAQ">๐Ÿ“‚ Accordion / FAQ</option>
407
+ <option value="Charts / Data Analytics">๐Ÿ“Š Charts / Data Visualizer</option>
408
+ <option value="Data Table">๐Ÿ“… Data Table</option>
409
+ </optgroup>
410
+ <optgroup label="Others">
411
+ <option value="Custom Component">โš™๏ธ Custom Component</option>
412
+ </optgroup>
413
+ </select>
414
+ </div>
415
+
416
+ <div class="form-group">
417
+ <label for="modal-notes-textarea">Developer Notes</label>
418
+ <textarea id="modal-notes-textarea" class="modal-textarea" placeholder="Write design notes or behavior specs for this component here..."></textarea>
419
+ </div>
420
+ </div>
421
+ <div class="modal-footer">
422
+ <button id="btn-cancel-modal" class="modal-btn modal-btn-secondary">Cancel</button>
423
+ <button id="btn-confirm-modal" class="modal-btn modal-btn-primary">Confirm Insertion</button>
424
+ </div>
425
+ </div>
426
+ </div>
427
+
428
+ <script src="app.js"></script>
429
+ </body>
430
+ </html>
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "visual-ai-staging",
3
+ "version": "0.0.1",
4
+ "description": "Visual AI Staging Companion โ€” Bridge the gap between UI design staging and AI coding assistants.",
5
+ "license": "MIT",
6
+ "main": "app.js",
7
+ "bin": {
8
+ "vais": "./cli.js"
9
+ }
10
+ }