@biggora/claude-plugins 1.1.1 → 1.2.2

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 (104) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/README.md +24 -17
  3. package/package.json +1 -1
  4. package/registry/registry.json +319 -244
  5. package/specs/coding.md +24 -0
  6. package/specs/pod.md +2 -0
  7. package/src/skills/captcha/README.md +221 -0
  8. package/src/skills/captcha/SKILL.md +355 -0
  9. package/src/skills/captcha/references/captcha-types.md +254 -0
  10. package/src/skills/captcha/references/services.md +172 -0
  11. package/src/skills/captcha/references/stealth.md +238 -0
  12. package/src/skills/captcha/scripts/solve_captcha.py +323 -0
  13. package/src/skills/captcha/scripts/solve_image_grid.py +350 -0
  14. package/src/skills/codex-cli/SKILL.md +21 -11
  15. package/src/skills/gemini-cli/SKILL.md +27 -13
  16. package/src/skills/gemini-cli/references/commands.md +21 -14
  17. package/src/skills/gemini-cli/references/configuration.md +23 -18
  18. package/src/skills/gemini-cli/references/headless-and-scripting.md +7 -17
  19. package/src/skills/gemini-cli/references/mcp-and-extensions.md +12 -6
  20. package/src/skills/google-merchant-api/SKILL.md +581 -0
  21. package/src/skills/google-merchant-api/references/accounts.md +247 -0
  22. package/src/skills/google-merchant-api/references/content-api-legacy.md +216 -0
  23. package/src/skills/google-merchant-api/references/datasources.md +233 -0
  24. package/src/skills/google-merchant-api/references/inventories.md +201 -0
  25. package/src/skills/google-merchant-api/references/migration.md +267 -0
  26. package/src/skills/google-merchant-api/references/products.md +316 -0
  27. package/src/skills/google-merchant-api/references/promotions.md +201 -0
  28. package/src/skills/google-merchant-api/references/reports.md +240 -0
  29. package/src/skills/lv-aggregators-api/SKILL.md +113 -0
  30. package/src/skills/lv-aggregators-api/references/integration-guide.md +368 -0
  31. package/src/skills/lv-aggregators-api/references/kurpirkt.md +103 -0
  32. package/src/skills/lv-aggregators-api/references/salidzini.md +122 -0
  33. package/src/skills/notebook-lm/SKILL.md +1 -1
  34. package/src/skills/screen-recording/SKILL.md +243 -213
  35. package/src/skills/screen-recording/references/design-patterns.md +4 -2
  36. package/src/skills/screen-recording/references/ffmpeg-recording.md +473 -0
  37. package/src/skills/screen-recording/references/{approach1-programmatic.md → programmatic-generation.md} +45 -22
  38. package/src/skills/screen-recording/references/python-fallback.md +222 -0
  39. package/src/skills/tailwindcss-best-practices/SKILL.md +180 -0
  40. package/src/skills/tailwindcss-best-practices/references/best-practices-utility-patterns.md +87 -0
  41. package/src/skills/tailwindcss-best-practices/references/core-installation.md +109 -0
  42. package/src/skills/tailwindcss-best-practices/references/core-preflight.md +200 -0
  43. package/src/skills/tailwindcss-best-practices/references/core-responsive.md +163 -0
  44. package/src/skills/tailwindcss-best-practices/references/core-source-detection.md +114 -0
  45. package/src/skills/tailwindcss-best-practices/references/core-theme.md +108 -0
  46. package/src/skills/tailwindcss-best-practices/references/core-utility-classes.md +59 -0
  47. package/src/skills/tailwindcss-best-practices/references/core-variants.md +204 -0
  48. package/src/skills/tailwindcss-best-practices/references/effects-form-controls.md +76 -0
  49. package/src/skills/tailwindcss-best-practices/references/effects-mask.md +91 -0
  50. package/src/skills/tailwindcss-best-practices/references/effects-scroll-snap.md +59 -0
  51. package/src/skills/tailwindcss-best-practices/references/effects-text-shadow.md +78 -0
  52. package/src/skills/tailwindcss-best-practices/references/effects-transition-animation.md +80 -0
  53. package/src/skills/tailwindcss-best-practices/references/effects-visibility-interactivity.md +82 -0
  54. package/src/skills/tailwindcss-best-practices/references/features-content-detection.md +175 -0
  55. package/src/skills/tailwindcss-best-practices/references/features-custom-styles.md +203 -0
  56. package/src/skills/tailwindcss-best-practices/references/features-dark-mode.md +137 -0
  57. package/src/skills/tailwindcss-best-practices/references/features-functions-directives.md +241 -0
  58. package/src/skills/tailwindcss-best-practices/references/features-upgrade.md +160 -0
  59. package/src/skills/tailwindcss-best-practices/references/layout-aspect-ratio.md +39 -0
  60. package/src/skills/tailwindcss-best-practices/references/layout-columns.md +80 -0
  61. package/src/skills/tailwindcss-best-practices/references/layout-display.md +110 -0
  62. package/src/skills/tailwindcss-best-practices/references/layout-flexbox.md +112 -0
  63. package/src/skills/tailwindcss-best-practices/references/layout-grid.md +87 -0
  64. package/src/skills/tailwindcss-best-practices/references/layout-height.md +97 -0
  65. package/src/skills/tailwindcss-best-practices/references/layout-inset.md +103 -0
  66. package/src/skills/tailwindcss-best-practices/references/layout-logical-properties.md +92 -0
  67. package/src/skills/tailwindcss-best-practices/references/layout-margin.md +126 -0
  68. package/src/skills/tailwindcss-best-practices/references/layout-min-max-sizing.md +63 -0
  69. package/src/skills/tailwindcss-best-practices/references/layout-object-fit-position.md +64 -0
  70. package/src/skills/tailwindcss-best-practices/references/layout-overflow.md +57 -0
  71. package/src/skills/tailwindcss-best-practices/references/layout-padding.md +77 -0
  72. package/src/skills/tailwindcss-best-practices/references/layout-position.md +85 -0
  73. package/src/skills/tailwindcss-best-practices/references/layout-tables.md +67 -0
  74. package/src/skills/tailwindcss-best-practices/references/layout-width.md +102 -0
  75. package/src/skills/tailwindcss-best-practices/references/transform-base.md +68 -0
  76. package/src/skills/tailwindcss-best-practices/references/transform-rotate.md +70 -0
  77. package/src/skills/tailwindcss-best-practices/references/transform-scale.md +83 -0
  78. package/src/skills/tailwindcss-best-practices/references/transform-skew.md +62 -0
  79. package/src/skills/tailwindcss-best-practices/references/transform-translate.md +77 -0
  80. package/src/skills/tailwindcss-best-practices/references/typography-font-text.md +142 -0
  81. package/src/skills/tailwindcss-best-practices/references/typography-list-style.md +65 -0
  82. package/src/skills/tailwindcss-best-practices/references/typography-text-align.md +60 -0
  83. package/src/skills/tailwindcss-best-practices/references/visual-background.md +76 -0
  84. package/src/skills/tailwindcss-best-practices/references/visual-border.md +108 -0
  85. package/src/skills/tailwindcss-best-practices/references/visual-effects.md +111 -0
  86. package/src/skills/tailwindcss-best-practices/references/visual-svg.md +82 -0
  87. package/src/skills/test-mobile-app/SKILL.md +11 -6
  88. package/src/skills/test-mobile-app/scripts/analyze_apk.py +15 -4
  89. package/src/skills/test-mobile-app/scripts/check_environment.py +5 -5
  90. package/src/skills/test-mobile-app/scripts/run_tests.py +1 -1
  91. package/src/skills/test-web-ui/SKILL.md +264 -84
  92. package/src/skills/test-web-ui/scripts/discover.py +25 -12
  93. package/src/skills/test-web-ui/scripts/run_tests.py +3 -2
  94. package/src/skills/tm-search/SKILL.md +242 -106
  95. package/src/skills/tm-search/references/scraping-fallback.md +60 -95
  96. package/src/skills/tm-search/scripts/tm_search.py +453 -375
  97. package/src/skills/vite-best-practices/SKILL.md +115 -0
  98. package/src/skills/vite-best-practices/references/build-and-ssr.md +255 -0
  99. package/src/skills/vite-best-practices/references/core-config.md +231 -0
  100. package/src/skills/vite-best-practices/references/core-features.md +222 -0
  101. package/src/skills/vite-best-practices/references/core-plugin-api.md +294 -0
  102. package/src/skills/vite-best-practices/references/environment-api.md +108 -0
  103. package/src/skills/vite-best-practices/references/rolldown-migration.md +242 -0
  104. package/src/skills/screen-recording/references/approach2-xvfb.md +0 -232
