@cometchat/skills 3.0.0 → 4.0.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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -17
  3. package/bin/install.js +389 -43
  4. package/package.json +19 -9
  5. package/skills/cometchat/SKILL.md +1066 -265
  6. package/skills/cometchat-android-v5/SKILL.md +120 -0
  7. package/skills/cometchat-android-v5-components/SKILL.md +430 -0
  8. package/skills/cometchat-android-v5-core/SKILL.md +468 -0
  9. package/skills/cometchat-android-v5-customization/SKILL.md +305 -0
  10. package/skills/cometchat-android-v5-extensions/SKILL.md +124 -0
  11. package/skills/cometchat-android-v5-features/SKILL.md +130 -0
  12. package/skills/cometchat-android-v5-placement/SKILL.md +276 -0
  13. package/skills/cometchat-android-v5-production/SKILL.md +94 -0
  14. package/skills/cometchat-android-v5-push/SKILL.md +620 -0
  15. package/skills/cometchat-android-v5-testing/SKILL.md +187 -0
  16. package/skills/cometchat-android-v5-theming/SKILL.md +166 -0
  17. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +73 -0
  18. package/skills/cometchat-android-v6/SKILL.md +107 -0
  19. package/skills/cometchat-android-v6-builder-settings/SKILL.md +145 -0
  20. package/skills/cometchat-android-v6-compose-components/SKILL.md +202 -0
  21. package/skills/cometchat-android-v6-compose-customization/SKILL.md +280 -0
  22. package/skills/cometchat-android-v6-compose-placement/SKILL.md +213 -0
  23. package/skills/cometchat-android-v6-compose-theming/SKILL.md +224 -0
  24. package/skills/cometchat-android-v6-core/SKILL.md +354 -0
  25. package/skills/cometchat-android-v6-events/SKILL.md +212 -0
  26. package/skills/cometchat-android-v6-extensions/SKILL.md +191 -0
  27. package/skills/cometchat-android-v6-features/SKILL.md +130 -0
  28. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +197 -0
  29. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +268 -0
  30. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +248 -0
  31. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +202 -0
  32. package/skills/cometchat-android-v6-production/SKILL.md +187 -0
  33. package/skills/cometchat-android-v6-push/SKILL.md +274 -0
  34. package/skills/cometchat-android-v6-testing/SKILL.md +279 -0
  35. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +249 -0
  36. package/skills/cometchat-angular-components/SKILL.md +706 -0
  37. package/skills/cometchat-angular-core/SKILL.md +444 -0
  38. package/skills/cometchat-angular-customization/SKILL.md +424 -0
  39. package/skills/cometchat-angular-features/SKILL.md +447 -0
  40. package/skills/cometchat-angular-patterns/SKILL.md +447 -0
  41. package/skills/cometchat-angular-placement/SKILL.md +685 -0
  42. package/skills/cometchat-angular-production/SKILL.md +415 -0
  43. package/skills/cometchat-angular-theming/SKILL.md +365 -0
  44. package/skills/cometchat-angular-troubleshooting/SKILL.md +329 -0
  45. package/skills/cometchat-astro-patterns/SKILL.md +3 -3
  46. package/skills/cometchat-components/SKILL.md +11 -0
  47. package/skills/cometchat-core/SKILL.md +11 -6
  48. package/skills/cometchat-customization/references/component-catalog.md +1 -1
  49. package/skills/cometchat-features/SKILL.md +176 -108
  50. package/skills/cometchat-flutter-v5/SKILL.md +167 -0
  51. package/skills/cometchat-flutter-v5-calls/SKILL.md +192 -0
  52. package/skills/cometchat-flutter-v5-conversations/SKILL.md +117 -0
  53. package/skills/cometchat-flutter-v5-core/SKILL.md +221 -0
  54. package/skills/cometchat-flutter-v5-customization/SKILL.md +227 -0
  55. package/skills/cometchat-flutter-v5-events/SKILL.md +155 -0
  56. package/skills/cometchat-flutter-v5-messages/SKILL.md +258 -0
  57. package/skills/cometchat-flutter-v5-production/SKILL.md +207 -0
  58. package/skills/cometchat-flutter-v5-push/SKILL.md +284 -0
  59. package/skills/cometchat-flutter-v5-theming/SKILL.md +160 -0
  60. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +129 -0
  61. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +151 -0
  62. package/skills/cometchat-flutter-v6/SKILL.md +445 -0
  63. package/skills/cometchat-flutter-v6-calls/SKILL.md +333 -0
  64. package/skills/cometchat-flutter-v6-components/SKILL.md +365 -0
  65. package/skills/cometchat-flutter-v6-conversations/SKILL.md +210 -0
  66. package/skills/cometchat-flutter-v6-core/SKILL.md +305 -0
  67. package/skills/cometchat-flutter-v6-customization/SKILL.md +666 -0
  68. package/skills/cometchat-flutter-v6-events/SKILL.md +216 -0
  69. package/skills/cometchat-flutter-v6-features/SKILL.md +406 -0
  70. package/skills/cometchat-flutter-v6-messages/SKILL.md +333 -0
  71. package/skills/cometchat-flutter-v6-migration/SKILL.md +381 -0
  72. package/skills/cometchat-flutter-v6-placement/SKILL.md +398 -0
  73. package/skills/cometchat-flutter-v6-production/SKILL.md +632 -0
  74. package/skills/cometchat-flutter-v6-theming/SKILL.md +260 -0
  75. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +726 -0
  76. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +216 -0
  77. package/skills/cometchat-ios/SKILL.md +323 -0
  78. package/skills/cometchat-ios-components/SKILL.md +651 -0
  79. package/skills/cometchat-ios-core/SKILL.md +822 -0
  80. package/skills/cometchat-ios-customization/SKILL.md +825 -0
  81. package/skills/cometchat-ios-features/SKILL.md +725 -0
  82. package/skills/cometchat-ios-placement/SKILL.md +750 -0
  83. package/skills/cometchat-ios-production/SKILL.md +730 -0
  84. package/skills/cometchat-ios-push/SKILL.md +582 -0
  85. package/skills/cometchat-ios-theming/SKILL.md +631 -0
  86. package/skills/cometchat-ios-troubleshooting/SKILL.md +983 -0
  87. package/skills/cometchat-native-bare-patterns/SKILL.md +470 -0
  88. package/skills/cometchat-native-components/SKILL.md +594 -0
  89. package/skills/cometchat-native-core/SKILL.md +407 -0
  90. package/skills/cometchat-native-customization/SKILL.md +594 -0
  91. package/skills/cometchat-native-expo-patterns/SKILL.md +485 -0
  92. package/skills/cometchat-native-features/SKILL.md +608 -0
  93. package/skills/cometchat-native-placement/SKILL.md +500 -0
  94. package/skills/cometchat-native-production/SKILL.md +694 -0
  95. package/skills/cometchat-native-push/SKILL.md +593 -0
  96. package/skills/cometchat-native-testing/SKILL.md +583 -0
  97. package/skills/cometchat-native-theming/SKILL.md +656 -0
  98. package/skills/cometchat-native-troubleshooting/SKILL.md +433 -0
  99. package/skills/cometchat-nextjs-patterns/SKILL.md +5 -5
  100. package/skills/cometchat-production/SKILL.md +60 -0
  101. package/skills/cometchat-react-router-patterns/SKILL.md +23 -21
