opencode-skills-collection 3.1.9 → 3.1.11

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 (66) hide show
  1. package/bundled-skills/.antigravity-install-manifest.json +8 -1
  2. package/bundled-skills/browser-testing-with-devtools/SKILL.md +334 -0
  3. package/bundled-skills/docs/integrations/jetski-cortex.md +3 -3
  4. package/bundled-skills/docs/integrations/jetski-gemini-loader/README.md +1 -1
  5. package/bundled-skills/docs/maintainers/repo-growth-seo.md +3 -3
  6. package/bundled-skills/docs/maintainers/skills-update-guide.md +1 -1
  7. package/bundled-skills/docs/sources/sources.md +4 -0
  8. package/bundled-skills/docs/users/bundles.md +1 -1
  9. package/bundled-skills/docs/users/claude-code-skills.md +1 -1
  10. package/bundled-skills/docs/users/gemini-cli-skills.md +1 -1
  11. package/bundled-skills/docs/users/getting-started.md +1 -1
  12. package/bundled-skills/docs/users/kiro-integration.md +1 -1
  13. package/bundled-skills/docs/users/usage.md +4 -4
  14. package/bundled-skills/docs/users/visual-guide.md +4 -4
  15. package/bundled-skills/drizzle-migration-conflict/SKILL.md +179 -0
  16. package/bundled-skills/drizzle-migration-conflict/references/ci-policy.md +87 -0
  17. package/bundled-skills/drizzle-migration-conflict/references/conflict-resolution.md +163 -0
  18. package/bundled-skills/drizzle-migration-conflict/references/report-template.md +69 -0
  19. package/bundled-skills/drizzle-migration-conflict/references/sources.md +51 -0
  20. package/bundled-skills/drizzle-migration-conflict/scripts/check_drizzle_migrations.py +721 -0
  21. package/bundled-skills/frontend-lighthouse/SKILL.md +348 -0
  22. package/bundled-skills/pre-release-review/SKILL.md +198 -0
  23. package/bundled-skills/pre-release-review/references/checklist.md +104 -0
  24. package/bundled-skills/pre-release-review/references/report-template.md +91 -0
  25. package/bundled-skills/re-create/SKILL.md +251 -0
  26. package/bundled-skills/weaviate/SKILL.md +132 -0
  27. package/bundled-skills/weaviate/references/ask.md +36 -0
  28. package/bundled-skills/weaviate/references/create_collection.md +152 -0
  29. package/bundled-skills/weaviate/references/environment_requirements.md +34 -0
  30. package/bundled-skills/weaviate/references/example_data.md +24 -0
  31. package/bundled-skills/weaviate/references/explore_collection.md +50 -0
  32. package/bundled-skills/weaviate/references/fetch_filter.md +88 -0
  33. package/bundled-skills/weaviate/references/get_collection.md +32 -0
  34. package/bundled-skills/weaviate/references/hybrid_search.md +47 -0
  35. package/bundled-skills/weaviate/references/import_data.md +160 -0
  36. package/bundled-skills/weaviate/references/keyword_search.md +38 -0
  37. package/bundled-skills/weaviate/references/list_collections.md +31 -0
  38. package/bundled-skills/weaviate/references/query_search.md +38 -0
  39. package/bundled-skills/weaviate/references/semantic_search.md +46 -0
  40. package/bundled-skills/weaviate/scripts/ask.py +106 -0
  41. package/bundled-skills/weaviate/scripts/create_collection.py +359 -0
  42. package/bundled-skills/weaviate/scripts/example_data.py +945 -0
  43. package/bundled-skills/weaviate/scripts/explore_collection.py +295 -0
  44. package/bundled-skills/weaviate/scripts/fetch_filter.py +261 -0
  45. package/bundled-skills/weaviate/scripts/get_collection.py +122 -0
  46. package/bundled-skills/weaviate/scripts/hybrid_search.py +157 -0
  47. package/bundled-skills/weaviate/scripts/import.py +701 -0
  48. package/bundled-skills/weaviate/scripts/keyword_search.py +142 -0
  49. package/bundled-skills/weaviate/scripts/list_collections.py +77 -0
  50. package/bundled-skills/weaviate/scripts/query_search.py +135 -0
  51. package/bundled-skills/weaviate/scripts/semantic_search.py +139 -0
  52. package/bundled-skills/weaviate/scripts/weaviate_conn.py +231 -0
  53. package/bundled-skills/weaviate-cookbooks/SKILL.md +67 -0
  54. package/bundled-skills/weaviate-cookbooks/references/advanced_rag.md +274 -0
  55. package/bundled-skills/weaviate-cookbooks/references/agentic_rag.md +360 -0
  56. package/bundled-skills/weaviate-cookbooks/references/async_client.md +428 -0
  57. package/bundled-skills/weaviate-cookbooks/references/basic_agent.md +270 -0
  58. package/bundled-skills/weaviate-cookbooks/references/basic_rag.md +219 -0
  59. package/bundled-skills/weaviate-cookbooks/references/data_explorer.md +336 -0
  60. package/bundled-skills/weaviate-cookbooks/references/environment_requirements.md +78 -0
  61. package/bundled-skills/weaviate-cookbooks/references/frontend_interface.md +104 -0
  62. package/bundled-skills/weaviate-cookbooks/references/pdf_multimodal_rag.md +635 -0
  63. package/bundled-skills/weaviate-cookbooks/references/project_setup.md +75 -0
  64. package/bundled-skills/weaviate-cookbooks/references/query_agent_chatbot.md +163 -0
  65. package/package.json +1 -1
  66. package/skills_index.json +156 -0
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # dependencies = [
4
+ # "weaviate-client==4.19.2",
5
+ # "weaviate-agents==1.2.0",
6
+ # "typer==0.21.0",
7
+ # ]
8
+ # ///
9
+ """
10
+ Query Weaviate using Query Agent in Ask mode.
11
+
12
+ Usage:
13
+ uv run ask.py --query "your question" --collections "Collection1,Collection2" [--json]
14
+
15
+ Environment Variables:
16
+ WEAVIATE_URL: Weaviate Cloud cluster URL
17
+ WEAVIATE_API_KEY: API key for authentication
18
+ + Any provider API keys (OPENAI_API_KEY, COHERE_API_KEY, etc.) - auto-detected
19
+ """
20
+
21
+ import json
22
+ import sys
23
+
24
+ import typer
25
+ import weaviate
26
+ from weaviate.agents.query import QueryAgent
27
+
28
+ # Import shared connection utilities (local to this skill)
29
+ from weaviate_conn import get_client
30
+
31
+ app = typer.Typer()
32
+
33
+
34
+ def parse_collections(collections_str: str) -> list[str]:
35
+ """Parse comma-separated collection names."""
36
+ collections = [c.strip() for c in collections_str.split(",") if c.strip()]
37
+ if not collections:
38
+ print("Error: At least one collection name required", file=sys.stderr)
39
+ raise typer.Exit(1)
40
+ return collections
41
+
42
+
43
+ @app.command()
44
+ def main(
45
+ query: str = typer.Option(..., "--query", "-q", help="Natural language question"),
46
+ collections: str = typer.Option(
47
+ ..., "--collections", "-c", help="Comma-separated collection names"
48
+ ),
49
+ json_output: bool = typer.Option(False, "--json", help="Output in JSON format"),
50
+ ):
51
+ """Query Weaviate using Query Agent in Ask mode (generates answer with sources)."""
52
+ collection_list = parse_collections(collections)
53
+
54
+ try:
55
+ with get_client() as client:
56
+ agent = QueryAgent(client=client, collections=collection_list)
57
+
58
+ print("Generating answer...", file=sys.stderr)
59
+ response = agent.ask(query)
60
+ print("Done.", file=sys.stderr)
61
+
62
+ # Extract data from response
63
+ answer = getattr(response, "final_answer", "") or ""
64
+ sources = []
65
+ if hasattr(response, "sources") and response.sources:
66
+ for src in response.sources:
67
+ sources.append(
68
+ {
69
+ "collection": getattr(src, "collection", None),
70
+ "object_id": getattr(src, "object_id", None),
71
+ }
72
+ )
73
+
74
+ result = {
75
+ "query": query,
76
+ "collections": collection_list,
77
+ "answer": answer,
78
+ "sources": sources,
79
+ "source_count": len(sources),
80
+ }
81
+
82
+ if json_output:
83
+ print(json.dumps(result, indent=2, default=str))
84
+ else:
85
+ # Markdown output for agent consumption
86
+ print(f"## Answer\n\n{answer}\n")
87
+
88
+ if sources:
89
+ print(f"## Sources ({len(sources)})\n")
90
+ print("| # | Collection | Object ID |")
91
+ print("|---|------------|-----------|")
92
+ for idx, src in enumerate(sources, 1):
93
+ print(
94
+ f"| {idx} | {src.get('collection', 'Unknown')} | `{src.get('object_id', 'N/A')}` |"
95
+ )
96
+
97
+ except weaviate.exceptions.WeaviateConnectionError as e:
98
+ print(f"Error: Connection failed - {e}", file=sys.stderr)
99
+ raise typer.Exit(1)
100
+ except Exception as e:
101
+ print(f"Error: {e}", file=sys.stderr)
102
+ raise typer.Exit(1)
103
+
104
+
105
+ if __name__ == "__main__":
106
+ app()
@@ -0,0 +1,359 @@
1
+ #!/usr/bin/env python3
2
+ # /// script
3
+ # dependencies = [
4
+ # "weaviate-client==4.19.2",
5
+ # "typer==0.21.0",
6
+ # ]
7
+ # ///
8
+ """
9
+ Create a Weaviate collection.
10
+
11
+ Usage:
12
+ uv run create_collection.py CollectionName --properties '[...]' [options]
13
+
14
+ Environment Variables:
15
+ WEAVIATE_URL: Weaviate Cloud cluster URL
16
+ WEAVIATE_API_KEY: API key for authentication
17
+ + Any provider API keys (OPENAI_API_KEY, COHERE_API_KEY, etc.) - auto-detected
18
+ """
19
+
20
+ import json
21
+ import sys
22
+
23
+ import typer
24
+ import weaviate
25
+ from weaviate.classes.config import (
26
+ Configure,
27
+ DataType,
28
+ Property,
29
+ Tokenization,
30
+ )
31
+
32
+ # Import shared connection utilities (local to this skill)
33
+ from weaviate_conn import get_client
34
+
35
+ app = typer.Typer()
36
+
37
+ # Data type string to enum mapping
38
+ DATA_TYPE_MAP = {
39
+ "text": DataType.TEXT,
40
+ "text[]": DataType.TEXT_ARRAY,
41
+ "boolean": DataType.BOOL,
42
+ "boolean[]": DataType.BOOL_ARRAY,
43
+ "bool": DataType.BOOL,
44
+ "bool[]": DataType.BOOL_ARRAY,
45
+ "int": DataType.INT,
46
+ "int[]": DataType.INT_ARRAY,
47
+ "number": DataType.NUMBER,
48
+ "number[]": DataType.NUMBER_ARRAY,
49
+ "date": DataType.DATE,
50
+ "date[]": DataType.DATE_ARRAY,
51
+ "uuid": DataType.UUID,
52
+ "uuid[]": DataType.UUID_ARRAY,
53
+ "geoCoordinates": DataType.GEO_COORDINATES,
54
+ "phoneNumber": DataType.PHONE_NUMBER,
55
+ "blob": DataType.BLOB,
56
+ "object": DataType.OBJECT,
57
+ "object[]": DataType.OBJECT_ARRAY,
58
+ }
59
+
60
+ # Types that support index_range_filters (enabled by default for better range query performance)
61
+ RANGE_FILTER_TYPES = {"int", "int[]", "number", "number[]", "date", "date[]"}
62
+
63
+ # Tokenization string to enum mapping
64
+ TOKENIZATION_MAP = {
65
+ "word": Tokenization.WORD,
66
+ "lowercase": Tokenization.LOWERCASE,
67
+ "whitespace": Tokenization.WHITESPACE,
68
+ "field": Tokenization.FIELD,
69
+ }
70
+
71
+ # Vectorizer string to config mapping
72
+ VECTORIZER_MAP = {
73
+ "text2vec_weaviate": lambda: Configure.Vectors.text2vec_weaviate(),
74
+ "text2vec_openai": lambda: Configure.Vectors.text2vec_openai(),
75
+ "text2vec_cohere": lambda: Configure.Vectors.text2vec_cohere(),
76
+ "text2vec_huggingface": lambda: Configure.Vectors.text2vec_huggingface(),
77
+ "text2vec_google_gemini": lambda: Configure.Vectors.text2vec_google_gemini(),
78
+ "text2vec_jinaai": lambda: Configure.Vectors.text2vec_jinaai(),
79
+ "text2vec_voyageai": lambda: Configure.Vectors.text2vec_voyageai(),
80
+ "text2vec_model2vec": lambda: Configure.Vectors.text2vec_model2vec(),
81
+ "text2vec_transformers": lambda: Configure.Vectors.text2vec_transformers(),
82
+ "text2vec_ollama": lambda: Configure.Vectors.text2vec_ollama(),
83
+ "multi2vec_clip": lambda: Configure.Vectors.multi2vec_clip(),
84
+ "multi2vec_bind": lambda: Configure.Vectors.multi2vec_bind(),
85
+ "none": lambda: Configure.Vectors.self_provided(),
86
+ }
87
+
88
+
89
+ def parse_property(prop_dict: dict) -> Property:
90
+ """
91
+ Parse a property definition from a dictionary.
92
+
93
+ Args:
94
+ prop_dict: Dictionary with property definition
95
+
96
+ Returns:
97
+ Property instance
98
+
99
+ Raises:
100
+ ValueError: If property definition is invalid
101
+ """
102
+ if "name" not in prop_dict:
103
+ raise ValueError("Property must have a 'name' field")
104
+ if "data_type" not in prop_dict:
105
+ raise ValueError(
106
+ f"Property '{prop_dict['name']}' must have a 'data_type' field"
107
+ )
108
+
109
+ name = prop_dict["name"]
110
+ data_type_str = prop_dict["data_type"].lower()
111
+
112
+ if data_type_str not in DATA_TYPE_MAP:
113
+ raise ValueError(
114
+ f"Invalid data_type '{prop_dict['data_type']}' for property '{name}'. "
115
+ f"Supported types: {', '.join(DATA_TYPE_MAP.keys())}"
116
+ )
117
+
118
+ data_type = DATA_TYPE_MAP[data_type_str]
119
+
120
+ # Build property kwargs
121
+ kwargs = {
122
+ "name": name,
123
+ "data_type": data_type,
124
+ }
125
+
126
+ # Add optional fields
127
+ if "description" in prop_dict:
128
+ kwargs["description"] = prop_dict["description"]
129
+
130
+ if "index_filterable" in prop_dict:
131
+ kwargs["index_filterable"] = bool(prop_dict["index_filterable"])
132
+
133
+ if "index_searchable" in prop_dict:
134
+ kwargs["index_searchable"] = bool(prop_dict["index_searchable"])
135
+
136
+ if "index_range_filters" in prop_dict:
137
+ kwargs["index_range_filters"] = bool(prop_dict["index_range_filters"])
138
+
139
+ # Handle tokenization for text types
140
+ if "tokenization" in prop_dict:
141
+ tokenization_str = prop_dict["tokenization"].lower()
142
+ if tokenization_str not in TOKENIZATION_MAP:
143
+ raise ValueError(
144
+ f"Invalid tokenization '{prop_dict['tokenization']}' for property '{name}'. "
145
+ f"Supported: {', '.join(TOKENIZATION_MAP.keys())}"
146
+ )
147
+ kwargs["tokenization"] = TOKENIZATION_MAP[tokenization_str]
148
+
149
+ # Handle nested properties for object types
150
+ if "nested_properties" in prop_dict:
151
+ if data_type not in [DataType.OBJECT, DataType.OBJECT_ARRAY]:
152
+ raise ValueError(
153
+ f"nested_properties can only be used with 'object' or 'object[]' data types "
154
+ f"(property '{name}' has type '{data_type_str}')"
155
+ )
156
+ kwargs["nested_properties"] = [
157
+ parse_property(nested_prop)
158
+ for nested_prop in prop_dict["nested_properties"]
159
+ ]
160
+
161
+ return Property(**kwargs)
162
+
163
+
164
+ @app.command()
165
+ def main(
166
+ name: str = typer.Argument(..., help="Collection name (capitalize first letter)"),
167
+ properties: str = typer.Option(
168
+ ...,
169
+ "--properties",
170
+ "-p",
171
+ help="JSON array of property definitions. Add a 'description' field to each property — the Query Agent uses these to understand your schema and construct accurate queries.",
172
+ ),
173
+ description: str = typer.Option(
174
+ None,
175
+ "--description",
176
+ "-d",
177
+ help="Collection description. Weaviate agents read this to understand what the collection contains and decide which collection to query.",
178
+ ),
179
+ vectorizer: str = typer.Option(
180
+ "text2vec_weaviate",
181
+ "--vectorizer",
182
+ "-v",
183
+ help=f"Vectorizer to use. Options: {', '.join(VECTORIZER_MAP.keys())}",
184
+ ),
185
+ replication_factor: int = typer.Option(
186
+ None, "--replication-factor", "-r", help="Replication factor (default: 1)"
187
+ ),
188
+ multi_tenancy: bool = typer.Option(
189
+ False, "--multi-tenancy", "-m", help="Enable multi-tenancy for data isolation"
190
+ ),
191
+ auto_tenant_creation: bool = typer.Option(
192
+ False,
193
+ "--auto-tenant-creation",
194
+ "-a",
195
+ help="Auto-create tenants on insert (requires --multi-tenancy)",
196
+ ),
197
+ json_output: bool = typer.Option(False, "--json", help="Output in JSON format"),
198
+ ):
199
+ """Create a new Weaviate collection with specified properties."""
200
+ try:
201
+ # Validate multi-tenancy options
202
+ if auto_tenant_creation and not multi_tenancy:
203
+ print(
204
+ "Error: --auto-tenant-creation requires --multi-tenancy to be enabled",
205
+ file=sys.stderr,
206
+ )
207
+ raise typer.Exit(1)
208
+
209
+ # Validate collection name (should start with uppercase)
210
+ if not name[0].isupper():
211
+ print(
212
+ f"Warning: Collection name '{name}' should start with an uppercase letter "
213
+ f"(GraphQL naming convention).",
214
+ file=sys.stderr,
215
+ )
216
+ name = name.capitalize()
217
+ print(f"Using '{name}' instead.", file=sys.stderr)
218
+
219
+ # Parse properties JSON
220
+ try:
221
+ properties_list = json.loads(properties)
222
+ if not isinstance(properties_list, list):
223
+ raise ValueError("Properties must be a JSON array")
224
+ if len(properties_list) == 0:
225
+ raise ValueError("Properties array cannot be empty")
226
+ except json.JSONDecodeError as e:
227
+ print(f"Error: Invalid JSON in properties: {e}", file=sys.stderr)
228
+ raise typer.Exit(1)
229
+
230
+ # Parse each property
231
+ try:
232
+ parsed_properties = [parse_property(prop) for prop in properties_list]
233
+ except ValueError as e:
234
+ print(f"Error: {e}", file=sys.stderr)
235
+ raise typer.Exit(1)
236
+
237
+ # Prepare collection config
238
+ collection_config = {
239
+ "name": name,
240
+ "properties": parsed_properties,
241
+ }
242
+
243
+ if description:
244
+ collection_config["description"] = description
245
+
246
+ # Add vectorizer if specified
247
+ if vectorizer:
248
+ vectorizer_lower = vectorizer.lower()
249
+ if vectorizer_lower not in VECTORIZER_MAP:
250
+ print(
251
+ f"Error: Invalid vectorizer '{vectorizer}'. "
252
+ f"Supported: {', '.join(VECTORIZER_MAP.keys())}",
253
+ file=sys.stderr,
254
+ )
255
+ raise typer.Exit(1)
256
+ collection_config["vector_config"] = VECTORIZER_MAP[vectorizer_lower]()
257
+
258
+ # Add replication config if specified
259
+ if replication_factor is not None:
260
+ if replication_factor < 1:
261
+ print("Error: Replication factor must be at least 1", file=sys.stderr)
262
+ raise typer.Exit(1)
263
+ collection_config["replication_config"] = Configure.replication(
264
+ factor=replication_factor
265
+ )
266
+
267
+ # Add multi-tenancy config if specified
268
+ if multi_tenancy:
269
+ collection_config["multi_tenancy_config"] = Configure.multi_tenancy(
270
+ enabled=True, auto_tenant_creation=auto_tenant_creation
271
+ )
272
+
273
+ with get_client() as client:
274
+ # Check if collection already exists
275
+ if client.collections.exists(name):
276
+ print(
277
+ f"Error: Collection '{name}' already exists. "
278
+ f"Delete it first or use a different name.",
279
+ file=sys.stderr,
280
+ )
281
+ raise typer.Exit(1)
282
+
283
+ print(f"Creating collection '{name}'...", file=sys.stderr)
284
+ client.collections.create(**collection_config)
285
+
286
+ # Verify creation by fetching the config
287
+ collection = client.collections.get(name)
288
+ config = collection.config.get()
289
+
290
+ result = {
291
+ "name": name,
292
+ "description": config.description,
293
+ "properties": [
294
+ {
295
+ "name": p.name,
296
+ "data_type": str(p.data_type),
297
+ "description": getattr(p, "description", None),
298
+ }
299
+ for p in config.properties
300
+ ],
301
+ "multi_tenancy": {
302
+ "enabled": (
303
+ config.multi_tenancy_config.enabled
304
+ if config.multi_tenancy_config
305
+ else False
306
+ ),
307
+ "auto_tenant_creation": (
308
+ config.multi_tenancy_config.auto_tenant_creation
309
+ if config.multi_tenancy_config
310
+ else False
311
+ ),
312
+ },
313
+ "status": "created",
314
+ }
315
+
316
+ if json_output:
317
+ print(json.dumps(result, indent=2, default=str))
318
+ else:
319
+ print(f"\n✓ Collection '{name}' created successfully!\n")
320
+ if not result["description"]:
321
+ print(
322
+ "Tip: No collection description provided. "
323
+ "Weaviate agents read the collection description to understand what data it contains and decide which collection to query.",
324
+ file=sys.stderr,
325
+ )
326
+ props_without_desc = [
327
+ p["name"] for p in result["properties"] if not p.get("description")
328
+ ]
329
+ if props_without_desc:
330
+ print(
331
+ f"Tip: {len(props_without_desc)} propert{'y has' if len(props_without_desc) == 1 else 'ies have'} no description. "
332
+ f"Adding descriptions helps the Query Agent understand your schema and construct accurate queries.",
333
+ file=sys.stderr,
334
+ )
335
+ print(f"**Description:** {config.description or 'N/A'}")
336
+
337
+ # Display multi-tenancy status
338
+ if result["multi_tenancy"]["enabled"]:
339
+ print(f"**Multi-Tenancy:** Enabled")
340
+ if result["multi_tenancy"]["auto_tenant_creation"]:
341
+ print(f"**Auto-Tenant Creation:** Enabled")
342
+
343
+ print(f"\n### Properties ({len(config.properties)})\n")
344
+ print("| Name | Data Type | Description |")
345
+ print("|------|-----------|-------------|")
346
+ for prop in result["properties"]:
347
+ desc = prop.get("description") or "-"
348
+ print(f"| {prop['name']} | {prop['data_type']} | {desc} |")
349
+
350
+ except weaviate.exceptions.WeaviateConnectionError as e:
351
+ print(f"Error: Connection failed - {e}", file=sys.stderr)
352
+ raise typer.Exit(1)
353
+ except Exception as e:
354
+ print(f"Error: {e}", file=sys.stderr)
355
+ raise typer.Exit(1)
356
+
357
+
358
+ if __name__ == "__main__":
359
+ app()