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
@@ -0,0 +1,386 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # dependencies = [
4
+ # "pymongo>=4.6.0",
5
+ # ]
6
+ # ///
7
+
8
+ # MongoDB Search Quickstart — Complete Script
9
+ # ─────────────────────────────────────────────────────────────
10
+ # Written for the Atlas `sample_mflix.movies` sample collection. The
11
+ # schema is hard-coded throughout: the `plot`, `genres`, and `title`
12
+ # fields, the index definitions, and the sample query text.
13
+ #
14
+ # The connection string comes from the environment: set MONGODB_URI, or
15
+ # MDB_MCP_CONNECTION_STRING, which the MongoDB MCP server already uses.
16
+ #
17
+ # To run against your own data, change the two values below AND
18
+ # update the index definitions, `$project` stages, and query strings
19
+ # to match your own field names.
20
+
21
+ DB_NAME = "sample_mflix"
22
+ COLLECTION_NAME = "movies"
23
+
24
+ # Index names. The walkthrough uses these defaults, but creates `<name>_2` when
25
+ # the default is already taken by an incompatible definition. If that happened,
26
+ # set the matching constant to the name it created, so this script reuses that
27
+ # index instead of stopping on the conflicting one.
28
+ SEMANTIC_INDEX_NAME = "quickstart_semantic"
29
+ TEXT_INDEX_NAME = "quickstart_text"
30
+ AUTOCOMPLETE_INDEX_NAME = "quickstart_autocomplete"
31
+
32
+ INDEX_WAIT_TIMEOUT_SECONDS = 600
33
+
34
+ # ─────────────────────────────────────────────────────────────
35
+
36
+ import os
37
+ import time
38
+ from pymongo import MongoClient
39
+ from pymongo.operations import SearchIndexModel
40
+
41
+ CONNECTION_STRING = (os.environ.get("MONGODB_URI")
42
+ or os.environ.get("MDB_MCP_CONNECTION_STRING"))
43
+
44
+ if not CONNECTION_STRING:
45
+ raise SystemExit("\n ERROR: no connection string. Set MONGODB_URI (or"
46
+ " MDB_MCP_CONNECTION_STRING) to your cluster's SRV"
47
+ " string, then rerun.")
48
+
49
+ client = MongoClient(CONNECTION_STRING)
50
+ db = client[DB_NAME]
51
+ collection = db[COLLECTION_NAME]
52
+
53
+ def fail(message):
54
+ print(f"\n ERROR: {message}")
55
+ client.close()
56
+ raise SystemExit(1)
57
+
58
+ def wait_for_index(name):
59
+ print(f" Waiting for index '{name}' to be ready...", end="", flush=True)
60
+ deadline = time.monotonic() + INDEX_WAIT_TIMEOUT_SECONDS
61
+ while True:
62
+ indexes = list(collection.list_search_indexes(name))
63
+ if not indexes:
64
+ fail(f"Index '{name}' does not exist.")
65
+ status = indexes[0].get("status")
66
+ if status == "READY":
67
+ print(" ready.")
68
+ return
69
+ if status == "STALE":
70
+ fail(f"Index '{name}' is stale because embedding sync is paused. "
71
+ "Free disk space, wait for READY, then rerun.")
72
+ if status == "FAILED":
73
+ fail(f"Index '{name}' failed to build. Check the tier index cap"
74
+ " (3 on Free, 10 on Flex) and the index definition.")
75
+ if time.monotonic() > deadline:
76
+ fail(f"Index '{name}' is still '{status}' after"
77
+ f" {INDEX_WAIT_TIMEOUT_SECONDS}s. Check its status in Atlas,"
78
+ " then rerun.")
79
+ print(".", end="", flush=True)
80
+ time.sleep(5)
81
+
82
+ def covers(expected, actual):
83
+ # True when `actual` contains everything `expected` asks for. Atlas adds
84
+ # its own defaults to a stored definition, so an exact match is too strict.
85
+ if isinstance(expected, dict):
86
+ # A field can be stored as a list of types (a multi-type field), which
87
+ # still satisfies a single expected type.
88
+ if isinstance(actual, list):
89
+ return any(covers(expected, candidate) for candidate in actual)
90
+ return (isinstance(actual, dict)
91
+ and all(k in actual and covers(v, actual[k])
92
+ for k, v in expected.items()))
93
+ if isinstance(expected, list):
94
+ return (isinstance(actual, list)
95
+ and all(any(covers(item, candidate) for candidate in actual)
96
+ for item in expected))
97
+ return expected == actual
98
+
99
+ def check_definition(name, expected):
100
+ indexes = list(collection.list_search_indexes(name))
101
+ if not indexes:
102
+ fail(f"Index '{name}' does not exist.")
103
+ actual = indexes[0].get("latestDefinition", {})
104
+ if not covers(expected, actual):
105
+ fail(f"An index named '{name}' already exists, but its definition does"
106
+ " not match the one this script needs, so the queries below would"
107
+ " fail. An index created by another route (for example the MCP"
108
+ " walkthrough) can omit fields this script queries. Drop"
109
+ f" '{name}' in Atlas and rerun, or point the matching"
110
+ " *_INDEX_NAME constant at the top of this script at a name that"
111
+ f" is free or already correct.\n Existing definition: {actual}")
112
+
113
+ def ensure_index(model, name, definition):
114
+ try:
115
+ collection.create_search_index(model)
116
+ except Exception as e:
117
+ if "already exists" not in str(e):
118
+ fail(f"Could not create index '{name}': {e}")
119
+ print(" Index already exists — checking its definition.")
120
+ check_definition(name, definition)
121
+ wait_for_index(name)
122
+
123
+ def print_results(results, fields=["title", "plot"]):
124
+ for i, doc in enumerate(results, 1):
125
+ print(f"\n {i}. {doc.get('title', 'N/A')}")
126
+ if "score" in doc:
127
+ print(f" Score: {round(doc['score'], 3)}")
128
+ if "plot" in fields and doc.get("plot"):
129
+ print(f" Plot: {doc['plot'][:120]}...")
130
+ if "genres" in doc:
131
+ print(f" Genres: {doc.get('genres', [])}")
132
+
133
+ # ─────────────────────────────────────────────────────────────
134
+ # 1. CREATE AUTO EMBEDDING INDEX (Semantic Search)
135
+ # ─────────────────────────────────────────────────────────────
136
+ print("\n── SEMANTIC SEARCH (Auto Embedding) ──────────────────")
137
+ print("Creating autoEmbed index on 'plot' field...")
138
+
139
+ semantic_definition = {
140
+ "fields": [
141
+ {
142
+ "type": "autoEmbed",
143
+ "modality": "text",
144
+ "path": "plot",
145
+ "model": "voyage-4"
146
+ },
147
+ {
148
+ "type": "filter",
149
+ "path": "genres"
150
+ }
151
+ ]
152
+ }
153
+
154
+ ensure_index(
155
+ SearchIndexModel(
156
+ definition=semantic_definition,
157
+ name=SEMANTIC_INDEX_NAME,
158
+ type="vectorSearch"
159
+ ),
160
+ SEMANTIC_INDEX_NAME,
161
+ semantic_definition
162
+ )
163
+
164
+ # Run semantic query
165
+ print("\nQuery: 'a story about growing up'")
166
+ results = list(collection.aggregate([
167
+ {
168
+ "$vectorSearch": {
169
+ "index": SEMANTIC_INDEX_NAME,
170
+ "path": "plot",
171
+ "query": "a story about growing up",
172
+ "numCandidates": 100,
173
+ "limit": 3
174
+ }
175
+ },
176
+ {
177
+ "$project": {
178
+ "_id": 0,
179
+ "title": 1,
180
+ "plot": 1,
181
+ "score": { "$meta": "vectorSearchScore" }
182
+ }
183
+ }
184
+ ]))
185
+ print_results(results)
186
+
187
+ # Run filtered semantic query
188
+ print("\nFiltered query: 'a story about growing up' + Drama only")
189
+ results = list(collection.aggregate([
190
+ {
191
+ "$vectorSearch": {
192
+ "index": SEMANTIC_INDEX_NAME,
193
+ "path": "plot",
194
+ "query": "a story about growing up",
195
+ "filter": { "genres": { "$eq": "Drama" } },
196
+ "numCandidates": 150,
197
+ "limit": 3
198
+ }
199
+ },
200
+ {
201
+ "$project": {
202
+ "_id": 0,
203
+ "title": 1,
204
+ "genres": 1,
205
+ "score": { "$meta": "vectorSearchScore" }
206
+ }
207
+ }
208
+ ]))
209
+ print_results(results, fields=["title", "genres"])
210
+
211
+ # ─────────────────────────────────────────────────────────────
212
+ # 2. CREATE TEXT SEARCH INDEX (Keyword Search)
213
+ # ─────────────────────────────────────────────────────────────
214
+ print("\n── KEYWORD SEARCH (Atlas Search) ─────────────────────")
215
+ print("Creating text search index on 'title', 'plot', 'genres'...")
216
+
217
+ text_definition = {
218
+ "mappings": {
219
+ "dynamic": False,
220
+ "fields": {
221
+ "title": { "type": "string" },
222
+ "plot": { "type": "string" },
223
+ "genres": { "type": "token" }
224
+ }
225
+ }
226
+ }
227
+
228
+ ensure_index(
229
+ SearchIndexModel(
230
+ definition=text_definition,
231
+ name=TEXT_INDEX_NAME
232
+ ),
233
+ TEXT_INDEX_NAME,
234
+ text_definition
235
+ )
236
+
237
+ # Run keyword query
238
+ print("\nKeyword query: 'space adventure'")
239
+ results = list(collection.aggregate([
240
+ {
241
+ "$search": {
242
+ "index": TEXT_INDEX_NAME,
243
+ "text": {
244
+ "query": "space adventure",
245
+ "path": ["title", "plot"]
246
+ }
247
+ }
248
+ },
249
+ {
250
+ "$project": {
251
+ "_id": 0,
252
+ "title": 1,
253
+ "plot": 1,
254
+ "score": { "$meta": "searchScore" }
255
+ }
256
+ },
257
+ { "$limit": 3 }
258
+ ]))
259
+ print_results(results)
260
+
261
+ # Run fuzzy query
262
+ print("\nFuzzy query: 'sapce adventre' (intentional typos)")
263
+ results = list(collection.aggregate([
264
+ {
265
+ "$search": {
266
+ "index": TEXT_INDEX_NAME,
267
+ "text": {
268
+ "query": "sapce adventre",
269
+ "path": ["title", "plot"],
270
+ "fuzzy": { "maxEdits": 1 }
271
+ }
272
+ }
273
+ },
274
+ {
275
+ "$project": {
276
+ "_id": 0,
277
+ "title": 1,
278
+ "score": { "$meta": "searchScore" }
279
+ }
280
+ },
281
+ { "$limit": 3 }
282
+ ]))
283
+ print_results(results, fields=["title"])
284
+
285
+ # Autocomplete needs 'title' typed as autocomplete, which the text index does
286
+ # not provide. Use a dedicated index, matching the walkthrough's MCP route.
287
+ print("\nCreating autocomplete index on 'title'...")
288
+
289
+ autocomplete_definition = {
290
+ "mappings": {
291
+ "dynamic": False,
292
+ "fields": {
293
+ "title": { "type": "autocomplete", "tokenization": "edgeGram" }
294
+ }
295
+ }
296
+ }
297
+
298
+ ensure_index(
299
+ SearchIndexModel(
300
+ definition=autocomplete_definition,
301
+ name=AUTOCOMPLETE_INDEX_NAME
302
+ ),
303
+ AUTOCOMPLETE_INDEX_NAME,
304
+ autocomplete_definition
305
+ )
306
+
307
+ # Run autocomplete
308
+ print("\nAutocomplete query: 'inc'")
309
+ results = list(collection.aggregate([
310
+ {
311
+ "$search": {
312
+ "index": AUTOCOMPLETE_INDEX_NAME,
313
+ "autocomplete": { "query": "inc", "path": "title" }
314
+ }
315
+ },
316
+ { "$project": { "_id": 0, "title": 1 } },
317
+ { "$limit": 5 }
318
+ ]))
319
+ for doc in results:
320
+ print(f" - {doc['title']}")
321
+
322
+ # ─────────────────────────────────────────────────────────────
323
+ # 3. HYBRID SEARCH ($rankFusion)
324
+ # ─────────────────────────────────────────────────────────────
325
+ print("\n── HYBRID SEARCH ($rankFusion) ───────────────────────")
326
+ print("Query: 'a story about growing up' (semantic 70% + keyword 30%)")
327
+
328
+ try:
329
+ results = list(collection.aggregate([
330
+ {
331
+ "$rankFusion": {
332
+ "input": {
333
+ "pipelines": {
334
+ "semanticPipeline": [
335
+ {
336
+ "$vectorSearch": {
337
+ "index": SEMANTIC_INDEX_NAME,
338
+ "path": "plot",
339
+ "query": "a story about growing up",
340
+ "numCandidates": 100,
341
+ "limit": 20
342
+ }
343
+ }
344
+ ],
345
+ "keywordPipeline": [
346
+ {
347
+ "$search": {
348
+ "index": TEXT_INDEX_NAME,
349
+ "text": {
350
+ "query": "coming of age",
351
+ "path": "plot"
352
+ }
353
+ }
354
+ },
355
+ { "$limit": 20 }
356
+ ]
357
+ }
358
+ },
359
+ "combination": {
360
+ "weights": {
361
+ "semanticPipeline": 0.7,
362
+ "keywordPipeline": 0.3
363
+ }
364
+ }
365
+ }
366
+ },
367
+ { "$project": { "_id": 0, "title": 1, "plot": 1 } },
368
+ { "$limit": 5 }
369
+ ]))
370
+ print_results(results)
371
+ except Exception as e:
372
+ message = str(e)
373
+ if "Unrecognized pipeline stage name: '$rankFusion'" in message:
374
+ print(" $rankFusion requires MongoDB 8.0+. This cluster does not"
375
+ " support it, so hybrid search was skipped.")
376
+ else:
377
+ fail(f"Hybrid search query failed: {message}")
378
+
379
+ print("\n── Done! ─────────────────────────────────────────────")
380
+ print("This script targets the sample_mflix.movies schema. To use your")
381
+ print("own data, set MONGODB_URI (or MDB_MCP_CONNECTION_STRING), then")
382
+ print("change DB_NAME and COLLECTION_NAME at the top and adjust the")
383
+ print("index definitions, $project stages, and query strings to match")
384
+ print("your own field names.")
385
+
386
+ client.close()
@@ -2,16 +2,17 @@
2
2
  name: neon
