@maccesar/aiskills 1.10.0 → 1.11.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maccesar/aiskills",
3
- "version": "1.10.0",
3
+ "version": "1.11.0",
4
4
  "description": "AI coding assistant skills for Claude Code, Gemini CLI, and Codex CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -186,13 +186,13 @@
186
186
  // Update badge text
187
187
  viewBadge.textContent = currentView === 'mobile' ? 'Mobile' : 'WEB';
188
188
 
189
- // Update toggle icon: show the icon of the OTHER mode (what you'll switch to)
189
+ // Update toggle icon: show the icon of the CURRENT mode (matches the badge)
190
190
  if (currentView === 'mobile') {
191
- iconPhone.classList.add('hidden');
192
- iconMonitor.classList.remove('hidden');
193
- } else {
194
191
  iconPhone.classList.remove('hidden');
195
192
  iconMonitor.classList.add('hidden');
193
+ } else {
194
+ iconPhone.classList.add('hidden');
195
+ iconMonitor.classList.remove('hidden');
196
196
  }
197
197
  }
198
198
  applyViewMode();
@@ -219,6 +219,21 @@
219
219
  var frameMobile = document.getElementById('viewer-frame-mobile');
220
220
  var frameWeb = document.getElementById('viewer-frame-web');
221
221
 
222
+ // Inject scrollbar-hiding CSS into iframes after load (cosmetic, viewer-level only).
223
+ // Keeps source HTMLs untouched so they're clean for downstream handoff.
224
+ function injectScrollbarCSS(frame) {
225
+ try {
226
+ var doc = frame.contentDocument || frame.contentWindow.document;
227
+ if (!doc || doc.getElementById('__no-scrollbar-style')) return;
228
+ var style = doc.createElement('style');
229
+ style.id = '__no-scrollbar-style';
230
+ style.textContent = '*::-webkit-scrollbar{display:none!important}*{scrollbar-width:none!important;-ms-overflow-style:none!important}';
231
+ doc.head.appendChild(style);
232
+ } catch (e) { /* cross-origin or not yet ready */ }
233
+ }
234
+ frameMobile.addEventListener('load', function () { injectScrollbarCSS(frameMobile); });
235
+ frameWeb.addEventListener('load', function () { injectScrollbarCSS(frameWeb); });
236
+
222
237
  var screens = SCREENS;
223
238
  var currentIndex = 0;
224
239
  var VIEW_KEY = 'showcase-view-mode-' + '{{PROJECT_SLUG}}';
@@ -230,13 +245,13 @@
230
245
  root.classList.remove('view-mobile', 'view-web');
231
246
  root.classList.add('view-' + currentView);
232
247
 
233
- // Toggle icon shows what you'll switch TO
248
+ // Toggle icon shows the CURRENT mode (matches the badge)
234
249
  if (currentView === 'mobile') {
235
- iconPhone.classList.add('hidden');
236
- iconMonitor.classList.remove('hidden');
237
- } else {
238
250
  iconPhone.classList.remove('hidden');
239
251
  iconMonitor.classList.add('hidden');
252
+ } else {
253
+ iconPhone.classList.add('hidden');
254
+ iconMonitor.classList.remove('hidden');
240
255
  }
241
256
 
242
257
  // Recalc phone scaling when switching to mobile
@@ -106,6 +106,18 @@ def build(source_dir: str, project_type: str = None, project_name: str = None) -
106
106
  print("Error: no screens found (no zips or folders with code.html).", file=sys.stderr)
107
107
  sys.exit(1)
108
108
 
109
+ # Copy shared asset folders (images, fonts, css, js) referenced by relative paths in HTMLs.
110
+ # Searches in source/, then source.parent/ (project root). Skips if already copied.
111
+ for asset_name in ('images', 'fonts', 'css', 'js'):
112
+ for candidate_root in (source, source.parent):
113
+ candidate = candidate_root / asset_name
114
+ if candidate.is_dir():
115
+ dest = assets_dir / asset_name
116
+ if not dest.exists():
117
+ shutil.copytree(candidate, dest)
118
+ print(f" ✓ Copied shared {asset_name}/ from {candidate_root.name}/")
119
+ break
120
+
109
121
  # Enrich with DESIGN.md metadata
110
122
  screens = _enrich_screens(screens_raw, metadata, source)
111
123
 
@@ -160,6 +172,18 @@ def build_context(source_dir: str, project_type: str = None, project_name: str =
160
172
  print("Error: no screens found (no zips or folders with code.html).", file=sys.stderr)
161
173
  sys.exit(1)
162
174
 
175
+ # Copy shared asset folders (images, fonts, css, js) referenced by relative paths in HTMLs.
176
+ # Searches in source/, then source.parent/ (project root). Skips if already copied.
177
+ for asset_name in ('images', 'fonts', 'css', 'js'):
178
+ for candidate_root in (source, source.parent):
179
+ candidate = candidate_root / asset_name
180
+ if candidate.is_dir():
181
+ dest = assets_dir / asset_name
182
+ if not dest.exists():
183
+ shutil.copytree(candidate, dest)
184
+ print(f" ✓ Copied shared {asset_name}/ from {candidate_root.name}/")
185
+ break
186
+
163
187
  # Enrich with DESIGN.md metadata
164
188
  screens = _enrich_screens(screens_raw, metadata, source)
165
189
 
@@ -136,16 +136,11 @@ def _process_dir(dir_path: Path, slug: str, assets: Path) -> dict | None:
136
136
  }
137
137
 
138
138
 
139
- _NO_SCROLLBAR_CSS = '<style>*::-webkit-scrollbar{display:none!important}*{scrollbar-width:none!important;-ms-overflow-style:none!important}</style>'
140
-
141
139
  def _copy_html(src: Path, dst: Path) -> None:
142
- """Copy HTML injecting scrollbar-hiding CSS into <head>."""
143
- text = src.read_text(encoding="utf-8", errors="ignore")
144
- if "</head>" in text:
145
- text = text.replace("</head>", f"{_NO_SCROLLBAR_CSS}</head>", 1)
146
- elif "<body" in text:
147
- text = text.replace("<body", f"{_NO_SCROLLBAR_CSS}<body", 1)
148
- dst.write_text(text, encoding="utf-8")
140
+ """Copy HTML verbatim. Scrollbar-hiding CSS is now injected at viewer level
141
+ (see references/viewer.html), keeping the source HTML untouched so it can be
142
+ handed off cleanly to downstream tools (e.g., Laravel Blade conversion)."""
143
+ shutil.copy2(src, dst)
149
144
 
150
145
 
151
146
  def _find_file(root: Path, filename: str) -> Path | None: