@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,201 @@
1
+ # Inventories Sub-API Reference
2
+
3
+ Base: `https://merchantapi.googleapis.com/inventories/v1`
4
+
5
+ Manage product availability and pricing at the store level (local) or region level (regional).
6
+
7
+ ## Local Inventories
8
+
9
+ Store-level inventory for brick-and-mortar locations.
10
+
11
+ | Method | Endpoint | Description |
12
+ |--------|----------|-------------|
13
+ | `POST` | `/accounts/{account}/products/{product}/localInventories` | Insert/update local inventory |
14
+ | `GET` | `/accounts/{account}/products/{product}/localInventories` | List local inventories |
15
+ | `DELETE` | `/accounts/{account}/products/{product}/localInventories/{storeCode}` | Delete local inventory |
16
+
17
+ ### LocalInventory Object
18
+
19
+ ```json
20
+ {
21
+ "name": "accounts/123456/products/en~US~SKU001/localInventories/STORE-NYC-01",
22
+ "account": "accounts/123456",
23
+ "storeCode": "STORE-NYC-01",
24
+ "availability": "in_stock",
25
+ "price": {
26
+ "amountMicros": "69990000",
27
+ "currencyCode": "USD"
28
+ },
29
+ "salePrice": {
30
+ "amountMicros": "59990000",
31
+ "currencyCode": "USD"
32
+ },
33
+ "salePriceEffectiveDate": {
34
+ "startTime": "2024-12-01T00:00:00Z",
35
+ "endTime": "2024-12-31T23:59:59Z"
36
+ },
37
+ "quantity": "25",
38
+ "pickupMethod": "buy",
39
+ "pickupSla": "same day",
40
+ "instoreProductLocation": "Aisle 5, Shelf B",
41
+ "customAttributes": [
42
+ { "name": "display_unit", "value": "true" }
43
+ ]
44
+ }
45
+ ```
46
+
47
+ ### Fields
48
+
49
+ | Field | Type | Required | Description |
50
+ |-------|------|----------|-------------|
51
+ | `storeCode` | string | Required | Your store identifier (must match Google Business Profile) |
52
+ | `availability` | enum | Optional | `in_stock`, `out_of_stock`, `preorder`, `backorder` |
53
+ | `price` | Price | Optional | Store-specific price override |
54
+ | `salePrice` | Price | Optional | Store-specific sale price |
55
+ | `salePriceEffectiveDate` | Interval | Optional | Sale period |
56
+ | `quantity` | int64 | Optional | Stock quantity |
57
+ | `pickupMethod` | enum | Optional | `buy`, `reserve`, `ship_to_store`, `not_supported` |
58
+ | `pickupSla` | enum | Optional | `same_day`, `next_day`, `2_day` ... `7_day`, `multi_week` |
59
+ | `instoreProductLocation` | string | Optional | Physical location in store |
60
+ | `customAttributes[]` | array | Optional | Additional attributes |
61
+
62
+ ### Insert Example
63
+
64
+ ```javascript
65
+ const MERCHANT_ID = '123456';
66
+ const PRODUCT_ID = 'en~US~SKU001';
67
+
68
+ const localInventory = {
69
+ storeCode: 'STORE-NYC-01',
70
+ availability: 'in_stock',
71
+ price: { amountMicros: '69990000', currencyCode: 'USD' },
72
+ quantity: '25',
73
+ pickupMethod: 'buy',
74
+ pickupSla: 'same_day',
75
+ };
76
+
77
+ const response = await fetch(
78
+ `https://merchantapi.googleapis.com/inventories/v1/accounts/${MERCHANT_ID}/products/${PRODUCT_ID}/localInventories`,
79
+ {
80
+ method: 'POST',
81
+ headers: {
82
+ 'Authorization': `Bearer ${token}`,
83
+ 'Content-Type': 'application/json',
84
+ },
85
+ body: JSON.stringify(localInventory),
86
+ }
87
+ );
88
+ ```
89
+
90
+ ## Regional Inventories
91
+
92
+ Region-level overrides for pricing and availability based on geographic regions you define.
93
+
94
+ | Method | Endpoint | Description |
95
+ |--------|----------|-------------|
96
+ | `POST` | `/accounts/{account}/products/{product}/regionalInventories` | Insert/update regional inventory |
97
+ | `GET` | `/accounts/{account}/products/{product}/regionalInventories` | List regional inventories |
98
+ | `DELETE` | `/accounts/{account}/products/{product}/regionalInventories/{region}` | Delete regional inventory |
99
+
100
+ ### RegionalInventory Object
101
+
102
+ ```json
103
+ {
104
+ "name": "accounts/123456/products/en~US~SKU001/regionalInventories/northeast",
105
+ "account": "accounts/123456",
106
+ "region": "northeast",
107
+ "availability": "in_stock",
108
+ "price": {
109
+ "amountMicros": "74990000",
110
+ "currencyCode": "USD"
111
+ },
112
+ "salePrice": {
113
+ "amountMicros": "64990000",
114
+ "currencyCode": "USD"
115
+ },
116
+ "salePriceEffectiveDate": {
117
+ "startTime": "2024-12-01T00:00:00Z",
118
+ "endTime": "2024-12-31T23:59:59Z"
119
+ },
120
+ "customAttributes": []
121
+ }
122
+ ```
123
+
124
+ ### Fields
125
+
126
+ | Field | Type | Required | Description |
127
+ |-------|------|----------|-------------|
128
+ | `region` | string | Required | Region ID (must be defined via Accounts > Regions) |
129
+ | `availability` | enum | Optional | Same as local inventory |
130
+ | `price` | Price | Optional | Region-specific price override |
131
+ | `salePrice` | Price | Optional | Region-specific sale price |
132
+ | `salePriceEffectiveDate` | Interval | Optional | Sale period |
133
+ | `customAttributes[]` | array | Optional | Additional attributes |
134
+
135
+ ### Workflow: Set Up Regional Pricing
136
+
137
+ 1. **Define regions** via the Accounts sub-API:
138
+ ```javascript
139
+ // Create a region
140
+ await fetch(
141
+ `https://merchantapi.googleapis.com/accounts/v1/accounts/${MERCHANT_ID}/regions`,
142
+ {
143
+ method: 'POST',
144
+ headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
145
+ body: JSON.stringify({
146
+ displayName: 'US Northeast',
147
+ postalCodeArea: {
148
+ regionCode: 'US',
149
+ postalCodes: [
150
+ { begin: '10000', end: '14999' },
151
+ { begin: '06000', end: '06999' },
152
+ ],
153
+ },
154
+ }),
155
+ }
156
+ );
157
+ ```
158
+
159
+ 2. **Set regional inventory** for products:
160
+ ```javascript
161
+ await fetch(
162
+ `https://merchantapi.googleapis.com/inventories/v1/accounts/${MERCHANT_ID}/products/en~US~SKU001/regionalInventories`,
163
+ {
164
+ method: 'POST',
165
+ headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
166
+ body: JSON.stringify({
167
+ region: 'northeast',
168
+ price: { amountMicros: '74990000', currencyCode: 'USD' },
169
+ availability: 'in_stock',
170
+ }),
171
+ }
172
+ );
173
+ ```
174
+
175
+ ## Bulk Inventory Updates
176
+
177
+ For updating many products' inventory, use async parallel requests:
178
+
179
+ ```javascript
180
+ // Update inventory for multiple products in parallel
181
+ const inventoryUpdates = [
182
+ { productId: 'en~US~SKU001', storeCode: 'STORE-01', quantity: '50', availability: 'in_stock' },
183
+ { productId: 'en~US~SKU002', storeCode: 'STORE-01', quantity: '0', availability: 'out_of_stock' },
184
+ { productId: 'en~US~SKU003', storeCode: 'STORE-01', quantity: '12', availability: 'in_stock' },
185
+ ];
186
+
187
+ const results = await Promise.allSettled(
188
+ inventoryUpdates.map(({ productId, ...inventory }) =>
189
+ fetch(
190
+ `https://merchantapi.googleapis.com/inventories/v1/accounts/${MERCHANT_ID}/products/${productId}/localInventories`,
191
+ {
192
+ method: 'POST',
193
+ headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
194
+ body: JSON.stringify(inventory),
195
+ }
196
+ )
197
+ )
198
+ );
199
+ ```
200
+
201
+ Respect rate limits — implement exponential backoff for `429` responses.
@@ -0,0 +1,267 @@
1
+ # Migration: Content API for Shopping to Merchant API
2
+
3
+ The Content API for Shopping (v2.1) sunsets **August 18, 2026**. The Merchant API (v1) is the replacement.
4
+
5
+ ## Key Architectural Changes
6
+
7
+ ### 1. Products Split into Input + Output
8
+
9
+ **Content API:** Single `products` resource for read and write.
10
+
11
+ **Merchant API:** Split into:
12
+ - `productInputs` - What you submit (write)
13
+ - `products` - What Google processed (read-only, includes status)
14
+
15
+ This means `productstatuses` is gone — status is now part of the `products` resource.
16
+
17
+ ### 2. Modular Sub-APIs
18
+
19
+ **Content API:** Monolithic API with all resources under one service.
20
+
21
+ **Merchant API:** 14 independent sub-APIs, each with own versioning:
22
+ - `products/v1`, `accounts/v1`, `inventories/v1`, `reports/v1`, etc.
23
+
24
+ ### 3. Resource Naming
25
+
26
+ **Content API ID format:**
27
+ ```
28
+ channel:contentLanguage:targetCountry:offerId
29
+ Example: online:en:US:sku123
30
+ ```
31
+
32
+ **Merchant API name format:**
33
+ ```
34
+ accounts/{accountId}/products/{contentLanguage}~{feedLabel}~{offerId}
35
+ Example: accounts/123456/products/en~US~sku123
36
+ ```
37
+
38
+ ### 4. Price Format
39
+
40
+ **Content API:**
41
+ ```json
42
+ { "value": "79.99", "currency": "USD" }
43
+ ```
44
+
45
+ **Merchant API:**
46
+ ```json
47
+ { "amountMicros": "79990000", "currencyCode": "USD" }
48
+ ```
49
+
50
+ Conversion: `amountMicros = value * 1000000`
51
+
52
+ ### 5. Field Nesting
53
+
54
+ **Content API:** Flat top-level attributes.
55
+ ```json
56
+ {
57
+ "offerId": "SKU-001",
58
+ "title": "My Product",
59
+ "price": { "value": "79.99", "currency": "USD" }
60
+ }
61
+ ```
62
+
63
+ **Merchant API:** Attributes nested under `productAttributes`.
64
+ ```json
65
+ {
66
+ "offerId": "SKU-001",
67
+ "productAttributes": {
68
+ "title": "My Product",
69
+ "price": { "amountMicros": "79990000", "currencyCode": "USD" }
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### 6. targetCountry → feedLabel
75
+
76
+ `targetCountry` is renamed to `feedLabel`. Values are the same (e.g., `US`, `GB`).
77
+
78
+ ### 7. Batching
79
+
80
+ **Content API:** `customBatch` methods.
81
+
82
+ **Merchant API:** No custom batch. Use async parallel requests or HTTP batching instead.
83
+
84
+ ### 8. Data Source Required
85
+
86
+ All `productInputs` write operations require a `dataSource` query parameter:
87
+ ```
88
+ POST /products/v1/accounts/{id}/productInputs:insert?dataSource=accounts/{id}/dataSources/{dsId}
89
+ ```
90
+
91
+ ### 9. Base64url Encoding
92
+
93
+ Product names containing special characters (`% . + / : ~ , ( * ! ) & ? = @ # $`) must use unpadded base64url encoding (RFC 4648 Section 5).
94
+
95
+ ## Method Mapping
96
+
97
+ | Content API Method | Merchant API Method |
98
+ |-------------------|---------------------|
99
+ | `products.insert` | `productInputs:insert` |
100
+ | `products.update` | `productInputs:patch` |
101
+ | `products.delete` | `productInputs:delete` |
102
+ | `products.get` | `products.get` |
103
+ | `products.list` | `products.list` |
104
+ | `products.custombatch` | Async parallel requests |
105
+ | `productstatuses.get` | `products.get` (status included) |
106
+ | `productstatuses.list` | `products.list` (status included) |
107
+ | `productstatuses.custombatch` | Async parallel requests |
108
+ | `accounts.get` | `accounts.get` |
109
+ | `accounts.list` | `accounts.list` |
110
+ | `accounts.update` | `accounts.patch` |
111
+ | `accounts.insert` | `accounts:createAndConfigure` |
112
+ | `accounts.delete` | `accounts.delete` |
113
+ | `accountstatuses.get` | `accounts/{id}/issues.list` |
114
+ | `datafeeds.*` | `dataSources.*` |
115
+ | `datafeedstatuses.*` | `dataSources/{id}/fileUploads/{id}` |
116
+ | `liasettings.*` | `omnichannelSettings.*` |
117
+ | `shippingsettings.*` | `shippingSettings.*` |
118
+ | `regions.*` | `regions.*` |
119
+ | `returnpolicy.*` | `onlineReturnPolicies.*` |
120
+
121
+ ## Migration Strategy
122
+
123
+ ### Recommended Order
124
+
125
+ 1. **Accounts** - Foundation for everything else
126
+ 2. **Products** - Core product management
127
+ 3. **Data Sources** - Feed management (compatible across APIs)
128
+ 4. **Reports** - Performance data
129
+ 5. **Everything else** - Promotions, inventory, notifications, etc.
130
+
131
+ ### Incremental Approach
132
+
133
+ You can migrate one sub-API at a time. Content API and Merchant API can coexist:
134
+ - Data sources created with Content API work with Merchant API
135
+ - Products inserted via Content API are visible through Merchant API
136
+ - Migrate sub-APIs independently, test each before moving to the next
137
+
138
+ ### Code Migration Example
139
+
140
+ **Before (Content API):**
141
+ ```javascript
142
+ // Insert product
143
+ const response = await fetch(
144
+ `https://shoppingcontent.googleapis.com/content/v2.1/${MERCHANT_ID}/products`,
145
+ {
146
+ method: 'POST',
147
+ headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
148
+ body: JSON.stringify({
149
+ offerId: 'SKU-001',
150
+ title: 'Premium Headphones',
151
+ description: 'Great headphones',
152
+ link: 'https://example.com/product',
153
+ imageLink: 'https://example.com/image.jpg',
154
+ contentLanguage: 'en',
155
+ targetCountry: 'US',
156
+ channel: 'online',
157
+ availability: 'in stock',
158
+ condition: 'new',
159
+ price: { value: '79.99', currency: 'USD' },
160
+ brand: 'AudioBrand',
161
+ gtin: '0123456789012',
162
+ }),
163
+ }
164
+ );
165
+
166
+ // Get product status
167
+ const status = await fetch(
168
+ `https://shoppingcontent.googleapis.com/content/v2.1/${MERCHANT_ID}/productstatuses/online:en:US:SKU-001`,
169
+ { headers: { 'Authorization': `Bearer ${token}` } }
170
+ );
171
+ ```
172
+
173
+ **After (Merchant API):**
174
+ ```javascript
175
+ // Insert product input
176
+ const response = await fetch(
177
+ `https://merchantapi.googleapis.com/products/v1/accounts/${MERCHANT_ID}/productInputs:insert?dataSource=accounts/${MERCHANT_ID}/dataSources/${DS_ID}`,
178
+ {
179
+ method: 'POST',
180
+ headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
181
+ body: JSON.stringify({
182
+ offerId: 'SKU-001',
183
+ contentLanguage: 'en',
184
+ feedLabel: 'US',
185
+ productAttributes: {
186
+ title: 'Premium Headphones',
187
+ description: 'Great headphones',
188
+ link: 'https://example.com/product',
189
+ imageLink: 'https://example.com/image.jpg',
190
+ availability: 'in_stock',
191
+ condition: 'new',
192
+ price: { amountMicros: '79990000', currencyCode: 'USD' },
193
+ brand: 'AudioBrand',
194
+ gtin: '0123456789012',
195
+ channel: 'ONLINE',
196
+ },
197
+ }),
198
+ }
199
+ );
200
+
201
+ // Get product (includes status)
202
+ const product = await fetch(
203
+ `https://merchantapi.googleapis.com/products/v1/accounts/${MERCHANT_ID}/products/en~US~SKU-001`,
204
+ { headers: { 'Authorization': `Bearer ${token}` } }
205
+ );
206
+ // product.productStatus contains destinationStatuses and itemLevelIssues
207
+ ```
208
+
209
+ ## Price Conversion Helper
210
+
211
+ ```javascript
212
+ // Content API price → Merchant API price
213
+ function toMerchantPrice(contentPrice) {
214
+ return {
215
+ amountMicros: String(Math.round(parseFloat(contentPrice.value) * 1_000_000)),
216
+ currencyCode: contentPrice.currency,
217
+ };
218
+ }
219
+
220
+ // Merchant API price → Content API price
221
+ function toContentPrice(merchantPrice) {
222
+ return {
223
+ value: String(parseInt(merchantPrice.amountMicros) / 1_000_000),
224
+ currency: merchantPrice.currencyCode,
225
+ };
226
+ }
227
+ ```
228
+
229
+ ```python
230
+ # Content API price → Merchant API price
231
+ def to_merchant_price(content_price):
232
+ return {
233
+ 'amountMicros': str(round(float(content_price['value']) * 1_000_000)),
234
+ 'currencyCode': content_price['currency'],
235
+ }
236
+
237
+ # Merchant API price → Content API price
238
+ def to_content_price(merchant_price):
239
+ return {
240
+ 'value': str(int(merchant_price['amountMicros']) / 1_000_000),
241
+ 'currency': merchant_price['currencyCode'],
242
+ }
243
+ ```
244
+
245
+ ## Product ID Conversion
246
+
247
+ ```javascript
248
+ // Content API ID → Merchant API name
249
+ function toMerchantProductName(contentId, accountId) {
250
+ // contentId format: "online:en:US:sku123"
251
+ const [channel, lang, country, ...offerId] = contentId.split(':');
252
+ const offer = offerId.join(':');
253
+ const prefix = channel === 'local' ? 'local~' : '';
254
+ return `accounts/${accountId}/products/${prefix}${lang}~${country}~${offer}`;
255
+ }
256
+
257
+ // Merchant API name → Content API ID
258
+ function toContentProductId(merchantName) {
259
+ // merchantName: "accounts/123/products/en~US~sku123"
260
+ const productPart = merchantName.split('/products/')[1];
261
+ const isLocal = productPart.startsWith('local~');
262
+ const parts = (isLocal ? productPart.slice(6) : productPart).split('~');
263
+ const [lang, feedLabel, ...offerId] = parts;
264
+ const channel = isLocal ? 'local' : 'online';
265
+ return `${channel}:${lang}:${feedLabel}:${offerId.join('~')}`;
266
+ }
267
+ ```