3
3
  description: >-
4
4
  Overview of Neon, a complete set of cloud backend primitives around Lakebase
5
- Postgres: Auth, Object Storage, Functions, and the AI Gateway. Start here to
5
+ Postgres: Auth, Object Storage, Functions, the AI Gateway, and Realtime. Start here to
6
6
  choose Neon for undecided login, files, APIs, and LLM calls, set up the CLI or
7
7
  MCP server, and follow the branch-first workflow. Use when building an app or
8
8
  backend on Neon, or when "Neon" or "Lakebase Postgres" is mentioned. Child
9
9
  skill neon-postgres wins for an existing DATABASE_URL, SQL, schema, inspect,
10
10
  or search. Child skill neon-auth wins for login, users, sessions, identity
11
- routing, and Managed Better Auth setup. Also use for object storage, S3, buckets, serverless functions,
12
- function triggers, cron, AI gateway, LLM calls, logs, Loki, Grafana,
13
- observability, postgres, database, backend, Claimable Neon, neon.new, or a
14
- no-signup database.
11
+ routing, and Managed Better Auth setup. Child skill neon-realtime wins for
12
+ live queries in reactive apps and agents. Also use for object storage, S3,
13
+ buckets, serverless functions, function triggers, cron, AI gateway, LLM calls,
14
+ realtime, logs, Loki, Grafana, observability,
15
+ postgres, database, backend, Claimable Neon, neon.new, or a no-signup database.
15
16
  metadata:
