@maccesar/aiskills 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +531 -0
  2. package/bin/aiskills.js +76 -0
  3. package/lib/cache.js +49 -0
  4. package/lib/cleanup.js +77 -0
  5. package/lib/commands/auto-update.js +131 -0
  6. package/lib/commands/doctor.js +139 -0
  7. package/lib/commands/list.js +77 -0
  8. package/lib/commands/skills.js +263 -0
  9. package/lib/commands/status.js +94 -0
  10. package/lib/commands/uninstall.js +182 -0
  11. package/lib/commands/update.js +149 -0
  12. package/lib/config.js +90 -0
  13. package/lib/downloader.js +110 -0
  14. package/lib/hooks.js +74 -0
  15. package/lib/installer.js +114 -0
  16. package/lib/platform.js +112 -0
  17. package/lib/prompts/checkboxCancel.js +264 -0
  18. package/lib/prompts/selectCancel.js +204 -0
  19. package/lib/symlink.js +154 -0
  20. package/lib/utils.js +49 -0
  21. package/package.json +61 -0
  22. package/skills/humaniza/SKILL.md +51 -0
  23. package/skills/humaniza/agents/openai.yaml +4 -0
  24. package/skills/humaniza/references/ai-patterns-es.md +51 -0
  25. package/skills/humaniza/references/checklist.md +9 -0
  26. package/skills/humaniza/references/examples.md +17 -0
  27. package/skills/humaniza/references/lexicon-es-mx.md +36 -0
  28. package/skills/humaniza/references/modes-es-mx.md +41 -0
  29. package/skills/humaniza/references/voice-es-mx.md +24 -0
  30. package/skills/refactoring-ui/SKILL.md +59 -0
  31. package/skills/refactoring-ui/references/01-design-process.md +72 -0
  32. package/skills/refactoring-ui/references/02-visual-hierarchy.md +84 -0
  33. package/skills/refactoring-ui/references/03-layout-spacing.md +69 -0
  34. package/skills/refactoring-ui/references/04-typography.md +70 -0
  35. package/skills/refactoring-ui/references/05-color.md +96 -0
  36. package/skills/refactoring-ui/references/06-depth-shadows.md +74 -0
  37. package/skills/refactoring-ui/references/07-images.md +75 -0
  38. package/skills/refactoring-ui/references/08-finishing-touches.md +91 -0
  39. package/skills/stitch-showcase/SKILL.md +411 -0
  40. package/skills/stitch-showcase/references/01-navbar.md +52 -0
  41. package/skills/stitch-showcase/references/02-hero.md +56 -0
  42. package/skills/stitch-showcase/references/03-design-system.md +102 -0
  43. package/skills/stitch-showcase/references/04-screen-gallery.md +102 -0
  44. package/skills/stitch-showcase/references/05-viewer-web.md +105 -0
  45. package/skills/stitch-showcase/references/06-viewer-mobile.md +104 -0
  46. package/skills/stitch-showcase/references/07-theme-system.md +77 -0
  47. package/skills/stitch-showcase/references/08-type-detection.md +81 -0
  48. package/skills/stitch-showcase/references/09-quality-standards.md +126 -0
  49. package/skills/stitch-showcase/references/10-component-standardization.md +40 -0
  50. package/skills/stitch-showcase/references/11-component-catalog.md +70 -0
  51. package/skills/stitch-showcase/references/catalog-template.html +841 -0
  52. package/skills/stitch-showcase/references/index.html +299 -0
  53. package/skills/stitch-showcase/references/viewer.html +412 -0
  54. package/skills/stitch-showcase/scripts/__pycache__/build_showcase.cpython-314.pyc +0 -0
  55. package/skills/stitch-showcase/scripts/__pycache__/component_utils.cpython-313.pyc +0 -0
  56. package/skills/stitch-showcase/scripts/__pycache__/detect_components.cpython-313.pyc +0 -0
  57. package/skills/stitch-showcase/scripts/__pycache__/extract_catalog.cpython-313.pyc +0 -0
  58. package/skills/stitch-showcase/scripts/__pycache__/extract_text.cpython-313.pyc +0 -0
  59. package/skills/stitch-showcase/scripts/__pycache__/extract_zips.cpython-313.pyc +0 -0
  60. package/skills/stitch-showcase/scripts/__pycache__/parse_design_md.cpython-313.pyc +0 -0
  61. package/skills/stitch-showcase/scripts/apply_canonical.py +238 -0
  62. package/skills/stitch-showcase/scripts/build_showcase.py +2103 -0
  63. package/skills/stitch-showcase/scripts/component_utils.py +398 -0
  64. package/skills/stitch-showcase/scripts/detect_components.py +284 -0
  65. package/skills/stitch-showcase/scripts/extract_catalog.py +913 -0
  66. package/skills/stitch-showcase/scripts/extract_text.py +268 -0
  67. package/skills/stitch-showcase/scripts/extract_zips.py +178 -0
  68. package/skills/stitch-showcase/scripts/parse_design_md.py +397 -0
  69. package/skills/vscode-extension-dev/SKILL.md +114 -0
  70. package/skills/vscode-extension-dev/references/api-patterns.md +625 -0
  71. package/skills/vscode-extension-dev/references/architecture.md +287 -0
  72. package/skills/vscode-extension-dev/references/package-json-schema.md +345 -0
  73. package/skills/vscode-extension-dev/references/publishing.md +251 -0