@@ -0,0 +1,368 @@
1
+ # Integration Guide
2
+
3
+ Code examples and strategies for generating XML product feeds for Latvian aggregators.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Dual-Feed Strategy](#dual-feed-strategy)
8
+ 2. [Node.js Implementation](#nodejs-implementation)
9
+ 3. [PHP Implementation](#php-implementation)
10
+ 4. [Python Implementation](#python-implementation)
11
+ 5. [Validation](#validation)
12
+ 6. [Scheduling](#scheduling)
13
+ 7. [Common Pitfalls](#common-pitfalls)
14
+
15
+ ## Dual-Feed Strategy
16
+
17
+ Since Salidzini.lv and KurPirkt.lv share a very similar XML structure, use a single product data source and generate both feeds with platform-specific adjustments:
18
+
19
+ 1. Query products from your database
20
+ 2. Map fields to each platform's tag names
21
+ 3. Generate separate XML files and host them at distinct URLs
22
+
23
+ Key field mappings between platforms:
24
+
25
+ ```
26
+ brand -> <brand> (Salidzini) | <manufacturer> (KurPirkt)
27
+ delivery -> <delivery_latvija> | <delivery_cost_riga>
28
+ category -> "A >> B >> C" | "A > B > C"
29
+ ```
30
+
31
+ ## Node.js Implementation
32
+
33
+ ### Basic Feed Generator
34
+
35
+ ```javascript
36
+ import { createWriteStream } from 'fs';
37
+ import { pipeline } from 'stream/promises';
38
+
39
+ // Platform-specific field mappings
40
+ const PLATFORM_CONFIG = {
41
+ salidzini: {
42
+ brandTag: 'brand',
43
+ deliveryTag: 'delivery_latvija',
44
+ categorySeparator: ' &gt;&gt; ',
45
+ extraFields: (product) => `
46
+ <model>${escapeXml(product.model || '')}</model>
47
+ <color>${escapeXml(product.color || '')}</color>
48
+ <mpn>${escapeXml(product.mpn || '')}</mpn>
49
+ <ean>${escapeXml(product.ean || '')}</ean>
50
+ <delivery_days_latvija>${product.deliveryDays || ''}</delivery_days_latvija>
51
+ <delivery_days_shop>${product.pickupDays || ''}</delivery_days_shop>
52
+ <service_fee>${product.serviceFee || ''}</service_fee>
53
+ <adult>${product.isAdult ? 'yes' : 'no'}</adult>`,
54
+ },
55
+ kurpirkt: {
56
+ brandTag: 'manufacturer',
57
+ deliveryTag: 'delivery_cost_riga',
58
+ categorySeparator: ' &gt; ',
59
+ extraFields: () => '',
60
+ },
61
+ };
62
+
63
+ function escapeXml(str) {
64
+ return String(str)
65
+ .replace(/&/g, '&amp;')
66
+ .replace(/</g, '&lt;')
67
+ .replace(/>/g, '&gt;')
68
+ .replace(/"/g, '&quot;')
69
+ .replace(/'/g, '&apos;');
70
+ }
71
+
72
+ function generateItem(product, platform) {
73
+ const config = PLATFORM_CONFIG[platform];
74
+ const categoryPath = product.categories
75
+ ?.join(config.categorySeparator) || '';
76
+
77
+ return ` <item>
78
+ <name>${escapeXml(product.name)}</name>
79
+ <link>${escapeXml(product.url)}</link>
80
+ <price>${product.price.toFixed(2)}</price>
81
+ <image>${escapeXml(product.imageUrl || '')}</image>
82
+ <${config.brandTag}>${escapeXml(product.brand || '')}</${config.brandTag}>
83
+ <category_full>${categoryPath}</category_full>
84
+ <category_link>${escapeXml(product.categoryUrl || '')}</category_link>
85
+ <in_stock>${product.stock ?? ''}</in_stock>
86
+ <${config.deliveryTag}>${product.deliveryCost ?? ''}</${config.deliveryTag}>
87
+ <used>${product.isUsed ? '1' : ''}</used>${config.extraFields(product)}
88
+ </item>`;
89
+ }
90
+
91
+ async function generateFeed(products, platform, outputPath) {
92
+ const stream = createWriteStream(outputPath);
93
+ stream.write('<?xml version="1.0" encoding="utf-8" ?>\n<root>\n');
94
+
95
+ for (const product of products) {
96
+ stream.write(generateItem(product, platform) + '\n');
97
+ }
98
+
99
+ stream.write('</root>\n');
100
+ stream.end();
101
+
102
+ return new Promise((resolve, reject) => {
103
+ stream.on('finish', resolve);
104
+ stream.on('error', reject);
105
+ });
106
+ }
107
+
108
+ // Usage
109
+ const products = await fetchProductsFromDatabase();
110
+ await Promise.all([
111
+ generateFeed(products, 'salidzini', './public/export/salidzini.xml'),
112
+ generateFeed(products, 'kurpirkt', './public/export/kurpirkt.xml'),
113
+ ]);
114
+ ```
115
+
116
+ ### Express.js Dynamic Feed Endpoint
117
+
118
+ ```javascript
119
+ import express from 'express';
120
+
121
+ const app = express();
122
+
123
+ app.get('/export/:platform.xml', async (req, res) => {
124
+ const { platform } = req.params;
125
+ if (!['salidzini', 'kurpirkt'].includes(platform)) {
126
+ return res.status(404).send('Unknown platform');
127
+ }
128
+
129
+ const products = await fetchProductsFromDatabase();
130
+
131
+ res.set('Content-Type', 'application/xml; charset=utf-8');
132
+ res.write('<?xml version="1.0" encoding="utf-8" ?>\n<root>\n');
133
+
134
+ for (const product of products) {
135
+ res.write(generateItem(product, platform) + '\n');
136
+ }
137
+
138
+ res.end('</root>\n');
139
+ });
140
+ ```
141
+
142
+ ## PHP Implementation
143
+
144
+ ```php
145
+ <?php
146
+ header('Content-Type: application/xml; charset=utf-8');
147
+
148
+ $platform = $_GET['platform'] ?? 'salidzini';
149
+
150
+ // Fetch products from your database
151
+ $products = getProductsFromDB();
152
+
153
+ $xml = new XMLWriter();
154
+ $xml->openMemory();
155
+ $xml->startDocument('1.0', 'UTF-8');
156
+ $xml->startElement('root');
157
+
158
+ foreach ($products as $product) {
159
+ $xml->startElement('item');
160
+
161
+ $xml->writeElement('name', $product['name']);
162
+ $xml->writeElement('link', $product['url']);
163
+ $xml->writeElement('price', number_format($product['price'], 2, '.', ''));
164
+ $xml->writeElement('image', $product['image_url'] ?? '');
165
+
166
+ // Platform-specific brand tag
167
+ $brandTag = $platform === 'kurpirkt' ? 'manufacturer' : 'brand';
168
+ $xml->writeElement($brandTag, $product['brand'] ?? '');
169
+
170
+ // Category with platform-specific separator
171
+ $separator = $platform === 'kurpirkt' ? ' > ' : ' >> ';
172
+ $categoryPath = implode($separator, $product['categories'] ?? []);
173
+ $xml->writeElement('category_full', $categoryPath);
174
+ $xml->writeElement('category_link', $product['category_url'] ?? '');
175
+
176
+ $xml->writeElement('in_stock', $product['stock'] ?? '');
177
+
178
+ // Platform-specific delivery tag
179
+ $deliveryTag = $platform === 'kurpirkt' ? 'delivery_cost_riga' : 'delivery_latvija';
180
+ $xml->writeElement($deliveryTag, $product['delivery_cost'] ?? '');
181
+
182
+ $xml->writeElement('used', $product['is_used'] ? '1' : '');
183
+
184
+ // Salidzini-specific extra fields
185
+ if ($platform === 'salidzini') {
186
+ $xml->writeElement('model', $product['model'] ?? '');
187
+ $xml->writeElement('color', $product['color'] ?? '');
188
+ $xml->writeElement('mpn', $product['mpn'] ?? '');
189
+ $xml->writeElement('ean', $product['ean'] ?? '');
190
+ $xml->writeElement('delivery_days_latvija', $product['delivery_days'] ?? '');
191
+ $xml->writeElement('delivery_days_shop', $product['pickup_days'] ?? '');
192
+ $xml->writeElement('adult', $product['is_adult'] ? 'yes' : 'no');
193
+ }
194
+
195
+ $xml->endElement(); // item
196
+ }
197
+
198
+ $xml->endElement(); // root
199
+ echo $xml->outputMemory();
200
+ ```
201
+
202
+ ## Python Implementation
203
+
204
+ ```python
205
+ import xml.etree.ElementTree as ET
206
+ from xml.dom import minidom
207
+
208
+ PLATFORM_CONFIG = {
209
+ 'salidzini': {
210
+ 'brand_tag': 'brand',
211
+ 'delivery_tag': 'delivery_latvija',
212
+ 'category_sep': ' >> ',
213
+ },
214
+ 'kurpirkt': {
215
+ 'brand_tag': 'manufacturer',
216
+ 'delivery_tag': 'delivery_cost_riga',
217
+ 'category_sep': ' > ',
218
+ },
219
+ }
220
+
221
+ def generate_feed(products: list[dict], platform: str, output_path: str):
222
+ config = PLATFORM_CONFIG[platform]
223
+ root = ET.Element('root')
224
+
225
+ for product in products:
226
+ item = ET.SubElement(root, 'item')
227
+
228
+ ET.SubElement(item, 'name').text = product['name']
229
+ ET.SubElement(item, 'link').text = product['url']
230
+ ET.SubElement(item, 'price').text = f"{product['price']:.2f}"
231
+ ET.SubElement(item, 'image').text = product.get('image_url', '')
232
+
233
+ ET.SubElement(item, config['brand_tag']).text = product.get('brand', '')
234
+
235
+ categories = product.get('categories', [])
236
+ ET.SubElement(item, 'category_full').text = config['category_sep'].join(categories)
237
+ ET.SubElement(item, 'category_link').text = product.get('category_url', '')
238
+
239
+ ET.SubElement(item, 'in_stock').text = str(product.get('stock', ''))
240
+ ET.SubElement(item, config['delivery_tag']).text = str(product.get('delivery_cost', ''))
241
+ ET.SubElement(item, 'used').text = '1' if product.get('is_used') else ''
242
+
243
+ # Salidzini-specific fields
244
+ if platform == 'salidzini':
245
+ ET.SubElement(item, 'model').text = product.get('model', '')
246
+ ET.SubElement(item, 'color').text = product.get('color', '')
247
+ ET.SubElement(item, 'mpn').text = product.get('mpn', '')
248
+ ET.SubElement(item, 'ean').text = product.get('ean', '')
249
+ ET.SubElement(item, 'delivery_days_latvija').text = str(product.get('delivery_days', ''))
250
+ ET.SubElement(item, 'delivery_days_shop').text = str(product.get('pickup_days', ''))
251
+ ET.SubElement(item, 'adult').text = 'yes' if product.get('is_adult') else 'no'
252
+
253
+ xml_str = minidom.parseString(ET.tostring(root, encoding='unicode')).toprettyxml(
254
+ indent=' ', encoding=None
255
+ )
256
+ # Replace default XML declaration with utf-8
257
+ xml_str = xml_str.replace(
258
+ "<?xml version=\"1.0\" ?>",
259
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
260
+ )
261
+
262
+ with open(output_path, 'w', encoding='utf-8') as f:
263
+ f.write(xml_str)
264
+
265
+
266
+ # Usage
267
+ products = fetch_products_from_db()
268
+ generate_feed(products, 'salidzini', 'export/salidzini.xml')
269
+ generate_feed(products, 'kurpirkt', 'export/kurpirkt.xml')
270
+ ```
271
+
272
+ ## Validation
273
+
274
+ ### Salidzini.lv Validator
275
+
276
+ Use the built-in validator at `https://www.salidzini.lv/shops_info.php` — paste your feed URL at the bottom of the page.
277
+
278
+ ### Manual Validation Checklist
279
+
280
+ Before submitting your feed, verify:
281
+
282
+ - [ ] XML is well-formed (valid UTF-8, proper encoding declaration)
283
+ - [ ] All required fields (`name`, `link`, `price`) are present for every item
284
+ - [ ] Prices are numeric with dot decimal separator (e.g., `305.77`)
285
+ - [ ] All URLs are absolute and accessible
286
+ - [ ] No duplicate products
287
+ - [ ] Product names are concise without promotional text
288
+ - [ ] Images have white backgrounds, no watermarks/logos
289
+ - [ ] Used/refurbished items have `<used>1</used>`
290
+ - [ ] No alcohol/tobacco products (Salidzini)
291
+ - [ ] Feed loads within 5 minutes (Salidzini)
292
+ - [ ] Stock quantities match what's shown on your shop pages
293
+
294
+ ### Simple XML Validation Script (Node.js)
295
+
296
+ ```javascript
297
+ import { readFileSync } from 'fs';
298
+ import { XMLParser } from 'fast-xml-parser';
299
+
300
+ const parser = new XMLParser();
301
+ const xml = readFileSync('export/salidzini.xml', 'utf-8');
302
+ const data = parser.parse(xml);
303
+
304
+ const items = Array.isArray(data.root.item) ? data.root.item : [data.root.item];
305
+ const errors = [];
306
+
307
+ items.forEach((item, i) => {
308
+ if (!item.name) errors.push(`Item ${i}: missing <name>`);
309
+ if (!item.link) errors.push(`Item ${i}: missing <link>`);
310
+ if (!item.price || isNaN(Number(item.price))) {
311
+ errors.push(`Item ${i}: invalid or missing <price>`);
312
+ }
313
+ if (item.name && String(item.name).length > 200) {
314
+ errors.push(`Item ${i}: name exceeds 200 characters`);
315
+ }
316
+ });
317
+
318
+ console.log(`Checked ${items.length} items, found ${errors.length} errors`);
319
+ errors.forEach(e => console.error(e));
320
+ ```
321
+
322
+ ## Scheduling
323
+
324
+ ### Cron (Linux)
325
+
326
+ ```bash
327
+ # Regenerate feeds every day at 3 AM
328
+ 0 3 * * * /usr/bin/node /var/www/shop/scripts/generate-feeds.js >> /var/log/feed-export.log 2>&1
329
+ ```
330
+
331
+ ### Node.js with node-cron
332
+
333
+ ```javascript
334
+ import cron from 'node-cron';
335
+
336
+ // Run daily at 3 AM
337
+ cron.schedule('0 3 * * *', async () => {
338
+ console.log('Generating aggregator feeds...');
339
+ const products = await fetchProductsFromDatabase();
340
+ await generateFeed(products, 'salidzini', './public/export/salidzini.xml');
341
+ await generateFeed(products, 'kurpirkt', './public/export/kurpirkt.xml');
342
+ console.log('Feeds generated successfully');
343
+ });
344
+ ```
345
+
346
+ ### Windows Task Scheduler
347
+
348
+ ```batch
349
+ schtasks /create /tn "GenerateAggregatorFeeds" /tr "node C:\shop\scripts\generate-feeds.js" /sc daily /st 03:00
350
+ ```
351
+
352
+ ## Common Pitfalls
353
+
354
+ 1. **Wrong encoding** - Always use UTF-8. Latvian characters (ā, č, ē, ģ, ī, ķ, ļ, ņ, š, ū, ž) will break if the file isn't properly encoded.
355
+
356
+ 2. **HTML entities in XML** - The category separator `>>` must be escaped as `&gt;&gt;` in Salidzini feeds. Use CDATA sections for fields that may contain special characters.
357
+
358
+ 3. **Price format** - Use dot (`.`), never comma (`,`). `305.77` is correct, `305,77` will fail.
359
+
360
+ 4. **Promotional text in names** - Aggregators actively check for and reject names with "Free shipping", "Best price", "Akcija", etc.
361
+
362
+ 5. **Missing or low-quality images** - Images with logos, text overlays, or non-white backgrounds get rejected. Better to leave `<image>` empty than provide a non-compliant image.
363
+
364
+ 6. **Stale feeds** - Update at least daily. If your feed shows products that are out of stock or have wrong prices, the aggregator may penalize your shop.
365
+
366
+ 7. **Slow feed response** - Salidzini requires feed delivery within 5 minutes. For large catalogs (10,000+ items), pre-generate the XML file rather than building it dynamically per request.
367
+
368
+ 8. **Duplicate products** - Same product with different colors/sizes should ideally be separate items with unique names, not duplicates of the same listing.
@@ -0,0 +1,103 @@
1
+ # KurPirkt.lv XML Feed Specification
2
+
3
+ Latvia's largest price comparison and product search portal (30,000-45,000 daily visitors, 1,200+ listed shops). Documentation source: `https://www.kurpirkt.lv/veikaliem.php`
4
+
5
+ ## Registration
6
+
7
+ Submit an application via email to **kurpirkt@kurpirkt.lv** with:
8
+
9
+ 1. URL to your product XML feed (e.g., `https://www.yourshop.lv/files/export/kurpirkt.php`)
10
+ 2. Link to your shop's contact information page
11
+ 3. Link to your shop's delivery information page
12
+ 4. Your company's legal details (rekvizīti)
13
+ 5. Email address for the shop's admin profile (e.g., `info@yourshop.lv`)
14
+ 6. Confirmation that the KurPirkt.lv partner banner is placed on your shop
15
+
16
+ **Phone:** +371 26533032
17
+
18
+ Each application is reviewed and verified before being added to the KurPirkt.lv database. Confirmation email is sent upon approval. If no confirmation within one week, contact them again.
19
+
20
+ ## Shop Requirements
21
+
22
+ - Products must have clearly displayed prices and payment methods
23
+ - All products must be deliverable or available for pickup in Latvia
24
+ - Delivery prices and terms must be clearly stated
25
+ - Clear product return process and warranty terms required
26
+ - KurPirkt.lv partner banner must be placed on shop's homepage
27
+ - Self-reviews on KurPirkt.lv are prohibited
28
+ - Misusing KurPirkt.lv database (copying, scraping) is prohibited
29
+ - Shops violating terms or consumer rights may be disconnected (with prior notice)
30
+ - KurPirkt.lv may charge for clicks from the search engine
31
+ - Terms changes are communicated at least 15 days before taking effect
32
+ - Shops can opt out of terms changes within 5 days before they take effect
33
+ - Shops can terminate cooperation with at least 5 days notice
34
+ - KurPirkt.lv can terminate cooperation with at least 30 days notice with stated reasons
35
+
36
+ ## XML Feed Structure
37
+
38
+ ```xml
39
+ <?xml version='1.0' encoding='utf-8' ?>
40
+ <root>
41
+ <item>
42
+ <name>Apple iPhone 13 PRO 512GB black</name>
43
+ <link>https://www.example.lv/page.php?prod=1234</link>
44
+ <price>1200.59</price>
45
+ <image>https://www.example.lv/bildes/apple_iphone_13_pro.jpg</image>
46
+ <manufacturer>Apple</manufacturer>
47
+ <category>Mobilie telefoni</category>
48
+ <category_full>Sakaru līdzekļi > Mobilie telefoni</category_full>
49
+ <category_link>https://www.example.lv/page.php?cat=12</category_link>
50
+ <in_stock>5</in_stock>
51
+ <delivery_cost_riga>2.25</delivery_cost_riga>
52
+ <used>0</used>
53
+ </item>
54
+ </root>
55
+ ```
56
+
57
+ ## Field Reference
58
+
59
+ | Tag | Required | Description | Constraints |
60
+ |-----|----------|-------------|-------------|
61
+ | `<name>` | Yes | Product name | Brand + model + key identifiers |
62
+ | `<link>` | Yes | Full product page URL | Complete URL to the product |
63
+ | `<price>` | Yes | Price in EUR including VAT | Numeric, dot decimal separator |
64
+ | `<image>` | No | Product image URL | White background, no watermarks |
65
+ | `<manufacturer>` | No | Product manufacturer/brand | **Note:** Salidzini uses `<brand>` |
66
+ | `<category>` | No | Short category name | Single-level category |
67
+ | `<category_full>` | No | Full category path with hierarchy | Use `>` as separator (not `>>`) |
68
+ | `<category_link>` | No | Category page URL | |
69
+ | `<in_stock>` | No | Available stock quantity | Numeric value |
70
+ | `<delivery_cost_riga>` | No | Delivery cost to Riga | Numeric, EUR. **Note:** Salidzini uses `<delivery_latvija>` (all Latvia) |
71
+ | `<used>` | No | Used/demo product marker | `1` for used items, `0` for new. **Mandatory** value `1` for used/demo products. |
72
+
73
+ ## Key Differences from Salidzini.lv
74
+
75
+ | Aspect | KurPirkt.lv | Salidzini.lv |
76
+ |--------|-------------|-------------|
77
+ | Brand tag | `<manufacturer>` | `<brand>` |
78
+ | Delivery cost tag | `<delivery_cost_riga>` (Riga only) | `<delivery_latvija>` (all Latvia) |
79
+ | Category separator | `>` | `>>` |
80
+ | Additional fields | Fewer (no model, color, mpn, ean, adult, medicine) | More detailed product attributes |
81
+ | Registration | Email application | Web form |
82
+ | Feed validator | Not mentioned | Available on shops_info page |
83
+ | Short category | `<category>` (single-level) | Not available |
84
+
85
+ ## Banner Code
86
+
87
+ Place the KurPirkt.lv banner on your shop's homepage. Two size options:
88
+
89
+ **88x31px:**
90
+ ```html
91
+ <a href="https://www.kurpirkt.lv" title="Kurpirkt.lv - visi Latvijas interneta veikali un cenas">
92
+ <img style="border:none;" alt="Kurpirkt.lv - visi Latvijas interneta veikali un cenas"
93
+ src="//www.kurpirkt.lv/media/kurpirkt88.gif" width="88" height="31">
94
+ </a>
95
+ ```
96
+
97
+ **120x40px:**
98
+ ```html
99
+ <a href="https://www.kurpirkt.lv" title="Kurpirkt.lv - visi Latvijas interneta veikali un cenas">
100
+ <img style="border:none;" alt="Kurpirkt.lv - visi Latvijas interneta veikali un cenas"
101
+ src="//www.kurpirkt.lv/media/kurpirkt120.gif" width="120" height="40">
102
+ </a>
103
+ ```
@@ -0,0 +1,122 @@
1
+ # Salidzini.lv XML Feed Specification
2
+
3
+ Latvia's largest price comparison engine (~47,000 daily visitors, ~1.3 million monthly). Documentation source: `https://www.salidzini.lv/shops_info.php`
4
+
5
+ ## Registration
6
+
7
+ 1. Fill out the application form at `https://www.salidzini.lv/shops_info.php`
8
+ 2. Provide your shop URL and contact email
9
+ 3. Indicate whether you need XML feed creation assistance (available from 2 EUR/month)
10
+ 4. After registration, shop name and domain cannot be changed
11
+
12
+ ## Shop Requirements
13
+
14
+ - Products must be purchasable online with delivery available in Latvia
15
+ - Payment and delivery process must be clearly described
16
+ - Salidzini.lv partner banner must be placed on the shop's website
17
+ - XML product feed must be created and hosted (specification below)
18
+ - Shops may be disconnected upon receiving many complaints or suspicion of unfair practices
19
+ - Registering multiple shops with similar product ranges is prohibited
20
+ - Listing the same product multiple times is prohibited
21
+ - Public contests encouraging review placement are prohibited
22
+ - Self-reviews or paid reviews are prohibited
23
+
24
+ ## XML Feed Structure
25
+
26
+ ```xml
27
+ <?xml version="1.0" encoding="utf-8" ?>
28
+ <root>
29
+ <item>
30
+ <!-- Required fields -->
31
+ <name>Samsung Galaxy S8 G950F Black</name>
32
+ <link>http://www.shop-name.lv/info/SamsungGalaxyS8G950FBlack/</link>
33
+ <price>305.77</price>
34
+
35
+ <!-- Optional fields -->
36
+ <image>http://www.shop-name.lv/images/SamsungGalaxyS8G950FBlack.jpg</image>
37
+ <category_full>Mobilie telefoni &gt;&gt; Samsung</category_full>
38
+ <category_link>http://www.shop-name.lv/Samsung</category_link>
39
+ <brand>Samsung</brand>
40
+ <model><![CDATA[Galaxy S8]]></model>
41
+ <color>Black</color>
42
+ <mpn>SM-G950F</mpn>
43
+ <ean>0644391356614</ean>
44
+ <in_stock>7</in_stock>
45
+ <delivery_latvija>1.90</delivery_latvija>
46
+ <delivery_days_latvija>5</delivery_days_latvija>
47
+ <delivery_days_shop>2</delivery_days_shop>
48
+ <service_fee>0.99</service_fee>
49
+ <used></used>
50
+ <adult>no</adult>
51
+ <over_the_counter_medicine></over_the_counter_medicine>
52
+ </item>
53
+ </root>
54
+ ```
55
+
56
+ ## Field Reference
57
+
58
+ ### Required Fields
59
+
60
+ | Tag | Description | Constraints |
61
+ |-----|-------------|-------------|
62
+ | `<name>` | Product name. Preferably only manufacturer, model, and code. | Max 200 characters. Must be concise, descriptive, no promo text. |
63
+ | `<link>` | Full product page URL on the registered domain. | Max 500 characters. Must be a complete URL. |
64
+ | `<price>` | Final price in EUR including VAT. | Numeric value with dot as decimal separator. Must include all additional costs except delivery. |
65
+
66
+ ### Optional Fields
67
+
68
+ | Tag | Description | Constraints |
69
+ |-----|-------------|-------------|
70
+ | `<image>` | Product image URL. | Max 500 chars, max 16MB file size. Min 500x500px recommended. White background, no frames, no logos/watermarks/overlays. Leave empty if no proper image. |
71
+ | `<category_full>` | Full category path with parent categories. | Max 200 chars. Use `>>` as hierarchy separator. Must describe the product category, no promo words. |
72
+ | `<category_link>` | URL to the category page. | Max 500 characters. |
73
+ | `<brand>` | Product brand / manufacturer. | |
74
+ | `<model>` | Product model name. | CDATA supported. |
75
+ | `<color>` | Product color in English or Latvian. | |
76
+ | `<mpn>` | Manufacturer Part Number. | |
77
+ | `<ean>` | EAN code (also GTIN, UPC, JAN, ISBN). | |
78
+ | `<in_stock>` | Available quantity in warehouse for delivery to Riga within 4 business days. | Numeric value. Must match the quantity shown on the shop's product page. |
79
+ | `<delivery_latvija>` | Lowest delivery cost in Latvia (to address, parcel locker, or post office). | Numeric value. Leave empty if unavailable. |
80
+ | `<delivery_days_latvija>` | Minimum guaranteed delivery days in Latvia. Example: if delivery is 3-5 days, specify `5`. | Numeric value. Leave empty if unavailable. |
81
+ | `<delivery_days_shop>` | Maximum business days for free in-store pickup. Use `0` if available today. | Numeric value. Leave empty if unavailable. |
82
+ | `<service_fee>` | Purchase service/handling fee, if any. | Numeric value. |
83
+ | `<used>` | Mark used, refurbished, demo, or damaged products. | Value `1` is **mandatory** for such products. |
84
+ | `<adult>` | Mark sexual, nude, erotic, or intimate products. | Values: `yes`/`no`. **Mandatory** for adult product sellers. |
85
+ | `<over_the_counter_medicine>` | Mark over-the-counter medicines (no prescription needed). | Value `1`. For pharmaceutical sellers. |
86
+
87
+ ## Naming Rules
88
+
89
+ Product names should follow the pattern: **Brand + Model + Key Identifier**
90
+
91
+ **Good:** `Samsung Galaxy S8 G950F Black`
92
+ **Bad:** `Super deal! Samsung Galaxy S8 - Free shipping - Best price - Buy now!`
93
+
94
+ Prohibited in names:
95
+ - "Ir uz vietas" (In stock), "Bezmaksas piegāde" (Free delivery), "Bezmaksas kredīts" (Free credit)
96
+ - "Labākā izvēle" (Best choice), "Augstākā kvalitāte" (Highest quality)
97
+ - "Iegādājies tagad" (Buy now), "Ideāli dāvanai" (Ideal for gift)
98
+ - "Super cena" (Super price), "Jaunums" (New), and similar promotional phrases
99
+ - Excessively long, unclear, or machine-translated names
100
+
101
+ ## Image Rules
102
+
103
+ - Must represent the product's actual appearance
104
+ - White background, no frames
105
+ - No shop logo, price, or other unrelated imagery
106
+ - No overlaid text ("In stock", "Good product", "10 years on market", "Gift", "0% credit")
107
+ - If no suitable product image exists, use empty `<image></image>`
108
+
109
+ ## Content Restrictions
110
+
111
+ - No alcohol or tobacco products
112
+ - Only products with delivery within 30 days
113
+ - Each product listed only once
114
+ - All information must match what's displayed on the shop's product page
115
+
116
+ ## Feed Validation
117
+
118
+ Salidzini provides an XML feed validator at `https://www.salidzini.lv/shops_info.php` (bottom of page). Enter your feed URL to check for errors.
119
+
120
+ ## Banner Code
121
+
122
+ The shop must display a Salidzini.lv banner. Three variants are available (blue, dark, light) at 190x60px. The banner images are hosted at `static.salidzini.lv/images/`.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: notebooklm
2
+ name: notebook-lm
3
3
  description: |
4
4
  Automate Google NotebookLM via the notebooklm-py Python library. Use this skill whenever the user wants to:
5
5
  - Create, manage, or delete NotebookLM notebooks