id3-cli 0.9.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.
Files changed (114) hide show
  1. package/README.ja-JP.md +769 -0
  2. package/README.ko-KR.md +769 -0
  3. package/README.md +769 -0
  4. package/README.tr-TR.md +769 -0
  5. package/README.zh-CN.md +769 -0
  6. package/dist/bin/cli.d.ts +2 -0
  7. package/dist/bin/cli.js +40 -0
  8. package/dist/bin/cli.js.map +1 -0
  9. package/dist/scripts/build-hooks.d.ts +1 -0
  10. package/dist/scripts/build-hooks.js +58 -0
  11. package/dist/scripts/build-hooks.js.map +1 -0
  12. package/dist/src/hooks/auto-audit.d.ts +4 -0
  13. package/dist/src/hooks/auto-audit.js +47 -0
  14. package/dist/src/hooks/auto-audit.js.map +1 -0
  15. package/dist/src/hooks/claude-pretool-entry.d.ts +1 -0
  16. package/dist/src/hooks/claude-pretool-entry.js +36 -0
  17. package/dist/src/hooks/claude-pretool-entry.js.map +1 -0
  18. package/dist/src/hooks/claude-stop-entry.d.ts +1 -0
  19. package/dist/src/hooks/claude-stop-entry.js +7 -0
  20. package/dist/src/hooks/claude-stop-entry.js.map +1 -0
  21. package/dist/src/hooks/post-commit-entry.d.ts +1 -0
  22. package/dist/src/hooks/post-commit-entry.js +7 -0
  23. package/dist/src/hooks/post-commit-entry.js.map +1 -0
  24. package/dist/src/hooks/pre-commit-entry.d.ts +1 -0
  25. package/dist/src/hooks/pre-commit-entry.js +16 -0
  26. package/dist/src/hooks/pre-commit-entry.js.map +1 -0
  27. package/dist/src/hooks/rule-check.d.ts +8 -0
  28. package/dist/src/hooks/rule-check.js +101 -0
  29. package/dist/src/hooks/rule-check.js.map +1 -0
  30. package/dist/src/hooks/schema-drift.d.ts +17 -0
  31. package/dist/src/hooks/schema-drift.js +151 -0
  32. package/dist/src/hooks/schema-drift.js.map +1 -0
  33. package/dist/src/hooks/shared.d.ts +43 -0
  34. package/dist/src/hooks/shared.js +98 -0
  35. package/dist/src/hooks/shared.js.map +1 -0
  36. package/dist/src/init.d.ts +20 -0
  37. package/dist/src/init.js +193 -0
  38. package/dist/src/init.js.map +1 -0
  39. package/dist/src/preview/mockup-generator.d.ts +56 -0
  40. package/dist/src/preview/mockup-generator.js +402 -0
  41. package/dist/src/preview/mockup-generator.js.map +1 -0
  42. package/dist/src/preview/renderer.d.ts +30 -0
  43. package/dist/src/preview/renderer.js +145 -0
  44. package/dist/src/preview/renderer.js.map +1 -0
  45. package/dist/src/preview/server.d.ts +9 -0
  46. package/dist/src/preview/server.js +55 -0
  47. package/dist/src/preview/server.js.map +1 -0
  48. package/dist/src/preview/ui-auditor.d.ts +27 -0
  49. package/dist/src/preview/ui-auditor.js +141 -0
  50. package/dist/src/preview/ui-auditor.js.map +1 -0
  51. package/dist/src/preview/ui-gate.d.ts +66 -0
  52. package/dist/src/preview/ui-gate.js +210 -0
  53. package/dist/src/preview/ui-gate.js.map +1 -0
  54. package/dist/src/utils/ascii.d.ts +7 -0
  55. package/dist/src/utils/ascii.js +41 -0
  56. package/dist/src/utils/ascii.js.map +1 -0
  57. package/dist/src/utils/fs.d.ts +6 -0
  58. package/dist/src/utils/fs.js +39 -0
  59. package/dist/src/utils/fs.js.map +1 -0
  60. package/dist/templates/hooks/iddd-auto-audit.js +121 -0
  61. package/dist/templates/hooks/iddd-schema-drift.js +279 -0
  62. package/dist/templates/hooks/post-commit +121 -0
  63. package/dist/templates/hooks/pre-commit +348 -0
  64. package/package.json +37 -0
  65. package/templates/.agents/skills/.gitkeep +0 -0
  66. package/templates/.claude/hooks/.gitkeep +0 -0
  67. package/templates/.claude/hooks/hook-config.json +34 -0
  68. package/templates/.claude/skills/.gitkeep +0 -0
  69. package/templates/.codex/.gitkeep +0 -0
  70. package/templates/.codex/hooks.json +40 -0
  71. package/templates/.iddd/commit-count +1 -0
  72. package/templates/.iddd/preview/.gitkeep +0 -0
  73. package/templates/AGENTS.md +204 -0
  74. package/templates/CLAUDE.md +215 -0
  75. package/templates/README.md +476 -0
  76. package/templates/docs/.gitkeep +0 -0
  77. package/templates/docs/business-rules.md +14 -0
  78. package/templates/docs/domain-glossary.md +8 -0
  79. package/templates/docs/info-debt.md +17 -0
  80. package/templates/docs/model-changelog.md +12 -0
  81. package/templates/hooks/.gitkeep +0 -0
  82. package/templates/hooks/iddd-auto-audit.js +121 -0
  83. package/templates/hooks/iddd-schema-drift.js +279 -0
  84. package/templates/hooks/post-commit +121 -0
  85. package/templates/hooks/pre-commit +348 -0
  86. package/templates/skills/id3-design-information/SKILL.md +170 -0
  87. package/templates/skills/id3-design-information/references/phase2-procedure.md +241 -0
  88. package/templates/skills/id3-design-ui/.gitkeep +0 -0
  89. package/templates/skills/id3-design-ui/SKILL.md +200 -0
  90. package/templates/skills/id3-design-ui/references/.gitkeep +0 -0
  91. package/templates/skills/id3-design-ui/references/step1-structure-derivation.md +177 -0
  92. package/templates/skills/id3-design-ui/references/step2-visual-contract.md +257 -0
  93. package/templates/skills/id3-design-ui/references/step3-gate-and-mockup.md +177 -0
  94. package/templates/skills/id3-design-ui/references/step4-implementation.md +244 -0
  95. package/templates/skills/id3-identify-entities/SKILL.md +239 -0
  96. package/templates/skills/id3-identify-entities/references/.gitkeep +0 -0
  97. package/templates/skills/id3-identify-entities/references/phase0-brownfield.md +377 -0
  98. package/templates/skills/id3-identify-entities/references/phase1-greenfield.md +319 -0
  99. package/templates/skills/id3-info-audit/.gitkeep +0 -0
  100. package/templates/skills/id3-info-audit/SKILL.md +191 -0
  101. package/templates/skills/id3-preview/.gitkeep +0 -0
  102. package/templates/skills/id3-preview/SKILL.md +168 -0
  103. package/templates/skills/id3-spawn-team/.gitkeep +0 -0
  104. package/templates/skills/id3-spawn-team/SKILL.md +213 -0
  105. package/templates/specs/.gitkeep +0 -0
  106. package/templates/specs/data-model.md +26 -0
  107. package/templates/specs/entity-catalog.md +22 -0
  108. package/templates/specs/ui-design-contract.md +54 -0
  109. package/templates/specs/ui-inventory.md +24 -0
  110. package/templates/specs/ui-structure.md +32 -0
  111. package/templates/src/.gitkeep +0 -0
  112. package/templates/steering/.gitkeep +0 -0
  113. package/templates/steering/data-conventions.md +42 -0
  114. package/templates/steering/product.md +38 -0
@@ -0,0 +1,402 @@
1
+ import { escapeHtml } from './renderer.js';
2
+ // ── Entity -> Screen derivation (9 rules) ──────────────
3
+ function pluralize(name) {
4
+ const lower = name.toLowerCase();
5
+ if (lower.endsWith('s'))
6
+ return lower + 'es';
7
+ if (lower.endsWith('y') && !/[aeiou]y$/i.test(name))
8
+ return lower.slice(0, -1) + 'ies';
9
+ return lower + 's';
10
+ }
11
+ export function deriveScreensFromEntities(entities) {
12
+ const screens = [];
13
+ for (const entity of entities) {
14
+ const plural = pluralize(entity.name);
15
+ const hasPk = entity.attributes.some(a => a.constraints.includes('PK'));
16
+ const hasNotNull = entity.attributes.some(a => a.constraints.includes('NOT NULL') && !a.constraints.includes('PK')
17
+ && !['created_at', 'updated_at', 'deleted_at'].includes(a.name));
18
+ const hasMutable = entity.attributes.some(a => !a.constraints.includes('PK')
19
+ && !['created_at', 'updated_at', 'deleted_at'].includes(a.name));
20
+ const hasStateTransitions = entity.stateTransitions.length > 0;
21
+ // Rule 1: Entity exists -> List View
22
+ screens.push({
23
+ name: `${entity.name} List`,
24
+ url: `/${plural}`,
25
+ entity: entity.name,
26
+ pattern: 'list',
27
+ priority: 'P1',
28
+ source: 'auto-derived',
29
+ });
30
+ // Rule 2: PK exists -> Detail View
31
+ if (hasPk) {
32
+ screens.push({
33
+ name: `${entity.name} Detail`,
34
+ url: `/${plural}/:id`,
35
+ entity: entity.name,
36
+ pattern: 'detail',
37
+ priority: 'P1',
38
+ source: 'auto-derived',
39
+ });
40
+ }
41
+ // Rule 3: NOT NULL attributes -> Create Form
42
+ if (hasNotNull) {
43
+ screens.push({
44
+ name: `Create ${entity.name}`,
45
+ url: `/${plural}/new`,
46
+ entity: entity.name,
47
+ pattern: 'create',
48
+ priority: 'P1',
49
+ source: 'auto-derived',
50
+ });
51
+ }
52
+ // Rule 4: Mutable attributes -> Edit Form
53
+ if (hasMutable) {
54
+ screens.push({
55
+ name: `Edit ${entity.name}`,
56
+ url: `/${plural}/:id/edit`,
57
+ entity: entity.name,
58
+ pattern: 'edit',
59
+ priority: 'P2',
60
+ source: 'auto-derived',
61
+ });
62
+ }
63
+ // Rule 5: State Transition -> Status Dashboard
64
+ if (hasStateTransitions) {
65
+ screens.push({
66
+ name: `${entity.name} Dashboard`,
67
+ url: `/${plural}/dashboard`,
68
+ entity: entity.name,
69
+ pattern: 'dashboard',
70
+ priority: 'P2',
71
+ source: 'auto-derived',
72
+ });
73
+ }
74
+ // Rule 6: 1:N FK (parent side) -> Child Tab
75
+ for (const rel of entity.relationships) {
76
+ if (rel.type === '1:N') {
77
+ screens.push({
78
+ name: `${entity.name} ${rel.target} Tab`,
79
+ url: `/${plural}/:id/${pluralize(rel.target)}`,
80
+ entity: entity.name,
81
+ pattern: 'child-tab',
82
+ priority: 'P2',
83
+ source: 'auto-derived',
84
+ relatedEntity: rel.target,
85
+ });
86
+ }
87
+ // Rule 7: N:M -> Association Manager
88
+ if (rel.type === 'N:M') {
89
+ screens.push({
90
+ name: `${entity.name} ${rel.target} Manager`,
91
+ url: `/${plural}/:id/${pluralize(rel.target)}/manage`,
92
+ entity: entity.name,
93
+ pattern: 'association-manager',
94
+ priority: 'P3',
95
+ source: 'auto-derived',
96
+ relatedEntity: rel.target,
97
+ });
98
+ }
99
+ }
100
+ }
101
+ return screens;
102
+ }
103
+ // ── Attribute -> Widget mapping (12 rules) ──────────────
104
+ export function mapAttributeToWidget(attr) {
105
+ // Rule 10: UUID PK -> hidden
106
+ if (attr.type === 'UUID' && attr.constraints.includes('PK'))
107
+ return 'hidden';
108
+ // Rule 12: Specialized input (email/url/phone)
109
+ if (attr.subtype && ['email', 'url', 'phone'].includes(attr.subtype))
110
+ return 'specialized-input';
111
+ // Rule 11: File -> file-upload
112
+ if (attr.type === 'FILE')
113
+ return 'file-upload';
114
+ // Rule 3: ENUM -> select
115
+ if (attr.type === 'ENUM')
116
+ return 'select';
117
+ // Rule 4: BOOLEAN -> toggle
118
+ if (attr.type === 'BOOLEAN')
119
+ return 'toggle';
120
+ // Rule 5-6: INTEGER/DECIMAL -> number-input
121
+ if (attr.type === 'INTEGER' || attr.type === 'DECIMAL')
122
+ return 'number-input';
123
+ // Rule 7: DATE -> date-picker
124
+ if (attr.type === 'DATE')
125
+ return 'date-picker';
126
+ // Rule 8: TIMESTAMP -> datetime-picker
127
+ if (attr.type === 'TIMESTAMP')
128
+ return 'datetime-picker';
129
+ // Rule 9: FK -> autocomplete
130
+ if (attr.type === 'FK')
131
+ return 'autocomplete';
132
+ // Rule: JSONB -> json-editor
133
+ if (attr.type === 'JSONB')
134
+ return 'json-editor';
135
+ // Rule 1-2: VARCHAR/TEXT based on length
136
+ if (attr.type === 'TEXT' || (attr.type === 'VARCHAR' && (attr.maxLength === undefined || attr.maxLength > 200))) {
137
+ return 'textarea';
138
+ }
139
+ return 'text-input';
140
+ }
141
+ // ── Sample data generation ────────────────────────────
142
+ const SAMPLE_NAMES = ['Alice Johnson', 'Bob Smith', 'Carol Williams', 'David Brown', 'Eve Davis'];
143
+ const SAMPLE_EMAILS = ['alice@example.com', 'bob@example.com', 'carol@example.com', 'david@example.com', 'eve@example.com'];
144
+ const SAMPLE_ORGS = ['Acme Corp', 'Globex Inc', 'Initech', 'Umbrella Corp', 'Stark Industries'];
145
+ const SAMPLE_TIMESTAMPS = ['2026-04-05 14:30', '2026-03-28 09:15', '2026-02-14 16:45', '2026-01-10 11:00', '2025-12-25 08:30'];
146
+ const SAMPLE_INTS = [42, 128, 7, 256, 1024];
147
+ export function generateSampleData(attr, count) {
148
+ const results = [];
149
+ for (let i = 0; i < count; i++) {
150
+ if (attr.type === 'BOOLEAN') {
151
+ results.push(i % 2 === 0);
152
+ }
153
+ else if (attr.type === 'INTEGER' || attr.type === 'DECIMAL') {
154
+ results.push(SAMPLE_INTS[i % SAMPLE_INTS.length]);
155
+ }
156
+ else if (attr.type === 'ENUM' && attr.enumValues) {
157
+ results.push(attr.enumValues[i % attr.enumValues.length]);
158
+ }
159
+ else if (attr.type === 'TIMESTAMP') {
160
+ results.push(SAMPLE_TIMESTAMPS[i % SAMPLE_TIMESTAMPS.length]);
161
+ }
162
+ else if (attr.type === 'DATE') {
163
+ results.push(SAMPLE_TIMESTAMPS[i % SAMPLE_TIMESTAMPS.length].split(' ')[0]);
164
+ }
165
+ else if (attr.type === 'FK') {
166
+ results.push(SAMPLE_ORGS[i % SAMPLE_ORGS.length]);
167
+ }
168
+ else if (attr.subtype === 'email' || attr.name.includes('email')) {
169
+ results.push(SAMPLE_EMAILS[i % SAMPLE_EMAILS.length]);
170
+ }
171
+ else if (attr.name.includes('name') || attr.name.includes('title')) {
172
+ results.push(SAMPLE_NAMES[i % SAMPLE_NAMES.length]);
173
+ }
174
+ else {
175
+ results.push(`Sample ${attr.name} ${i + 1}`);
176
+ }
177
+ }
178
+ return results;
179
+ }
180
+ // ── Mockup Index HTML (left menu + full screen list) ─────
181
+ export function renderMockupIndexHtml(screens, title) {
182
+ // Group screens by entity
183
+ const byEntity = new Map();
184
+ for (const s of screens) {
185
+ if (!byEntity.has(s.entity))
186
+ byEntity.set(s.entity, []);
187
+ byEntity.get(s.entity).push(s);
188
+ }
189
+ const navItems = Array.from(byEntity.entries())
190
+ .map(([entity, entityScreens]) => {
191
+ const links = entityScreens
192
+ .map(s => ` <li><a href="mockup-${entity.toLowerCase()}.html#${s.pattern}">${escapeHtml(s.name)}</a></li>`)
193
+ .join('\n');
194
+ return ` <li class="nav-group">
195
+ <strong>${escapeHtml(entity)}</strong>
196
+ <ul>
197
+ ${links}
198
+ </ul>
199
+ </li>`;
200
+ })
201
+ .join('\n');
202
+ const cards = screens
203
+ .map(s => ` <div class="card">
204
+ <div class="card-header">${escapeHtml(s.name)}</div>
205
+ <div class="card-url">${escapeHtml(s.url)}</div>
206
+ <div class="card-meta">Entity: ${escapeHtml(s.entity)} | Pattern: ${escapeHtml(s.pattern)} | Priority: ${escapeHtml(s.priority)}</div>
207
+ </div>`)
208
+ .join('\n');
209
+ return `<!DOCTYPE html>
210
+ <html lang="en">
211
+ <head>
212
+ <meta charset="UTF-8">
213
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
214
+ <title>${escapeHtml(title)}</title>
215
+ <style>
216
+ :root { --bg: #ffffff; --text: #1a1a2e; --card: #f8f9fa; --border: #dee2e6; --accent: #3b82f6; --nav-bg: #f1f5f9; }
217
+ @media (prefers-color-scheme: dark) {
218
+ :root { --bg: #1a1a2e; --text: #e0e0e0; --card: #16213e; --border: #334155; --nav-bg: #0f172a; }
219
+ }
220
+ * { margin: 0; padding: 0; box-sizing: border-box; }
221
+ body { font-family: -apple-system, system-ui, sans-serif; background: var(--bg); color: var(--text); display: flex; min-height: 100vh; }
222
+ nav { width: 260px; background: var(--nav-bg); border-right: 1px solid var(--border); padding: 1rem; overflow-y: auto; position: fixed; top: 0; bottom: 0; }
223
+ nav h2 { font-size: 1.1rem; margin-bottom: 1rem; }
224
+ nav ul { list-style: none; }
225
+ nav .nav-group { margin-bottom: 0.75rem; }
226
+ nav .nav-group ul { margin-top: 0.25rem; padding-left: 1rem; }
227
+ nav a { color: var(--accent); text-decoration: none; font-size: 0.9rem; }
228
+ nav a:hover { text-decoration: underline; }
229
+ main { margin-left: 260px; padding: 2rem; flex: 1; }
230
+ h1 { font-size: 1.5rem; border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; margin-bottom: 1.5rem; }
231
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem; }
232
+ .card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; }
233
+ .card-header { font-weight: bold; font-size: 1.1rem; }
234
+ .card-url { font-family: monospace; color: #6c757d; margin: 0.25rem 0; }
235
+ .card-meta { font-size: 0.85rem; color: #6c757d; }
236
+ .meta { font-size: 0.85rem; color: #6c757d; margin-top: 2rem; }
237
+ </style>
238
+ </head>
239
+ <body>
240
+ <nav>
241
+ <h2>Screens</h2>
242
+ <ul>
243
+ ${navItems}
244
+ </ul>
245
+ </nav>
246
+ <main>
247
+ <h1>${escapeHtml(title)}</h1>
248
+ <div class="grid">
249
+ ${cards}
250
+ </div>
251
+ <p class="meta">Generated by IDDD Phase 2.5 -- ${new Date().toISOString().split('T')[0]}</p>
252
+ </main>
253
+ </body>
254
+ </html>`;
255
+ }
256
+ // ── Entity Mockup HTML (3 fidelity levels + traceability) ──
257
+ export function renderEntityMockupHtml(entity, tokens) {
258
+ const visibleAttrs = entity.attributes.filter(a => !a.constraints.includes('PK')
259
+ && !['created_at', 'updated_at', 'deleted_at'].includes(a.name));
260
+ // Generate wireframe tab content
261
+ const wireframeRows = visibleAttrs
262
+ .map(a => {
263
+ const widget = mapAttributeToWidget(a);
264
+ const required = a.constraints.includes('NOT NULL') ? ' *' : '';
265
+ return ` <tr><td>${escapeHtml(a.name)}${required}</td><td>[${escapeHtml(widget)}]</td></tr>`;
266
+ })
267
+ .join('\n');
268
+ const wireframeHtml = `
269
+ <table class="wireframe-table">
270
+ <tr><th>Field</th><th>Widget</th></tr>
271
+ ${wireframeRows}
272
+ </table>`;
273
+ // Generate styled tab content (design tokens applied)
274
+ const styledRows = visibleAttrs
275
+ .map(a => {
276
+ const widget = mapAttributeToWidget(a);
277
+ const required = a.constraints.includes('NOT NULL') ? '<span class="required">*</span>' : '';
278
+ return ` <div class="form-group" style="margin-bottom: ${tokens.spacing.base * 2}px;">
279
+ <label style="font-size: ${tokens.typography.body.size}; font-weight: ${tokens.typography.body.weight};">${escapeHtml(a.name)}${required}</label>
280
+ <div class="widget" data-type="${escapeHtml(widget)}">${escapeHtml(widget)}</div>
281
+ </div>`;
282
+ })
283
+ .join('\n');
284
+ const styledHtml = `
285
+ <div class="styled-form" style="background: ${tokens.colors.surface}; padding: ${tokens.spacing.base * 3}px;">
286
+ ${styledRows}
287
+ <button style="background: ${tokens.colors.accent}; color: white; border: none; padding: ${tokens.spacing.base}px ${tokens.spacing.base * 2}px; border-radius: 4px;">Save</button>
288
+ </div>`;
289
+ // Generate interactive tab content (sample data)
290
+ const sampleCount = 3;
291
+ const headerCells = visibleAttrs.map(a => `<th>${escapeHtml(a.name)}</th>`).join('');
292
+ const bodyRows = [];
293
+ for (let row = 0; row < sampleCount; row++) {
294
+ const cells = visibleAttrs
295
+ .map(a => {
296
+ const samples = generateSampleData(a, sampleCount);
297
+ return `<td>${escapeHtml(String(samples[row]))}</td>`;
298
+ })
299
+ .join('');
300
+ bodyRows.push(` <tr>${cells}</tr>`);
301
+ }
302
+ const interactiveHtml = `
303
+ <table class="interactive-table">
304
+ <thead><tr>${headerCells}</tr></thead>
305
+ <tbody>
306
+ ${bodyRows.join('\n')}
307
+ </tbody>
308
+ </table>`;
309
+ // Generate traceability panel
310
+ const traceRows = entity.attributes
311
+ .map(a => {
312
+ const widget = mapAttributeToWidget(a);
313
+ const constraints = a.constraints.join(', ') || '-';
314
+ return ` <tr>
315
+ <td>${escapeHtml(entity.name)}</td>
316
+ <td>${escapeHtml(a.name)}</td>
317
+ <td>${escapeHtml(a.type)}</td>
318
+ <td>${escapeHtml(widget)}</td>
319
+ <td>${escapeHtml(constraints)}</td>
320
+ </tr>`;
321
+ })
322
+ .join('\n');
323
+ const traceHtml = `
324
+ <div class="traceability">
325
+ <h3>Traceability</h3>
326
+ <table>
327
+ <thead><tr><th>Entity</th><th>Attribute</th><th>Type</th><th>Widget</th><th>Constraints</th></tr></thead>
328
+ <tbody>
329
+ ${traceRows}
330
+ </tbody>
331
+ </table>
332
+ </div>`;
333
+ return `<!DOCTYPE html>
334
+ <html lang="en">
335
+ <head>
336
+ <meta charset="UTF-8">
337
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
338
+ <title>Mockup: ${escapeHtml(entity.name)}</title>
339
+ <style>
340
+ :root { --bg: #ffffff; --text: #1a1a2e; --card: #f8f9fa; --border: #dee2e6; --accent: ${tokens.colors.accent}; }
341
+ @media (prefers-color-scheme: dark) {
342
+ :root { --bg: #1a1a2e; --text: #e0e0e0; --card: #16213e; --border: #334155; }
343
+ }
344
+ body { font-family: -apple-system, system-ui, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 2rem; }
345
+ h1 { font-size: 1.5rem; border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; }
346
+ .tabs { display: flex; gap: 0; margin: 1.5rem 0 0; border-bottom: 2px solid var(--border); }
347
+ .tab { padding: 0.5rem 1.5rem; cursor: pointer; border: 1px solid transparent; border-bottom: none; background: transparent; font-size: 1rem; color: var(--text); }
348
+ .tab.active { background: var(--card); border-color: var(--border); border-bottom: 2px solid var(--bg); margin-bottom: -2px; font-weight: bold; }
349
+ .tab-content { display: none; padding: 1.5rem; background: var(--card); border: 1px solid var(--border); border-top: none; }
350
+ .tab-content.active { display: block; }
351
+ table { width: 100%; border-collapse: collapse; }
352
+ th, td { padding: 0.5rem; border: 1px solid var(--border); text-align: left; }
353
+ th { background: var(--card); font-weight: 600; }
354
+ .wireframe-table { font-family: monospace; }
355
+ .form-group label { display: block; margin-bottom: 4px; }
356
+ .widget { padding: 8px; border: 1px dashed var(--border); border-radius: 4px; color: ${tokens.colors.secondary}; }
357
+ .required { color: #ef4444; margin-left: 2px; }
358
+ .traceability { margin-top: 2rem; padding-top: 1rem; border-top: 2px solid var(--border); }
359
+ .traceability h3 { margin-bottom: 0.5rem; }
360
+ .meta { font-size: 0.85rem; color: #6c757d; margin-top: 1rem; }
361
+ </style>
362
+ </head>
363
+ <body>
364
+ <h1>Mockup: ${escapeHtml(entity.name)}</h1>
365
+
366
+ <div class="tabs">
367
+ <button class="tab active" onclick="switchTab('wireframe')">Wireframe</button>
368
+ <button class="tab" onclick="switchTab('styled')">Styled</button>
369
+ <button class="tab" onclick="switchTab('interactive')">Interactive</button>
370
+ </div>
371
+
372
+ <div id="wireframe" class="tab-content active">
373
+ <h2>Wireframe</h2>
374
+ ${wireframeHtml}
375
+ </div>
376
+
377
+ <div id="styled" class="tab-content">
378
+ <h2>Styled</h2>
379
+ ${styledHtml}
380
+ </div>
381
+
382
+ <div id="interactive" class="tab-content">
383
+ <h2>Interactive</h2>
384
+ ${interactiveHtml}
385
+ </div>
386
+
387
+ ${traceHtml}
388
+
389
+ <p class="meta">Generated by IDDD Phase 2.5 -- ${new Date().toISOString().split('T')[0]}</p>
390
+
391
+ <script>
392
+ function switchTab(tabId) {
393
+ document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
394
+ document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
395
+ document.getElementById(tabId).classList.add('active');
396
+ document.querySelector('[onclick="switchTab(\\'' + tabId + '\\')"]').classList.add('active');
397
+ }
398
+ </script>
399
+ </body>
400
+ </html>`;
401
+ }
402
+ //# sourceMappingURL=mockup-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockup-generator.js","sourceRoot":"","sources":["../../../src/preview/mockup-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export declare function extractMermaidBlock(markdown: string): string;
2
+ export declare function renderErdHtml(mermaidCode: string, title: string): string;
3
+ export interface ScreenDef {
4
+ name: string;
5
+ url: string;
6
+ entity: string;
7
+ pattern: string;
8
+ }
9
+ export declare function renderMockupHtml(screens: ScreenDef[], title: string): string;
10
+ export interface AuditData {
11
+ version: string;
12
+ lastVerified: string;
13
+ entities: {
14
+ defined: number;
15
+ implemented: number;
16
+ missing: number;
17
+ };
18
+ rules: {
19
+ defined: number;
20
+ implemented: number;
21
+ missing: number;
22
+ };
23
+ screens: {
24
+ defined: number;
25
+ implemented: number;
26
+ missing: number;
27
+ };
28
+ }
29
+ export declare function renderAuditHtml(data: AuditData): string;
30
+ export declare function escapeHtml(str: string): string;
@@ -0,0 +1,145 @@
1
+ export function extractMermaidBlock(markdown) {
2
+ const match = markdown.match(/```mermaid\n([\s\S]*?)```/);
3
+ return match ? match[1].trim() : '';
4
+ }
5
+ export function renderErdHtml(mermaidCode, title) {
6
+ return `<!DOCTYPE html>
7
+ <html lang="en">
8
+ <head>
9
+ <meta charset="UTF-8">
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ <title>${escapeHtml(title)}</title>
12
+ <style>
13
+ :root { --bg: #ffffff; --text: #1a1a2e; --card: #f8f9fa; --border: #dee2e6; }
14
+ @media (prefers-color-scheme: dark) {
15
+ :root { --bg: #1a1a2e; --text: #e0e0e0; --card: #16213e; --border: #334155; }
16
+ }
17
+ body { font-family: -apple-system, system-ui, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 2rem; }
18
+ h1 { font-size: 1.5rem; border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; }
19
+ .mermaid { background: var(--card); border-radius: 8px; padding: 2rem; border: 1px solid var(--border); }
20
+ .meta { font-size: 0.85rem; color: #6c757d; margin-top: 1rem; }
21
+ #theme-toggle { position: fixed; top: 1rem; right: 1rem; cursor: pointer; font-size: 1.5rem; background: none; border: none; }
22
+ </style>
23
+ </head>
24
+ <body>
25
+ <button id="theme-toggle" onclick="toggleTheme()">šŸŒ“</button>
26
+ <h1>${escapeHtml(title)}</h1>
27
+ <div class="mermaid">
28
+ ${mermaidCode}
29
+ </div>
30
+ <p class="meta">Generated by IDDD Preview — ${new Date().toISOString().split('T')[0]}</p>
31
+ <script type="module">
32
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
33
+ mermaid.initialize({
34
+ startOnLoad: false,
35
+ theme: window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'default',
36
+ maxTextSize: 200000,
37
+ });
38
+ await mermaid.run({ querySelector: '.mermaid' });
39
+ </script>
40
+ <script>
41
+ function toggleTheme() {
42
+ document.documentElement.style.colorScheme = document.documentElement.style.colorScheme === 'dark' ? 'light' : 'dark';
43
+ location.reload();
44
+ }
45
+ </script>
46
+ </body>
47
+ </html>`;
48
+ }
49
+ export function renderMockupHtml(screens, title) {
50
+ const cards = screens
51
+ .map((s) => `
52
+ <div class="card">
53
+ <div class="card-header">${escapeHtml(s.name)}</div>
54
+ <div class="card-url">${escapeHtml(s.url)}</div>
55
+ <div class="card-meta">Entity: ${escapeHtml(s.entity)} | Pattern: ${escapeHtml(s.pattern)}</div>
56
+ <div class="card-wireframe">${wireframe(s.pattern)}</div>
57
+ </div>`)
58
+ .join('\n');
59
+ return `<!DOCTYPE html>
60
+ <html lang="en">
61
+ <head>
62
+ <meta charset="UTF-8">
63
+ <title>${escapeHtml(title)}</title>
64
+ <style>
65
+ :root { --bg: #ffffff; --text: #1a1a2e; --card: #f8f9fa; --border: #dee2e6; }
66
+ @media (prefers-color-scheme: dark) { :root { --bg: #1a1a2e; --text: #e0e0e0; --card: #16213e; --border: #334155; } }
67
+ body { font-family: -apple-system, system-ui, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 2rem; }
68
+ h1 { font-size: 1.5rem; border-bottom: 2px solid var(--border); padding-bottom: 0.5rem; }
69
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem; margin-top: 1.5rem; }
70
+ .card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; }
71
+ .card-header { font-weight: bold; font-size: 1.1rem; }
72
+ .card-url { font-family: monospace; color: #6c757d; margin: 0.25rem 0; }
73
+ .card-meta { font-size: 0.85rem; color: #6c757d; margin-bottom: 0.75rem; }
74
+ .card-wireframe { background: var(--bg); border: 1px dashed var(--border); border-radius: 4px; padding: 1rem; font-family: monospace; font-size: 0.8rem; white-space: pre; }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <h1>${escapeHtml(title)}</h1>
79
+ <div class="grid">${cards}</div>
80
+ </body>
81
+ </html>`;
82
+ }
83
+ function wireframe(pattern) {
84
+ switch (pattern) {
85
+ case 'list':
86
+ return 'ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n│ [Search...] [+New] │\nā”œā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n│ # │ Name │ Status │\nā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n│ 1 │ ā–ˆā–ˆā–ˆā–ˆ │ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ │\n│ 2 │ ā–ˆā–ˆā–ˆā–ˆ │ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ │\n│ 3 │ ā–ˆā–ˆā–ˆā–ˆ │ ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ │\nā””ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜';
87
+ case 'detail':
88
+ return 'ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n│ ← Back [Edit] │\nā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n│ Title: ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ │\n│ Status: ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ │\n│ Created: ā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆā–ˆ │\nā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n│ [Related Items Tab] │\nā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜';
89
+ case 'form':
90
+ return 'ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n│ Create / Edit │\nā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤\n│ Name: [________] │\n│ Email: [________] │\n│ Role: [ā–¼ Select ] │\n│ │\n│ [Cancel] [Save] │\nā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜';
91
+ default:
92
+ return 'ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”\n│ [Screen Wireframe] │\nā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜';
93
+ }
94
+ }
95
+ export function renderAuditHtml(data) {
96
+ return `<!DOCTYPE html>
97
+ <html lang="en">
98
+ <head>
99
+ <meta charset="UTF-8">
100
+ <title>IDDD Audit Report</title>
101
+ <style>
102
+ :root { --bg: #ffffff; --text: #1a1a2e; --card: #f8f9fa; --border: #dee2e6; --green: #28a745; --yellow: #ffc107; --red: #dc3545; }
103
+ @media (prefers-color-scheme: dark) { :root { --bg: #1a1a2e; --text: #e0e0e0; --card: #16213e; --border: #334155; } }
104
+ body { font-family: -apple-system, system-ui, sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 2rem; }
105
+ h1 { font-size: 1.5rem; }
106
+ .summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; margin: 1.5rem 0; }
107
+ .stat { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1.5rem; text-align: center; }
108
+ .stat-value { font-size: 2rem; font-weight: bold; }
109
+ .stat-label { font-size: 0.85rem; color: #6c757d; }
110
+ .ok { color: var(--green); }
111
+ .warn { color: var(--yellow); }
112
+ .err { color: var(--red); }
113
+ .bar { height: 8px; border-radius: 4px; background: var(--border); margin-top: 0.5rem; overflow: hidden; }
114
+ .bar-fill { height: 100%; border-radius: 4px; }
115
+ </style>
116
+ </head>
117
+ <body>
118
+ <h1>IDDD Audit Report</h1>
119
+ <p>Model version: ${escapeHtml(data.version)} | Last verified: ${escapeHtml(data.lastVerified)}</p>
120
+ <div class="summary">
121
+ ${auditCard('Entities', data.entities)}
122
+ ${auditCard('Business Rules', data.rules)}
123
+ ${auditCard('UI Screens', data.screens)}
124
+ </div>
125
+ </body>
126
+ </html>`;
127
+ }
128
+ function auditCard(label, data) {
129
+ const pct = data.defined > 0 ? Math.round((data.implemented / data.defined) * 100) : 0;
130
+ const color = pct === 100 ? 'var(--green)' : pct >= 80 ? 'var(--yellow)' : 'var(--red)';
131
+ return `<div class="stat">
132
+ <div class="stat-value" style="color:${color}">${data.implemented}/${data.defined}</div>
133
+ <div class="stat-label">${escapeHtml(label)}</div>
134
+ <div class="bar"><div class="bar-fill" style="width:${pct}%;background:${color}"></div></div>
135
+ ${data.missing > 0 ? `<div class="stat-label err">${data.missing} missing</div>` : ''}
136
+ </div>`;
137
+ }
138
+ export function escapeHtml(str) {
139
+ return str
140
+ .replace(/&/g, '&amp;')
141
+ .replace(/</g, '&lt;')
142
+ .replace(/>/g, '&gt;')
143
+ .replace(/"/g, '&quot;');
144
+ }
145
+ //# sourceMappingURL=renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../src/preview/renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface PreviewServerResult {
2
+ port: number;
3
+ close: () => void;
4
+ }
5
+ export declare function startPreviewServer(previewDir: string): Promise<PreviewServerResult>;
6
+ export declare function printPreviewReady(port: number, files: Array<{
7
+ name: string;
8
+ path: string;
9
+ }>): void;