@curenorway/kode-cli 1.6.0 → 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.
@@ -861,6 +861,321 @@ The staging URL for testing is typically:
861
861
 
862
862
  Always test on staging before promoting to production!
863
863
 
864
+ ## \u{1F4F1} Mobile Testing
865
+
866
+ **50%+ of web traffic is mobile!** Always test on mobile viewports.
867
+
868
+ ### Playwright Viewport Testing
869
+
870
+ \`\`\`
871
+ 1. browser_navigate \u2192 page URL
872
+ 2. browser_resize \u2192 { width: 375, height: 812 } (iPhone)
873
+ 3. browser_snapshot \u2192 check mobile layout
874
+ 4. browser_click \u2192 test touch interactions
875
+ \`\`\`
876
+
877
+ ### Common Mobile Viewports
878
+
879
+ | Device | Width | Height |
880
+ |--------|-------|--------|
881
+ | iPhone SE | 375 | 667 |
882
+ | iPhone 14 | 390 | 844 |
883
+ | iPhone 14 Pro Max | 430 | 932 |
884
+ | iPad | 768 | 1024 |
885
+ | Android (common) | 360 | 800 |
886
+
887
+ ### Mobile-Specific Issues to Check
888
+
889
+ - [ ] Touch targets large enough (44x44px minimum)
890
+ - [ ] No horizontal scroll
891
+ - [ ] Text readable without zooming
892
+ - [ ] Modals/dropdowns work on touch
893
+ - [ ] Hover states have touch alternatives
894
+
895
+ ### Testing Pattern
896
+
897
+ \`\`\`
898
+ // Test on desktop first
899
+ browser_navigate(url)
900
+ browser_snapshot \u2192 verify desktop
901
+
902
+ // Then test mobile
903
+ browser_resize({ width: 375, height: 812 })
904
+ browser_snapshot \u2192 verify mobile layout
905
+ browser_click(".mobile-menu-btn") \u2192 test mobile nav
906
+ \`\`\`
907
+
908
+ ## \u{1F4DA} External Libraries
909
+
910
+ Need GSAP, Swiper, Lodash, or other libraries? Here's how to manage them.
911
+
912
+ ### Pattern 1: CDN Script Loader (Recommended)
913
+
914
+ Create a global "libraries" script that loads dependencies:
915
+
916
+ \`\`\`javascript
917
+ // Script: libraries.js (Global, autoLoad: true)
918
+ // This loads FIRST and makes libraries available to other scripts
919
+
920
+ window.CureLibs = window.CureLibs || {};
921
+
922
+ // Load a library from CDN
923
+ function loadLib(name, url, globalVar) {
924
+ return new Promise((resolve, reject) => {
925
+ if (window[globalVar]) {
926
+ resolve(window[globalVar]);
927
+ return;
928
+ }
929
+ const script = document.createElement('script');
930
+ script.src = url;
931
+ script.onload = () => {
932
+ window.CureLibs[name] = window[globalVar];
933
+ resolve(window[globalVar]);
934
+ };
935
+ script.onerror = reject;
936
+ document.head.appendChild(script);
937
+ });
938
+ }
939
+
940
+ // Pre-load common libraries (add what you need)
941
+ window.CureLibs.load = {
942
+ gsap: () => loadLib('gsap', 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js', 'gsap'),
943
+ scrollTrigger: () => loadLib('ScrollTrigger', 'https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js', 'ScrollTrigger'),
944
+ swiper: () => loadLib('Swiper', 'https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js', 'Swiper'),
945
+ lottie: () => loadLib('lottie', 'https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js', 'lottie'),
946
+ anime: () => loadLib('anime', 'https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js', 'anime'),
947
+ lodash: () => loadLib('_', 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js', '_'),
948
+ };
949
+
950
+ // Also load CSS for libraries that need it
951
+ function loadCSS(url) {
952
+ const link = document.createElement('link');
953
+ link.rel = 'stylesheet';
954
+ link.href = url;
955
+ document.head.appendChild(link);
956
+ }
957
+
958
+ window.CureLibs.loadCSS = loadCSS;
959
+ \`\`\`
960
+
961
+ ### Pattern 2: Using Libraries in Scripts
962
+
963
+ \`\`\`javascript
964
+ // Script: hero-animations.js (depends on GSAP)
965
+
966
+ (async function() {
967
+ // Wait for library to load
968
+ const gsap = await window.CureLibs.load.gsap();
969
+ await window.CureLibs.load.scrollTrigger();
970
+
971
+ // Register plugin
972
+ gsap.registerPlugin(ScrollTrigger);
973
+
974
+ // Now use GSAP
975
+ gsap.from('.hero-title', {
976
+ y: 100,
977
+ opacity: 0,
978
+ duration: 1,
979
+ scrollTrigger: {
980
+ trigger: '.hero-section',
981
+ start: 'top 80%',
982
+ }
983
+ });
984
+ })();
985
+ \`\`\`
986
+
987
+ ### Pattern 3: Swiper Slider Example
988
+
989
+ \`\`\`javascript
990
+ // Script: testimonial-slider.js
991
+
992
+ (async function() {
993
+ // Load Swiper JS and CSS
994
+ const Swiper = await window.CureLibs.load.swiper();
995
+ window.CureLibs.loadCSS('https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css');
996
+
997
+ // Wait for CSS to load
998
+ await new Promise(resolve => setTimeout(resolve, 100));
999
+
1000
+ // Initialize Swiper
1001
+ new Swiper('.testimonial-slider', {
1002
+ slidesPerView: 1,
1003
+ spaceBetween: 30,
1004
+ pagination: {
1005
+ el: '.swiper-pagination',
1006
+ clickable: true,
1007
+ },
1008
+ breakpoints: {
1009
+ 768: { slidesPerView: 2 },
1010
+ 1024: { slidesPerView: 3 },
1011
+ }
1012
+ });
1013
+ })();
1014
+ \`\`\`
1015
+
1016
+ ### Popular Libraries CDN URLs
1017
+
1018
+ | Library | CDN URL |
1019
+ |---------|---------|
1020
+ | GSAP | \`https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js\` |
1021
+ | ScrollTrigger | \`https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js\` |
1022
+ | Swiper | \`https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js\` |
1023
+ | Lottie | \`https://cdnjs.cloudflare.com/ajax/libs/lottie-web/5.12.2/lottie.min.js\` |
1024
+ | Anime.js | \`https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js\` |
1025
+ | Lodash | \`https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js\` |
1026
+ | Alpine.js | \`https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js\` |
1027
+ | Chart.js | \`https://cdn.jsdelivr.net/npm/chart.js\` |
1028
+
1029
+ ### Library Management Best Practices
1030
+
1031
+ 1. **Create a central libraries.js script** - Load ALL external deps from one place
1032
+ 2. **Use async/await pattern** - Ensure libraries load before using them
1033
+ 3. **Don't duplicate loading** - Check if library already exists
1034
+ 4. **Version pin CDN URLs** - Avoid unexpected breaking changes
1035
+ 5. **Load CSS when needed** - Some libraries (Swiper) need CSS too
1036
+
1037
+ ## \u{1F517} Script Dependencies & Load Order
1038
+
1039
+ Scripts sometimes depend on each other. Here's how to manage that.
1040
+
1041
+ ### Understanding Load Order
1042
+
1043
+ | Scope | autoLoad | When it Loads |
1044
+ |-------|----------|---------------|
1045
+ | Global | true | Immediately, inlined in init.js |
1046
+ | Global | false | On-demand via \`CK.loadScript()\` |
1047
+ | Page | true | When URL matches page pattern |
1048
+ | Page | false | On-demand via \`CK.loadScript()\` |
1049
+
1050
+ **Global autoLoad scripts load FIRST**, in the order they appear in the script list.
1051
+
1052
+ ### Dependency Pattern
1053
+
1054
+ \`\`\`javascript
1055
+ // Script: libraries.js (Global, autoLoad: true, position: FIRST)
1056
+ // Loads external libraries
1057
+
1058
+ // Script: utils.js (Global, autoLoad: true, position: SECOND)
1059
+ // Depends on libraries.js, provides shared utilities
1060
+
1061
+ // Script: hero-animations.js (Page-specific for /home)
1062
+ // Depends on both libraries.js and utils.js
1063
+ (async function() {
1064
+ // Libraries are already loaded (global autoLoad runs first)
1065
+ const gsap = await window.CureLibs.load.gsap();
1066
+
1067
+ // Utils are available
1068
+ const elements = window.CureUtils.queryAll('.hero-title');
1069
+
1070
+ // Now animate
1071
+ gsap.from(elements, { opacity: 0 });
1072
+ })();
1073
+ \`\`\`
1074
+
1075
+ ### Manual Loading for Complex Dependencies
1076
+
1077
+ \`\`\`javascript
1078
+ // If you need explicit control, use CK.loadScript()
1079
+ async function initComplexFeature() {
1080
+ // Load dependencies in order
1081
+ await CK.loadScript('libraries');
1082
+ await CK.loadScript('utils');
1083
+ await CK.loadScript('complex-feature');
1084
+ }
1085
+
1086
+ // Trigger when needed
1087
+ document.querySelector('.trigger-btn').addEventListener('click', initComplexFeature);
1088
+ \`\`\`
1089
+
1090
+ ### Avoiding Conflicts with Webflow
1091
+
1092
+ Webflow has its own JS (Webflow.js, IX2 interactions). To avoid conflicts:
1093
+
1094
+ 1. **Wrap in IIFE** - Isolate your code
1095
+ \`\`\`javascript
1096
+ (function() {
1097
+ // Your code here, isolated from global scope
1098
+ })();
1099
+ \`\`\`
1100
+
1101
+ 2. **Use unique prefixes** - \`CureSlider\` not \`Slider\`
1102
+
1103
+ 3. **Check before init** - Don't re-init Webflow components
1104
+ \`\`\`javascript
1105
+ if (!element.hasAttribute('data-cure-initialized')) {
1106
+ // Initialize
1107
+ element.setAttribute('data-cure-initialized', 'true');
1108
+ }
1109
+ \`\`\`
1110
+
1111
+ 4. **Respect Webflow events**
1112
+ \`\`\`javascript
1113
+ // Wait for Webflow to be ready
1114
+ window.Webflow && window.Webflow.push(function() {
1115
+ // Your code runs after Webflow initializes
1116
+ });
1117
+ \`\`\`
1118
+
1119
+ ## \u23EA Rollback & Version Recovery
1120
+
1121
+ Things go wrong. Here's how to recover quickly.
1122
+
1123
+ ### Checking Version History
1124
+
1125
+ Use \`kode_get_script\` to see version info, or check the Cure Kode UI.
1126
+
1127
+ ### Quick Rollback Pattern
1128
+
1129
+ \`\`\`
1130
+ 1. Identify the broken script
1131
+ 2. kode_get_script \u2192 get current (broken) version
1132
+ 3. Check version history in Cure Kode UI
1133
+ 4. Copy the previous working version
1134
+ 5. kode_update_script \u2192 paste the working code
1135
+ 6. kode_deploy \u2192 push fix to staging
1136
+ 7. Verify with Playwright
1137
+ 8. kode_promote \u2192 restore production
1138
+ \`\`\`
1139
+
1140
+ ### Emergency Production Fix
1141
+
1142
+ If production is broken RIGHT NOW:
1143
+
1144
+ \`\`\`
1145
+ Option A: Quick disable
1146
+ - kode_update_script \u2192 set autoLoad: false
1147
+ - kode_deploy + kode_promote
1148
+ - Script stops loading immediately
1149
+
1150
+ Option B: Empty script
1151
+ - kode_update_script \u2192 replace with: // temporarily disabled
1152
+ - kode_deploy + kode_promote
1153
+
1154
+ Option C: Full rollback
1155
+ - Get previous version from history
1156
+ - kode_update_script with old code
1157
+ - kode_deploy + kode_promote
1158
+ \`\`\`
1159
+
1160
+ ### Prevention: Before Major Changes
1161
+
1162
+ 1. **Note the current working state** in context.md
1163
+ 2. **Test thoroughly on staging** with Playwright
1164
+ 3. **Deploy during low-traffic hours** if risky
1165
+ 4. **Have rollback plan ready** before promoting
1166
+
1167
+ ### Debugging Production Issues
1168
+
1169
+ \`\`\`
1170
+ 1. browser_navigate \u2192 production URL
1171
+ 2. browser_console_messages \u2192 look for errors
1172
+ 3. Compare with staging \u2192 same error?
1173
+ 4. If staging works but production doesn't:
1174
+ - Check if promotion completed
1175
+ - Check for caching issues (hard refresh)
1176
+ - Check for environment differences
1177
+ \`\`\`
1178
+
864
1179
  `;
865
1180
  }
866
1181
 
package/dist/cli.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  readPageContext,
16
16
  statusCommand,
17
17
  watchCommand
18
- } from "./chunk-GKNPODOV.js";
18
+ } from "./chunk-KAYIHS2T.js";
19
19
 
20
20
  // src/cli.ts
21
21
  import { Command } from "commander";
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  updateScriptPurpose,
28
28
  watchCommand,
29
29
  writeContext
30
- } from "./chunk-GKNPODOV.js";
30
+ } from "./chunk-KAYIHS2T.js";
31
31
  export {
32
32
  KodeApiClient,
33
33
  KodeApiError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curenorway/kode-cli",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "CLI tool for Cure Kode - manage JS/CSS scripts for Webflow sites",
5
5
  "type": "module",
6
6
  "bin": {