vybekiit 0.7.33 → 0.7.35

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 (132) hide show
  1. package/dist/bin.js +818 -92
  2. package/dist/global-skills/eas-app-stores/SKILL.md +2 -2
  3. package/dist/global-skills/eas-hosting/SKILL.md +2 -2
  4. package/dist/global-skills/eas-observe/SKILL.md +7 -15
  5. package/dist/global-skills/eas-observe/references/queries.md +51 -10
  6. package/dist/global-skills/eas-observe/references/setup.md +60 -7
  7. package/dist/global-skills/eas-simulator/SKILL.md +2 -2
  8. package/dist/global-skills/eas-simulator/references/run-your-app.md +2 -0
  9. package/dist/global-skills/eas-update/SKILL.md +2 -2
  10. package/dist/global-skills/eas-update-insights/SKILL.md +2 -2
  11. package/dist/global-skills/eas-workflows/SKILL.md +2 -2
  12. package/dist/global-skills/expo-animation/SKILL.md +2 -2
  13. package/dist/global-skills/expo-app-clip/SKILL.md +2 -2
  14. package/dist/global-skills/expo-brownfield/SKILL.md +2 -2
  15. package/dist/global-skills/expo-data-fetching/SKILL.md +2 -2
  16. package/dist/global-skills/expo-design-system/SKILL.md +2 -2
  17. package/dist/global-skills/expo-dev-client/SKILL.md +4 -2
  18. package/dist/global-skills/expo-dom/SKILL.md +2 -2
  19. package/dist/global-skills/expo-examples/SKILL.md +2 -2
  20. package/dist/global-skills/expo-migrate-module/SKILL.md +2 -2
  21. package/dist/global-skills/expo-module/SKILL.md +2 -2
  22. package/dist/global-skills/expo-native-ui/SKILL.md +2 -2
  23. package/dist/global-skills/expo-overview/SKILL.md +9 -4
  24. package/dist/global-skills/expo-overview/references/launch-without-dev-menu.md +24 -0
  25. package/dist/global-skills/expo-project-structure/SKILL.md +2 -2
  26. package/dist/global-skills/expo-router/SKILL.md +2 -2
  27. package/dist/global-skills/expo-ui/SKILL.md +2 -2
  28. package/dist/global-skills/expo-upgrade/SKILL.md +2 -2
  29. package/dist/global-skills/expo-web-to-native/SKILL.md +2 -2
  30. package/dist/global-skills/expo-web-to-native/references/verify-on-device.md +1 -1
  31. package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +16 -3
  32. package/dist/global-skills/firebase-app-hosting-basics/references/cli_commands.md +10 -12
  33. package/dist/global-skills/firebase-app-hosting-basics/references/configuration.md +2 -1
  34. package/dist/global-skills/firebase-basics/SKILL.md +6 -4
  35. package/dist/global-skills/firebase-basics/references/web_setup.md +3 -3
  36. package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +81 -333
  37. package/dist/global-skills/instrument-feature-flags/references/android.md +19 -13
  38. package/dist/global-skills/instrument-feature-flags/references/api.md +17 -13
  39. package/dist/global-skills/instrument-feature-flags/references/best-practices.md +35 -35
  40. package/dist/global-skills/instrument-feature-flags/references/django.md +120 -72
  41. package/dist/global-skills/instrument-feature-flags/references/dotnet.md +48 -102
  42. package/dist/global-skills/instrument-feature-flags/references/elixir.md +4 -10
  43. package/dist/global-skills/instrument-feature-flags/references/flask.md +55 -39
  44. package/dist/global-skills/instrument-feature-flags/references/flutter.md +19 -13
  45. package/dist/global-skills/instrument-feature-flags/references/go.md +21 -13
  46. package/dist/global-skills/instrument-feature-flags/references/ios.md +19 -13
  47. package/dist/global-skills/instrument-feature-flags/references/java.md +4 -12
  48. package/dist/global-skills/instrument-feature-flags/references/laravel.md +18 -16
  49. package/dist/global-skills/instrument-feature-flags/references/next-js.md +44 -54
  50. package/dist/global-skills/instrument-feature-flags/references/nodejs.md +21 -13
  51. package/dist/global-skills/instrument-feature-flags/references/php.md +21 -13
  52. package/dist/global-skills/instrument-feature-flags/references/python.md +22 -14
  53. package/dist/global-skills/instrument-feature-flags/references/react-native.md +18 -13
  54. package/dist/global-skills/instrument-feature-flags/references/react.md +21 -14
  55. package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +31 -68
  56. package/dist/global-skills/instrument-feature-flags/references/ruby.md +21 -13
  57. package/dist/global-skills/instrument-feature-flags/references/rust.md +10 -34
  58. package/dist/global-skills/instrument-feature-flags/references/usage.md +94 -114
  59. package/dist/global-skills/instrument-feature-flags/references/web.md +21 -13
  60. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-android.md +7 -7
  61. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-expo.md +2 -2
  62. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +1 -1
  63. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +1 -1
  64. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-laravel.md +2 -2
  65. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-php.md +1 -1
  66. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-python.md +1 -1
  67. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby.md +1 -1
  68. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-swift.md +4 -4
  69. package/dist/global-skills/instrument-product-analytics/references/android.md +64 -109
  70. package/dist/global-skills/instrument-product-analytics/references/angular.md +32 -28
  71. package/dist/global-skills/instrument-product-analytics/references/astro.md +29 -34
  72. package/dist/global-skills/instrument-product-analytics/references/configuration.md +27 -42
  73. package/dist/global-skills/instrument-product-analytics/references/django.md +120 -72
  74. package/dist/global-skills/instrument-product-analytics/references/dotnet.md +48 -102
  75. package/dist/global-skills/instrument-product-analytics/references/elixir.md +25 -50
  76. package/dist/global-skills/instrument-product-analytics/references/flask.md +55 -39
  77. package/dist/global-skills/instrument-product-analytics/references/flutter.md +94 -96
  78. package/dist/global-skills/instrument-product-analytics/references/go.md +39 -77
  79. package/dist/global-skills/instrument-product-analytics/references/identify-users.md +24 -26
  80. package/dist/global-skills/instrument-product-analytics/references/ios.md +22 -22
  81. package/dist/global-skills/instrument-product-analytics/references/laravel.md +18 -16
  82. package/dist/global-skills/instrument-product-analytics/references/next-js.md +44 -54
  83. package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +32 -34
  84. package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +36 -36
  85. package/dist/global-skills/instrument-product-analytics/references/php.md +42 -87
  86. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +15 -12
  87. package/dist/global-skills/instrument-product-analytics/references/python.md +106 -154
  88. package/dist/global-skills/instrument-product-analytics/references/react-native.md +97 -176
  89. package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +29 -40
  90. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +29 -38
  91. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +29 -40
  92. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +32 -37
  93. package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +31 -68
  94. package/dist/global-skills/instrument-product-analytics/references/ruby.md +40 -96
  95. package/dist/global-skills/instrument-product-analytics/references/svelte.md +34 -34
  96. package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +19 -19
  97. package/dist/global-skills/instrument-product-analytics/references/usage.md +94 -114
  98. package/dist/global-skills/instrument-product-analytics/references/vue-js.md +33 -45
  99. package/dist/global-skills/manifest.json +2 -1
  100. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +40 -22
  101. package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +8 -2
  102. package/dist/global-skills/mongodb-search-and-ai/references/quick-start.md +725 -0
  103. package/dist/global-skills/mongodb-search-and-ai/scripts/quickstart_complete.py +386 -0
  104. package/dist/global-skills/neon/SKILL.md +15 -10
  105. package/dist/global-skills/neon/references/claimable-neon.md +2 -0
  106. package/dist/global-skills/neon-functions/SKILL.md +12 -11
  107. package/dist/global-skills/neon-functions/references/sse.md +2 -2
  108. package/dist/global-skills/neon-object-storage/SKILL.md +5 -4
  109. package/dist/global-skills/neon-postgres/SKILL.md +4 -1
  110. package/dist/global-skills/neon-realtime/SKILL.md +207 -0
  111. package/dist/global-skills/neon-realtime/references/mutations.md +743 -0
  112. package/dist/global-skills/neon-realtime/references/queries.md +509 -0
  113. package/dist/global-skills/neon-realtime/references/reactivity.md +407 -0
  114. package/dist/global-skills/neon-realtime/references/ssr.md +695 -0
  115. package/dist/global-skills/neon-realtime/references/subscribing.md +485 -0
  116. package/dist/global-skills/resend/SKILL.md +4 -2
  117. package/dist/global-skills/resend/references/inboxes.md +377 -0
  118. package/dist/global-skills/resend/references/webhooks.md +9 -0
  119. package/dist/global-skills/stripe-best-practices/SKILL.md +1 -1
  120. package/dist/global-skills/stripe-best-practices/references/connect.md +1 -1
  121. package/dist/global-skills/stripe-best-practices/references/security.md +9 -9
  122. package/dist/global-skills/vybekiitReferences/backend/AGENTS.md +1 -1
  123. package/dist/global-skills/vybekiitReferences/backend/agent/goal-routes.json +303 -18
  124. package/dist/global-skills/vybekiitReferences/extension/AGENTS.md +1 -1
  125. package/dist/global-skills/vybekiitReferences/extension/agent/goal-routes.json +352 -18
  126. package/dist/global-skills/vybekiitReferences/mobile/AGENTS.md +1 -1
  127. package/dist/global-skills/vybekiitReferences/mobile/agent/goal-routes.json +413 -22
  128. package/dist/global-skills/vybekiitReferences/spa/AGENTS.md +1 -1
  129. package/dist/global-skills/vybekiitReferences/spa/agent/goal-routes.json +391 -21
  130. package/dist/global-skills/vybekiitReferences/web/AGENTS.md +14 -2
  131. package/dist/global-skills/vybekiitReferences/web/agent/goal-routes.json +490 -32
  132. package/package.json +8 -8
package/dist/bin.js CHANGED
@@ -265,7 +265,7 @@ var twilioConfigSchema = Schema2.Struct({
265
265
  });
266
266
  var anthropicConfigSchema = Schema2.Struct({
267
267
  ANTHROPIC_API_KEY: NonEmpty,
268
- ANTHROPIC_MODEL: Schema2.optionalWith(NonEmpty, { default: () => "claude-3-5-haiku-latest" })
268
+ ANTHROPIC_MODEL: Schema2.optionalWith(NonEmpty, { default: () => "claude-haiku-5-5" })
269
269
  });