package/bin/install.js CHANGED
@@ -5,6 +5,7 @@
5
5
  const fs = require("fs");
6
6
  const path = require("path");
7
7
  const os = require("os");
8
+ const readline = require("readline");
8
9
 
9
10
  // ── Lazy-load optional deps ───────────────────────────────────────────────────
10
11
  function tryRequire(name) {
@@ -27,25 +28,158 @@ const c = {
27
28
  // ── Skills registry ───────────────────────────────────────────────────────────
28
29
  const SKILLS_SRC_DIR = path.join(__dirname, "..", "skills");
29
30
 
31
+ // Each skill declares which families it belongs to. The dispatcher (`cometchat`)
32
+ // is shared across all families; pattern skills are family-specific. Adding a
33
+ // new family (e.g. flutter) means flipping its `coming soon` placeholder below
34
+ // to real entries with `families: ["flutter"]`.
30
35
  const SKILLS = [
31
- // Core (always installed)
32
- { name: "cometchat", description: "Entry point — detects framework, handles onboarding, guides integration" },
33
- { name: "cometchat-core", description: "Foundational rules — init, login, CSS, env vars, SSR safety, provider" },
34
- { name: "cometchat-components", description: "Component catalog names, props, composition patterns" },
35
- { name: "cometchat-placement", description: "Where to put chatroute, modal, drawer, widget, embedded" },
36
- // Framework patterns
37
- { name: "cometchat-react-patterns", description: "React / Vite / CRA integration patterns" },
38
- { name: "cometchat-nextjs-patterns", description: "Next.js App Router + Pages Router patterns" },
39
- { name: "cometchat-react-router-patterns", description: "React Router v6 / v7 patterns" },
40
- { name: "cometchat-astro-patterns", description: "Astro React islands patterns" },
41
- // Phase B
42
- { name: "cometchat-theming", description: "Theme presets, brand colors, CSS variable overrides" },
43
- { name: "cometchat-features", description: "40+ feature catalog — calls, polls, AI, moderation" },
44
- { name: "cometchat-customization", description: "Component customization — custom views, builders, events" },
45
- { name: "cometchat-production", description: "Production auth — token endpoints, user management, security" },
46
- { name: "cometchat-troubleshooting", description: "Diagnostics — verify, drift, doctor, symptom lookup" },
36
+ // Dispatcher shared across every family
37
+ { name: "cometchat", families: ["web", "native", "flutter", "angular", "android", "ios"], description: "Entry point — detects framework, handles onboarding, guides integration" },
38
+
39
+ // Web (React / Next.js / React Router / Astro)
40
+ { name: "cometchat-core", families: ["web"], description: "Foundational rulesinit, login, CSS, env vars, SSR safety, provider" },
41
+ { name: "cometchat-components", families: ["web"], description: "Component catalog — names, props, composition patterns" },
42
+ { name: "cometchat-placement", families: ["web"], description: "Where to put chat route, modal, drawer, widget, embedded" },
43
+ { name: "cometchat-react-patterns", families: ["web"], description: "React / Vite / CRA integration patterns" },
44
+ { name: "cometchat-nextjs-patterns", families: ["web"], description: "Next.js App Router + Pages Router patterns" },
45
+ { name: "cometchat-react-router-patterns", families: ["web"], description: "React Router v6 / v7 patterns" },
46
+ { name: "cometchat-astro-patterns", families: ["web"], description: "Astro React islands patterns" },
47
+ { name: "cometchat-theming", families: ["web"], description: "Theme presets, brand colors, CSS variable overrides" },
48
+ { name: "cometchat-features", families: ["web"], description: "40+ feature catalog — calls, polls, AI, moderation" },
49
+ { name: "cometchat-customization", families: ["web"], description: "Component customization — custom views, builders, events" },
50
+ { name: "cometchat-production", families: ["web"], description: "Production auth — token endpoints, user management, security" },
51
+ { name: "cometchat-troubleshooting", families: ["web"], description: "Diagnostics — verify, drift, doctor, symptom lookup" },
52
+
53
+ // React Native (Expo + bare RN)
54
+ { name: "cometchat-native-core", families: ["native"], description: "RN: init, login, provider chain, env vars, anti-patterns" },
55
+ { name: "cometchat-native-components", families: ["native"], description: "RN component catalog — names, props, slot views, request builders" },
56
+ { name: "cometchat-native-placement", families: ["native"], description: "RN: stack screen, bottom tab, modal, bottom sheet, embedded" },
57
+ { name: "cometchat-native-expo-patterns", families: ["native"], description: "Expo managed workflow + Expo Router + app.json config" },
58
+ { name: "cometchat-native-bare-patterns", families: ["native"], description: "Bare RN: pod install, native modules, privacy manifest" },
59
+ { name: "cometchat-native-theming", families: ["native"], description: "RN: CometChatThemeProvider — colors, typography, dark mode" },
60
+ { name: "cometchat-native-features", families: ["native"], description: "RN feature catalog — calls, extensions, AI agent, reactions, polls" },
61
+ { name: "cometchat-native-customization", families: ["native"], description: "RN: custom text formatters, events, request builder filtering" },
62
+ { name: "cometchat-native-production", families: ["native"], description: "RN: server-minted auth tokens, user management, external-backend recipes" },
63
+ { name: "cometchat-native-push", families: ["native"], description: "RN push: APNs + FCM, dashboard providers, client registration, deep-link" },
64
+ { name: "cometchat-native-testing", families: ["native"], description: "RN testing: Jest + RNTL, mocking the kit/SDK, Detox vs Maestro, CI" },
65
+ { name: "cometchat-native-troubleshooting", families: ["native"], description: "RN troubleshooting: Metro cache, pod install, native module linking" },
66
+
67
+ // Angular (12-15)
68
+ { name: "cometchat-angular-core", families: ["angular"], description: "Angular: UIKitSettingsBuilder init, login order, environment config, provider" },
69
+ { name: "cometchat-angular-components", families: ["angular"], description: "Angular component catalog — selectors, inputs, content projection, modules" },
70
+ { name: "cometchat-angular-placement", families: ["angular"], description: "Angular: route, modal, drawer, embedded panel — where to put chat" },
71
+ { name: "cometchat-angular-patterns", families: ["angular"], description: "Angular integration patterns — modules, lazy loading, environment files" },
72
+ { name: "cometchat-angular-theming", families: ["angular"], description: "Angular: CometChatThemeService — colors, typography, dark mode" },
73
+ { name: "cometchat-angular-features", families: ["angular"], description: "Angular feature catalog — calls, polls, reactions, extensions, AI" },
74
+ { name: "cometchat-angular-customization", families: ["angular"], description: "Angular: content projection, ng-template slots, custom views" },
75
+ { name: "cometchat-angular-production", families: ["angular"], description: "Angular: server-minted auth tokens, user management, external-backend recipes" },
76
+ { name: "cometchat-angular-troubleshooting", families: ["angular"], description: "Angular troubleshooting: build errors, module imports, Zone.js issues" },
77
+
78
+ // Android native — both V5 (live, Java + Kotlin Views) and V6 (beta,
79
+ // Compose + Kotlin Views) ship together. The V5 + V6 dispatcher entries
80
+ // (`cometchat-android-v5` / `cometchat-android-v6`) are routed by the
81
+ // unified `cometchat` dispatcher after detecting the gradle dep.
82
+ { name: "cometchat-android-v5", families: ["android"], description: "V5 dispatcher — Java + Kotlin Views (com.cometchat:chat-uikit-android:5.x)" },
83
+ { name: "cometchat-android-v5-core", families: ["android"], description: "V5: UIKitSettings init, login, dependency setup" },
84
+ { name: "cometchat-android-v5-components", families: ["android"], description: "V5 component catalog — Conversations, Messages, Users, Groups, Calls" },
85
+ { name: "cometchat-android-v5-placement", families: ["android"], description: "V5: Activity, Fragment, BottomSheet — where to put chat" },
86
+ { name: "cometchat-android-v5-theming", families: ["android"], description: "V5: theme attrs, colors.xml, dark mode, brand styling" },
87
+ { name: "cometchat-android-v5-features", families: ["android"], description: "V5 feature catalog — calls, reactions, polls, extensions, AI" },
88
+ { name: "cometchat-android-v5-customization", families: ["android"], description: "V5: custom views, DataSource decorators, request builders" },
89
+ { name: "cometchat-android-v5-production", families: ["android"], description: "V5: server-minted auth tokens, user management, external-backend recipes" },
90
+ { name: "cometchat-android-v5-push", families: ["android"], description: "V5 push: FCM, dashboard providers, deep-link, foreground/background" },
91
+ { name: "cometchat-android-v5-extensions", families: ["android"], description: "V5 extensions — moderation, smart replies, message translation" },
92
+ { name: "cometchat-android-v5-testing", families: ["android"], description: "V5 testing: Espresso, Robolectric, mocking the kit/SDK" },
93
+ { name: "cometchat-android-v5-troubleshooting", families: ["android"], description: "V5 troubleshooting: gradle conflicts, manifest, lifecycle, ProGuard" },
94
+
95
+ { name: "cometchat-android-v6", families: ["android"], description: "V6 dispatcher — Compose + Kotlin Views (chatuikit-{compose,kotlin}-android:6.x)" },
96
+ { name: "cometchat-android-v6-core", families: ["android"], description: "V6: gradle deps, init, login, message sending" },
97
+ { name: "cometchat-android-v6-events", families: ["android"], description: "V6: SDK event subscriptions and lifecycle" },
98
+ { name: "cometchat-android-v6-compose-components", families: ["android"], description: "V6 Compose component catalog — Composables for chat UI" },
99
+ { name: "cometchat-android-v6-compose-placement", families: ["android"], description: "V6 Compose: NavHost, modal, bottom sheet — where to put chat" },
100
+ { name: "cometchat-android-v6-compose-theming", families: ["android"], description: "V6 Compose: CometChatTheme, color schemes, typography" },
101
+ { name: "cometchat-android-v6-compose-customization", families: ["android"], description: "V6 Compose: custom slots, DataSource, message templates" },
102
+ { name: "cometchat-android-v6-kotlin-components", families: ["android"], description: "V6 Kotlin Views component catalog — custom View classes" },
103
+ { name: "cometchat-android-v6-kotlin-placement", families: ["android"], description: "V6 Kotlin Views: Activity, Fragment, BottomSheet placement" },
104
+ { name: "cometchat-android-v6-kotlin-theming", families: ["android"], description: "V6 Kotlin Views: style attributes, colors.xml, dark mode" },
105
+ { name: "cometchat-android-v6-kotlin-customization", families: ["android"], description: "V6 Kotlin Views: custom Views, DataSource, request builders" },
106
+ { name: "cometchat-android-v6-features", families: ["android"], description: "V6 feature catalog — calls, reactions, polls, AI agent, extensions" },
107
+ { name: "cometchat-android-v6-extensions", families: ["android"], description: "V6 extensions — moderation, smart replies, message translation" },
108
+ { name: "cometchat-android-v6-builder-settings", families: ["android"], description: "V6: UIKitSettingsBuilder options — presence, typing, receipts" },
109
+ { name: "cometchat-android-v6-production", families: ["android"], description: "V6: server-minted auth tokens, user management, external-backend recipes" },
110
+ { name: "cometchat-android-v6-push", families: ["android"], description: "V6 push: FCM, dashboard providers, deep-link" },
111
+ { name: "cometchat-android-v6-testing", families: ["android"], description: "V6 testing: Espresso, Robolectric, Compose UI tests, mocking" },
112
+ { name: "cometchat-android-v6-troubleshooting", families: ["android"], description: "V6 troubleshooting: gradle, Compose runtime, R8, BuildConfig" },
113
+
114
+ // Flutter — V5 stable (`cometchat_chat_uikit:^5.2`) + V6 beta
115
+ // (`cometchat_chat_uikit:^6.0.0-beta`) ship together. Routed by the
116
+ // unified `cometchat` dispatcher after detecting the pubspec.yaml dep.
117
+ { name: "cometchat-flutter-v5", families: ["flutter"], description: "V5 dispatcher — cometchat_chat_uikit ^5.2 + cometchat_calls_uikit ^5.0" },
118
+ { name: "cometchat-flutter-v5-core", families: ["flutter"], description: "V5: pubspec deps, UIKitSettings, init/login, app entry" },
119
+ { name: "cometchat-flutter-v5-conversations", families: ["flutter"], description: "V5: CometChatConversations widget — props, callbacks, request builder" },
120
+ { name: "cometchat-flutter-v5-messages", families: ["flutter"], description: "V5: CometChatMessages screen — message list, header, composer wiring" },
121
+ { name: "cometchat-flutter-v5-users-groups", families: ["flutter"], description: "V5: CometChatUsers / CometChatGroups / CometChatGroupMembers" },
122
+ { name: "cometchat-flutter-v5-calls", families: ["flutter"], description: "V5: voice/video calling — incoming/outgoing/ongoing screens, call buttons" },
123
+ { name: "cometchat-flutter-v5-theming", families: ["flutter"], description: "V5: CometChatTheme, color palette, typography, dark mode" },
124
+ { name: "cometchat-flutter-v5-customization", families: ["flutter"], description: "V5: custom message templates, options, text formatters, builders" },
125
+ { name: "cometchat-flutter-v5-events", families: ["flutter"], description: "V5: CometChatMessageEvents / GroupEvents / CallEvents subscription" },
126
+ { name: "cometchat-flutter-v5-production", families: ["flutter"], description: "V5: server-minted auth tokens, user management, external-backend recipes" },
127
+ { name: "cometchat-flutter-v5-push", families: ["flutter"], description: "V5: FCM/APNs push, token lifecycle, deep-link" },
128
+ { name: "cometchat-flutter-v5-troubleshooting", families: ["flutter"], description: "V5 troubleshooting: pubspec, GetX, Pod errors, runtime crashes" },
129
+
130
+ { name: "cometchat-flutter-v6", families: ["flutter"], description: "V6 dispatcher — cometchat_chat_uikit ^6.0.0-beta (Bloc-based)" },
131
+ { name: "cometchat-flutter-v6-core", families: ["flutter"], description: "V6: pubspec deps, UIKitSettings, init/login, app entry" },
132
+ { name: "cometchat-flutter-v6-components", families: ["flutter"], description: "V6 component catalog — Bloc-driven widgets, slots, request builders" },
133
+ { name: "cometchat-flutter-v6-conversations", families: ["flutter"], description: "V6: CometChatConversations widget — Bloc, request builder, callbacks" },
134
+ { name: "cometchat-flutter-v6-messages", families: ["flutter"], description: "V6: CometChatMessages — list / header / composer composition" },
135
+ { name: "cometchat-flutter-v6-users-groups", families: ["flutter"], description: "V6: CometChatUsers / CometChatGroups / CometChatGroupMembers" },
136
+ { name: "cometchat-flutter-v6-calls", families: ["flutter"], description: "V6: voice/video calling — incoming/outgoing/ongoing screens" },
137
+ { name: "cometchat-flutter-v6-features", families: ["flutter"], description: "V6 feature catalog — calls, polls, reactions, AI, extensions" },
138
+ { name: "cometchat-flutter-v6-placement", families: ["flutter"], description: "V6: route, modal sheet, embedded widget — where chat lives in the app" },
139
+ { name: "cometchat-flutter-v6-theming", families: ["flutter"], description: "V6: CometChatThemeHelper, CometChatColorPalette, light/dark schemes" },
140
+ { name: "cometchat-flutter-v6-customization", families: ["flutter"], description: "V6: bubble factories, message templates, text formatters, slot widgets" },
141
+ { name: "cometchat-flutter-v6-events", families: ["flutter"], description: "V6: Bloc-based event streams + listener registration" },
142
+ { name: "cometchat-flutter-v6-production", families: ["flutter"], description: "V6: server-minted auth tokens, user management, external-backend recipes" },
143
+ { name: "cometchat-flutter-v6-troubleshooting", families: ["flutter"], description: "V6 troubleshooting: pubspec, Bloc, theme cache, build errors" },
144
+ { name: "cometchat-flutter-v6-migration", families: ["flutter"], description: "V5→V6 migration recipes — GetX → Bloc, theme API rewrite, breaking changes" },
145
+
146
+ // iOS — V5 stable (`CometChatUIKitSwift:^5`). No V6 beta yet; when
147
+ // it ships, add per-cohort namespacing as Android/Flutter do today.
148
+ { name: "cometchat-ios", families: ["ios"], description: "iOS dispatcher — Swift project setup, dependency manager routing" },
149
+ { name: "cometchat-ios-core", families: ["ios"], description: "iOS: SDK init, login, UIKit settings builder, SwiftUI/UIKit entry points" },
150
+ { name: "cometchat-ios-components", families: ["ios"], description: "iOS component catalog — view controllers, SwiftUI views, request builders" },
151
+ { name: "cometchat-ios-placement", families: ["ios"], description: "iOS: navigation controller, modal, tab, embedded — where chat lives" },
152
+ { name: "cometchat-ios-theming", families: ["ios"], description: "iOS: CometChatTheme, color tokens, typography, dark mode" },
153
+ { name: "cometchat-ios-features", families: ["ios"], description: "iOS feature catalog — calls, polls, reactions, AI, extensions" },
154
+ { name: "cometchat-ios-customization", families: ["ios"], description: "iOS: custom views, message templates, text formatters, DataSource decorators" },
155
+ { name: "cometchat-ios-production", families: ["ios"], description: "iOS: server-minted auth tokens, user management, external-backend recipes" },
156
+ { name: "cometchat-ios-push", families: ["ios"], description: "iOS push: APNs + VoIP, CallKit, token lifecycle, deep-link" },
157
+ { name: "cometchat-ios-troubleshooting", families: ["ios"], description: "iOS troubleshooting: SPM, CocoaPods, Xcode build errors, Info.plist, runtime crashes" },
47
158
  ];
48
159
 
160
+ // ── Framework → family routing ────────────────────────────────────────────────
161
+ const FRAMEWORK_TO_FAMILY = {
162
+ reactjs: "web",
163
+ nextjs: "web",
164
+ "react-router": "web",
165
+ astro: "web",
166
+ expo: "native",
167
+ "react-native": "native",
168
+ flutter: "flutter",
169
+ angular: "angular",
170
+ android: "android",
171
+ ios: "ios",
172
+ };
173
+
174
+ const FAMILY_LABELS = {
175
+ web: "Web (React / Next.js / React Router / Astro)",
176
+ native: "React Native (Expo / bare RN)",
177
+ angular: "Angular (12-15)",
178
+ flutter: "Flutter (V5 stable + V6 beta)",
179
+ android: "Android native (V5 stable + V6 beta)",
180
+ ios: "iOS native (V5 stable)",
181
+ };
182
+
49
183
  // ── Helpers ───────────────────────────────────────────────────────────────────
50
184
  function ensureDir(dir) {
51
185
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
@@ -53,16 +187,166 @@ function ensureDir(dir) {
53
187
 
54
188
  // ── IDE target directories ────────────────────────────────────────────────────
55
189
  const IDE_TARGETS = {
56
- claude: { local: ".claude/skills", global: path.join(os.homedir(), ".claude", "skills"), skillFile: "SKILL.md" },
190
+ claude: { local: ".claude/skills", global: path.join(os.homedir(), ".claude", "skills"), skillFile: "SKILL.md" },
57
191
  // Cursor loads agent "skills" from `.cursor/skills/` (not `.cursor/rules/`).
58
- cursor: { local: ".cursor/skills", global: path.join(os.homedir(), ".cursor", "skills"), skillFile: "SKILL.md" },
59
- kiro: { local: ".kiro/skills", global: path.join(os.homedir(), ".kiro", "skills"), skillFile: "SKILL.md" },
60
- copilot: { local: ".github", global: null, skillFile: null }, // single-file mode
192
+ cursor: { local: ".cursor/skills", global: path.join(os.homedir(), ".cursor", "skills"), skillFile: "SKILL.md" },
193
+ kiro: { local: ".kiro/skills", global: path.join(os.homedir(), ".kiro", "skills"), skillFile: "SKILL.md" },
194
+ copilot: { local: ".github", global: null, skillFile: null }, // single-file mode
195
+ // Replit Agent reads `.agents/skills/` per docs.replit.com/core-concepts/agent/skills.
196
+ // Global path matches the convention published by vercel-labs/skills.
197
+ replit: { local: ".agents/skills", global: path.join(os.homedir(), ".config", "agents", "skills"), skillFile: "SKILL.md" },
61
198
  };
62
199
 
63
- // Each skill is installed as <base>/<name>/SKILL.md (or concatenated for copilot)
64
- // Returns the destination path on success, or null if the source SKILL.md
65
- // doesn't exist.
200
+ // ── Framework detection (inline no subprocess) ─────────────────────────────
201
+ //
202
+ // Reads package.json + signal files in cwd to determine which family this
203
+ // project belongs to. Returns the family string ("web", "native", "flutter",
204
+ // "angular", "android", "ios") or null if undetectable.
205
+ //
206
+ // We inline this rather than subprocess to @cometchat/skills-cli because:
207
+ // 1. Cold `npx -y` adds 5-15 s on first run — bad first impression
208
+ // 2. Avoids attack surface of auto-installing a separate package
209
+ // 3. The unified installer only needs family resolution, not the CLI's
210
+ // richer detection (router/bundler/env-prefix/SSR strategy etc.)
211
+ //
212
+ // Detection order matters — more specific first:
213
+ // 1. RN (expo / react-native dep) — must come before generic React
214
+ // 2. Next.js (next dep)
215
+ // 3. React Router (any of the v6/v7 deps)
216
+ // 4. Astro (deps OR astro.config.*)
217
+ // 5. Angular (@angular/core dep OR angular.json)
218
+ // 6. Generic React (react / react-dom dep) → web
219
+ // 7. Flutter (pubspec.yaml with `flutter:` key)
220
+ // 8. Android (build.gradle / settings.gradle)
221
+ // 9. iOS (*.xcodeproj, *.xcworkspace, Package.swift with .iOS, Podfile with platform :ios)
222
+ function detectFamily(cwd) {
223
+ const pkgPath = path.join(cwd, "package.json");
224
+ if (fs.existsSync(pkgPath)) {
225
+ try {
226
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
227
+ const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
228
+ if (deps["expo"] || deps["react-native"]) return "native";
229
+ if (deps["next"]) return "web";
230
+ if (deps["@react-router/dev"] || deps["react-router-dom"] || deps["react-router"]) return "web";
231
+ if (deps["astro"]) return "web";
232
+ if (deps["@angular/core"]) return "angular";
233
+ if (deps["react"] || deps["react-dom"]) return "web";
234
+ } catch { /* malformed package.json — fall through */ }
235
+ }
236
+
237
+ // Astro config exists even before deps install
238
+ for (const ext of ["ts", "mjs", "js", "cjs"]) {
239
+ if (fs.existsSync(path.join(cwd, `astro.config.${ext}`))) return "web";
240
+ }
241
+
242
+ // Flutter — pubspec.yaml with `flutter:` key
243
+ const pubspecPath = path.join(cwd, "pubspec.yaml");
244
+ if (fs.existsSync(pubspecPath)) {
245
+ try {
246
+ const pubspec = fs.readFileSync(pubspecPath, "utf-8");
247
+ if (/^flutter:/m.test(pubspec)) return "flutter";
248
+ } catch { /* fall through */ }
249
+ }
250
+
251
+ // Angular workspace
252
+ if (fs.existsSync(path.join(cwd, "angular.json"))) return "angular";
253
+
254
+ // Android (Gradle-based)
255
+ if (
256
+ fs.existsSync(path.join(cwd, "build.gradle")) ||
257
+ fs.existsSync(path.join(cwd, "build.gradle.kts")) ||
258
+ fs.existsSync(path.join(cwd, "settings.gradle"))
259
+ ) {
260
+ return "android";
261
+ }
262
+
263
+ // iOS — Xcode project / workspace, or Package.swift with .iOS, or Podfile with `platform :ios`
264
+ try {
265
+ for (const f of fs.readdirSync(cwd)) {
266
+ if (f.endsWith(".xcodeproj") || f.endsWith(".xcworkspace")) return "ios";
267
+ }
268
+ } catch { /* unreadable cwd — fall through */ }
269
+ const podfilePath = path.join(cwd, "Podfile");
270
+ if (fs.existsSync(podfilePath)) {
271
+ try {
272
+ if (/platform\s+:ios/.test(fs.readFileSync(podfilePath, "utf-8"))) return "ios";
273
+ } catch { /* fall through */ }
274
+ }
275
+ const packageSwiftPath = path.join(cwd, "Package.swift");
276
+ if (fs.existsSync(packageSwiftPath)) {
277
+ try {
278
+ if (/\.iOS\s*\(/.test(fs.readFileSync(packageSwiftPath, "utf-8"))) return "ios";
279
+ } catch { /* fall through */ }
280
+ }
281
+
282
+ return null;
283
+ }
284
+
285
+ function promptFamily() {
286
+ // Refuse to prompt in non-interactive environments — readline would block
287
+ // forever waiting for stdin that never comes (CI, Dockerfile, scripted
288
+ // installs). Tell the user how to recover.
289
+ if (!process.stdin.isTTY) {
290
+ console.error(c.red(`\n Cannot prompt for family in a non-interactive environment.`));
291
+ console.error(` Pass ${c.cyan("--family <name>")} explicitly. Valid:`);
292
+ console.error(` ${Object.keys(FAMILY_LABELS).join(", ")}, all\n`);
293
+ process.exit(1);
294
+ }
295
+
296
+ const families = ["web", "native", "flutter", "angular", "android", "ios"];
297
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
298
+ console.log(`\n ${c.bold("Which framework does your project use?")}\n`);
299
+ families.forEach((f, i) => {
300
+ console.log(` ${c.cyan(String(i + 1))}. ${FAMILY_LABELS[f]}`);
301
+ });
302
+ return new Promise((resolve) => {
303
+ rl.question(`\n Enter 1-${families.length}: `, (answer) => {
304
+ rl.close();
305
+ const idx = parseInt(answer.trim(), 10) - 1;
306
+ if (Number.isNaN(idx) || idx < 0 || idx >= families.length) {
307
+ console.error(c.red(`\n Invalid choice: ${answer}\n`));
308
+ process.exit(1);
309
+ }
310
+ resolve(families[idx]);
311
+ });
312
+ });
313
+ }
314
+
315
+ // Returns an array of families. Most calls return a single-item array;
316
+ // repeated `--family` flags (`--family web --family native`) return multiple,
317
+ // useful for monorepos with both web + RN packages. `--family all` is a single
318
+ // item that means "every family" downstream.
319
+ async function resolveFamilies(args) {
320
+ // 1. Explicit --family flag(s) — repeatable
321
+ const explicit = [];
322
+ for (let i = 0; i < args.length; i++) {
323
+ if (args[i] === "--family" && args[i + 1]) {
324
+ const f = args[i + 1];
325
+ if (f === "all") { explicit.length = 0; explicit.push("all"); break; }
326
+ if (!Object.keys(FAMILY_LABELS).includes(f)) {
327
+ console.error(c.red(`\n Unknown family: ${f}. Valid: ${Object.keys(FAMILY_LABELS).join(", ")}, all\n`));
328
+ process.exit(1);
329
+ }
330
+ if (!explicit.includes(f)) explicit.push(f);
331
+ i++; // skip the value
332
+ }
333
+ }
334
+ if (explicit.length > 0) return explicit;
335
+
336
+ // 2. Auto-detect (inline, no subprocess)
337
+ process.stdout.write(c.dim("\n Detecting framework... "));
338
+ const family = detectFamily(process.cwd());
339
+ if (family) {
340
+ console.log(c.green(`✓ ${family} — ${FAMILY_LABELS[family]}`));
341
+ return [family];
342
+ }
343
+ console.log(c.dim("could not detect from project files"));
344
+
345
+ // 3. Prompt the user (with TTY guard)
346
+ return [await promptFamily()];
347
+ }
348
+
349
+ // ── Install one skill (per-IDE write) ─────────────────────────────────────────
66
350
  function installSkill(skill, baseDir, skillFile) {
67
351
  const src = path.join(SKILLS_SRC_DIR, skill.name, "SKILL.md");
68
352
  if (!fs.existsSync(src)) {
@@ -87,15 +371,13 @@ function installSkill(skill, baseDir, skillFile) {
87
371
  return dest;
88
372
  }
89
373
 
90
- function installCopilotSkills(baseDir) {
374
+ function installCopilotSkills(skillsToInstall, baseDir) {
91
375
  ensureDir(baseDir);
92
376
  const dest = path.join(baseDir, "copilot-instructions.md");
93
377
  let content = "# CometChat Skills\n\n";
94
- for (const skill of SKILLS) {
378
+ for (const skill of skillsToInstall) {
95
379
  const src = path.join(SKILLS_SRC_DIR, skill.name, "SKILL.md");
96
- if (!fs.existsSync(src)) {
97
- continue; // skip skills that haven't been promoted yet
98
- }
380
+ if (!fs.existsSync(src)) continue;
99
381
  content += fs.readFileSync(src, "utf8") + "\n\n---\n\n";
100
382
  }
101
383
  fs.writeFileSync(dest, content, "utf8");
@@ -104,18 +386,31 @@ function installCopilotSkills(baseDir) {
104
386
 
105
387
  function printHelp() {
106
388
  console.log(`
107
- ${c.bold("cometchat-skills")} — Install CometChat AI coding skills
389
+ ${c.bold("@cometchat/skills")} — Install CometChat AI coding skills
108
390
 
109
391
  ${c.bold("Usage:")}
110
- ${c.cyan("npx @cometchat/skills add")} Install for Claude Code (default)
111
- ${c.cyan("npx @cometchat/skills add --ide cursor")} Install for Cursor
112
- ${c.cyan("npx @cometchat/skills add --ide kiro")} Install for Kiro
113
- ${c.cyan("npx @cometchat/skills add --ide copilot")} Install for VS Code Copilot
114
- ${c.cyan("npx @cometchat/skills add --ide all")} Install for all supported IDEs
115
- ${c.cyan("npx @cometchat/skills add --global")} Install globally
116
- ${c.cyan("npx @cometchat/skills add --list")} Show available skills
392
+ ${c.cyan("npx @cometchat/skills add")} Auto-detect framework + install
393
+ ${c.cyan("npx @cometchat/skills add --family <name>")} Override detection
394
+
395
+ ${c.bold("Family values:")}
396
+ ${c.cyan("web")} React / Next.js / React Router / Astro
397
+ ${c.cyan("native")} Expo / bare React Native
398
+ ${c.cyan("angular")} Angular (12-15)
399
+ ${c.cyan("android")} Android native (V5 stable + V6 beta)
400
+ ${c.cyan("flutter")} Flutter (V5 stable + V6 beta)
401
+ ${c.cyan("ios")} iOS native (V5 stable)
402
+ ${c.cyan("all")} Install every skill (legacy v3 behavior)
403
+
404
+ ${c.bold("IDE selection (default: claude):")}
405
+ ${c.cyan("--ide cursor")} ${c.cyan("--ide kiro")} ${c.cyan("--ide copilot")} ${c.cyan("--ide replit")} ${c.cyan("--ide all")}
117
406
 
118
- ${c.bold("Supported IDEs:")} claude, cursor, kiro, copilot, all
407
+ ${c.bold("Multi-family / monorepo:")}
408
+ ${c.cyan("--family web --family native")} Install BOTH families (repeat flag)
409
+
410
+ ${c.bold("Other:")}
411
+ ${c.cyan("--global")} Install globally (~/.claude/skills/, etc.)
412
+ ${c.cyan("--clean")} Wipe existing cometchat-* skill dirs before install
413
+ ${c.cyan("--list")} Show every skill with its family tags
119
414
 
120
415
  ${c.bold("After installing, open your project in your IDE and run:")}
121
416
  ${c.cyan("/cometchat")}
@@ -140,18 +435,52 @@ async function main() {
140
435
 
141
436
  const isGlobal = args.includes("--global") || args.includes("-g");
142
437
  const listOnly = args.includes("--list") || args.includes("-l");
438
+ const isClean = args.includes("--clean");
143
439
  const ideIdx = args.indexOf("--ide");
144
440
  const ideArg = ideIdx !== -1 ? args[ideIdx + 1] : "claude";
145
441
 
146
442
  if (listOnly) {
147
443
  console.log(`\n ${c.bold("Available skills:")}\n`);
148
444
  for (const s of SKILLS) {
149
- console.log(` ${c.cyan(s.name)}`);
445
+ console.log(` ${c.cyan(s.name)} ${c.dim(`[${s.families.join(", ")}]`)}`);
150
446
  console.log(` ${c.dim(s.description)}\n`);
151
447
  }
152
448
  process.exit(0);
153
449
  }
154
450
 
451
+ // Resolve which families to install (flag(s) → detect → prompt).
452
+ const families = await resolveFamilies(args);
453
+
454
+ // Build the set of skills to install — union over all selected families.
455
+ // "all" is a singleton meaning "every published skill" (legacy v3 behavior).
456
+ let skillsToInstall;
457
+ if (families.includes("all")) {
458
+ skillsToInstall = SKILLS;
459
+ } else {
460
+ const seen = new Set();
461
+ skillsToInstall = [];
462
+ for (const fam of families) {
463
+ for (const s of SKILLS) {
464
+ if (s.families.includes(fam) && !seen.has(s.name)) {
465
+ seen.add(s.name);
466
+ skillsToInstall.push(s);
467
+ }
468
+ }
469
+ }
470
+ }
471
+
472
+ // If no pattern skills matched (only the dispatcher), all selected families
473
+ // are "coming soon" — bail with a friendly message rather than installing a
474
+ // half-broken set.
475
+ const patternSkills = skillsToInstall.filter(s => s.name !== "cometchat");
476
+ if (patternSkills.length === 0) {
477
+ const labels = families.map(f => FAMILY_LABELS[f] || f).join(", ");
478
+ console.log(c.yellow(`\n ⚠ Pattern skills for ${labels} aren't published yet.`));
479
+ console.log(` Supported families today: ${c.cyan("web")}, ${c.cyan("native")}, ${c.cyan("angular")}, ${c.cyan("android")}, ${c.cyan("flutter")}, ${c.cyan("ios")}.`);
480
+ console.log(` Run with one of those, or wait for ${families.join(" + ")} skills to ship.\n`);
481
+ process.exit(1);
482
+ }
483
+
155
484
  const targets = ideArg === "all" ? Object.keys(IDE_TARGETS) : [ideArg];
156
485
 
157
486
  for (const ide of targets) {
@@ -171,23 +500,40 @@ async function main() {
171
500
  ? `global ${c.gray(`(${target.global}/`)}`
172
501
  : `local ${c.gray(`(${target.local}/)`)}`;
173
502
 
174
- console.log(`\n ${c.bold(c.cyan("CometChat Skills"))} — ${ide} integration\n`);
503
+ const familyLabel = families.includes("all") ? "all" : families.join("+");
504
+ console.log(`\n ${c.bold(c.cyan("CometChat Skills"))} — ${ide} — ${c.bold(familyLabel)} family\n`);
175
505
  console.log(` Scope: ${scopeLabel}\n`);
176
506
 
177
507
  ensureDir(baseDir);
178
508
 
509
+ // --clean: wipe existing cometchat-* skill dirs in baseDir before install.
510
+ // Avoids stale skills accumulating across multiple --family runs in the
511
+ // same project (e.g. user runs --family web then later switches to
512
+ // --family native and wants only the new family present). Only touches
513
+ // dirs prefixed `cometchat` so we never blow away unrelated skills.
514
+ if (isClean && ide !== "copilot" && fs.existsSync(baseDir)) {
515
+ let wiped = 0;
516
+ for (const entry of fs.readdirSync(baseDir)) {
517
+ if (entry === "cometchat" || entry.startsWith("cometchat-")) {
518
+ fs.rmSync(path.join(baseDir, entry), { recursive: true, force: true });
519
+ wiped++;
520
+ }
521
+ }
522
+ if (wiped > 0) console.log(c.dim(` ✓ cleaned ${wiped} existing cometchat-* skill ${wiped === 1 ? "dir" : "dirs"}\n`));
523
+ }
524
+
179
525
  if (ide === "copilot") {
180
526
  const spinner = ora ? ora({ text: "copilot-instructions.md", prefixText: " " }).start() : null;
181
527
  try {
182
- const dest = installCopilotSkills(baseDir);
183
- if (spinner) spinner.succeed(c.green("✓ ") + c.bold("copilot-instructions.md") + ` ${c.dim("All skills concatenated")}`);
184
- else console.log(` ✓ copilot-instructions.md`);
528
+ installCopilotSkills(skillsToInstall, baseDir);
529
+ if (spinner) spinner.succeed(c.green("✓ ") + c.bold("copilot-instructions.md") + ` ${c.dim(`(${skillsToInstall.length} skills concatenated)`)}`);
530
+ else console.log(` ✓ copilot-instructions.md (${skillsToInstall.length} skills)`);
185
531
  } catch (err) {
186
532
  if (spinner) spinner.fail(c.red(`✗ copilot-instructions.md: ${err.message}`));
187
533
  else console.error(` ✗ copilot-instructions.md: ${err.message}`);
188
534
  }
189
535
  } else {
190
- for (const skill of SKILLS) {
536
+ for (const skill of skillsToInstall) {
191
537
  const spinner = ora ? ora({ text: skill.name, prefixText: " " }).start() : null;
192
538
  try {
193
539
  installSkill(skill, baseDir, target.skillFile);
package/package.json CHANGED
@@ -1,40 +1,50 @@
1
1
  {
2
2
  "name": "@cometchat/skills",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "description": "AI coding skills for CometChat UI Kit — works with Claude Code, Cursor, Kiro, and Copilot",
7
+ "description": "AI-coding skills for the CometChat UI Kit — auto-detects your framework (React, Next.js, React Router, Astro, Expo, React Native, Angular, native Android, Flutter, native iOS) and installs the right skills. Works with Claude Code, Cursor, Kiro, Copilot, Replit Agent, and 30+ more agents.",
8
8
  "keywords": [
9
9
  "claude-code",
10
10
  "claude-skill",
11
+ "agent-skills",
11
12
  "cometchat",
13
+ "chat",
14
+ "messaging",
12
15
  "react",
13
16
  "nextjs",
14
17
  "react-router",
15
18
  "astro",
16
- "chat",
19
+ "react-native",
20
+ "expo",
21
+ "angular",
22
+ "android",
23
+ "flutter",
24
+ "ios",
25
+ "swift",
26
+ "kotlin",
17
27
  "ui-kit"
18
28
  ],
19
29
  "author": "swapnil-cometchat",
20
30
  "license": "MIT",
21
31
  "repository": {
22
32
  "type": "git",
23
- "url": "https://github.com/cometchat/cometchat-skills.git"
33
+ "url": "git+https://github.com/cometchat/cometchat-skills.git"
24
34
  },
25
35
  "homepage": "https://github.com/cometchat/cometchat-skills#readme",
26
36
  "bugs": {
27
37
  "url": "https://github.com/cometchat/cometchat-skills/issues"
28
38
  },
29
39
  "bin": {
30
- "cometchat-skills": "./bin/install.js"
40
+ "cometchat-skills": "bin/install.js"
31
41
  },
32
42
  "files": [
33
43
  "bin/",
34
44
  "skills/"
35
45
  ],
36
46
  "engines": {
37
- "node": ">=16"
47
+ "node": ">=18"
38
48
  },
39
49
  "scripts": {
40
50
  "setup": "node bin/install.js add",
@@ -61,10 +71,10 @@
61
71
  "ora": "^5.4.1"
62
72
  },
63
73
  "devDependencies": {
64
- "@playwright/test": "^1.59.0",
74
+ "@playwright/test": "^1.59.1",
65
75
  "playwright": "^1.59.0",
66
- "ts-morph": "^27.0.2",
76
+ "ts-morph": "^28.0.0",
67
77
  "@google/genai": "^1.47.0",
68
- "openai": "^4.80.0"
78
+ "openai": "^6.35.0"
69
79
  }
70
80
  }