@@ -0,0 +1,299 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>{{PROJECT_NAME}} — Showcase</title>
8
+ {{FONT_LINK}}
9
+ <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
10
+ <script>
11
+ // Apply theme before render to prevent flash
12
+ (function () {
13
+ const saved = localStorage.getItem('showcase-theme');
14
+ const fallback = '{{DEFAULT_THEME}}';
15
+ if ((saved ?? fallback) === 'dark') document.documentElement.classList.add('dark');
16
+ // Apply view mode before render (scoped per project so different showcases don't conflict)
17
+ const viewKey = 'showcase-view-mode-' + '{{PROJECT_SLUG}}';
18
+ const view = localStorage.getItem(viewKey) || '{{DEFAULT_VIEW}}';
19
+ document.documentElement.classList.add('view-' + view);
20
+ })();
21
+ tailwind.config = {
22
+ darkMode: 'class',
23
+ theme: {
24
+ extend: {
25
+ colors: { accent: '{{PRIMARY_COLOR}}' },
26
+ fontFamily: { sans: ['{{FONT_FAMILY}}', 'system-ui', 'sans-serif'] }
27
+ }
28
+ }
29
+ }
30
+ </script>
31
+ <style>
32
+ /* View mode: card thumbnail aspect ratios */
33
+ .view-mobile .card-thumb { aspect-ratio: 9/19.5; background: #000; }
34
+ .view-web .card-thumb { aspect-ratio: 16/10; }
35
+ html:not(.dark).view-web .card-thumb { background: #fff; }
36
+ html.dark.view-web .card-thumb { background: #1a1a1a; }
37
+
38
+ /* List mode overrides — thumbnail always horizontal rectangle, regardless of view mode */
39
+ .screens-grid.list-mode { display: flex; flex-direction: column; gap: 8px; }
40
+ .screens-grid.list-mode .screen-card { display: flex; flex-direction: row; gap: 16px; }
41
+ .screens-grid.list-mode .screen-card .card-thumb { width: 240px; flex-shrink: 0; aspect-ratio: 16/10 !important; border-radius: 12px; }
42
+ .screens-grid.list-mode .screen-card .card-info { flex: 1; min-width: 0; padding-top: 4px; }
43
+ .screens-grid.list-mode .screen-card .card-desc { -webkit-line-clamp: unset; overflow: visible; white-space: normal; }
44
+
45
+ /* Grid columns per view mode */
46
+ .view-mobile .screens-grid:not(.list-mode) { grid-template-columns: repeat(4, 1fr) !important; }
47
+ .view-web .screens-grid:not(.list-mode) { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)) !important; }
48
+
49
+ /* Hide scrollbar on tabs */
50
+ .tabs-scroll { -ms-overflow-style: none; scrollbar-width: none; }
51
+ .tabs-scroll::-webkit-scrollbar { display: none; }
52
+ </style>
53
+ </head>
54
+
55
+ <body class="min-h-screen bg-[#fafafa] text-gray-900 transition-colors duration-200 dark:bg-[#0d0d0d] dark:text-gray-100">
56
+
57
+ <!-- ── Header ─────────────────────────────────────────── -->
58
+ <header class="sticky top-0 z-50 border-b border-gray-200/60 backdrop-blur-xl bg-white/80 dark:border-white/10 dark:bg-[#0d0d0d]/80">
59
+ <div class="mx-auto flex h-14 max-w-[1280px] items-center justify-between gap-4 px-6">
60
+
61
+ <div class="flex min-w-0 items-center gap-3">
62
+ <span class="truncate text-sm font-semibold">{{PROJECT_NAME}}</span>
63
+ <span id="view-badge" class="shrink-0 inline-flex items-center gap-1.5 rounded-full border border-gray-200 bg-gray-100 px-2.5 py-0.5 text-[11px] font-medium text-gray-500 dark:border-white/10 dark:bg-white/5 dark:text-gray-400">
64
+ </span>
65
+ <span class="shrink-0 text-xs text-gray-400 dark:text-gray-500">{{SCREEN_COUNT}} screens</span>
66
+ <a href="catalog.html" class="shrink-0 inline-flex items-center gap-1 rounded-full border border-gray-200 bg-gray-50 px-2.5 py-0.5 text-[11px] font-medium text-gray-500 transition-colors hover:border-accent hover:text-accent dark:border-white/10 dark:bg-white/5 dark:text-gray-400 dark:hover:border-accent dark:hover:text-accent">
67
+ <svg class="h-3 w-3" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
68
+ Catalog
69
+ </a>
70
+ </div>
71
+
72
+ <div class="flex shrink-0 items-center gap-2">
73
+ <!-- View mode toggle (mobile/web) -->
74
+ <button id="view-mode-toggle" title="Toggle mobile/web view" class="flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/10">
75
+ <svg id="icon-phone" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
76
+ <rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="12" y1="18" x2="12.01" y2="18"/>
77
+ </svg>
78
+ <svg id="icon-monitor" class="hidden h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
79
+ <rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/>
80
+ </svg>
81
+ </button>
82
+ <!-- Grid/list toggle -->
83
+ <button id="view-toggle" title="Toggle grid/list view" class="flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/10">
84
+ <svg id="icon-grid" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
85
+ <rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/>
86
+ </svg>
87
+ <svg id="icon-list" class="hidden h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
88
+ <line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/>
89
+ </svg>
90
+ </button>
91
+ <!-- Theme toggle -->
92
+ <button id="theme-toggle" title="Toggle light/dark" class="flex h-8 w-8 items-center justify-center rounded-lg text-gray-500 transition-colors hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-white/10">
93
+ <svg class="block h-4 w-4 dark:hidden" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
94
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
95
+ </svg>
96
+ <svg class="hidden h-4 w-4 dark:block" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
97
+ <circle cx="12" cy="12" r="5" />
98
+ <line x1="12" y1="1" x2="12" y2="3" />
99
+ <line x1="12" y1="21" x2="12" y2="23" />
100
+ <line x1="4.22" y1="4.22" x2="5.64" y2="5.64" />
101
+ <line x1="18.36" y1="18.36" x2="19.78" y2="19.78" />
102
+ <line x1="1" y1="12" x2="3" y2="12" />
103
+ <line x1="21" y1="12" x2="23" y2="12" />
104
+ <line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
105
+ <line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
106
+ </svg>
107
+ </button>
108
+ </div>
109
+
110
+ </div>
111
+ </header>
112
+
113
+ <!-- ── Hero ───────────────────────────────────────────── -->
114
+ <section class="mx-auto max-w-[1280px] px-6 py-16 sm:py-20">
115
+ <h2 class="text-4xl font-bold tracking-tight text-gray-900 dark:text-white sm:text-5xl">{{PROJECT_NAME}}</h2>
116
+ <div class="mt-4 max-w-2xl prose prose-gray dark:prose-invert prose-p:text-gray-500 dark:prose-p:text-gray-400 prose-p:leading-relaxed">{{PROJECT_DESCRIPTION}}</div>
117
+ <div class="mt-8 flex items-center gap-6 text-sm text-gray-500 dark:text-gray-400">
118
+ <div class="flex items-center gap-2">
119
+ <span class="font-semibold text-gray-900 dark:text-white">{{SCREEN_COUNT}}</span>
120
+ <span>Screens</span>
121
+ </div>
122
+ <div class="h-4 w-px bg-gray-200 dark:bg-white/10"></div>
123
+ <div class="flex items-center gap-2">
124
+ <span class="inline-block h-3 w-3 rounded-full" style="background-color: {{PRIMARY_COLOR}}"></span>
125
+ <span>{{PRIMARY_COLOR}}</span>
126
+ </div>
127
+ <div class="h-4 w-px bg-gray-200 dark:bg-white/10"></div>
128
+ <div class="flex items-center gap-2">
129
+ <span>{{PROJECT_TYPE_LABEL}}</span>
130
+ </div>
131
+ </div>
132
+ </section>
133
+
134
+ <!-- ── Design System ──────────────────────────────────── -->
135
+ {{DESIGN_SYSTEM_HTML}}
136
+
137
+ <!-- ── Gallery ────────────────────────────────────────── -->
138
+ <section class="mx-auto max-w-[1280px] px-6 pb-20">
139
+
140
+ <div class="mb-8">
141
+ <h3 class="text-xl font-semibold tracking-tight text-gray-900 dark:text-white">Pantallas</h3>
142
+ <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{SCREENS_INTRO}}</p>
143
+ </div>
144
+
145
+ <!-- Section filter tabs + search -->
146
+ <div class="flex flex-wrap items-center justify-center gap-3 mb-8">
147
+ {{SECTION_TABS_HTML}}
148
+ <div class="relative">
149
+ <svg class="pointer-events-none absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-gray-400" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
150
+ <circle cx="11" cy="11" r="8" />
151
+ <path d="m21 21-4.35-4.35" />
152
+ </svg>
153
+ <input id="search-input" type="text" placeholder="Search screens..." autocomplete="off" class="h-8 w-48 rounded-lg border border-gray-200 bg-gray-50 pl-8 pr-3 text-xs text-gray-900 placeholder-gray-400 transition-all focus:w-64 focus:outline-none focus:ring-2 focus:ring-accent/40 dark:border-white/10 dark:bg-white/5 dark:text-gray-100">
154
+ </div>
155
+ </div>
156
+
157
+ <!-- Screens grid -->
158
+ {{SCREENS_HTML}}
159
+
160
+ <!-- Empty state -->
161
+ <div id="empty-state" class="hidden py-16 text-center text-gray-400">
162
+ <svg class="mx-auto mb-2 h-8 w-8 opacity-40" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
163
+ <circle cx="11" cy="11" r="8" />
164
+ <path d="m21 21-4.35-4.35" />
165
+ </svg>
166
+ <p class="text-sm">No screens match your search.</p>
167
+ </div>
168
+
169
+ </section>
170
+
171
+ <script>
172
+ // ── View mode (mobile/web) ──────────────────────────────
173
+ const DEFAULT_VIEW = '{{DEFAULT_VIEW}}';
174
+ const VIEW_KEY = 'showcase-view-mode-' + '{{PROJECT_SLUG}}';
175
+ let currentView = localStorage.getItem(VIEW_KEY) || DEFAULT_VIEW;
176
+
177
+ const viewBadge = document.getElementById('view-badge');
178
+ const iconPhone = document.getElementById('icon-phone');
179
+ const iconMonitor = document.getElementById('icon-monitor');
180
+
181
+ function applyViewMode() {
182
+ const root = document.documentElement;
183
+ root.classList.remove('view-mobile', 'view-web');
184
+ root.classList.add('view-' + currentView);
185
+
186
+ // Update badge text
187
+ viewBadge.textContent = currentView === 'mobile' ? 'Mobile' : 'WEB';
188
+
189
+ // Update toggle icon: show the icon of the OTHER mode (what you'll switch to)
190
+ if (currentView === 'mobile') {
191
+ iconPhone.classList.add('hidden');
192
+ iconMonitor.classList.remove('hidden');
193
+ } else {
194
+ iconPhone.classList.remove('hidden');
195
+ iconMonitor.classList.add('hidden');
196
+ }
197
+ }
198
+ applyViewMode();
199
+
200
+ document.getElementById('view-mode-toggle').addEventListener('click', () => {
201
+ currentView = currentView === 'mobile' ? 'web' : 'mobile';
202
+ localStorage.setItem(VIEW_KEY, currentView);
203
+ applyViewMode();
204
+ });
205
+
206
+ // ── Theme toggle ────────────────────────────────────────
207
+ const html = document.documentElement;
208
+
209
+ document.getElementById('theme-toggle').addEventListener('click', () => {
210
+ html.classList.toggle('dark');
211
+ localStorage.setItem('showcase-theme', html.classList.contains('dark') ? 'dark' : 'light');
212
+ });
213
+
214
+ // ── Section filter tabs ────────────────────────────────
215
+ const accentColor = '{{PRIMARY_COLOR}}';
216
+ function accentTextColor(hex) {
217
+ if (!hex || hex.length < 7) return '#000';
218
+ const r = parseInt(hex.slice(1, 3), 16);
219
+ const g = parseInt(hex.slice(3, 5), 16);
220
+ const b = parseInt(hex.slice(5, 7), 16);
221
+ return (0.299 * r + 0.587 * g + 0.114 * b) > 140 ? '#000' : '#fff';
222
+ }
223
+ const accentText = accentTextColor(accentColor);
224
+
225
+ function setActiveTab(tab) {
226
+ document.querySelectorAll('.filter-tab').forEach(t => {
227
+ t.style.backgroundColor = '';
228
+ t.style.color = '';
229
+ t.classList.add('hover:bg-gray-100', 'dark:hover:bg-white/10', 'text-gray-600', 'dark:text-gray-400');
230
+ });
231
+ tab.style.backgroundColor = accentColor;
232
+ tab.style.color = accentText;
233
+ tab.classList.remove('hover:bg-gray-100', 'dark:hover:bg-white/10', 'text-gray-600', 'dark:text-gray-400');
234
+ }
235
+
236
+ const allTab = document.querySelector('.filter-tab[data-section="all"]');
237
+ if (allTab) setActiveTab(allTab);
238
+
239
+ document.querySelectorAll('.filter-tab').forEach(tab => {
240
+ tab.addEventListener('click', () => {
241
+ setActiveTab(tab);
242
+ const target = tab.dataset.section;
243
+ document.querySelectorAll('.screen-section').forEach(sec => {
244
+ sec.style.display = (target === 'all' || sec.dataset.section === target) ? '' : 'none';
245
+ });
246
+ });
247
+ });
248
+
249
+ // ── Grid/List toggle with persistence ─────────────────
250
+ let listMode = localStorage.getItem('showcase-layout') === 'list';
251
+ function applyLayoutMode() {
252
+ document.querySelectorAll('.screens-grid').forEach(g => g.classList.toggle('list-mode', listMode));
253
+ document.getElementById('icon-grid').classList.toggle('hidden', listMode);
254
+ document.getElementById('icon-list').classList.toggle('hidden', !listMode);
255
+ }
256
+ applyLayoutMode();
257
+
258
+ document.getElementById('view-toggle').addEventListener('click', () => {
259
+ listMode = !listMode;
260
+ localStorage.setItem('showcase-layout', listMode ? 'list' : 'grid');
261
+ applyLayoutMode();
262
+ });
263
+
264
+ // ── Search filter (debounced) ──────────────────────────
265
+ const searchInput = document.getElementById('search-input');
266
+ const empty = document.getElementById('empty-state');
267
+ let debounceTimer;
268
+
269
+ function filterCards() {
270
+ const q = (searchInput?.value || '').trim().toLowerCase();
271
+ const cards = document.querySelectorAll('.screen-card');
272
+ let visible = 0;
273
+
274
+ cards.forEach(card => {
275
+ const match = !q || card.textContent.toLowerCase().includes(q);
276
+ card.classList.toggle('hidden', !match);
277
+ if (match) visible++;
278
+ });
279
+
280
+ document.querySelectorAll('.screen-section').forEach(section => {
281
+ const anyVisible = [...section.querySelectorAll('.screen-card')].some(c => !c.classList.contains('hidden'));
282
+ section.style.display = anyVisible ? '' : 'none';
283
+ });
284
+
285
+ empty.classList.toggle('hidden', visible > 0);
286
+ empty.classList.toggle('block', visible === 0);
287
+ }
288
+
289
+ function handleSearch() {
290
+ clearTimeout(debounceTimer);
291
+ debounceTimer = setTimeout(filterCards, 150);
292
+ }
293
+
294
+ if (searchInput) searchInput.addEventListener('input', handleSearch);
295
+ </script>
296
+
297
+ </body>
298
+
299
+ </html>