270
270
  var openrouterConfigSchema = Schema2.Struct({
271
271
  OPENROUTER_API_KEY: NonEmpty,
@@ -1061,6 +1061,18 @@ var GOAL_ENTRIES = [
1061
1061
  "what can you do",
1062
1062
  "where do i start"
1063
1063
  ],
1064
+ stems: [
1065
+ "\u05DE\u05D0\u05D9\u05E4\u05D4 \u05DE\u05EA\u05D7\u05D9\u05DC\u05D9\u05DD",
1066
+ "\u05DE\u05D0\u05D9\u05E4\u05D4 \u05DC\u05D4\u05EA\u05D7\u05D9\u05DC",
1067
+ "\u05E8\u05E7 \u05E7\u05E0\u05D9\u05EA\u05D9",
1068
+ "\u05DE\u05D4 \u05D0\u05EA\u05D4 \u05D9\u05D5\u05D3\u05E2 \u05DC\u05E2\u05E9\u05D5\u05EA",
1069
+ "\u0441 \u0447\u0435\u0433\u043E \u043D\u0430\u0447\u0430\u0442\u044C",
1070
+ "\u0447\u0442\u043E \u0442\u044B \u0443\u043C\u0435\u0435\u0448\u044C",
1071
+ "\u0442\u043E\u043B\u044C\u043A\u043E \u0447\u0442\u043E \u043A\u0443\u043F\u0438\u043B",
1072
+ "\u0645\u0646 \u0623\u064A\u0646 \u0623\u0628\u062F\u0623",
1073
+ "\u0645\u0627\u0630\u0627 \u062A\u0633\u062A\u0637\u064A\u0639",
1074
+ "\u0627\u0634\u062A\u0631\u064A\u062A \u0644\u0644\u062A\u0648"
1075
+ ],
1064
1076
  skills: {
1065
1077
  web: "onboarding",
1066
1078
  mobile: "onboarding",
@@ -1078,6 +1090,20 @@ var GOAL_ENTRIES = [
1078
1090
  "marketplace",
1079
1091
  "like airbnb"
1080
1092
  ],
1093
+ stems: [
1094
+ "\u05DC\u05EA\u05DB\u05E0\u05DF",
1095
+ "\u05D4\u05E8\u05E2\u05D9\u05D5\u05DF \u05E9\u05DC\u05D9",
1096
+ "\u05DE\u05E8\u05E7\u05D8\u05E4\u05DC\u05D9\u05D9\u05E1",
1097
+ "\u05DB\u05DE\u05D5 airbnb",
1098
+ "\u0441\u043F\u043B\u0430\u043D\u0438\u0440",
1099
+ "\u043C\u043E\u044E \u0438\u0434\u0435\u044E",
1100
+ "\u043C\u0430\u0440\u043A\u0435\u0442\u043F\u043B\u0435\u0439\u0441",
1101
+ "\u043A\u0430\u043A airbnb",
1102
+ "\u062E\u0637\u0637",
1103
+ "\u0641\u0643\u0631\u062A\u064A",
1104
+ "\u0633\u0648\u0642 \u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A",
1105
+ "\u0645\u062B\u0644 airbnb"
1106
+ ],
1081
1107
  skills: {
1082
1108
  web: "plan-my-idea",
1083
1109
  mobile: "plan-my-idea",
@@ -1089,6 +1115,25 @@ var GOAL_ENTRIES = [
1089
1115
  {
1090
1116
  id: "setup-payments",
1091
1117
  phrases: ["add payments", "take money", "sell something", "charge people"],
1118
+ stems: [
1119
+ "\u05EA\u05E9\u05DC\u05D5\u05DD",
1120
+ "\u05EA\u05E9\u05DC\u05D5\u05DE\u05D9\u05DD",
1121
+ "\u05E1\u05DC\u05D9\u05E7\u05D4",
1122
+ "\u05DC\u05D2\u05D1\u05D5\u05EA \u05DB\u05E1\u05E3",
1123
+ "\u05DC\u05D2\u05D1\u05D5\u05EA \u05EA\u05E9\u05DC\u05D5\u05DD",
1124
+ "\u05DC\u05E7\u05D1\u05DC \u05DB\u05E1\u05E3",
1125
+ "\u05DC\u05DE\u05DB\u05D5\u05E8",
1126
+ "\u043E\u043F\u043B\u0430\u0442",
1127
+ "\u043F\u043B\u0430\u0442\u0435\u0436",
1128
+ "\u043F\u043B\u0430\u0442\u0451\u0436",
1129
+ "\u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0442\u044C \u0434\u0435\u043D\u044C\u0433\u0438",
1130
+ "\u043F\u0440\u043E\u0434\u0430\u0432\u0430\u0442\u044C",
1131
+ "\u062F\u0641\u0639",
1132
+ "\u0645\u062F\u0641\u0648\u0639\u0627\u062A",
1133
+ "\u0627\u0633\u062A\u0644\u0627\u0645 \u0627\u0644\u0645\u0627\u0644",
1134
+ "\u0623\u0628\u064A\u0639",
1135
+ "\u0627\u0644\u0628\u064A\u0639"
1136
+ ],
1092
1137
  skills: {
1093
1138
  web: "setup-payments",
1094
1139
  mobile: "setup-payments",
@@ -1100,6 +1145,23 @@ var GOAL_ENTRIES = [
1100
1145
  {
1101
1146
  id: "go-live",
1102
1147
  phrases: ["put it online", "publish", "make it live", "ship it", "deploy"],
1148
+ stems: [
1149
+ "\u05DC\u05D0\u05D5\u05D5\u05D9\u05E8",
1150
+ "\u05D1\u05D0\u05D5\u05D5\u05D9\u05E8",
1151
+ "\u05DC\u05D4\u05E2\u05DC\u05D5\u05EA \u05D0\u05EA \u05D4\u05D0\u05EA\u05E8",
1152
+ "\u05DC\u05E4\u05E8\u05E1\u05DD \u05D0\u05EA \u05D4\u05D0\u05EA\u05E8",
1153
+ "\u05D0\u05D5\u05E0\u05DC\u05D9\u05D9\u05DF",
1154
+ "\u05D3\u05D9\u05E4\u05DC\u05D5\u05D9",
1155
+ "\u043E\u043F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u0442\u044C",
1156
+ "\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0441\u0430\u0439\u0442",
1157
+ "\u0432\u044B\u043B\u043E\u0436\u0438\u0442\u044C",
1158
+ "\u0437\u0430\u0434\u0435\u043F\u043B\u043E\u0438\u0442\u044C",
1159
+ "\u0434\u0435\u043F\u043B\u043E\u0439",
1160
+ "\u0627\u0646\u0634\u0631",
1161
+ "\u0646\u0634\u0631 \u0627\u0644\u0645\u0648\u0642\u0639",
1162
+ "\u0639\u0644\u0649 \u0627\u0644\u0625\u0646\u062A\u0631\u0646\u062A",
1163
+ "\u0623\u0637\u0644\u0642 \u0627\u0644\u0645\u0648\u0642\u0639"
1164
+ ],
1103
1165
  skills: {
1104
1166
  web: "go-live",
1105
1167
  mobile: "publish-app",
@@ -1111,6 +1173,25 @@ var GOAL_ENTRIES = [
1111
1173
  {
1112
1174
  id: "sign-in",
1113
1175
  phrases: ["sign in", "log in", "create accounts", "add users"],
1176
+ stems: [
1177
+ "\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA",
1178
+ "\u05DC\u05D4\u05EA\u05D7\u05D1\u05E8",
1179
+ "\u05D4\u05E8\u05E9\u05DE\u05D4",
1180
+ "\u05DC\u05D4\u05D9\u05E8\u05E9\u05DD",
1181
+ "\u05E0\u05E8\u05E9\u05DD",
1182
+ "\u05D9\u05E6\u05D9\u05E8\u05EA \u05D7\u05E9\u05D1\u05D5\u05DF",
1183
+ "\u05DC\u05D4\u05D5\u05E1\u05D9\u05E3 \u05DE\u05E9\u05EA\u05DE\u05E9\u05D9\u05DD",
1184
+ "\u0432\u043E\u0439\u0442\u0438",
1185
+ "\u0432\u0445\u043E\u0434",
1186
+ "\u043B\u043E\u0433\u0438\u043D",
1187
+ "\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446",
1188
+ "\u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440",
1189
+ "\u0430\u043A\u043A\u0430\u0443\u043D\u0442",
1190
+ "\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644",
1191
+ "\u0625\u0646\u0634\u0627\u0621 \u062D\u0633\u0627\u0628",
1192
+ "\u062A\u0633\u062C\u064A\u0644 \u062D\u0633\u0627\u0628",
1193
+ "\u0627\u0644\u062A\u0633\u062C\u064A\u0644"
1194
+ ],
1114
1195
  skills: {
1115
1196
  web: "add-signin",
1116
1197
  mobile: "connect-account",
@@ -1122,6 +1203,20 @@ var GOAL_ENTRIES = [
1122
1203
  {
1123
1204
  id: "reset-password",
1124
1205
  phrases: ["forgot password", "reset password", "lost password", "change password email"],
1206
+ stems: [
1207
+ "\u05E9\u05DB\u05D7\u05EA\u05D9 \u05E1\u05D9\u05E1\u05DE\u05D4",
1208
+ "\u05E9\u05DB\u05D7\u05EA\u05D9 \u05D0\u05EA \u05D4\u05E1\u05D9\u05E1\u05DE\u05D4",
1209
+ "\u05D0\u05D9\u05E4\u05D5\u05E1 \u05E1\u05D9\u05E1\u05DE\u05D4",
1210
+ "\u05DC\u05D0\u05E4\u05E1 \u05E1\u05D9\u05E1\u05DE\u05D4",
1211
+ "\u05E9\u05D7\u05D6\u05D5\u05E8 \u05E1\u05D9\u05E1\u05DE\u05D4",
1212
+ "\u0437\u0430\u0431\u044B\u043B \u043F\u0430\u0440\u043E\u043B\u044C",
1213
+ "\u0441\u0431\u0440\u043E\u0441\u0438\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044C",
1214
+ "\u0441\u0431\u0440\u043E\u0441 \u043F\u0430\u0440\u043E\u043B\u044F",
1215
+ "\u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C \u043F\u0430\u0440\u043E\u043B\u044C",
1216
+ "\u0646\u0633\u064A\u062A \u0643\u0644\u0645\u0629 \u0627\u0644\u0645\u0631\u0648\u0631",
1217
+ "\u0625\u0639\u0627\u062F\u0629 \u062A\u0639\u064A\u064A\u0646 \u0643\u0644\u0645\u0629 \u0627\u0644\u0645\u0631\u0648\u0631",
1218
+ "\u0627\u0633\u062A\u0639\u0627\u062F\u0629 \u0643\u0644\u0645\u0629 \u0627\u0644\u0645\u0631\u0648\u0631"
1219
+ ],
1125
1220
  skills: {
1126
1221
  web: "reset-password",
1127
1222
  mobile: "connect-account",
@@ -1133,6 +1228,18 @@ var GOAL_ENTRIES = [
1133
1228
  {
1134
1229
  id: "sign-in-with-email-link",
1135
1230
  phrases: ["magic link", "email link sign in", "sign in without password", "passwordless email"],
1231
+ stems: [
1232
+ "\u05E7\u05D9\u05E9\u05D5\u05E8 \u05E7\u05E1\u05DD",
1233
+ "\u05E7\u05D9\u05E9\u05D5\u05E8 \u05D1\u05DE\u05D9\u05D9\u05DC",
1234
+ "\u05D1\u05DC\u05D9 \u05E1\u05D9\u05E1\u05DE\u05D4",
1235
+ "\u05DC\u05DC\u05D0 \u05E1\u05D9\u05E1\u05DE\u05D4",
1236
+ "\u0432\u043E\u043B\u0448\u0435\u0431\u043D\u0430\u044F \u0441\u0441\u044B\u043B\u043A\u0430",
1237
+ "\u0441\u0441\u044B\u043B\u043A\u0430 \u043D\u0430 \u043F\u043E\u0447\u0442\u0443",
1238
+ "\u0431\u0435\u0437 \u043F\u0430\u0440\u043E\u043B\u044F",
1239
+ "\u0631\u0627\u0628\u0637 \u0633\u062D\u0631\u064A",
1240
+ "\u0631\u0627\u0628\u0637 \u0639\u0628\u0631 \u0627\u0644\u0628\u0631\u064A\u062F",
1241
+ "\u0628\u062F\u0648\u0646 \u0643\u0644\u0645\u0629 \u0645\u0631\u0648\u0631"
1242
+ ],
1136
1243
  skills: {
1137
1244
  web: "sign-in-with-email-link",
1138
1245
  mobile: "connect-account",
@@ -1144,6 +1251,19 @@ var GOAL_ENTRIES = [
1144
1251
  {
1145
1252
  id: "sign-in-with-phone",
1146
1253
  phrases: ["sign in with phone", "text me a code", "sms login", "phone number login"],
1254
+ stems: [
1255
+ "\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA \u05E2\u05DD \u05D8\u05DC\u05E4\u05D5\u05DF",
1256
+ "\u05DB\u05E0\u05D9\u05E1\u05D4 \u05E2\u05DD \u05D8\u05DC\u05E4\u05D5\u05DF",
1257
+ "\u05E7\u05D5\u05D3 \u05DC\u05D8\u05DC\u05E4\u05D5\u05DF",
1258
+ "\u05E7\u05D5\u05D3 \u05D1\u05E1\u05DE\u05E1",
1259
+ "\u0432\u0445\u043E\u0434 \u043F\u043E \u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0443",
1260
+ "\u0432\u043E\u0439\u0442\u0438 \u043F\u043E \u043D\u043E\u043C\u0435\u0440\u0443",
1261
+ "\u043A\u043E\u0434 \u043F\u043E \u0441\u043C\u0441",
1262
+ "\u043A\u043E\u0434 \u0432 \u0441\u043C\u0441",
1263
+ "\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0628\u0627\u0644\u0647\u0627\u062A\u0641",
1264
+ "\u0627\u0644\u062F\u062E\u0648\u0644 \u0628\u0631\u0642\u0645 \u0627\u0644\u0647\u0627\u062A\u0641",
1265
+ "\u0631\u0645\u0632 \u0639\u0628\u0631 \u0627\u0644\u0631\u0633\u0627\u0626\u0644"
1266
+ ],
1147
1267
  skills: {
1148
1268
  web: "sign-in-with-phone",
1149
1269
  mobile: "connect-account",
@@ -1155,6 +1275,19 @@ var GOAL_ENTRIES = [
1155
1275
  {
1156
1276
  id: "setup-sms",
1157
1277
  phrases: ["set up sms", "text messages", "twilio", "whatsapp messages", "send texts"],
1278
+ stems: [
1279
+ "\u05E1\u05DE\u05E1",
1280
+ "\u05D4\u05D5\u05D3\u05E2\u05D5\u05EA \u05D8\u05E7\u05E1\u05D8",
1281
+ "\u05D5\u05D5\u05D0\u05D8\u05E1\u05D0\u05E4",
1282
+ "\u05D5\u05D5\u05D8\u05E1\u05D0\u05E4",
1283
+ "\u0441\u043C\u0441",
1284
+ "\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0435 \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F",
1285
+ "\u0432\u0430\u0442\u0441\u0430\u043F",
1286
+ "\u0432\u043E\u0442\u0441\u0430\u043F",
1287
+ "\u0631\u0633\u0627\u0626\u0644 \u0646\u0635\u064A\u0629",
1288
+ "\u0631\u0633\u0627\u0644\u0629 \u0646\u0635\u064A\u0629",
1289
+ "\u0648\u0627\u062A\u0633\u0627\u0628"
1290
+ ],
1158
1291
  skills: {
1159
1292
  web: "setup-sms",
1160
1293
  mobile: "connect-account",
@@ -1179,6 +1312,32 @@ var GOAL_ENTRIES = [
1179
1312
  "appointments",
1180
1313
  "student accessibility"
1181
1314
  ],
1315
+ stems: [
1316
+ "\u05DC\u05E9\u05DE\u05D5\u05E8",
1317
+ "\u05E9\u05DE\u05D9\u05E8\u05EA \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD",
1318
+ "\u05DE\u05E1\u05D3 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD",
1319
+ "\u05D1\u05E1\u05D9\u05E1 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD",
1320
+ "\u05EA\u05D5\u05E8\u05D9\u05DD",
1321
+ "\u05E7\u05D1\u05D9\u05E2\u05EA \u05EA\u05D5\u05E8",
1322
+ "\u05DC\u05E7\u05D1\u05D5\u05E2 \u05EA\u05D5\u05E8",
1323
+ "\u05D4\u05D6\u05DE\u05E0\u05D5\u05EA",
1324
+ "\u05DC\u05D1\u05D8\u05DC \u05D4\u05D6\u05DE\u05E0\u05D4",
1325
+ "\u05E9\u05D9\u05E2\u05D5\u05E8\u05D9\u05DD",
1326
+ "\u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435",
1327
+ "\u0431\u0430\u0437\u0430 \u0434\u0430\u043D\u043D\u044B\u0445",
1328
+ "\u0431\u0430\u0437\u0443 \u0434\u0430\u043D\u043D\u044B\u0445",
1329
+ "\u0431\u0440\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u043D",
1330
+ "\u0437\u0430\u043F\u0438\u0441\u044C \u043D\u0430",
1331
+ "\u0440\u0430\u0441\u043F\u0438\u0441\u0430\u043D\u0438",
1332
+ "\u043E\u0442\u043C\u0435\u043D\u0438\u0442\u044C \u0431\u0440\u043E\u043D\u044C",
1333
+ "\u062D\u0641\u0638 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A",
1334
+ "\u0642\u0627\u0639\u062F\u0629 \u0628\u064A\u0627\u0646\u0627\u062A",
1335
+ "\u062D\u062C\u0632",
1336
+ "\u062D\u062C\u0648\u0632\u0627\u062A",
1337
+ "\u0645\u0648\u0627\u0639\u064A\u062F",
1338
+ "\u0645\u0648\u0639\u062F",
1339
+ "\u062C\u062F\u0648\u0644 \u0627\u0644\u062D\u0635\u0635"
1340
+ ],
1182
1341
  skills: {
1183
1342
  web: "save-data",
1184
1343
  mobile: "save-data",
@@ -1190,6 +1349,18 @@ var GOAL_ENTRIES = [
1190
1349
  {
1191
1350
  id: "design-my-data",
1192
1351
  phrases: ["design my database", "what data do i need", "what should my app remember"],
1352
+ stems: [
1353
+ "\u05DC\u05EA\u05DB\u05E0\u05DF \u05D0\u05EA \u05D4\u05E0\u05EA\u05D5\u05E0\u05D9\u05DD",
1354
+ "\u05DE\u05D1\u05E0\u05D4 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD",
1355
+ "\u05D0\u05D9\u05DC\u05D5 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD",
1356
+ "\u05DE\u05D4 \u05D4\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4 \u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D6\u05DB\u05D5\u05E8",
1357
+ "\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0434\u0430\u043D\u043D\u044B\u0445",
1358
+ "\u043A\u0430\u043A\u0438\u0435 \u0434\u0430\u043D\u043D\u044B\u0435",
1359
+ "\u0441\u043F\u0440\u043E\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0431\u0430\u0437\u0443",
1360
+ "\u062A\u0635\u0645\u064A\u0645 \u0642\u0627\u0639\u062F\u0629 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A",
1361
+ "\u0645\u0627 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A",
1362
+ "\u0647\u064A\u0643\u0644 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A"
1363
+ ],
1193
1364
  skills: {
1194
1365
  web: "design-my-data",
1195
1366
  mobile: "design-my-data",
@@ -1201,6 +1372,20 @@ var GOAL_ENTRIES = [
1201
1372
  {
1202
1373
  id: "add-files",
1203
1374
  phrases: ["upload", "store files", "attachments"],
1375
+ stems: [
1376
+ "\u05D4\u05E2\u05DC\u05D0\u05EA \u05E7\u05D1\u05E6\u05D9\u05DD",
1377
+ "\u05DC\u05D4\u05E2\u05DC\u05D5\u05EA \u05E7\u05D1\u05E6\u05D9\u05DD",
1378
+ "\u05E7\u05D1\u05E6\u05D9\u05DD",
1379
+ "\u05E7\u05D5\u05D1\u05E5",
1380
+ "\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B",
1381
+ "\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0430 \u0444\u0430\u0439\u043B\u043E\u0432",
1382
+ "\u0444\u0430\u0439\u043B",
1383
+ "\u0432\u043B\u043E\u0436\u0435\u043D\u0438",
1384
+ "\u0631\u0641\u0639 \u0645\u0644\u0641\u0627\u062A",
1385
+ "\u0645\u0644\u0641\u0627\u062A",
1386
+ "\u0645\u0644\u0641",
1387
+ "\u0645\u0631\u0641\u0642\u0627\u062A"
1388
+ ],
1204
1389
  skills: {
1205
1390
  web: "add-files",
1206
1391
  mobile: "add-files",
@@ -1212,6 +1397,19 @@ var GOAL_ENTRIES = [
1212
1397
  {
1213
1398
  id: "setup-email",
1214
1399
  phrases: ["send emails", "email my users", "set up email"],
1400
+ stems: [
1401
+ "\u05DE\u05D9\u05D9\u05DC",
1402
+ "\u05D0\u05D9\u05DE\u05D9\u05D9\u05DC",
1403
+ "\u05D3\u05D5\u05D0\u05E8 \u05D0\u05DC\u05E7\u05D8\u05E8\u05D5\u05E0\u05D9",
1404
+ "\u043F\u0438\u0441\u044C\u043C\u0430",
1405
+ "\u043F\u0438\u0441\u044C\u043C\u043E",
1406
+ "\u043F\u043E\u0447\u0442\u0443",
1407
+ "\u0440\u0430\u0441\u0441\u044B\u043B\u043A",
1408
+ "\u0628\u0631\u064A\u062F \u0625\u0644\u0643\u062A\u0631\u0648\u0646\u064A",
1409
+ "\u0627\u0644\u0628\u0631\u064A\u062F",
1410
+ "\u0625\u064A\u0645\u064A\u0644",
1411
+ "\u0627\u064A\u0645\u064A\u0644"
1412
+ ],
1215
1413
  skills: { web: "setup-email", mobile: null, extension: null, spa: null, backend: "wire-email" }
1216
1414
  },
1217
1415
  {
@@ -1223,6 +1421,19 @@ var GOAL_ENTRIES = [
1223
1421
  "suggest a kit improvement",
1224
1422
  "the kit is confusing"
1225
1423
  ],
1424
+ stems: [
1425
+ "\u05DE\u05E9\u05D5\u05D1",
1426
+ "\u05D1\u05D0\u05D2 \u05D1\u05E7\u05D9\u05D8",
1427
+ "\u05D4\u05E7\u05D9\u05D8 \u05DE\u05D1\u05DC\u05D1\u05DC",
1428
+ "\u05D4\u05E6\u05E2\u05D4 \u05DC\u05E9\u05D9\u05E4\u05D5\u05E8",
1429
+ "\u043E\u0442\u0437\u044B\u0432 \u043E \u043A\u0438\u0442\u0435",
1430
+ "\u043E\u0448\u0438\u0431\u043A\u0430 \u0432 \u043A\u0438\u0442\u0435",
1431
+ "\u043A\u0438\u0442 \u0437\u0430\u043F\u0443\u0442\u0430\u043D",
1432
+ "\u043F\u0440\u0435\u0434\u043B\u043E\u0436\u0438\u0442\u044C \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u0438\u0435",
1433
+ "\u062E\u0637\u0623 \u0641\u064A \u0627\u0644\u0643\u064A\u062A",
1434
+ "\u0627\u0644\u0643\u064A\u062A \u0645\u062D\u064A\u0631",
1435
+ "\u0627\u0642\u062A\u0631\u0627\u062D \u062A\u062D\u0633\u064A\u0646"
1436
+ ],
1226
1437
  skills: {
1227
1438
  web: "vybekiit-feedback",
1228
1439
  mobile: "vybekiit-feedback",
@@ -1234,6 +1445,23 @@ var GOAL_ENTRIES = [
1234
1445
  {
1235
1446
  id: "doctor",
1236
1447
  phrases: ["it's broken", "nothing works", "get an error", "check my app"],
1448
+ stems: [
1449
+ "\u05DC\u05D0 \u05E2\u05D5\u05D1\u05D3",
1450
+ "\u05E9\u05D1\u05D5\u05E8",
1451
+ "\u05E0\u05E9\u05D1\u05E8",
1452
+ "\u05E9\u05D2\u05D9\u05D0\u05D4",
1453
+ "\u05EA\u05E7\u05DC\u05D4",
1454
+ "\u05EA\u05D1\u05D3\u05D5\u05E7 \u05D0\u05EA \u05D4\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4",
1455
+ "\u043D\u0435 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442",
1456
+ "\u0441\u043B\u043E\u043C\u0430\u043B",
1457
+ "\u043E\u0448\u0438\u0431\u043A",
1458
+ "\u043F\u0440\u043E\u0432\u0435\u0440\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435",
1459
+ "\u0644\u0627 \u064A\u0639\u0645\u0644",
1460
+ "\u0645\u0639\u0637\u0644",
1461
+ "\u062E\u0637\u0623",
1462
+ "\u0645\u0634\u0643\u0644\u0629",
1463
+ "\u0627\u0641\u062D\u0635 \u0627\u0644\u062A\u0637\u0628\u064A\u0642"
1464
+ ],
1237
1465
  skills: {
1238
1466
  web: "doctor",
1239
1467
  mobile: "doctor",
@@ -1245,6 +1473,18 @@ var GOAL_ENTRIES = [
1245
1473
  {
1246
1474
  id: "update-kit",
1247
1475
  phrases: ["update the kit", "get the latest", "upgrade"],
1476
+ stems: [
1477
+ "\u05DC\u05E2\u05D3\u05DB\u05DF \u05D0\u05EA \u05D4\u05E7\u05D9\u05D8",
1478
+ "\u05E2\u05D3\u05DB\u05D5\u05DF \u05D4\u05E7\u05D9\u05D8",
1479
+ "\u05D4\u05D2\u05E8\u05E1\u05D4 \u05D4\u05D0\u05D7\u05E8\u05D5\u05E0\u05D4",
1480
+ "\u05DC\u05E9\u05D3\u05E8\u05D2",
1481
+ "\u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u043A\u0438\u0442",
1482
+ "\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u043A\u0438\u0442\u0430",
1483
+ "\u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044E\u044E \u0432\u0435\u0440\u0441\u0438\u044E",
1484
+ "\u062A\u062D\u062F\u064A\u062B \u0627\u0644\u0643\u064A\u062A",
1485
+ "\u0622\u062E\u0631 \u0625\u0635\u062F\u0627\u0631",
1486
+ "\u062A\u0631\u0642\u064A\u0629"
1487
+ ],
1248
1488
  skills: {
1249
1489
  web: "update-kit",
1250
1490
  mobile: "update-kit",
@@ -1256,6 +1496,18 @@ var GOAL_ENTRIES = [
1256
1496
  {
1257
1497
  id: "harden",
1258
1498
  phrases: ["lock down", "make it safe", "protect from abuse"],
1499
+ stems: [
1500
+ "\u05DC\u05D0\u05D1\u05D8\u05D7",
1501
+ "\u05D0\u05D1\u05D8\u05D7\u05D4",
1502
+ "\u05D4\u05D2\u05E0\u05D4 \u05DE\u05E4\u05E0\u05D9",
1503
+ "\u05E0\u05D9\u05E6\u05D5\u05DC \u05DC\u05E8\u05E2\u05D4",
1504
+ "\u0437\u0430\u0449\u0438\u0442\u0438\u0442\u044C \u043E\u0442",
1505
+ "\u0437\u043B\u043E\u0443\u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D",
1506
+ "\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442",
1507
+ "\u062D\u0645\u0627\u064A\u0629",
1508
+ "\u0625\u0633\u0627\u0621\u0629 \u0627\u0644\u0627\u0633\u062A\u062E\u062F\u0627\u0645",
1509
+ "\u062A\u0623\u0645\u064A\u0646"
1510
+ ],
1259
1511
  skills: {
1260
1512
  web: "harden",
1261
1513
  mobile: "check-safety",
@@ -1267,16 +1519,48 @@ var GOAL_ENTRIES = [
1267
1519
  {
1268
1520
  id: "add-route",
1269
1521
  phrases: ["add an endpoint", "add api", "new route"],
1522
+ stems: [
1523
+ "\u05E0\u05E7\u05D5\u05D3\u05EA \u05E7\u05E6\u05D4",
1524
+ "\u05E8\u05D0\u05D5\u05D8 \u05D7\u05D3\u05E9",
1525
+ "\u05E0\u05EA\u05D9\u05D1 \u05D7\u05D3\u05E9",
1526
+ "\u044D\u043D\u0434\u043F\u043E\u0438\u043D\u0442",
1527
+ "\u043D\u043E\u0432\u044B\u0439 \u043C\u0430\u0440\u0448\u0440\u0443\u0442",
1528
+ "\u043D\u043E\u0432\u044B\u0439 \u0440\u043E\u0443\u0442",
1529
+ "\u0646\u0642\u0637\u0629 \u0646\u0647\u0627\u064A\u0629",
1530
+ "\u0645\u0633\u0627\u0631 \u062C\u062F\u064A\u062F"
1531
+ ],
1270
1532
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "add-route" }
1271
1533
  },
1272
1534
  {
1273
1535
  id: "add-crud",
1274
1536
  phrases: ["crud", "create read update delete"],
1537
+ stems: [
1538
+ "\u05D9\u05E6\u05D9\u05E8\u05D4 \u05E2\u05E8\u05D9\u05DB\u05D4 \u05D5\u05DE\u05D7\u05D9\u05E7\u05D4",
1539
+ "\u05D4\u05D5\u05E1\u05E4\u05D4 \u05E2\u05E8\u05D9\u05DB\u05D4 \u05D5\u05DE\u05D7\u05D9\u05E7\u05D4",
1540
+ "\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435",
1541
+ "\u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u0437\u043C\u0435\u043D\u0438\u0442\u044C \u0443\u0434\u0430\u043B\u0438\u0442\u044C",
1542
+ "\u0625\u0636\u0627\u0641\u0629 \u0648\u062A\u0639\u062F\u064A\u0644 \u0648\u062D\u0630\u0641",
1543
+ "\u0625\u0646\u0634\u0627\u0621 \u0648\u062A\u0639\u062F\u064A\u0644 \u0648\u062D\u0630\u0641"
1544
+ ],
1275
1545
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "add-crud" }
1276
1546
  },
1277
1547
  {
1278
1548
  id: "add-images",
1279
1549
  phrases: ["add my logo", "hero image", "app icon", "add images"],
1550
+ stems: [
1551
+ "\u05DC\u05D5\u05D2\u05D5",
1552
+ "\u05EA\u05DE\u05D5\u05E0\u05D4",
1553
+ "\u05EA\u05DE\u05D5\u05E0\u05D5\u05EA",
1554
+ "\u05D0\u05D9\u05D9\u05E7\u05D5\u05DF",
1555
+ "\u043B\u043E\u0433\u043E\u0442\u0438\u043F",
1556
+ "\u043A\u0430\u0440\u0442\u0438\u043D\u043A",
1557
+ "\u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438",
1558
+ "\u0438\u043A\u043E\u043D\u043A",
1559
+ "\u0634\u0639\u0627\u0631",
1560
+ "\u0635\u0648\u0631\u0629",
1561
+ "\u0635\u0648\u0631",
1562
+ "\u0623\u064A\u0642\u0648\u0646\u0629"
1563
+ ],
1280
1564
  skills: {
1281
1565
  web: "add-images",
1282
1566
  mobile: "add-images",
@@ -1288,6 +1572,18 @@ var GOAL_ENTRIES = [
1288
1572
  {
1289
1573
  id: "add-teams",
1290
1574
  phrases: ["invite teammates", "add my team", "organizations"],
1575
+ stems: [
1576
+ "\u05D7\u05D1\u05E8\u05D9 \u05E6\u05D5\u05D5\u05EA",
1577
+ "\u05DC\u05D4\u05D6\u05DE\u05D9\u05DF",
1578
+ "\u05E6\u05D5\u05D5\u05EA",
1579
+ "\u05D0\u05E8\u05D2\u05D5\u05E0\u05D9\u05DD",
1580
+ "\u043F\u0440\u0438\u0433\u043B\u0430\u0441\u0438\u0442\u044C \u043A\u043E\u043B\u043B\u0435\u0433",
1581
+ "\u043C\u043E\u044E \u043A\u043E\u043C\u0430\u043D\u0434\u0443",
1582
+ "\u043E\u0440\u0433\u0430\u043D\u0438\u0437\u0430\u0446\u0438",
1583
+ "\u0641\u0631\u064A\u0642",
1584
+ "\u062F\u0639\u0648\u0629",
1585
+ "\u0645\u0624\u0633\u0633\u0627\u062A"
1586
+ ],
1291
1587
  skills: {
1292
1588
  web: "add-teams",
1293
1589
  mobile: "add-teams",
@@ -1299,6 +1595,7 @@ var GOAL_ENTRIES = [
1299
1595
  {
1300
1596
  id: "add-notifications",
1301
1597
  phrases: ["notify users", "send alerts"],
1598
+ stems: ["\u05D4\u05EA\u05E8\u05D0\u05D5\u05EA", "\u05D4\u05EA\u05E8\u05D0\u05D4", "\u05DC\u05D4\u05D5\u05D3\u05D9\u05E2", "\u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D", "\u043E\u043F\u043E\u0432\u0435\u0449", "\u0625\u0634\u0639\u0627\u0631\u0627\u062A", "\u0625\u0634\u0639\u0627\u0631", "\u062A\u0646\u0628\u064A\u0647\u0627\u062A"],
1302
1599
  skills: {
1303
1600
  web: "add-notifications",
1304
1601
  mobile: "add-notifications",
@@ -1310,6 +1607,18 @@ var GOAL_ENTRIES = [
1310
1607
  {
1311
1608
  id: "add-analytics",
1312
1609
  phrases: ["visitor stats", "analytics", "track usage"],
1610
+ stems: [
1611
+ "\u05D0\u05E0\u05DC\u05D9\u05D8\u05D9\u05E7\u05E1",
1612
+ "\u05D0\u05E0\u05DC\u05D9\u05D8\u05D9\u05E7\u05D4",
1613
+ "\u05E1\u05D8\u05D8\u05D9\u05E1\u05D8\u05D9\u05E7\u05D5\u05EA",
1614
+ "\u05DE\u05D1\u05E7\u05E8\u05D9\u05DD",
1615
+ "\u0430\u043D\u0430\u043B\u0438\u0442\u0438\u043A",
1616
+ "\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A",
1617
+ "\u043F\u043E\u0441\u0435\u0442\u0438\u0442\u0435\u043B",
1618
+ "\u062A\u062D\u0644\u064A\u0644\u0627\u062A",
1619
+ "\u0625\u062D\u0635\u0627\u0626\u064A\u0627\u062A",
1620
+ "\u0627\u0644\u0632\u0648\u0627\u0631"
1621
+ ],
1313
1622
  skills: {
1314
1623
  web: "add-analytics",
1315
1624
  mobile: "add-analytics",
@@ -1321,31 +1630,101 @@ var GOAL_ENTRIES = [
1321
1630
  {
1322
1631
  id: "add-ai",
1323
1632
  phrases: ["add ai", "chatbot", "smart replies"],
1633
+ stems: [
1634
+ "\u05D1\u05D9\u05E0\u05D4 \u05DE\u05DC\u05D0\u05DB\u05D5\u05EA\u05D9\u05EA",
1635
+ "\u05D0\u05D8\u05D1\u05D5\u05D8",
1636
+ "\u05EA\u05E9\u05D5\u05D1\u05D5\u05EA \u05D7\u05DB\u05DE\u05D5\u05EA",
1637
+ "\u0438\u0441\u043A\u0443\u0441\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439 \u0438\u043D\u0442\u0435\u043B\u043B\u0435\u043A\u0442",
1638
+ "\u0447\u0430\u0442 \u0431\u043E\u0442",
1639
+ "\u0447\u0430\u0442\u0431\u043E\u0442",
1640
+ "\u043D\u0435\u0439\u0440\u043E\u0441\u0435\u0442",
1641
+ "\u0443\u043C\u043D\u044B\u0435 \u043E\u0442\u0432\u0435\u0442\u044B",
1642
+ "\u0630\u0643\u0627\u0621",
1643
+ "\u0634\u0627\u062A \u0628\u0648\u062A",
1644
+ "\u0631\u0648\u0628\u0648\u062A \u0645\u062D\u0627\u062F\u062B\u0629",
1645
+ "\u0631\u062F\u0648\u062F \u0630\u0643\u064A\u0629"
1646
+ ],
1324
1647
  skills: { web: "add-ai", mobile: null, extension: null, spa: null, backend: null }
1325
1648
  },
1326
1649
  {
1327
1650
  id: "add-search",
1328
1651
  phrases: ["let users search", "find things", "search my data"],
1652
+ stems: ["\u05D7\u05D9\u05E4\u05D5\u05E9", "\u05DC\u05D7\u05E4\u05E9", "\u043F\u043E\u0438\u0441\u043A", "\u0438\u0441\u043A\u0430\u0442\u044C", "\u0628\u062D\u062B", "\u0627\u0628\u062D\u062B"],
1329
1653
  skills: { web: "add-search", mobile: null, extension: null, spa: null, backend: null }
1330
1654
  },
1331
1655
  {
1332
1656
  id: "add-realtime",
1333
1657
  phrases: ["live updates", "real-time", "push changes instantly", "refresh without reload"],
1658
+ stems: [
1659
+ "\u05D1\u05D6\u05DE\u05DF \u05D0\u05DE\u05EA",
1660
+ "\u05E2\u05D3\u05DB\u05D5\u05E0\u05D9\u05DD \u05D7\u05D9\u05D9\u05DD",
1661
+ "\u05D1\u05DC\u05D9 \u05DC\u05E8\u05E2\u05E0\u05DF",
1662
+ "\u05D1\u05DC\u05D9 \u05E8\u05D9\u05E2\u05E0\u05D5\u05DF",
1663
+ "\u0440\u0435\u0430\u043B\u044C\u043D\u043E\u043C \u0432\u0440\u0435\u043C\u0435\u043D\u0438",
1664
+ "\u0431\u0435\u0437 \u043F\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438",
1665
+ "\u0436\u0438\u0432\u044B\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F",
1666
+ "\u0627\u0644\u0648\u0642\u062A \u0627\u0644\u062D\u0642\u064A\u0642\u064A",
1667
+ "\u0627\u0644\u0648\u0642\u062A \u0627\u0644\u0641\u0639\u0644\u064A",
1668
+ "\u062A\u062D\u062F\u064A\u062B\u0627\u062A \u0645\u0628\u0627\u0634\u0631\u0629",
1669
+ "\u0628\u062F\u0648\u0646 \u0625\u0639\u0627\u062F\u0629 \u062A\u062D\u0645\u064A\u0644"
1670
+ ],
1334
1671
  skills: { web: "add-realtime", mobile: null, extension: null, spa: null, backend: null }
1335
1672
  },
1336
1673
  {
1337
1674
  id: "add-blog",
1338
1675
  phrases: ["add a blog", "write articles", "changelog"],
1676
+ stems: [
1677
+ "\u05D1\u05DC\u05D5\u05D2",
1678
+ "\u05DE\u05D0\u05DE\u05E8\u05D9\u05DD",
1679
+ "\u05DB\u05EA\u05D1\u05D5\u05EA",
1680
+ "\u05D9\u05D5\u05DE\u05DF \u05E9\u05D9\u05E0\u05D5\u05D9\u05D9\u05DD",
1681
+ "\u0431\u043B\u043E\u0433",
1682
+ "\u0441\u0442\u0430\u0442\u044C\u0438",
1683
+ "\u0441\u0442\u0430\u0442\u0435\u0439",
1684
+ "\u0645\u062F\u0648\u0646\u0629",
1685
+ "\u0645\u0642\u0627\u0644\u0627\u062A",
1686
+ "\u0633\u062C\u0644 \u0627\u0644\u062A\u063A\u064A\u064A\u0631\u0627\u062A"
1687
+ ],
1339
1688
  skills: { web: "add-blog", mobile: null, extension: null, spa: null, backend: null }
1340
1689
  },
1341
1690
  {
1342
1691
  id: "buy-domain",
1343
1692
  phrases: ["get a domain", "buy a web address", "my own url"],
1693
+ stems: [
1694
+ "\u05D3\u05D5\u05DE\u05D9\u05D9\u05DF",
1695
+ "\u05DB\u05EA\u05D5\u05D1\u05EA \u05D0\u05EA\u05E8",
1696
+ "\u05DB\u05EA\u05D5\u05D1\u05EA \u05DE\u05E9\u05DC\u05D9",
1697
+ "\u0434\u043E\u043C\u0435\u043D",
1698
+ "\u0441\u0432\u043E\u0439 \u0430\u0434\u0440\u0435\u0441 \u0441\u0430\u0439\u0442\u0430",
1699
+ "\u0646\u0637\u0627\u0642",
1700
+ "\u062F\u0648\u0645\u064A\u0646",
1701
+ "\u0639\u0646\u0648\u0627\u0646 \u0645\u0648\u0642\u0639"
1702
+ ],
1344
1703
  skills: { web: "buy-domain", mobile: null, extension: null, spa: null, backend: null }
1345
1704
  },
1346
1705
  {
1347
1706
  id: "sign-in-with-google",
1348
1707
  phrases: ["sign in with google", "continue with google"],
1708
+ stems: [
1709
+ "\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA \u05E2\u05DD google",
1710
+ "\u05D4\u05EA\u05D7\u05D1\u05E8\u05D5\u05EA \u05E2\u05DD \u05D2\u05D5\u05D2\u05DC",
1711
+ "\u05E2\u05DD google",
1712
+ "\u05E2\u05DD \u05D2\u05D5\u05D2\u05DC",
1713
+ "\u05D3\u05E8\u05DA google",
1714
+ "\u05D3\u05E8\u05DA \u05D2\u05D5\u05D2\u05DC",
1715
+ "\u05D7\u05E9\u05D1\u05D5\u05DF \u05D2\u05D5\u05D2\u05DC",
1716
+ "\u0447\u0435\u0440\u0435\u0437 google",
1717
+ "\u0447\u0435\u0440\u0435\u0437 \u0433\u0443\u0433\u043B",
1718
+ "\u0430\u043A\u043A\u0430\u0443\u043D\u0442 google",
1719
+ "\u0441 \u043F\u043E\u043C\u043E\u0449\u044C\u044E google",
1720
+ "\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0639\u0628\u0631 \u062C\u0648\u062C\u0644",
1721
+ "\u062A\u0633\u062C\u064A\u0644 \u0627\u0644\u062F\u062E\u0648\u0644 \u0628\u062D\u0633\u0627\u0628 \u062C\u0648\u062C\u0644",
1722
+ "\u0639\u0628\u0631 \u062C\u0648\u062C\u0644",
1723
+ "\u0628\u062D\u0633\u0627\u0628 \u062C\u0648\u062C\u0644",
1724
+ "\u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 \u062C\u0648\u062C\u0644",
1725
+ "\u0639\u0628\u0631 google",
1726
+ "\u0628\u0627\u0633\u062A\u062E\u062F\u0627\u0645 google"
1727
+ ],
1349
1728
  skills: {
1350
1729
  web: "sign-in-with-google",
1351
1730
  mobile: "sign-in-with-google",
@@ -1357,6 +1736,17 @@ var GOAL_ENTRIES = [
1357
1736
  {
1358
1737
  id: "check-safety",
1359
1738
  phrases: ["am i ready to ship", "is my app safe", "did we cover security"],
1739
+ stems: [
1740
+ "\u05DE\u05D5\u05DB\u05DF \u05DC\u05E2\u05DC\u05D5\u05EA",
1741
+ "\u05D4\u05D0\u05DD \u05D6\u05D4 \u05D1\u05D8\u05D5\u05D7",
1742
+ "\u05D1\u05D8\u05D5\u05D7 \u05DC\u05E2\u05DC\u05D5\u05EA",
1743
+ "\u0433\u043E\u0442\u043E\u0432 \u043A \u0437\u0430\u043F\u0443\u0441\u043A\u0443",
1744
+ "\u044D\u0442\u043E \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E",
1745
+ "\u043F\u0440\u043E\u0432\u0435\u0440\u044C \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u044C",
1746
+ "\u062C\u0627\u0647\u0632 \u0644\u0644\u0625\u0637\u0644\u0627\u0642",
1747
+ "\u0647\u0644 \u0647\u0648 \u0622\u0645\u0646",
1748
+ "\u062A\u062D\u0642\u0642 \u0645\u0646 \u0627\u0644\u0623\u0645\u0627\u0646"
1749
+ ],
1360
1750
  skills: {
1361
1751
  web: "check-safety",
1362
1752
  mobile: "check-safety",
@@ -1368,6 +1758,19 @@ var GOAL_ENTRIES = [
1368
1758
  {
1369
1759
  id: "track-errors",
1370
1760
  phrases: ["tell me when things break", "error alerts", "app crashes"],
1761
+ stems: [
1762
+ "\u05E7\u05E8\u05D9\u05E1\u05D4",
1763
+ "\u05E7\u05E8\u05D9\u05E1\u05D5\u05EA",
1764
+ "\u05D4\u05EA\u05E8\u05D0\u05D5\u05EA \u05E9\u05D2\u05D9\u05D0\u05D4",
1765
+ "\u05DE\u05E2\u05E7\u05D1 \u05E9\u05D2\u05D9\u05D0\u05D5\u05EA",
1766
+ "\u0441\u043E\u043E\u0431\u0449\u0430\u0439 \u043E\u0431 \u043E\u0448\u0438\u0431\u043A\u0430\u0445",
1767
+ "\u043F\u0430\u0434\u0430\u0435\u0442",
1768
+ "\u043E\u0442\u0441\u043B\u0435\u0436\u0438\u0432\u0430\u0442\u044C \u043E\u0448\u0438\u0431\u043A\u0438",
1769
+ "\u062A\u0639\u0637\u0644 \u0627\u0644\u062A\u0637\u0628\u064A\u0642",
1770
+ "\u0623\u0639\u0637\u0627\u0644",
1771
+ "\u062A\u0646\u0628\u064A\u0647\u0627\u062A \u0627\u0644\u0623\u062E\u0637\u0627\u0621",
1772
+ "\u062A\u062A\u0628\u0639 \u0627\u0644\u0623\u062E\u0637\u0627\u0621"
1773
+ ],
1371
1774
  skills: {
1372
1775
  web: "track-errors",
1373
1776
  mobile: "track-errors",
@@ -1380,6 +1783,19 @@ var GOAL_ENTRIES = [
1380
1783
  id: "watch-my-app",
1381
1784
  pageRecipeRequired: false,
1382
1785
  phrases: ["watch my app", "check if my app is working", "tell me when my app is down"],
1786
+ stems: [
1787
+ "\u05E0\u05D9\u05D8\u05D5\u05E8",
1788
+ "\u05D4\u05D0\u05EA\u05E8 \u05E0\u05E4\u05DC",
1789
+ "\u05D4\u05D0\u05EA\u05E8 \u05DC\u05DE\u05D8\u05D4",
1790
+ "\u05DC\u05D1\u05D3\u05D5\u05E7 \u05E9\u05D4\u05D0\u05EA\u05E8 \u05E2\u05D5\u05D1\u05D3",
1791
+ "\u043C\u043E\u043D\u0438\u0442\u043E\u0440\u0438\u043D\u0433",
1792
+ "\u0441\u0430\u0439\u0442 \u0443\u043F\u0430\u043B",
1793
+ "\u0441\u043B\u0435\u0434\u0438\u0442\u044C \u0437\u0430 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043C",
1794
+ "\u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043B\u0438 \u0441\u0430\u0439\u0442",
1795
+ "\u0645\u0631\u0627\u0642\u0628\u0629",
1796
+ "\u0627\u0644\u0645\u0648\u0642\u0639 \u0645\u062A\u0648\u0642\u0641",
1797
+ "\u0647\u0644 \u0627\u0644\u0645\u0648\u0642\u0639 \u064A\u0639\u0645\u0644"
1798
+ ],
1383
1799
  skills: {
1384
1800
  web: "watch-my-app",
1385
1801
  mobile: "watch-my-app",
@@ -1391,6 +1807,19 @@ var GOAL_ENTRIES = [
1391
1807
  {
1392
1808
  id: "back-up-my-code",
1393
1809
  phrases: ["save my code", "back up", "put it on github"],
1810
+ stems: [
1811
+ "\u05D2\u05D9\u05D1\u05D5\u05D9",
1812
+ "\u05DC\u05D2\u05D1\u05D5\u05EA \u05D0\u05EA \u05D4\u05E7\u05D5\u05D3",
1813
+ "\u05DC\u05E9\u05DE\u05D5\u05E8 \u05D0\u05EA \u05D4\u05E7\u05D5\u05D3",
1814
+ "\u05D2\u05D9\u05D8\u05D4\u05D0\u05D1",
1815
+ "\u0431\u044D\u043A\u0430\u043F",
1816
+ "\u0440\u0435\u0437\u0435\u0440\u0432\u043D",
1817
+ "\u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C \u043A\u043E\u0434",
1818
+ "\u0433\u0438\u0442\u0445\u0430\u0431",
1819
+ "\u0646\u0633\u062E\u0629 \u0627\u062D\u062A\u064A\u0627\u0637\u064A\u0629",
1820
+ "\u0646\u0633\u062E \u0627\u062D\u062A\u064A\u0627\u0637\u064A",
1821
+ "\u0627\u062D\u0641\u0638 \u0627\u0644\u0643\u0648\u062F"
1822
+ ],
1394
1823
  skills: {
1395
1824
  web: "back-up-my-code",
1396
1825
  mobile: "back-up-my-code",
@@ -1403,6 +1832,19 @@ var GOAL_ENTRIES = [
1403
1832
  id: "validate-my-idea",
1404
1833
  pageRecipeRequired: false,
1405
1834
  phrases: ["validate my idea", "test demand", "start a waitlist", "test my offer"],
1835
+ stems: [
1836
+ "\u05DC\u05D1\u05D3\u05D5\u05E7 \u05D0\u05EA \u05D4\u05E8\u05E2\u05D9\u05D5\u05DF",
1837
+ "\u05DC\u05EA\u05E7\u05E3 \u05D0\u05EA \u05D4\u05E8\u05E2\u05D9\u05D5\u05DF",
1838
+ "\u05E8\u05E9\u05D9\u05DE\u05EA \u05D4\u05DE\u05EA\u05E0\u05D4",
1839
+ "\u05D1\u05D9\u05E7\u05D5\u05E9",
1840
+ "\u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u0438\u0434\u0435\u044E",
1841
+ "\u0441\u043F\u0440\u043E\u0441",
1842
+ "\u043B\u0438\u0441\u0442 \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F",
1843
+ "\u0441\u043F\u0438\u0441\u043E\u043A \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F",
1844
+ "\u0627\u062E\u062A\u0628\u0627\u0631 \u0627\u0644\u0641\u0643\u0631\u0629",
1845
+ "\u0627\u0644\u062A\u062D\u0642\u0642 \u0645\u0646 \u0641\u0643\u0631\u062A\u064A",
1846
+ "\u0642\u0627\u0626\u0645\u0629 \u0627\u0646\u062A\u0638\u0627\u0631"
1847
+ ],
1406
1848
  skills: {
1407
1849
  web: "validate-my-idea",
1408
1850
  mobile: null,
@@ -1414,6 +1856,24 @@ var GOAL_ENTRIES = [
1414
1856
  {
1415
1857
  id: "add-language",
1416
1858
  phrases: ["translate my app", "add spanish", "make it hebrew"],
1859
+ stems: [
1860
+ "\u05DC\u05EA\u05E8\u05D2\u05DD",
1861
+ "\u05EA\u05E8\u05D2\u05D5\u05DD",
1862
+ "\u05E9\u05E4\u05D4 \u05E0\u05D5\u05E1\u05E4\u05EA",
1863
+ "\u05E9\u05E4\u05D5\u05EA",
1864
+ "\u05D0\u05E0\u05D2\u05DC\u05D9\u05EA",
1865
+ "\u05D3\u05D5 \u05DC\u05E9\u05D5\u05E0\u05D9",
1866
+ "\u043F\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438",
1867
+ "\u043F\u0435\u0440\u0435\u0432\u043E\u0434",
1868
+ "\u0430\u043D\u0433\u043B\u0438\u0439\u0441\u043A",
1869
+ "\u0434\u0440\u0443\u0433\u043E\u0439 \u044F\u0437\u044B\u043A",
1870
+ "\u0434\u0432\u0443\u044F\u0437\u044B\u0447",
1871
+ "\u062A\u0631\u062C\u0645\u0629",
1872
+ "\u062A\u0631\u062C\u0645",
1873
+ "\u0627\u0644\u0625\u0646\u062C\u0644\u064A\u0632\u064A\u0629",
1874
+ "\u0644\u063A\u0629 \u0623\u062E\u0631\u0649",
1875
+ "\u0644\u063A\u062A\u064A\u0646"
1876
+ ],
1417
1877
  skills: {
1418
1878
  web: "add-language",
1419
1879
  mobile: "add-language",
@@ -1425,6 +1885,17 @@ var GOAL_ENTRIES = [
1425
1885
  {
1426
1886
  id: "configure-capabilities",
1427
1887
  phrases: ["camera", "location permission", "notifications permission"],
1888
+ stems: [
1889
+ "\u05DE\u05E6\u05DC\u05DE\u05D4",
1890
+ "\u05D4\u05E8\u05E9\u05D0\u05EA \u05DE\u05D9\u05E7\u05D5\u05DD",
1891
+ "\u05D4\u05E8\u05E9\u05D0\u05D5\u05EA",
1892
+ "\u043A\u0430\u043C\u0435\u0440",
1893
+ "\u0434\u043E\u0441\u0442\u0443\u043F \u043A \u0433\u0435\u043E\u043B\u043E\u043A\u0430\u0446\u0438\u0438",
1894
+ "\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438",
1895
+ "\u0627\u0644\u0643\u0627\u0645\u064A\u0631\u0627",
1896
+ "\u0625\u0630\u0646 \u0627\u0644\u0645\u0648\u0642\u0639",
1897
+ "\u0635\u0644\u0627\u062D\u064A\u0627\u062A"
1898
+ ],
1428
1899
  skills: {
1429
1900
  web: null,
1430
1901
  mobile: "configure-capabilities",
@@ -1436,41 +1907,67 @@ var GOAL_ENTRIES = [
1436
1907
  {
1437
1908
  id: "publish-app",
1438
1909
  phrases: ["publish app", "app store"],
1910
+ stems: [
1911
+ "\u05D7\u05E0\u05D5\u05EA \u05D4\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D5\u05EA",
1912
+ "\u05D0\u05E4 \u05E1\u05D8\u05D5\u05E8",
1913
+ "\u05D2\u05D5\u05D2\u05DC \u05E4\u05DC\u05D9\u05D9",
1914
+ "\u05DC\u05E4\u05E8\u05E1\u05DD \u05D0\u05EA \u05D4\u05D0\u05E4\u05DC\u05D9\u05E7\u05E6\u05D9\u05D4",
1915
+ "\u0430\u043F\u043F \u0441\u0442\u043E\u0440",
1916
+ "\u0433\u0443\u0433\u043B \u043F\u043B\u0435\u0439",
1917
+ "\u043E\u043F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435",
1918
+ "\u0645\u062A\u062C\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642\u0627\u062A",
1919
+ "\u0646\u0634\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642",
1920
+ "\u062C\u0648\u062C\u0644 \u0628\u0644\u0627\u064A"
1921
+ ],
1439
1922
  skills: { web: null, mobile: "publish-app", extension: null, spa: null, backend: null }
1440
1923
  },
1441
1924
  {
1442
1925
  id: "publish-extension",
1443
1926
  phrases: ["chrome store", "publish extension"],
1927
+ stems: [
1928
+ "\u05D7\u05E0\u05D5\u05EA \u05DB\u05E8\u05D5\u05DD",
1929
+ "\u05DC\u05E4\u05E8\u05E1\u05DD \u05D0\u05EA \u05D4\u05EA\u05D5\u05E1\u05E3",
1930
+ "\u043C\u0430\u0433\u0430\u0437\u0438\u043D chrome",
1931
+ "\u043E\u043F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435",
1932
+ "\u0645\u062A\u062C\u0631 \u0643\u0631\u0648\u0645",
1933
+ "\u0646\u0634\u0631 \u0627\u0644\u0625\u0636\u0627\u0641\u0629"
1934
+ ],
1444
1935
  skills: { web: null, mobile: null, extension: "publish-extension", spa: null, backend: null }
1445
1936
  },
1446
1937
  {
1447
1938
  id: "add-upload",
1448
1939
  phrases: ["file upload endpoint"],
1940
+ stems: ["\u05E0\u05E7\u05D5\u05D3\u05EA \u05E7\u05E6\u05D4 \u05DC\u05D4\u05E2\u05DC\u05D0\u05D4", "\u044D\u043D\u0434\u043F\u043E\u0438\u043D\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438", "\u0646\u0642\u0637\u0629 \u0631\u0641\u0639 \u0627\u0644\u0645\u0644\u0641\u0627\u062A"],
1449
1941
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "add-upload" }
1450
1942
  },
1451
1943
  {
1452
1944
  id: "wire-auth",
1453
1945
  phrases: ["wire auth"],
1946
+ stems: ["\u05DC\u05D7\u05D1\u05E8 \u05D0\u05D9\u05DE\u05D5\u05EA", "\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0430\u0432\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u044E", "\u0631\u0628\u0637 \u0627\u0644\u0645\u0635\u0627\u062F\u0642\u0629"],
1454
1947
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "wire-auth" }
1455
1948
  },
1456
1949
  {
1457
1950
  id: "wire-database",
1458
1951
  phrases: ["wire database"],
1952
+ stems: ["\u05DC\u05D7\u05D1\u05E8 \u05DE\u05E1\u05D3 \u05E0\u05EA\u05D5\u05E0\u05D9\u05DD", "\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0431\u0430\u0437\u0443", "\u0631\u0628\u0637 \u0642\u0627\u0639\u062F\u0629 \u0627\u0644\u0628\u064A\u0627\u0646\u0627\u062A"],
1459
1953
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "wire-database" }
1460
1954
  },
1461
1955
  {
1462
1956
  id: "wire-payments",
1463
1957
  phrases: ["wire payments"],
1958
+ stems: ["\u05DC\u05D7\u05D1\u05E8 \u05EA\u05E9\u05DC\u05D5\u05DE\u05D9\u05DD", "\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043E\u043F\u043B\u0430\u0442\u0443", "\u0631\u0628\u0637 \u0627\u0644\u062F\u0641\u0639"],
1464
1959
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "wire-payments" }
1465
1960
  },
1466
1961
  {
1467
1962
  id: "wire-email",
1468
1963
  phrases: ["wire email"],
1964
+ stems: ["\u05DC\u05D7\u05D1\u05E8 \u05DE\u05D9\u05D9\u05DC", "\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043F\u043E\u0447\u0442\u0443", "\u0631\u0628\u0637 \u0627\u0644\u0628\u0631\u064A\u062F"],
1469
1965
  skills: { web: null, mobile: null, extension: null, spa: null, backend: "wire-email" }
1470
1966
  },
1471
1967
  {
1472
1968
  id: "connect-account-backend",
1473
1969
  phrases: ["connect account backend"],
1970
+ stems: ["\u05DC\u05D7\u05D1\u05E8 \u05D0\u05EA \u05D4\u05E9\u05E8\u05EA", "\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u0431\u044D\u043A\u0435\u043D\u0434", "\u0631\u0628\u0637 \u0627\u0644\u062E\u0627\u062F\u0645"],
1474
1971
  skills: {
1475
1972
  web: null,
1476
1973
  mobile: "connect-account-backend",
@@ -1480,7 +1977,7 @@ var GOAL_ENTRIES = [
1480
1977
  }
1481
1978
  }
1482
1979
  ];
1483
- var normalizeGoalRequest = (request) => request.toLowerCase().replace(/[^a-z0-9' ]+/g, " ").replace(/\s+/g, " ").trim();
1980
+ var normalizeGoalRequest = (request) => request.toLowerCase().replace(/[^\p{L}\p{N}' ]+/gu, " ").replace(/\s+/g, " ").trim();
1484
1981
  var GOAL_CATALOG = Object.fromEntries(
1485
1982
  GOAL_ENTRIES.map((entry) => [entry.id, entry])
1486
1983
  );
@@ -2406,6 +2903,7 @@ var AGENT_LAYER_PATHS = [
2406
2903
  "language.md",
2407
2904
  ".claude/settings.json",
2408
2905
  ".claude/hooks",
2906
+ ".codex/hooks.json",
2409
2907
  ".cursor/rules/vybekiit.mdc",
2410
2908
  ".cursor/rules/patterns.mdc",
2411
2909
  ".github/copilot-instructions.md",
@@ -2660,16 +3158,18 @@ var planGoalRoutes = (template) => {
2660
3158
  continue;
2661
3159
  }
2662
3160
  const known = phrasesBySkill.get(skill);
2663
- const collected = known === void 0 ? { phrases: [], wholeRequestPhrases: [] } : known;
3161
+ const collected = known === void 0 ? { phrases: [], wholeRequestPhrases: [], stems: [] } : known;
2664
3162
  collected.phrases.push(...entry.phrases);
2665
3163
  collected.wholeRequestPhrases.push(...entry.wholeRequestPhrases || []);
3164
+ collected.stems.push(...entry.stems);
2666
3165
  phrasesBySkill.set(skill, collected);
2667
3166
  }
2668
3167
  return [...phrasesBySkill].map(([skill, collected]) => ({
2669
3168
  skill,
2670
3169
  path: buyerSkillStubPath(skill),
2671
3170
  phrases: uniqueNormalized(collected.phrases),
2672
- wholeRequestPhrases: uniqueNormalized(collected.wholeRequestPhrases)
3171
+ wholeRequestPhrases: uniqueNormalized(collected.wholeRequestPhrases),
3172
+ stems: uniqueNormalized(collected.stems)
2673
3173
  }));
2674
3174
  };
2675
3175
  var renderGoalRoutes = (template) => {
@@ -13791,6 +14291,7 @@ var KitPackageManifest = Schema12.Struct({
13791
14291
  peerDependencies: Schema12.optional(DependencyVersions),
13792
14292
  optionalDependencies: Schema12.optional(DependencyVersions),
13793
14293
  packageManager: Schema12.optional(Schema12.String),
14294
+ scripts: Schema12.optional(Schema12.Record({ key: Schema12.String, value: Schema12.String })),
13794
14295
  pnpm: Schema12.optional(
13795
14296
  Schema12.Struct({
13796
14297
  overrides: Schema12.optional(DependencyVersions),
@@ -14070,7 +14571,8 @@ var mergeMissingSetupMessages = async (kitRoot, dest, locale) => {
14070
14571
  }
14071
14572
  };
14072
14573
  var CATALOG_BLOCK_START = /^catalog:\s*$/m;
14073
- var kitWorkspacePackageJson = (kitRootPkg, template) => {
14574
+ var SURFACE_SCRIPT_NAMES = ["dev", "build", "start", "typecheck", "test", "verify"];
14575
+ var kitWorkspacePackageJson = (kitRootPkg, surfacePkg, template) => {
14074
14576
  const packageManager = kitRootPkg?.packageManager !== void 0 && kitRootPkg.packageManager !== "" ? kitRootPkg.packageManager : "pnpm@10.33.2";
14075
14577
  const rootDependencyNames = /* @__PURE__ */ new Set([
14076
14578
  "@types/node",
@@ -14081,6 +14583,15 @@ var kitWorkspacePackageJson = (kitRootPkg, template) => {
14081
14583
  ([dependencyName]) => rootDependencyNames.has(dependencyName)
14082
14584
  )
14083
14585
  );
14586
+ const forwardedScriptNames = SURFACE_SCRIPT_NAMES.filter(
14587
+ (scriptName) => surfacePkg?.scripts?.[scriptName] !== void 0
14588
+ );
14589
+ const surfaceScripts = Object.fromEntries(
14590
+ forwardedScriptNames.map((scriptName) => [
14591
+ scriptName,
14592
+ `pnpm --dir templates/${template} ${scriptName}`
14593
+ ])
14594
+ );
14084
14595
  return `${JSON.stringify(
14085
14596
  {
14086
14597
  name: "my-vybekiit-kit",
@@ -14090,9 +14601,8 @@ var kitWorkspacePackageJson = (kitRootPkg, template) => {
14090
14601
  ...kitRootPkg?.pnpm === void 0 ? {} : { pnpm: kitRootPkg.pnpm },
14091
14602
  scripts: {
14092
14603
  // Run the surface from the kit root so agents don't have to discover templates/*.
14093
- dev: `pnpm --dir templates/${template} dev`,
14094
- "build:packages": 'pnpm --config.node-options=--max-old-space-size=4096 -r --workspace-concurrency=1 --filter "./packages/**" run build',
14095
- verify: `pnpm --dir templates/${template} verify`
14604
+ ...surfaceScripts,
14605
+ "build:packages": 'pnpm --config.node-options=--max-old-space-size=4096 -r --workspace-concurrency=1 --filter "./packages/**" run build'
14096
14606
  }
14097
14607
  },
14098
14608
  null,
@@ -14175,8 +14685,12 @@ var copyPackageIntoKit = async (packagesRoot, packageDir, dest) => {
14175
14685
  filter: (src) => shouldCopyScaffoldPath(src)
14176
14686
  });
14177
14687
  };
14178
- var writeWorkspaceClaudeSettings = async (surfaceDest, dest, template) => {
14179
- const appSettingsPath = join14(surfaceDest, ".claude", "settings.json");
14688
+ var AGENT_HOOK_SETTINGS_FILES = [
14689
+ [".claude", "settings.json"],
14690
+ [".codex", "hooks.json"]
14691
+ ];
14692
+ var writeWorkspaceHookSettings = async (dest, template, [settingsFolder, settingsFile]) => {
14693
+ const appSettingsPath = join14(dest, "templates", template, settingsFolder, settingsFile);
14180
14694
  if (!await pathExists3(appSettingsPath)) {
14181
14695
  return;
14182
14696
  }
@@ -14185,8 +14699,8 @@ var writeWorkspaceClaudeSettings = async (surfaceDest, dest, template) => {
14185
14699
  "/.claude/hooks/",
14186
14700
  `/templates/${template}/.claude/hooks/`
14187
14701
  );
14188
- await mkdir5(join14(dest, ".claude"), { recursive: true });
14189
- await writeFile6(join14(dest, ".claude", "settings.json"), workspaceSettings);
14702
+ await mkdir5(join14(dest, settingsFolder), { recursive: true });
14703
+ await writeFile6(join14(dest, settingsFolder, settingsFile), workspaceSettings);
14190
14704
  };
14191
14705
  var scaffoldKitWorkspace = async (options) => {
14192
14706
  const surfaceSource = join14(options.kitRoot, "templates", options.template);
@@ -14217,9 +14731,10 @@ var scaffoldKitWorkspace = async (options) => {
14217
14731
  packageDirs.map((packageDir) => copyPackageIntoKit(packagesRoot, packageDir, options.dest))
14218
14732
  );
14219
14733
  const kitRootPkg = await readPackageJson2(join14(options.kitRoot, "package.json"));
14734
+ const surfacePkg = await readPackageJson2(join14(surfaceSource, "package.json"));
14220
14735
  await writeFile6(
14221
14736
  join14(options.dest, "package.json"),
14222
- kitWorkspacePackageJson(kitRootPkg, options.template)
14737
+ kitWorkspacePackageJson(kitRootPkg, surfacePkg, options.template)
14223
14738
  );
14224
14739
  let sourceWorkspaceYaml = null;
14225
14740
  try {
@@ -14237,7 +14752,7 @@ var scaffoldKitWorkspace = async (options) => {
14237
14752
  join14(options.dest, "AGENTS.md"),
14238
14753
  `# Your VybeKiit app
14239
14754
 
14240
- The app lives in templates/${options.template}. Before planning or changing it, read templates/${options.template}/AGENTS.md; paths in it are relative to templates/${options.template}. Customize that app; reuse the maintained packages in packages/.
14755
+ The app lives in templates/${options.template}. Its guide, templates/${options.template}/AGENTS.md, is imported below; read that file yourself only if your tool did not load it. Paths in it are relative to templates/${options.template}. Customize that app; reuse the maintained packages in packages/. The app's own pnpm commands, such as \`pnpm dev\` and \`pnpm test\`, also run from here.
14241
14756
 
14242
14757
  @templates/${options.template}/AGENTS.md
14243
14758
  `
@@ -14252,7 +14767,11 @@ The app lives in templates/${options.template}. Before planning or changing it,
14252
14767
  );
14253
14768
  await ensureAgentSkillSymlinks(options.dest);
14254
14769
  }
14255
- await writeWorkspaceClaudeSettings(surfaceDest, options.dest, options.template);
14770
+ await Promise.all(
14771
+ AGENT_HOOK_SETTINGS_FILES.map(
14772
+ (settingsPath) => writeWorkspaceHookSettings(options.dest, options.template, settingsPath)
14773
+ )
14774
+ );
14256
14775
  await shipFirstPartyMcpConfigs({ dest: options.dest, template: options.template });
14257
14776
  await writeKitWorkspaceManifest({
14258
14777
  projectRoot: options.dest,
@@ -15768,7 +16287,7 @@ var getAgentConfigsForTemplate = () => ({
15768
16287
  "Claude Code": ".claude/settings.json + hooks/",
15769
16288
  Kiro: ".kiro/steering/vybekiit.md",
15770
16289
  Cursor: ".cursor/rules/vybekiit.mdc",
15771
- Codex: "AGENTS.md",
16290
+ Codex: "AGENTS.md + .codex/hooks.json",
15772
16291
  Gemini: "GEMINI.md",
15773
16292
  Copilot: ".github/copilot-instructions.md",
15774
16293
  Windsurf: ".windsurfrules",
@@ -16536,7 +17055,7 @@ var readInitPackageJson = async (cwd) => {
16536
17055
  // src/commands/initAssets.ts
16537
17056
  var execFileAsync4 = promisify4(execFile4);
16538
17057
  var HERE5 = dirname10(fileURLToPath5(import.meta.url));
16539
- var copyClaudeHooks = async (cwd, templateDir) => {
17058
+ var copyAgentHooks = async (cwd, templateDir) => {
16540
17059
  const claudeSource = join27(templateDir, ".claude");
16541
17060
  if (!await pathExists4(claudeSource)) {
16542
17061
  process.stdout.write(" \u26A0\uFE0F Could not copy .claude hooks (source missing)\n");
@@ -16544,6 +17063,13 @@ var copyClaudeHooks = async (cwd, templateDir) => {
16544
17063
  }
16545
17064
  await cp4(claudeSource, join27(cwd, ".claude"), { recursive: true, force: true });
16546
17065
  process.stdout.write(" \u2705 .claude/settings.json + hooks\n");
17066
+ const codexHooksSource = join27(templateDir, ".codex", "hooks.json");
17067
+ if (!await pathExists4(codexHooksSource)) {
17068
+ return;
17069
+ }
17070
+ await mkdir10(join27(cwd, ".codex"), { recursive: true });
17071
+ await cp4(codexHooksSource, join27(cwd, ".codex", "hooks.json"), { force: true });
17072
+ process.stdout.write(" \u2705 .codex/hooks.json\n");
16547
17073
  };
16548
17074
  var copyWorkflows = async (cwd, templateDir, pm) => {
16549
17075
  const workflowsDir = join27(cwd, ".github", "workflows");
@@ -16766,11 +17292,11 @@ var writeInitSuccess = (pm) => {
16766
17292
  `);
16767
17293
  process.stdout.write("\n");
16768
17294
  process.stdout.write(" Platform configs generated:\n");
16769
- process.stdout.write(" .kiro/steering/vybekiit.md -> Kiro\n");
16770
- process.stdout.write(" .cursor/rules/vybekiit.mdc -> Cursor\n");
16771
- process.stdout.write(" AGENTS.md -> OpenAI Codex\n");
16772
- process.stdout.write(" GEMINI.md -> Gemini CLI\n");
16773
- process.stdout.write(" AGENTS.md + .claude/hooks/ -> Claude Code\n");
17295
+ process.stdout.write(" .kiro/steering/vybekiit.md -> Kiro\n");
17296
+ process.stdout.write(" .cursor/rules/vybekiit.mdc -> Cursor\n");
17297
+ process.stdout.write(" AGENTS.md + .codex/hooks.json -> OpenAI Codex\n");
17298
+ process.stdout.write(" GEMINI.md -> Gemini CLI\n");
17299
+ process.stdout.write(" AGENTS.md + .claude/hooks/ -> Claude Code\n");
16774
17300
  };
16775
17301
 
16776
17302
  // src/commands/initPatches.ts
@@ -16837,7 +17363,7 @@ var runInit = async (args) => {
16837
17363
  const { cleanup: resolvedCleanup, source } = await locateTemplateSource(projectType);
16838
17364
  cleanup = resolvedCleanup;
16839
17365
  const templateDir = join30(source, projectType);
16840
- await copyClaudeHooks(cwd, templateDir);
17366
+ await copyAgentHooks(cwd, templateDir);
16841
17367
  await copyWorkflows(cwd, templateDir, pm);
16842
17368
  await copyPrePushHook(cwd, templateDir);
16843
17369
  await copySecurityFile(cwd, templateDir);
@@ -20400,9 +20926,8 @@ var VerifyGateFailedError = class extends Error {
20400
20926
  };
20401
20927
 
20402
20928
  // ../packages/browserAutomation/src/domains/extension/connect.ts
20403
- var DEFAULT_CDP_ENDPOINT2 = "http://localhost:9222";
20404
20929
  var connectToCwsChrome = async (ctx) => {
20405
- const endpoint = ctx.cdpEndpoint === void 0 ? DEFAULT_CDP_ENDPOINT2 : ctx.cdpEndpoint;
20930
+ const endpoint = ctx.cdpEndpoint === void 0 ? DEFAULT_CDP_ENDPOINT : ctx.cdpEndpoint;
20406
20931
  const log = verbLogger(ctx);
20407
20932
  const profileDir = await chromeProfilePath("extension");
20408
20933
  log.log(`[cws] attaching to CWS Chrome at ${endpoint}`);
@@ -29939,7 +30464,7 @@ var SUPABASE = {
29939
30464
  command: "supabase",
29940
30465
  args: ["projects", "list"],
29941
30466
  loginHint: "supabase login",
29942
- signIn: { command: "supabase", args: ["login"] }
30467
+ signIn: { command: "supabase", args: ["login"], needsTerminal: true }
29943
30468
  }
29944
30469
  };
29945
30470
  var NEON = {
@@ -31458,6 +31983,7 @@ var reportFor = (reports, toolName) => reports.find((report) => report.tool ===
31458
31983
  import { existsSync as existsSync16, readFileSync as readFileSync11 } from "fs";
31459
31984
  import { join as join62 } from "path";
31460
31985
  import process33 from "process";
31986
+ var UPDATE_KIT_HINT = 'Ask your AI helper: "Update my kit."';
31461
31987
  var readManifest2 = (cwd) => {
31462
31988
  const path = join62(cwd, "platform-skills.manifest.json");
31463
31989
  if (!existsSync16(path)) {
@@ -31517,19 +32043,17 @@ var formatPlatformSkillsReport = (report) => {
31517
32043
  const count = Object.keys(lock.skills).length;
31518
32044
  lines.push(`\u2713 platform skills lock - ${count} pinned skill(s) in skills-lock.json.`);
31519
32045
  } catch {
31520
- lines.push("\u2192 platform skills lock - skills-lock.json unreadable.");
32046
+ lines.push(`\u2192 platform skills lock - skills-lock.json unreadable. ${UPDATE_KIT_HINT}`);
31521
32047
  }
31522
32048
  } else {
31523
- lines.push("\u2192 platform skills lock - skills-lock.json missing (run pin-platform-skills).");
32049
+ lines.push(`\u2192 platform skills lock - skills-lock.json missing. ${UPDATE_KIT_HINT}`);
31524
32050
  }
31525
32051
  if (report.ok) {
31526
32052
  const scope = report.lockCount > 0 ? `all ${report.lockCount} locked skill(s)` : "all explicit manifest skills";
31527
32053
  lines.push(`\u2713 platform skills - ${scope} are present.`);
31528
32054
  return lines;
31529
32055
  }
31530
- lines.push(
31531
- `\u2192 platform skills - missing: ${report.missing.join(", ")}. Ask your agent to refresh platform skills (update-kit) or run the pin script.`
31532
- );
32056
+ lines.push(`\u2192 platform skills - missing: ${report.missing.join(", ")}. ${UPDATE_KIT_HINT}`);
31533
32057
  return lines;
31534
32058
  };
31535
32059
 
@@ -32631,7 +33155,7 @@ import { homedir as homedir15 } from "os";
32631
33155
  import { join as join72 } from "path";
32632
33156
  import process39 from "process";
32633
33157
  import { confirm as confirm3, isCancel as isCancel5 } from "@clack/prompts";
32634
- import { Effect as Effect45, Schema as Schema31 } from "effect";
33158
+ import { Effect as Effect46, Schema as Schema32 } from "effect";
32635
33159
 
32636
33160
  // src/global/agentGuidance.ts
32637
33161
  import { constants as constants3, existsSync as existsSync20 } from "fs";
@@ -33058,6 +33582,9 @@ var formatEntitlementBlock = (entitlement) => {
33058
33582
  return ["", ...accountLines, ...helpLines, ""];
33059
33583
  };
33060
33584
 
33585
+ // src/global/installCodexMcp.ts
33586
+ import { Data as Data14, Effect as Effect45, Schema as Schema31 } from "effect";
33587
+
33061
33588
  // src/global/installGlobalMcp.ts
33062
33589
  import process38 from "process";
33063
33590
  var ZERO_CONFIG = [
@@ -33206,6 +33733,114 @@ var installGlobalMcp = async (deps = defaultDeps4) => {
33206
33733
  return { enabled, alreadyPresent, refreshed, needsKey, failed, claudeMissing: false };
33207
33734
  };
33208
33735
 
33736
+ // src/global/installCodexMcp.ts
33737
+ var CodexListingError = class extends Data14.TaggedError("CodexListingError") {
33738
+ };
33739
+ var CodexMcpRegistration = Schema31.Struct({
33740
+ name: Schema31.String,
33741
+ transport: Schema31.Struct({
33742
+ command: Schema31.optionalWith(Schema31.String, { default: () => "" }),
33743
+ args: Schema31.optionalWith(Schema31.Array(Schema31.String), { default: () => [] })
33744
+ })
33745
+ });
33746
+ var decodeCodexMcpListing = Schema31.decodeUnknown(
33747
+ Schema31.parseJson(Schema31.Array(CodexMcpRegistration))
33748
+ );
33749
+ var CODEX_MCP_SERVERS = GLOBAL_MCP_SERVERS.filter(
33750
+ (mcpServer) => mcpServer.transport === "stdio"
33751
+ );
33752
+ var codexMcpAddArguments = (mcpServer, environment) => {
33753
+ const envFlags = (mcpServer.envKeys || []).flatMap((key) => [
33754
+ "--env",
33755
+ `${key}=${environment[key] || ""}`
33756
+ ]);
33757
+ return ["mcp", "add", ...envFlags, mcpServer.name, "--", ...mcpServer.command];
33758
+ };
33759
+ var codexMcpOwner = (mcpServer, registrations) => {
33760
+ const registration = registrations.find((registered) => registered.name === mcpServer.name);
33761
+ if (registration === void 0) {
33762
+ return "absent";
33763
+ }
33764
+ const registeredCommand = [registration.transport.command, ...registration.transport.args].join(
33765
+ " "
33766
+ );
33767
+ const vybekiitRegistration = mcpServer.name === "vybekiit" || registeredCommand === mcpServer.command.join(" ");
33768
+ return vybekiitRegistration ? "vybekiit" : "user";
33769
+ };
33770
+ var codexInstalled = (codex) => Effect45.promise(() => codex(["--version"])).pipe(
33771
+ Effect45.map((codexVersion) => codexVersion.code !== MISSING_COMMAND_CODE)
33772
+ );
33773
+ var listCodexMcpRegistrations = (codex) => Effect45.promise(() => codex(["mcp", "list", "--json"])).pipe(
33774
+ Effect45.filterOrFail(
33775
+ (codexListing) => codexListing.code === 0,
33776
+ (codexListing) => new CodexListingError({
33777
+ message: `Codex could not list its tool connections. ${codexListing.stderr.trim()}`
33778
+ })
33779
+ ),
33780
+ Effect45.flatMap(
33781
+ (codexListing) => decodeCodexMcpListing(codexListing.stdout).pipe(
33782
+ Effect45.mapError(
33783
+ (cause) => new CodexListingError({
33784
+ message: "Codex listed its tool connections in a shape VybeKiit does not know.",
33785
+ cause
33786
+ })
33787
+ )
33788
+ )
33789
+ )
33790
+ );
33791
+ var codexServerOutcome = (codexSetup, mcpServer, registrations) => {
33792
+ if (!hasKeys(mcpServer, codexSetup.environment)) {
33793
+ return Effect45.succeed({ name: mcpServer.name, outcome: "needsKey" });
33794
+ }
33795
+ const registered = codexMcpOwner(mcpServer, registrations) !== "absent";
33796
+ const refreshDue = registered && codexSetup.forceRefresh && isZeroConfig(mcpServer);
33797
+ if (registered && !refreshDue) {
33798
+ return Effect45.succeed({ name: mcpServer.name, outcome: "alreadyPresent" });
33799
+ }
33800
+ const addedOutcome = refreshDue ? "refreshed" : "enabled";
33801
+ const addArguments = codexMcpAddArguments(mcpServer, codexSetup.environment);
33802
+ return Effect45.promise(() => codexSetup.codex(addArguments)).pipe(
33803
+ Effect45.map(
33804
+ (codexAdd) => ({
33805
+ name: mcpServer.name,
33806
+ outcome: codexAdd.code === 0 ? addedOutcome : "failed"
33807
+ })
33808
+ )
33809
+ );
33810
+ };
33811
+ var serverNamesWith = (serverOutcomes, outcome) => serverOutcomes.filter((serverOutcome) => serverOutcome.outcome === outcome).map((serverOutcome) => serverOutcome.name);
33812
+ var codexInstallation = (serverOutcomes, codexMissing) => ({
33813
+ enabled: serverNamesWith(serverOutcomes, "enabled"),
33814
+ alreadyPresent: serverNamesWith(serverOutcomes, "alreadyPresent"),
33815
+ refreshed: serverNamesWith(serverOutcomes, "refreshed"),
33816
+ needsKey: serverNamesWith(serverOutcomes, "needsKey"),
33817
+ failed: serverNamesWith(serverOutcomes, "failed"),
33818
+ codexMissing
33819
+ });
33820
+ var installCodexMcp = (codexSetup) => Effect45.gen(function* () {
33821
+ if (!(yield* codexInstalled(codexSetup.codex))) {
33822
+ return codexInstallation([], true);
33823
+ }
33824
+ const unlistedOutcomes = CODEX_MCP_SERVERS.map(
33825
+ (mcpServer) => ({
33826
+ name: mcpServer.name,
33827
+ outcome: hasKeys(mcpServer, codexSetup.environment) ? "failed" : "needsKey"
33828
+ })
33829
+ );
33830
+ const serverOutcomes = yield* listCodexMcpRegistrations(codexSetup.codex).pipe(
33831
+ Effect45.flatMap(
33832
+ (registrations) => Effect45.all(
33833
+ CODEX_MCP_SERVERS.map(
33834
+ (mcpServer) => codexServerOutcome(codexSetup, mcpServer, registrations)
33835
+ ),
33836
+ { concurrency: 1 }
33837
+ )
33838
+ ),
33839
+ Effect45.catchTag("CodexListingError", () => Effect45.succeed(unlistedOutcomes))
33840
+ );
33841
+ return codexInstallation(serverOutcomes, false);
33842
+ });
33843
+
33209
33844
  // src/global/installGlobalSkills.ts
33210
33845
  import { cp as cp5, mkdir as mkdir22, readdir as readdir14, readFile as readFile37, rm as rm5, stat as stat3, writeFile as writeFile27 } from "fs/promises";
33211
33846
  import { join as join71 } from "path";
@@ -33274,7 +33909,18 @@ var installGlobalSkills = async (paths, sourceDir = paths.bundledSkillsDir) => {
33274
33909
 
33275
33910
  // src/global/runGlobalInstall.ts
33276
33911
  var shouldRunSessionOneOnInstall = (args, isFirstInstall) => isFirstInstall || args.includes("--session-one");
33277
- var globalSetupComplete = (managedFilesReady, mcpInstallation) => managedFilesReady && (mcpInstallation.claudeMissing || isVybekiitMcpReady(mcpInstallation));
33912
+ var globalSetupComplete = (managedFilesReady, mcpInstallation, codexMcpInstallation) => managedFilesReady && (mcpInstallation.claudeMissing || isVybekiitMcpReady(mcpInstallation)) && (codexMcpInstallation.codexMissing || isVybekiitMcpReady(codexMcpInstallation));
33913
+ var codexMcpLines = (codexMcp) => {
33914
+ if (codexMcp.codexMissing) {
33915
+ return [];
33916
+ }
33917
+ const enabledLabel = codexMcp.enabled.length > 0 ? codexMcp.enabled.join(", ") : "none newly added";
33918
+ return [
33919
+ ` \u2022 Codex ${enabledLabel} (the same tool connections in Codex)`,
33920
+ ...codexMcp.refreshed.length > 0 ? [` refreshed: ${codexMcp.refreshed.join(", ")}`] : [],
33921
+ ...codexMcp.failed.length > 0 ? [` failed to register: ${codexMcp.failed.join(", ")}`] : []
33922
+ ];
33923
+ };
33278
33924
  var formatGlobalInstallSummary = (summary) => {
33279
33925
  const isUpdate = summary.previousVersion !== null && summary.previousVersion !== summary.version;
33280
33926
  const isRerun = summary.previousVersion !== null && summary.previousVersion === summary.version;
@@ -33326,6 +33972,7 @@ var formatGlobalInstallSummary = (summary) => {
33326
33972
  lines.push(` failed to register: ${summary.mcpFailed.join(", ")}`);
33327
33973
  }
33328
33974
  }
33975
+ lines.push(...codexMcpLines(summary.codexMcp));
33329
33976
  if (skillsEmpty) {
33330
33977
  lines.push("");
33331
33978
  } else {
@@ -33371,7 +34018,7 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
33371
34018
  }
33372
34019
  }
33373
34020
  const paths = globalInstallPaths();
33374
- const agentSettings = Schema31.decodeUnknownSync(AgentInstallationSettings)({
34021
+ const agentSettings = Schema32.decodeUnknownSync(AgentInstallationSettings)({
33375
34022
  homeDirectory: homedir15(),
33376
34023
  claudeDirectory: paths.configDir,
33377
34024
  codexDirectory: process39.env.CODEX_HOME || join72(homedir15(), ".codex"),
@@ -33392,8 +34039,11 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
33392
34039
  env: process39.env,
33393
34040
  forceRefresh: isRerun
33394
34041
  });
34042
+ const codexMcp = await Effect46.runPromise(
34043
+ installCodexMcp({ codex: makeExec("codex"), environment: process39.env, forceRefresh: isRerun })
34044
+ );
33395
34045
  const awareness = await installAwareness(paths);
33396
- const agentInstallations = await Effect45.runPromise(
34046
+ const agentInstallations = await Effect46.runPromise(
33397
34047
  installAgentGuidance(agentSettings, detectedAgents, paths.skillsDir, skills.installed, version)
33398
34048
  );
33399
34049
  process39.stdout.write(
@@ -33421,13 +34071,14 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
33421
34071
  mcpNeedsKey: mcp.needsKey,
33422
34072
  mcpFailed: mcp.failed,
33423
34073
  claudeMissing: mcp.claudeMissing,
34074
+ codexMcp,
33424
34075
  commandInstalled: awareness.commandWritten,
33425
34076
  version,
33426
34077
  previousVersion: previous?.version ?? null
33427
34078
  };
33428
- if (!globalSetupComplete(postStatus.skillCount > 0 && usableAgent, mcp)) {
34079
+ if (!globalSetupComplete(postStatus.skillCount > 0 && usableAgent, mcp, codexMcp)) {
33429
34080
  process39.stderr.write(
33430
- "VybeKiit setup is incomplete: the managed files or an available Claude Code connection could not be prepared.\n"
34081
+ "VybeKiit setup is incomplete: the managed files or the VybeKiit connection in Claude Code or Codex could not be prepared.\n"
33431
34082
  );
33432
34083
  return 1;
33433
34084
  }
@@ -33569,6 +34220,10 @@ var playWelcomeBanner = async (options = {}) => {
33569
34220
  };
33570
34221
 
33571
34222
  // src/commands/setupAuthentication.ts
34223
+ var DESKTOP_MACHINE = {
34224
+ canOpenBrowser: canOpenDesktopBrowser,
34225
+ hasTerminal: isInteractive
34226
+ };
33572
34227
  var AUTH_PROBE_TIMEOUT_MILLISECONDS = 6e4;
33573
34228
  var defaultSetupCommandRunner = (command, args, interactive) => runProcess(
33574
34229
  command,
@@ -33576,19 +34231,26 @@ var defaultSetupCommandRunner = (command, args, interactive) => runProcess(
33576
34231
  interactive ? { stdio: "inherit" } : { timeout: AUTH_PROBE_TIMEOUT_MILLISECONDS }
33577
34232
  );
33578
34233
  var needsSignIn = (tool, loginHint) => ({
33579
- connected: false,
34234
+ status: "needsSignIn",
33580
34235
  line: `\u2717 ${tool.name} needs sign-in. Run: ${loginHint}`
33581
34236
  });
33582
- var connectTool = async (tool, run, canOpenBrowser) => {
34237
+ var connectTool = async (tool, run, machine) => {
33583
34238
  const { auth } = tool;
33584
34239
  if (auth === void 0) {
33585
- return { connected: true, line: `\u2713 ${tool.name} is ready.` };
34240
+ return { status: "connected", line: `\u2713 ${tool.name} is ready.` };
33586
34241
  }
33587
34242
  const existingSignIn = await run(auth.command, auth.args, false);
33588
34243
  if (isSignedIn2(auth, existingSignIn)) {
33589
- return { connected: true, line: `\u2713 ${tool.name} reused your existing sign-in.` };
34244
+ return { status: "connected", line: `\u2713 ${tool.name} reused your existing sign-in.` };
33590
34245
  }
33591
- if (auth.signIn === void 0 || !canOpenBrowser()) {
34246
+ const signInWaitsForTerminal = auth.signIn?.needsTerminal === true && !machine.hasTerminal();
34247
+ if (signInWaitsForTerminal) {
34248
+ return {
34249
+ status: "later",
34250
+ line: `\u2192 ${tool.name} sign-in waits until your app needs it, because it asks for a code typed in a terminal. Then run: ${auth.loginHint}`
34251
+ };
34252
+ }
34253
+ if (auth.signIn === void 0 || !machine.canOpenBrowser()) {
33592
34254
  return needsSignIn(tool, auth.loginHint);
33593
34255
  }
33594
34256
  process.stdout.write(`
@@ -33599,22 +34261,22 @@ Opening the ${tool.name} sign-in page in your browser...
33599
34261
  return needsSignIn(tool, auth.loginHint);
33600
34262
  }
33601
34263
  const verifiedSignIn = await run(auth.command, auth.args, false);
33602
- return isSignedIn2(auth, verifiedSignIn) ? { connected: true, line: `\u2713 ${tool.name} sign-in verified.` } : needsSignIn(tool, auth.loginHint);
34264
+ return isSignedIn2(auth, verifiedSignIn) ? { status: "connected", line: `\u2713 ${tool.name} sign-in verified.` } : needsSignIn(tool, auth.loginHint);
33603
34265
  };
33604
- var connectSetupServices = async (preferences, withoutGithub, run = defaultSetupCommandRunner, canOpenBrowser = canOpenDesktopBrowser) => {
34266
+ var connectSetupServices = async (preferences, withoutGithub, run = defaultSetupCommandRunner, machine = DESKTOP_MACHINE) => {
33605
34267
  const selectedTools = selectToolchain(setupEnvironment(preferences), {
33606
34268
  wantsGoogleAuth: preferences.googleSignIn,
33607
34269
  withoutGithub
33608
34270
  });
33609
34271
  const attempts = await selectedTools.reduce(async (earlierAttempts, tool) => {
33610
34272
  const finishedAttempts = await earlierAttempts;
33611
- const connection = await connectTool(tool, run, canOpenBrowser);
34273
+ const connection = await connectTool(tool, run, machine);
33612
34274
  return [...finishedAttempts, { tool, connection }];
33613
34275
  }, Promise.resolve([]));
33614
34276
  return {
33615
- ok: attempts.every(({ connection }) => connection.connected),
33616
- connected: attempts.filter(({ connection }) => connection.connected).map(({ tool }) => tool.name),
33617
- needsAttention: attempts.filter(({ connection }) => !connection.connected).map(({ tool }) => tool.name),
34277
+ ok: attempts.every(({ connection }) => connection.status !== "needsSignIn"),
34278
+ connected: attempts.filter(({ connection }) => connection.status === "connected").map(({ tool }) => tool.name),
34279
+ needsAttention: attempts.filter(({ connection }) => connection.status === "needsSignIn").map(({ tool }) => tool.name),
33618
34280
  lines: attempts.map(({ connection }) => connection.line)
33619
34281
  };
33620
34282
  };
@@ -33977,8 +34639,9 @@ import { confirm as confirm5, isCancel as isCancel7 } from "@clack/prompts";
33977
34639
  // src/lib/kitUpdateInspection.ts
33978
34640
  import { readFile as readFile39 } from "fs/promises";
33979
34641
  import { join as join75 } from "path";
33980
- import { Schema as Schema32 } from "effect";
34642
+ import { Schema as Schema33 } from "effect";
33981
34643
  var WORKSPACE_SUPPORT_PATHS = [
34644
+ "biome.json",
33982
34645
  "tsconfig.base.json",
33983
34646
  "tsup.base.ts",
33984
34647
  "scripts/lib/packageExportEntries.mjs",
@@ -33986,10 +34649,10 @@ var WORKSPACE_SUPPORT_PATHS = [
33986
34649
  "scripts/lib/tsupWorkspaceAliases.d.mts",
33987
34650
  "scripts/lib/repoRoot.mjs"
33988
34651
  ];
33989
- var KitSourcePackage = Schema32.Struct({ version: Schema32.String });
34652
+ var KitSourcePackage = Schema33.Struct({ version: Schema33.String });
33990
34653
  var packageVersion = async (packagePath) => {
33991
34654
  const packageText = await readFile39(packagePath, "utf8");
33992
- const kitPackage = await Schema32.decodeUnknownPromise(KitSourcePackage)(JSON.parse(packageText));
34655
+ const kitPackage = await Schema33.decodeUnknownPromise(KitSourcePackage)(JSON.parse(packageText));
33993
34656
  return kitPackage.version;
33994
34657
  };
33995
34658
  var packageRootFromManifestPath = (workspacePath) => {
@@ -34174,8 +34837,21 @@ var restoreBuyerPaths = async (projectRoot, backupRoot, buyerPaths) => {
34174
34837
  })
34175
34838
  );
34176
34839
  };
34840
+ var changedHookSettingsFor = (inspection) => AGENT_HOOK_SETTINGS_FILES.filter(
34841
+ ([settingsFolder, settingsFile]) => inspection.changedMaintainedPaths.includes(
34842
+ `templates/${inspection.manifest.surface}/${settingsFolder}/${settingsFile}`
34843
+ )
34844
+ );
34177
34845
  var applyVerifiedPreview = async (projectRoot, previewRoot, backupRoot, inspection) => {
34178
- const protectedPaths = [...inspection.changedMaintainedPaths, KIT_WORKSPACE_MANIFEST_PATH];
34846
+ const changedHookSettings = changedHookSettingsFor(inspection);
34847
+ const workspaceHookSettingsPaths = changedHookSettings.map(
34848
+ ([settingsFolder, settingsFile]) => `${settingsFolder}/${settingsFile}`
34849
+ );
34850
+ const protectedPaths = [
34851
+ ...inspection.changedMaintainedPaths,
34852
+ KIT_WORKSPACE_MANIFEST_PATH,
34853
+ ...workspaceHookSettingsPaths
34854
+ ];
34179
34855
  await rm6(backupRoot, { recursive: true, force: true });
34180
34856
  await mkdir23(backupRoot, { recursive: true });
34181
34857
  const buyerPaths = await Promise.all(
@@ -34190,6 +34866,11 @@ var applyVerifiedPreview = async (projectRoot, previewRoot, backupRoot, inspecti
34190
34866
  )
34191
34867
  );
34192
34868
  await overlayMaintainedPaths(previewRoot, projectRoot, inspection.changedMaintainedPaths).then(async () => {
34869
+ await Promise.all(
34870
+ changedHookSettings.map(
34871
+ (settingsPath) => writeWorkspaceHookSettings(projectRoot, inspection.manifest.surface, settingsPath)
34872
+ )
34873
+ );
34193
34874
  await writeKitWorkspaceManifest({
34194
34875
  projectRoot,
34195
34876
  kitVersion: inspection.plan.targetVersion,
@@ -34424,11 +35105,12 @@ import { homedir as homedir17 } from "os";
34424
35105
  import { join as join77, resolve as resolve24 } from "path";
34425
35106
  import process46 from "process";
34426
35107
  import { confirm as confirm6, isCancel as isCancel8 } from "@clack/prompts";
34427
- import { Cause, Data as Data14, Effect as Effect46, Either as Either13, Exit, Option as Option4, Schema as Schema33 } from "effect";
34428
- var GlobalUninstallError = class extends Data14.TaggedError("GlobalUninstallError") {
35108
+ import { Cause, Data as Data15, Effect as Effect47, Either as Either13, Exit, Option as Option4, Schema as Schema34 } from "effect";
35109
+ var GlobalUninstallError = class extends Data15.TaggedError("GlobalUninstallError") {
34429
35110
  };
34430
35111
  var REMOVAL_GROUPS = {
34431
35112
  mcp: "Claude Code tool connections",
35113
+ codexMcp: "Codex tool connections",
34432
35114
  skillLinks: "Skill links for your other coding assistants",
34433
35115
  skills: "Skills",
34434
35116
  instructions: "VybeKiit instructions in your coding assistants",
@@ -34445,32 +35127,37 @@ var mcpRemoval = (name) => ({
34445
35127
  group: REMOVAL_GROUPS.mcp,
34446
35128
  name
34447
35129
  });
35130
+ var codexMcpRemoval = (name) => ({
35131
+ kind: "codexMcp",
35132
+ group: REMOVAL_GROUPS.codexMcp,
35133
+ name
35134
+ });
34448
35135
  var uninstallPlan = (removals, keptNotes = [], repairNotes = []) => ({ removals, keptNotes, repairNotes });
34449
35136
  var combinedPlan = (plans) => uninstallPlan(
34450
35137
  plans.flatMap((plan) => plan.removals),
34451
35138
  plans.flatMap((plan) => plan.keptNotes),
34452
35139
  plans.flatMap((plan) => plan.repairNotes)
34453
35140
  );
34454
- var readOptionalText2 = (path) => Effect46.tryPromise({
35141
+ var readOptionalText2 = (path) => Effect47.tryPromise({
34455
35142
  try: async () => existsSync22(path) ? Option4.some(await readFile40(path, "utf8")) : Option4.none(),
34456
35143
  catch: (cause) => new GlobalUninstallError({ message: `Could not read ${path}.`, cause })
34457
35144
  });
34458
- var readDirectoryNames = (directory) => Effect46.tryPromise({
35145
+ var readDirectoryNames = (directory) => Effect47.tryPromise({
34459
35146
  try: async () => existsSync22(directory) ? await readdir16(directory) : [],
34460
35147
  catch: (cause) => new GlobalUninstallError({ message: `Could not read ${directory}.`, cause })
34461
35148
  });
34462
- var planMcpRemovals = (claude) => Effect46.gen(function* () {
34463
- const claudeVersion = yield* Effect46.promise(() => claude(["--version"]));
35149
+ var planMcpRemovals = (claude) => Effect47.gen(function* () {
35150
+ const claudeVersion = yield* Effect47.promise(() => claude(["--version"]));
34464
35151
  if (claudeVersion.code === 127) {
34465
35152
  return uninstallPlan(
34466
35153
  [],
34467
35154
  ["Claude Code tool connections, because Claude Code is not installed."]
34468
35155
  );
34469
35156
  }
34470
- const registrations = yield* Effect46.all(
35157
+ const registrations = yield* Effect47.all(
34471
35158
  GLOBAL_MCP_SERVERS.map(
34472
- (mcpServer) => Effect46.promise(() => claude(["mcp", "get", mcpServer.name])).pipe(
34473
- Effect46.map((registeredServer) => ({
35159
+ (mcpServer) => Effect47.promise(() => claude(["mcp", "get", mcpServer.name])).pipe(
35160
+ Effect47.map((registeredServer) => ({
34474
35161
  name: mcpServer.name,
34475
35162
  owner: registeredServer.code === 0 ? mcpRegistrationOwner(mcpServer, registeredServer.stdout) : "absent"
34476
35163
  }))
@@ -34483,11 +35170,34 @@ var planMcpRemovals = (claude) => Effect46.gen(function* () {
34483
35170
  registrations.filter((registration) => registration.owner === "user").map((registration) => `Your own ${registration.name} tool connection in Claude Code.`)
34484
35171
  );
34485
35172
  });
34486
- var planSkillLinkRemovals = (skillLinksDirectory, claudeSkillsDirectory, managedSkills) => Effect46.gen(function* () {
35173
+ var planCodexMcpRemovals = (codex) => Effect47.gen(function* () {
35174
+ if (!(yield* codexInstalled(codex))) {
35175
+ return uninstallPlan([]);
35176
+ }
35177
+ const registrations = yield* Effect47.either(listCodexMcpRegistrations(codex));
35178
+ if (Either13.isLeft(registrations)) {
35179
+ return uninstallPlan(
35180
+ [],
35181
+ [],
35182
+ [
35183
+ `${registrations.left.message} Run \`codex mcp list\` and remove the VybeKiit ones with \`codex mcp remove <name>\`.`
35184
+ ]
35185
+ );
35186
+ }
35187
+ const owners = CODEX_MCP_SERVERS.map((mcpServer) => ({
35188
+ name: mcpServer.name,
35189
+ owner: codexMcpOwner(mcpServer, registrations.right)
35190
+ }));
35191
+ return uninstallPlan(
35192
+ owners.filter((registration) => registration.owner === "vybekiit").map((registration) => codexMcpRemoval(registration.name)),
35193
+ owners.filter((registration) => registration.owner === "user").map((registration) => `Your own ${registration.name} tool connection in Codex.`)
35194
+ );
35195
+ });
35196
+ var planSkillLinkRemovals = (skillLinksDirectory, claudeSkillsDirectory, managedSkills) => Effect47.gen(function* () {
34487
35197
  const linkedSkillNames = yield* readDirectoryNames(skillLinksDirectory);
34488
- const managedLinks = yield* Effect46.all(
35198
+ const managedLinks = yield* Effect47.all(
34489
35199
  linkedSkillNames.filter((skillName) => managedSkills.includes(skillName)).map(
34490
- (skillName) => Effect46.tryPromise({
35200
+ (skillName) => Effect47.tryPromise({
34491
35201
  try: async () => {
34492
35202
  const skillLink = join77(skillLinksDirectory, skillName);
34493
35203
  if (!(await lstat5(skillLink)).isSymbolicLink()) {
@@ -34508,13 +35218,13 @@ var planSkillLinkRemovals = (skillLinksDirectory, claudeSkillsDirectory, managed
34508
35218
  managedLinks.flatMap(Option4.toArray).map((skillLink) => pathRemoval(REMOVAL_GROUPS.skillLinks, skillLink))
34509
35219
  );
34510
35220
  });
34511
- var planInstructionRemoval = (instructionPath) => Effect46.gen(function* () {
35221
+ var planInstructionRemoval = (instructionPath) => Effect47.gen(function* () {
34512
35222
  const installedInstruction = yield* readOptionalText2(instructionPath);
34513
35223
  if (Option4.isNone(installedInstruction)) {
34514
35224
  return uninstallPlan([]);
34515
35225
  }
34516
- const userInstruction = yield* Effect46.either(
34517
- Effect46.try(() => removeAgentInstruction(installedInstruction.value))
35226
+ const userInstruction = yield* Effect47.either(
35227
+ Effect47.try(() => removeAgentInstruction(installedInstruction.value))
34518
35228
  );
34519
35229
  if (Either13.isLeft(userInstruction)) {
34520
35230
  return uninstallPlan(
@@ -34548,7 +35258,7 @@ var planInstructionRemoval = (instructionPath) => Effect46.gen(function* () {
34548
35258
  pathRemoval(REMOVAL_GROUPS.instructionBackups, backupPath)
34549
35259
  ]);
34550
35260
  });
34551
- var planStatusLineRemoval = (settingsFile) => Effect46.gen(function* () {
35261
+ var planStatusLineRemoval = (settingsFile) => Effect47.gen(function* () {
34552
35262
  const claudeSettingsText = yield* readOptionalText2(settingsFile);
34553
35263
  if (Option4.isNone(claudeSettingsText)) {
34554
35264
  return uninstallPlan([]);
@@ -34573,7 +35283,7 @@ var planStatusLineRemoval = (settingsFile) => Effect46.gen(function* () {
34573
35283
  }
34574
35284
  return uninstallPlan([]);
34575
35285
  });
34576
- var planGuideRemoval = (guideDirectory) => Effect46.gen(function* () {
35286
+ var planGuideRemoval = (guideDirectory) => Effect47.gen(function* () {
34577
35287
  const guideEntries = yield* readDirectoryNames(guideDirectory);
34578
35288
  const otherEntries = guideEntries.filter((fileName) => !GUIDE_FILES.includes(fileName));
34579
35289
  const guideRemovals = guideEntries.filter((fileName) => GUIDE_FILES.includes(fileName)).map((fileName) => pathRemoval(REMOVAL_GROUPS.guide, join77(guideDirectory, fileName)));
@@ -34590,25 +35300,26 @@ var planGuideRemoval = (guideDirectory) => Effect46.gen(function* () {
34590
35300
  { kind: "emptyDirectory", group: REMOVAL_GROUPS.guide, path: guideDirectory }
34591
35301
  ]);
34592
35302
  });
34593
- var planInstallStampRemoval = (claudeDirectory) => Effect46.gen(function* () {
34594
- const previousSetup = yield* Effect46.promise(() => readInstallState(claudeDirectory));
35303
+ var planInstallStampRemoval = (claudeDirectory) => Effect47.gen(function* () {
35304
+ const previousSetup = yield* Effect47.promise(() => readInstallState(claudeDirectory));
34595
35305
  const installStampPath = installStatePath(claudeDirectory);
34596
35306
  const firstAppPath2 = previousSetup?.firstAppPath ?? "";
34597
35307
  const appNotes = firstAppPath2 === "" ? [] : [`Your app at ${firstAppPath2}. Delete that folder yourself if you no longer want it.`];
34598
35308
  const installStampRemovals = existsSync22(installStampPath) ? [pathRemoval(REMOVAL_GROUPS.installStamp, installStampPath)] : [];
34599
35309
  return uninstallPlan(installStampRemovals, appNotes);
34600
35310
  });
34601
- var planGlobalUninstall = (settings, claude) => Effect46.gen(function* () {
35311
+ var planGlobalUninstall = (settings, assistantCommands) => Effect47.gen(function* () {
34602
35312
  const paths = globalInstallPaths(settings.claudeDirectory);
34603
- const managedSkills = yield* Effect46.promise(() => listManagedSkillNames(paths.skillsDir));
35313
+ const managedSkills = yield* Effect47.promise(() => listManagedSkillNames(paths.skillsDir));
34604
35314
  const commandPath = join77(paths.commandsDir, "vybekiit.md");
34605
- const mcpPlan = yield* planMcpRemovals(claude);
34606
- const skillLinkPlans = yield* Effect46.all(
35315
+ const mcpPlan = yield* planMcpRemovals(assistantCommands.claude);
35316
+ const codexMcpPlan = yield* planCodexMcpRemovals(assistantCommands.codex);
35317
+ const skillLinkPlans = yield* Effect47.all(
34607
35318
  agentSkillLinkDirectories(settings).map(
34608
35319
  (directory) => planSkillLinkRemovals(directory, paths.skillsDir, managedSkills)
34609
35320
  )
34610
35321
  );
34611
- const instructionPlans = yield* Effect46.all(
35322
+ const instructionPlans = yield* Effect47.all(
34612
35323
  agentInstructionPaths(settings).map(planInstructionRemoval)
34613
35324
  );
34614
35325
  const statusLinePlan = yield* planStatusLineRemoval(paths.settingsFile);
@@ -34616,6 +35327,7 @@ var planGlobalUninstall = (settings, claude) => Effect46.gen(function* () {
34616
35327
  const installStampPlan = yield* planInstallStampRemoval(paths.configDir);
34617
35328
  return combinedPlan([
34618
35329
  mcpPlan,
35330
+ codexMcpPlan,
34619
35331
  ...skillLinkPlans,
34620
35332
  uninstallPlan(
34621
35333
  managedSkills.map(
@@ -34631,11 +35343,23 @@ var planGlobalUninstall = (settings, claude) => Effect46.gen(function* () {
34631
35343
  installStampPlan
34632
35344
  ]);
34633
35345
  });
34634
- var applyRemoval = (removal, claude) => {
35346
+ var applyRemoval = (removal, assistantCommands) => {
35347
+ if (removal.kind === "codexMcp") {
35348
+ return Effect47.promise(() => assistantCommands.codex(["mcp", "remove", removal.name])).pipe(
35349
+ Effect47.flatMap(
35350
+ (codexRemoval) => codexRemoval.code === 0 ? Effect47.void : Effect47.fail(
35351
+ new GlobalUninstallError({
35352
+ message: `Could not remove the ${removal.name} tool connection from Codex.`
35353
+ })
35354
+ )
35355
+ )
35356
+ );
35357
+ }
34635
35358
  if (removal.kind === "mcp") {
34636
- return Effect46.promise(() => claude(["mcp", "remove", "-s", "user", removal.name])).pipe(
34637
- Effect46.flatMap(
34638
- (mcpRemoval2) => mcpRemoval2.code === 0 ? Effect46.void : Effect46.fail(
35359
+ const claudeRemoval = ["mcp", "remove", "-s", "user", removal.name];
35360
+ return Effect47.promise(() => assistantCommands.claude(claudeRemoval)).pipe(
35361
+ Effect47.flatMap(
35362
+ (mcpRemoval2) => mcpRemoval2.code === 0 ? Effect47.void : Effect47.fail(
34639
35363
  new GlobalUninstallError({
34640
35364
  message: `Could not remove the ${removal.name} tool connection from Claude Code.`
34641
35365
  })
@@ -34643,7 +35367,7 @@ var applyRemoval = (removal, claude) => {
34643
35367
  )
34644
35368
  );
34645
35369
  }
34646
- return Effect46.tryPromise({
35370
+ return Effect47.tryPromise({
34647
35371
  try: async () => {
34648
35372
  if (removal.kind === "rewrite") {
34649
35373
  await writeFile29(removal.path, removal.remainingText, "utf8");
@@ -34658,33 +35382,35 @@ var applyRemoval = (removal, claude) => {
34658
35382
  catch: (cause) => new GlobalUninstallError({ message: `Could not remove ${removal.path}.`, cause })
34659
35383
  });
34660
35384
  };
34661
- var applyGlobalUninstall = (plan, claude) => Effect46.all(plan.removals.map((removal) => Effect46.either(applyRemoval(removal, claude)))).pipe(
34662
- Effect46.map(
35385
+ var applyGlobalUninstall = (plan, assistantCommands) => Effect47.all(
35386
+ plan.removals.map((removal) => Effect47.either(applyRemoval(removal, assistantCommands)))
35387
+ ).pipe(
35388
+ Effect47.map(
34663
35389
  (attempts) => attempts.flatMap((attempt) => Either13.isLeft(attempt) ? [attempt.left.message] : [])
34664
35390
  )
34665
35391
  );
34666
- var removalSubject = (removal) => removal.kind === "mcp" ? removal.name : removal.path;
35392
+ var removalSubject = (removal) => removal.kind === "mcp" || removal.kind === "codexMcp" ? removal.name : removal.path;
34667
35393
  var formatUninstallPlan = (plan) => [...new Set(plan.removals.map((removal) => removal.group))].map((group) => {
34668
35394
  const subjects = plan.removals.filter((removal) => removal.group === group).map(removalSubject);
34669
35395
  const listedSubjects = subjects.length <= 3 ? `: ${subjects.join(", ")}` : "";
34670
35396
  return ` \u2022 ${group} (${subjects.length})${listedSubjects}`;
34671
35397
  });
34672
35398
  var noteLines = (heading, notes) => notes.length === 0 ? [] : [heading, ...notes.map((note) => ` \u2022 ${note}`)];
34673
- var printLines = (lines) => Effect46.sync(() => process46.stdout.write(`${lines.join("\n")}
35399
+ var printLines = (lines) => Effect47.sync(() => process46.stdout.write(`${lines.join("\n")}
34674
35400
  `));
34675
- var runGlobalUninstall = async (commandArguments, interactiveTerminal, claude = makeExec("claude")) => {
35401
+ var runGlobalUninstall = async (commandArguments, interactiveTerminal, assistantCommands = { claude: makeExec("claude"), codex: makeExec("codex") }) => {
34676
35402
  const confirmedUpfront = commandArguments.includes("--yes") || commandArguments.includes("-y");
34677
35403
  const dryRun = commandArguments.includes("--dry-run");
34678
35404
  const paths = globalInstallPaths();
34679
- const settings = Schema33.decodeUnknownSync(AgentInstallationSettings)({
35405
+ const settings = Schema34.decodeUnknownSync(AgentInstallationSettings)({
34680
35406
  homeDirectory: homedir17(),
34681
35407
  claudeDirectory: paths.configDir,
34682
35408
  codexDirectory: process46.env.CODEX_HOME || join77(homedir17(), ".codex"),
34683
35409
  executablePath: "",
34684
35410
  plainLanguageGuide: paths.bundledLanguageGuide
34685
35411
  });
34686
- const uninstallProgram = Effect46.gen(function* () {
34687
- const plan = yield* planGlobalUninstall(settings, claude);
35412
+ const uninstallProgram = Effect47.gen(function* () {
35413
+ const plan = yield* planGlobalUninstall(settings, assistantCommands);
34688
35414
  const keptLines = noteLines("Not removed:", plan.keptNotes);
34689
35415
  const repairLines = noteLines("Needs your attention:", plan.repairNotes);
34690
35416
  const needsRepair = plan.repairNotes.length > 0;
@@ -34708,7 +35434,7 @@ var runGlobalUninstall = async (commandArguments, interactiveTerminal, claude =
34708
35434
  return 0;
34709
35435
  }
34710
35436
  if (!confirmedUpfront) {
34711
- const removalApproved = yield* Effect46.promise(
35437
+ const removalApproved = yield* Effect47.promise(
34712
35438
  () => confirm6({ message: "Remove VybeKiit from this computer?", initialValue: false })
34713
35439
  );
34714
35440
  if (isCancel8(removalApproved) || removalApproved !== true) {
@@ -34716,7 +35442,7 @@ var runGlobalUninstall = async (commandArguments, interactiveTerminal, claude =
34716
35442
  return 0;
34717
35443
  }
34718
35444
  }
34719
- const failures = yield* applyGlobalUninstall(plan, claude);
35445
+ const failures = yield* applyGlobalUninstall(plan, assistantCommands);
34720
35446
  const headline = failures.length === 0 ? "\u2705 VybeKiit was removed from this computer." : "\u2717 VybeKiit was only partly removed.";
34721
35447
  yield* printLines([
34722
35448
  headline,
@@ -34729,7 +35455,7 @@ var runGlobalUninstall = async (commandArguments, interactiveTerminal, claude =
34729
35455
  ]);
34730
35456
  return failures.length > 0 || needsRepair ? 1 : 0;
34731
35457
  });
34732
- const uninstallExit = await Effect46.runPromiseExit(uninstallProgram);
35458
+ const uninstallExit = await Effect47.runPromiseExit(uninstallProgram);
34733
35459
  if (Exit.isSuccess(uninstallExit)) {
34734
35460
  return uninstallExit.value;
34735
35461
  }