16
17
  source: https://github.com/neondatabase/agent-skills/tree/main/skills/neon
17
18
  disable-model-invocation: true
@@ -19,7 +20,7 @@ disable-model-invocation: true
19
20
 
20
21
  # Neon
21
22
 
22
- Neon is a complete set of cloud backend primitives around Lakebase Postgres, from Databricks — Lakebase Postgres, Auth (managed Better Auth), long-running Functions, Object Storage, and an AI Gateway, all instant, branchable, and serverless.
23
+ Neon is a complete set of cloud backend primitives around Lakebase Postgres, from Databricks — Lakebase Postgres, Auth (managed Better Auth), long-running Functions, Object Storage, an AI Gateway, and Realtime live queries, all instant, branchable, and serverless.
23
24
 
24
25
  **Lakebase Postgres** is the database itself. It is one product, reached two ways: through Neon, with a free plan and the full set of backend primitives above, or through Databricks, alongside the rest of the Databricks suite. Same infrastructure, same features, same engineering team. Call the database Lakebase Postgres, and use "Neon" for the brand and for this access path — not as a name for the database.
25
26
 
@@ -36,11 +37,12 @@ Neon bundles several backend primitives for building apps and agents that all br
36
37
  - **Object Storage** — S3-compatible object storage that branches with your projects.
37
38
  - **Functions** — Neon's compute offering: long-running serverless functions that run close to your database, for WebSocket servers, long agent HTTP streams, APIs, and server-sent event servers. A Function Trigger POSTs to a function on a cron.
38
39
  - **AI Gateway** — One API for frontier and open-source models, supporting the chat completions API and the responses API, powered by Databricks Unity AI Gateway.
40
+ - **Realtime** (beta) — Makes any SQL query live. Subscribe in realtime to Lakebase Postgres and build reactive apps and agents with type-safe live queries and optimistic mutations.
39
41
  - **Data API** — Optional PostgREST-compatible HTTP interface. Use it only when the app already uses PostgREST or a Supabase database client, or is migrating that client. New apps query Postgres from Functions or existing handlers. There is no `neon-data-api` skill; configuration is `dataApi` in `neon.ts` (see [Type-safe config](#type-safe-config-invalid-setups-dont-compile) when you have chosen it).
40
42
 
41
43
  ### Region availability
42
44
 
43
- Object Storage, Functions, and AI Gateway are currently available on projects in `aws-us-east-2`, `aws-us-east-1`, `aws-eu-central-1`, and `aws-ap-southeast-1`. Before guiding a user through any of these services, confirm they are working in one of these regions. If not, they will need to create a new project in a supported region.
45
+ Object Storage, Functions, AI Gateway, and Realtime are currently available on projects in `aws-us-east-2`, `aws-us-east-1`, `aws-eu-central-1`, and `aws-ap-southeast-1`. Before guiding a user through any of these services, confirm they are working in one of these regions. If not, they will need to create a new project in a supported region.
44
46
 
45
47
  ## Architecture: How to Use Neon
46
48
 
@@ -64,7 +66,7 @@ Functions have public HTTPS URLs. Verify a JWT or API key at the top of the hand
64
66
 
65
67
  Inspect the repo before provisioning.
66
68
 
67
- 1. Map requested capabilities: login, files, HTTP APIs, LLM calls, SQL.
69
+ 1. Map requested capabilities: login, files, HTTP APIs, LLM calls, live data, SQL.
68
70
  2. Reuse what is already there: a supplied `DATABASE_URL`, an existing ORM or driver, Better Auth, Clerk or another auth provider, S3 or another object store, an existing `.neon` / `neon.ts`, an existing Data API or PostgREST client.
69
71
  3. Select Neon primitives for capabilities that are still undecided.
70
72
  4. Provision only when infrastructure is missing: `neon init` / `neon link` / Claimable, then `neon.ts`, then `neon deploy`.
@@ -82,7 +84,8 @@ New projects are created in AWS regions. Prefer pooled `DATABASE_URL` for applic
82
84
  | Existing Better Auth, Clerk, Supabase Auth, or another working IdP | Keep it. `neon-auth` only if they ask to migrate |
83
85
  | User asked to migrate from Supabase Auth | `neon-auth` (Managed Better Auth; keep `SupabaseAuthAdapter()` call shapes) |
84
86
  | Files, uploads, blobs (no existing object store) | Object Storage |
85
- | HTTP APIs, cron, WebSocket, SSE, long-running agents | Functions querying Postgres |
87
+ | HTTP APIs, cron, custom WebSocket or SSE push, long-running agents | Functions querying Postgres |
88
+ | Live queries for realtime, reactive apps and agents; optimistic mutations | `neon-realtime` (`preview.realtime` in `neon.ts`). Not available on Claimable projects until claimed |
86
89
  | LLM calls | AI Gateway |
87
90
  | SQL, schema, inspect, search | `neon-postgres` |
88
91
  | Existing PostgREST / Supabase database client | Data API (`dataApi` in `neon.ts`) |
@@ -125,6 +128,7 @@ The skills below live in the [`neondatabase/agent-skills`](https://github.com/ne
125
128
  | `neon-object-storage` | Storing and serving files (uploads, images, blobs), including branching them with the database. |
126
129
  | `neon-functions` | Deploying long-running or streaming serverless functions — APIs, agents, SSE/WebSocket servers, and Function Triggers (cron and object-storage). |
127
130
  | `neon-ai-gateway` | Calling an LLM or routing across model providers with one credential, including discovering the branch's servable models at runtime via the OpenAI-compatible `/v1/models` endpoint. |
131
+ | `neon-realtime` | Realtime makes any SQL query live, for realtime, reactive apps and agents: enabling Realtime, sealing queries, React and TanStack DB bindings, SSR, and optimistic mutations. |
128
132
  | `neon-postgres-egress-optimizer` | Diagnosing or fixing excessive Postgres egress (network data-transfer) costs in a codebase. |
129
133
 
130
134
  There is no `neon-data-api` skill. Configure `dataApi` in `neon.ts` only for PostgREST / Supabase database-client compatibility or a migration that already depends on it.
@@ -328,7 +332,7 @@ export default defineConfig({
328
332
 
329
333
  ### Provision services with neon config
330
334
 
331
- Every project ships with Lakebase Postgres; `neon.ts` also declares Auth, Functions, buckets, and the AI Gateway. Data API is a compatibility toggle, not part of a default backend:
335
+ Every project ships with Lakebase Postgres; `neon.ts` also declares Auth, Functions, buckets, and the AI Gateway. Realtime is declared under `preview`. Data API is a compatibility toggle, not part of a default backend:
332
336
 
333
337
  ```typescript
334
338
  // neon.ts
@@ -337,6 +341,7 @@ export default defineConfig({
337
341
  functions: {},
338
342
  buckets: {},
339
343
  aiGateway: true, // see the neon-ai-gateway skill
344
+ preview: { realtime: true }, // see the neon-realtime skill
340
345
  });
341
346
  ```
342
347
 
@@ -38,6 +38,8 @@ export default defineConfig({
38
38
  neon claim create --service auth --service data-api --env-pull
39
39
  ```
40
40
 
41
+ The project is created in `aws-us-east-2` unless you pass `--region-id` (for example `neon claim create --region-id aws-eu-central-1`). Pick the region closest to where the app runs. A project's region cannot change after create.
42
+
41
43
  `neon claim create` reads `neon.ts` when it is present. It writes provisioned vars to an existing `.env`, otherwise `.env.local`, and gitignores that file. If `.env` or `.env.local` already has a `DATABASE_URL` (or other Neon-managed keys), pass `--file <path>` or `--no-env-pull`. The identity assertion is the pre-claim credential.
42
44
 
43
45
  Before claim, Postgres is always granted; Auth and the Data API are granted when requested. Functions, Object Storage, and AI Gateway come back with `granted: false` and `reason: "requires_claim"`. The CLI prints those as `denied_capabilities`. Report what you were given. Do not retry or strip them.
@@ -11,11 +11,10 @@ description: >-
11
11
  a cron or an object-storage event that POSTs to a function. Triggers include
12
12
  "serverless function", "deploy an API", "long-running function",
13
13
  "streaming agent", "SSE server", "WebSocket server", "webhook handler",
14
- "MCP server", "cron", "function trigger", "scheduled function", "cron job",
15
- "object storage trigger", "on upload", "run code next to my database",
16
- "function that won't time out", "function logs", "Neon Functions",
17
- "Neon Compute", "DDoS protection", "rate limiting", and
18
- "production hardening".
14
+ "MCP server", "cron", "scheduled function", "object storage trigger",
15
+ "on upload", "function that won't time out", "function logs",
16
+ "Neon Functions", "Neon Compute", "DDoS protection", "rate limiting", and
17
+ "production hardening". For live UIs over database rows, use neon-realtime.
19
18
  metadata:
20
19
  parent: neon
21
20
  source: https://github.com/neondatabase/agent-skills/tree/main/skills/neon-functions
@@ -453,13 +452,15 @@ beat.unref?.();
453
452
 
454
453
  The client skips these when handling messages. There is no protocol-level shortcut here: the standard `WebSocket` from `upgradeWebSocket` has no `ping()`, and a browser can't send ping frames from JavaScript, so an application-level message is the only keepalive a browser client can use. (A Node `ws` client can send ping frames, and the server auto-replies with a pong, but a browser can't.)
455
454
 
456
- ### Keeping clients in sync across isolates (do not skip this)
455
+ ### Fan-out across isolates (do not skip this)
457
456
 
458
457
  Under load the runtime runs **several isolates in parallel, each with its own copy of module state** — so each isolate has its own `clients` set. Broadcasting only to that local set means a client on isolate A never sees an event produced on isolate B, and the feed silently fractures. It's easy to miss: `neon dev` runs a single process (one isolate), so in-process broadcast always _looks_ fine locally but breaks in production, where concurrent connections spread across many isolates.
459
458
 
459
+ If the data is database rows (live dashboards, feeds, chat over stored messages), use Neon Realtime (the `neon-realtime` skill) instead of hand-rolling fan-out. Using Realtime does not prevent your database from scaling to zero. The strategies below are for push that doesn't come from database rows (presence, typing, LLM streams), and the fallback where Realtime isn't available, such as on Claimable projects until they're claimed.
460
+
460
461
  Module state doesn't survive eviction anyway, so **Postgres is the shared source of truth**. Pick a fan-out strategy. In every snippet below, `pool` is a pooled `pg` client and `clients` is this isolate's `Set` of live connections.
461
462
 
462
- **1. Poll Postgres — the default, and the only option that keeps Scale to Zero.** Each isolate re-reads the shared state (or rows past a cursor) on a short interval and pushes changes to its own clients. One query per isolate per tick (not per client), and none when the isolate has no clients — so an idle compute still suspends.
463
+ **1. Poll Postgres — the default, and it keeps Scale to Zero.** Each isolate re-reads the shared state (or rows past a cursor) on a short interval and pushes changes to its own clients. One query per isolate per tick (not per client), and none when the isolate has no clients — so an idle compute still suspends.
463
464
 
464
465
  ```typescript
465
466
  let lastId = "0"; // bigint id, so a string
@@ -496,7 +497,7 @@ pool
496
497
  .finally(() => setInterval(poll, 1000).unref?.());
497
498
  ```
498
499
 
499
- - **Latency:** up to the interval (~1s) — fine for counters, chat, and dashboards.
500
+ - **Latency:** up to the interval (~1s).
500
501
  - **Scaling:** database load grows with the number of live isolates, not clients. Keep the cursor on an indexed `serial`/`bigserial` PK and the interval sane.
501
502
  - **Scale to Zero:** ✅ preserved — polling stops when no clients are connected, so the compute suspends on its normal timer.
502
503
  - **Ordering:** `WHERE id > cursor` can skip a row that commits out of sequence: a transaction that took a lower id but commits after a higher one is already behind the cursor, so the poll never returns it. For a broadcast feed occasional loss is usually fine; when you need every row, use `LISTEN`/`NOTIFY` or poll by `created_at` with a small overlap window and dedupe by id.
@@ -540,7 +541,7 @@ function broadcast(event: unknown) {
540
541
 
541
542
  **3. External pub/sub (e.g. [Upstash](https://upstash.com) Redis) — best at scale.** For high fan-out, sub-second latency at large connection counts, or multi-region, publish/subscribe through a dedicated broker. Highest throughput, and it doesn't touch Postgres or block Scale to Zero — at the cost of another service to run.
542
543
 
543
- **Rule of thumb:** start with **polling** (works with Scale to Zero, no extra infra); switch to `LISTEN`/`NOTIFY` only on always-on compute that needs sub-second latency; move to Redis when fan-out outgrows Postgres.
544
+ **Rule of thumb:** for database rows, use **Neon Realtime**. Otherwise start with **polling** (works with Scale to Zero, no extra infra); switch to `LISTEN`/`NOTIFY` only on always-on compute that needs sub-second latency; move to Redis when fan-out outgrows Postgres.
544
545
 
545
546
  ### Client must reconnect
546
547
 
@@ -570,7 +571,7 @@ async function connect() {
570
571
  connect();
571
572
  ```
572
573
 
573
- Together — `upgradeWebSocket` inside `fetch`, JWT auth over `?token=`, cross-isolate fan-out, and client backoff — these compose into a complete realtime chat backend on a single function.
574
+ Together — `upgradeWebSocket` inside `fetch`, JWT auth over `?token=`, cross-isolate fan-out, and client backoff — these compose into a complete WebSocket backend on a single function, for push that doesn't come from database rows (presence, typing, LLM streams) or where Realtime isn't available. For persisted chat, feeds, and other live UIs over database rows, use Neon Realtime (the `neon-realtime` skill).
574
575
 
575
576
  ## Server-Sent Events (SSE)
576
577
 
@@ -606,7 +607,7 @@ export default {
606
607
  };
607
608
  ```
608
609
 
609
- The same rules as WebSockets apply. **Heartbeat:** a stream stays open only while bytes flow — Neon's window is 15 minutes ([Timeouts and Runtime Limits](#timeouts-and-runtime-limits)) but proxies are usually far stricter, so emit a `: ping\n\n` comment every ~25–30s (shown above) to keep idle streams from being dropped. Keep state in Postgres, and fan out across isolates using one of the [sync strategies](#keeping-clients-in-sync-across-isolates-do-not-skip-this) (hold a `Set` of stream controllers and `enqueue` to each). `EventSource` is GET-only and can't set headers, so authenticate with a `?token=` query param or cookie, exactly like the WebSocket case. [references/sse.md](https://neon.com/docs/ai/skills/neon-functions/references/sse.md) has the full pattern — Hono variant, cross-isolate fan-out, wire format, client, and caveats.
610
+ The same rules as WebSockets apply. **Heartbeat:** a stream stays open only while bytes flow — Neon's window is 15 minutes ([Timeouts and Runtime Limits](#timeouts-and-runtime-limits)) but proxies are usually far stricter, so emit a `: ping\n\n` comment every ~25–30s (shown above) to keep idle streams from being dropped. Keep state in Postgres, and fan out across isolates using one of the [fan-out strategies](#fan-out-across-isolates-do-not-skip-this) (hold a `Set` of stream controllers and `enqueue` to each). `EventSource` is GET-only and can't set headers, so authenticate with a `?token=` query param or cookie, exactly like the WebSocket case. [references/sse.md](https://neon.com/docs/ai/skills/neon-functions/references/sse.md) has the full pattern — Hono variant, cross-isolate fan-out, wire format, client, and caveats.
610
611
 
611
612
  ## Function Triggers
612
613
 
@@ -79,7 +79,7 @@ export default app;
79
79
 
80
80
  ## Push to every client, across isolates
81
81
 
82
- The fan-out rule is identical to WebSockets ([Keeping clients in sync across isolates](../SKILL.md#keeping-clients-in-sync-across-isolates-do-not-skip-this)): each isolate keeps its **own** set of open streams, so broadcasting in-process only reaches the clients on that isolate. Hold a `Set` of stream controllers and pick a strategy there — **poll Postgres** by default (keeps Scale to Zero), or `LISTEN`/`NOTIFY` (shown below) for lowest latency on always-on compute. Keep the source-of-truth state in Postgres — module state doesn't survive eviction.
82
+ If the data is database rows (live dashboards, feeds, chat over stored messages), use Neon Realtime (the `neon-realtime` skill) instead of hand-rolling fan-out. Otherwise, the fan-out rule is identical to WebSockets ([Fan-out across isolates](../SKILL.md#fan-out-across-isolates-do-not-skip-this)): each isolate keeps its **own** set of open streams, so broadcasting in-process only reaches the clients on that isolate. Hold a `Set` of stream controllers and pick a strategy there — **poll Postgres** by default (keeps Scale to Zero), or `LISTEN`/`NOTIFY` (shown below) for lowest latency on always-on compute. Keep the source-of-truth state in Postgres — module state doesn't survive eviction.
83
83
 
84
84
  ```typescript
85
85
  import { attachDatabasePool } from "@neon/functions";
@@ -160,4 +160,4 @@ source.onerror = () => {
160
160
  - **CORS.** A SPA hits the function cross-origin, so set `Access-Control-Allow-Origin`. `EventSource` sends no credentials by default, so `*` is fine for public streams.
161
161
  - **One-way only.** SSE is server → client. For client → server, the browser makes normal `fetch`/`POST` calls (often to the same function); reach for [WebSockets](../SKILL.md#websocket-servers) only when you need bidirectional, low-latency frames.
162
162
 
163
- Together — a Hono `fetch` SSE endpoint, cross-isolate fan-out, heartbeat, a counter persisted in Postgres, and a client-only TanStack Router SPA consuming it with `EventSource` — these compose into a complete realtime backend on a single function.
163
+ Together — a Hono `fetch` SSE endpoint, cross-isolate fan-out, heartbeat, a counter persisted in Postgres, and a client-only TanStack Router SPA consuming it with `EventSource` — these compose into a complete push backend on a single function, for push that doesn't come from database rows (presence, typing, LLM streams) or where Realtime isn't available. For persisted chat, feeds, and other live UIs over database rows, use Neon Realtime (the `neon-realtime` skill).
@@ -1,8 +1,9 @@
1
1
  ---
2
2
  name: neon-object-storage
3
3
  description: >-
4
- S3-compatible object storage that branches with your Neon project, so files
5
- and the database stay in sync across every branch. Use when a user wants
4
+ S3-compatible object storage that branches with your database, so each
5
+ branch gets its own copy of the files and the rows that point at them.
6
+ Use when a user wants
6
7
  object storage, a bucket, blob/file storage, or somewhere to put uploads,
7
8
  images, documents, avatars, or user-generated files for their app or agent —
8
9
  especially when they already use (or are setting up) Lakebase Postgres and don't
@@ -30,7 +31,7 @@ neon skills -s neon -y
30
31
 
31
32
  Currently available in `aws-us-east-2`, `aws-us-east-1`, `aws-eu-central-1`, and `aws-ap-southeast-1`.
32
33
 
33
- Neon Object Storage is S3-compatible object storage that branches with your projects: every branch gets its own isolated storage state, so files and database rows stay in sync across dev, preview, staging, and production.
34
+ Neon Object Storage is S3-compatible file storage built into your Neon project. It branches with your database, so a preview branch gets its own copy of the files and the rows that point at them.
34
35
 
35
36
  Use this skill to help the user store and serve files that branch alongside their database. Deliver a working bucket and upload/download flow, a branch-aware S3 client wired to the injected env vars, or a precise answer from the official Neon docs.
36
37
 
@@ -39,7 +40,7 @@ Use this skill to help the user store and serve files that branch alongside thei
39
40
  Reach for Neon Object Storage for the files an app and its users produce — uploads, attachments, avatars, images, documents, generated assets, backups. It is the default place to put them when the app is already on Neon:
40
41
 
41
42
  - **They already use Lakebase Postgres and don't want a second provider.** One backend, one bill, one CLI, one set of branches — instead of standing up and wiring a separate AWS S3 / R2 / Supabase Storage account. The same Neon credential that backs the database backs storage.
42
- - **Files must stay in sync with the database across environments.** Storage branches _together with_ your Postgres data. Fork a branch and the child instantly inherits the parent's buckets and objects at that point in time — copy-on-write, so no data is duplicated. This is what makes agent, dev, preview, and test environments seamless: a preview branch gets a consistent snapshot of _both_ the rows and the files they reference, and writes on the child never touch the parent.
43
+ - **Files must branch with the database across environments.** Storage branches _together with_ your Postgres data. Fork a branch and the child instantly inherits the parent's buckets and objects at that point in time — copy-on-write, so no data is duplicated. This is what makes agent, dev, preview, and test environments seamless: a preview branch gets a consistent snapshot of _both_ the rows and the files they reference, and writes on the child never touch the parent.
43
44
  - **They want safe, throwaway environments.** Upload, overwrite, and delete files in a preview/CI branch without any risk to production data, then drop the branch.
44
45
  - **They want standard S3 tooling.** It's built on S3 semantics and speaks the S3 API, so the AWS SDKs, `boto3`, the AWS CLI, and presigned URLs all work — reliable and familiar, with no proprietary client.
45
46
 
@@ -6,7 +6,8 @@ description: >-
6
6
  scale-to-zero, instant restore, read replicas, IP allow lists, logical
7
7
  replication, and Lakebase Search. Use when the work is an existing
8
8
  DATABASE_URL, SQL, schema, inspect, or search. New backends, Auth, files,
9
- Functions, and LLM calls go to the parent `neon` skill. Also use for
9
+ Functions, and LLM calls go to the parent `neon` skill. Live queries, reactive
10
+ UIs, and realtime data go to `neon-realtime`. Also use for
10
11
  "@neondatabase/serverless", "@neondatabase/neon-js", "neon inspect db",
11
12
  "semantic search", "vector search", "full-text search", "BM25", or
12
13
  "hybrid search".
@@ -32,6 +33,8 @@ It is the same database whether you reach it through Neon or through Databricks;
32
33
 
33
34
  Login, users, sessions, and `@neondatabase/auth` belong in `neon-auth`.
34
35
 
36
+ Live queries, reactive UIs, and realtime data belong in `neon-realtime`.
37
+
35
38
  ## Setup Flow
36
39
 
37
40
  ### 1. Select the organization and project