@ssheleg/sheleg-dev 0.4.0

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 (32) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/LICENSE +21 -0
  3. package/README.md +132 -0
  4. package/SECURITY.md +63 -0
  5. package/bin/sheleg-dev.js +99 -0
  6. package/package.json +45 -0
  7. package/plugins/sheleg-dev/.claude-plugin/plugin.json +28 -0
  8. package/plugins/sheleg-dev/skills/ad-tracking/SKILL.md +442 -0
  9. package/plugins/sheleg-dev/skills/ad-tracking/references/consent-mode.md +257 -0
  10. package/plugins/sheleg-dev/skills/ad-tracking/references/event-tracking.md +201 -0
  11. package/plugins/sheleg-dev/skills/ad-tracking/references/gtag-api.md +389 -0
  12. package/plugins/sheleg-dev/skills/ad-tracking/references/meta-linkedin.md +103 -0
  13. package/plugins/sheleg-dev/skills/ad-tracking/references/performance-security.md +288 -0
  14. package/plugins/sheleg-dev/skills/crypto-payments/SKILL.md +384 -0
  15. package/plugins/sheleg-dev/skills/crypto-payments/references/heleket-provider.md +1357 -0
  16. package/plugins/sheleg-dev/skills/frontend-performance/SKILL.md +147 -0
  17. package/plugins/sheleg-dev/skills/frontend-performance/references/accessibility-perf.md +172 -0
  18. package/plugins/sheleg-dev/skills/frontend-performance/references/css-performance.md +180 -0
  19. package/plugins/sheleg-dev/skills/frontend-performance/references/nextjs.md +271 -0
  20. package/plugins/sheleg-dev/skills/google-auth/SKILL.md +275 -0
  21. package/plugins/sheleg-dev/skills/google-auth/references/adc-and-service-accounts.md +464 -0
  22. package/plugins/sheleg-dev/skills/google-auth/references/oauth2-web-server.md +615 -0
  23. package/plugins/sheleg-dev/skills/google-auth/references/sign-in-with-google.md +593 -0
  24. package/plugins/sheleg-dev/skills/google-auth/references/workload-identity.md +376 -0
  25. package/plugins/sheleg-dev/skills/google-signin/SKILL.md +121 -0
  26. package/plugins/sheleg-dev/skills/google-signin/references/full-guide.md +421 -0
  27. package/plugins/sheleg-dev/skills/stripe-billing/SKILL.md +458 -0
  28. package/plugins/sheleg-dev/skills/stripe-billing/references/price-integrity.md +201 -0
  29. package/plugins/sheleg-dev/skills/stripe-billing/references/stripe-agent-toolchain.md +173 -0
  30. package/plugins/sheleg-dev/skills/stripe-billing/references/subscription-lifecycle.md +294 -0
  31. package/plugins/sheleg-dev/skills/stripe-billing/references/testing-and-local-dev.md +214 -0
  32. package/plugins/sheleg-dev/skills/stripe-billing/references/webhook-events.md +211 -0
@@ -0,0 +1,389 @@
1
+ # gtag.js API Reference
2
+
3
+ Source: [Google Tag Platform — gtag.js](https://developers.google.com/tag-platform/gtagjs)
4
+
5
+ ## Contents
6
+
7
+ - [Table of Contents](#table-of-contents)
8
+ - [Overview](#overview)
9
+ - [Installation](#installation)
10
+ - [Tag ID Formats](#tag-id-formats)
11
+ - [Commands](#commands)
12
+ - [Parameter Scope & Precedence](#parameter-scope--precedence)
13
+ - [Data Routing](#data-routing)
14
+ - [Multi-Product Configuration](#multi-product-configuration)
15
+ - [Next.js / React Integration](#nextjs--react-integration)
16
+
17
+
18
+ ## Table of Contents
19
+
20
+ - [Overview](#overview)
21
+ - [Installation](#installation)
22
+ - [Tag ID Formats](#tag-id-formats)
23
+ - [Commands](#commands)
24
+ - [config](#config)
25
+ - [event](#event)
26
+ - [set](#set)
27
+ - [get](#get)
28
+ - [consent](#consent)
29
+ - [Parameter Scope & Precedence](#parameter-scope--precedence)
30
+ - [Data Routing](#data-routing)
31
+ - [Multi-Product Configuration](#multi-product-configuration)
32
+ - [Next.js / React Integration](#nextjs--react-integration)
33
+
34
+ ## Overview
35
+
36
+ The Google tag (`gtag.js`) API consists of a single function:
37
+
38
+ ```javascript
39
+ gtag(<command>, <command_parameters>);
40
+ ```
41
+
42
+ Commands: `config`, `event`, `set`, `get`, `consent`.
43
+
44
+ `gtag()` can be called anywhere on the page **after** the Google tag snippet. Commands are
45
+ queued via `dataLayer.push()` and processed once the gtag.js script loads.
46
+
47
+ ## Installation
48
+
49
+ Place immediately after `<head>` on every page:
50
+
51
+ ```html
52
+ <!-- Google tag (gtag.js) -->
53
+ <script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
54
+ <script>
55
+ window.dataLayer = window.dataLayer || [];
56
+ function gtag(){dataLayer.push(arguments);}
57
+ gtag('js', new Date());
58
+ gtag('config', 'TAG_ID');
59
+ </script>
60
+ ```
61
+
62
+ The `config` command is **required** — it sends data to Google products and enables features
63
+ like automatically collected events and conversion linking.
64
+
65
+ ## Tag ID Formats
66
+
67
+ | Prefix | Type | Description |
68
+ |--------|------|-------------|
69
+ | `GT-XXXXXX` | Google tag | New-format Google tag ID |
70
+ | `G-XXXXXX` | Google tag (legacy) | Google Analytics 4 measurement ID |
71
+ | `AW-XXXXXX` | Google tag (legacy) | Google Ads account ID |
72
+ | `DC-XXXXXX` | Google tag (legacy) | Google Floodlight ID |
73
+
74
+ All prefixes are interchangeable with the Google tag. A single tag can have multiple IDs.
75
+ Universal Analytics (`UA-`) tags are **not** compatible.
76
+
77
+ ## Commands
78
+
79
+ ### config
80
+
81
+ Configures a target (product/account) and establishes data flow.
82
+
83
+ ```javascript
84
+ gtag('config', 'TAG_ID', {<additional_config_params>});
85
+ ```
86
+
87
+ The `config` command may also trigger product-specific behavior. For example, GA4's `config`
88
+ automatically sends a `page_view` event unless disabled:
89
+
90
+ ```javascript
91
+ gtag('config', 'G-XXXXXXXXXX', { 'send_page_view': false });
92
+ ```
93
+
94
+ Common config parameters:
95
+
96
+ | Parameter | Type | Description |
97
+ |-----------|------|-------------|
98
+ | `send_page_view` | boolean | Auto-send `page_view` on config (default: `true` for GA4) |
99
+ | `debug_mode` | boolean | Enable GA4 DebugView for this session |
100
+ | `groups` | string | Assign this target to a named group for routing |
101
+ | `user_id` | string | Set a known user ID for cross-device tracking |
102
+ | `cookie_domain` | string | Domain for GA cookies (default: `'auto'`) |
103
+ | `cookie_expires` | number | Cookie expiration in seconds (default: `63072000` = 2 years) |
104
+ | `cookie_prefix` | string | Prefix for GA cookie names |
105
+ | `cookie_flags` | string | Additional flags for cookies (e.g. `'SameSite=None;Secure'`) |
106
+ | `page_title` | string | Override page title |
107
+ | `page_location` | string | Override page URL |
108
+
109
+ ### event
110
+
111
+ Sends event data to all configured targets (or specific ones via `send_to`).
112
+
113
+ ```javascript
114
+ gtag('event', '<event_name>', {<event_params>});
115
+ ```
116
+
117
+ Event names are either **recommended** (predefined by Google) or **custom** (arbitrary).
118
+
119
+ ```javascript
120
+ // Recommended event
121
+ gtag('event', 'login', { method: 'Google' });
122
+
123
+ // Custom event
124
+ gtag('event', 'newsletter_signup', { time: Date.now() });
125
+ ```
126
+
127
+ Key event parameters:
128
+
129
+ | Parameter | Description |
130
+ |-----------|-------------|
131
+ | `send_to` | Route event to specific target(s) or group(s) |
132
+ | `event_callback` | Function called after event is processed |
133
+ | `event_timeout` | Max ms to wait before calling callback (default: 2000) |
134
+
135
+ ### set
136
+
137
+ Defines parameters associated with **every subsequent event** on the page.
138
+
139
+ ```javascript
140
+ gtag('set', {<parameter_value_pairs>});
141
+ ```
142
+
143
+ ```javascript
144
+ // All subsequent events will include these campaign params
145
+ gtag('set', {
146
+ 'campaign_name': 'Black Friday Sale',
147
+ 'campaign_id': '1234'
148
+ });
149
+ ```
150
+
151
+ Use sparingly — prefer `config` or `event` params when possible.
152
+
153
+ ### get
154
+
155
+ Retrieves values from gtag.js, including values set with `set`.
156
+
157
+ ```javascript
158
+ gtag('get', '<target>', '<field_name>', callback);
159
+ ```
160
+
161
+ Available fields:
162
+
163
+ | Field | Supported targets |
164
+ |-------|------------------|
165
+ | `client_id` | GA4 (`G-*`) |
166
+ | `session_id` | GA4 (`G-*`) |
167
+ | `session_number` | GA4 (`G-*`) |
168
+ | `gclid` | Floodlight (`DC-*`), Google Ads (`AW-*`) |
169
+
170
+ ```javascript
171
+ // Get GA4 client ID
172
+ gtag('get', 'G-XXXXXXXXXX', 'client_id', (clientId) => {
173
+ console.log('Client ID:', clientId);
174
+ });
175
+
176
+ // Get into a Promise
177
+ const clientIdPromise = new Promise(resolve => {
178
+ gtag('get', 'G-XXXXXXXXXX', 'client_id', resolve);
179
+ });
180
+ ```
181
+
182
+ ### consent
183
+
184
+ Configures consent state. See [consent-mode.md](consent-mode.md) for full patterns.
185
+
186
+ ```javascript
187
+ gtag('consent', '<consent_arg>', {<consent_params>});
188
+ ```
189
+
190
+ `consent_arg`: `'default'` (set initial state) or `'update'` (change after user action).
191
+
192
+ | Parameter | Values | Description |
193
+ |-----------|--------|-------------|
194
+ | `ad_storage` | `'granted'` / `'denied'` | Advertising cookies/identifiers |
195
+ | `ad_user_data` | `'granted'` / `'denied'` | User data sent for advertising |
196
+ | `ad_personalization` | `'granted'` / `'denied'` | Personalized advertising |
197
+ | `analytics_storage` | `'granted'` / `'denied'` | Analytics cookies (`_ga`, `_ga_*`) |
198
+ | `wait_for_update` | positive integer (ms) | Time to wait for CMP consent update |
199
+
200
+ ## Parameter Scope & Precedence
201
+
202
+ Parameters can be set at three scopes. Higher-precedence scopes override lower ones:
203
+
204
+ ```
205
+ event > config > set (global)
206
+ ```
207
+
208
+ ```javascript
209
+ gtag('set', { 'currency': 'EUR' }); // global
210
+ gtag('config', 'G-XXXXXX', { 'currency': 'USD' }); // config-scoped
211
+ gtag('event', 'purchase', { 'currency': 'GBP' }); // event-scoped → GBP wins
212
+ ```
213
+
214
+ Setting a parameter in one scope does NOT modify the value in another scope.
215
+
216
+ ## Data Routing
217
+
218
+ ### Default routing
219
+
220
+ All events go to every target configured with `config` (the `default` group):
221
+
222
+ ```javascript
223
+ gtag('config', 'G-XXXXXX'); // added to 'default' group
224
+ gtag('event', 'sign_in'); // sent to G-XXXXXX
225
+ ```
226
+
227
+ ### send_to — Route to specific targets
228
+
229
+ Override default routing with `send_to`:
230
+
231
+ ```javascript
232
+ gtag('event', 'sign_in', { 'send_to': 'G-XXXXXX-2' });
233
+ ```
234
+
235
+ ### Groups — Route to named sets
236
+
237
+ ```javascript
238
+ gtag('config', 'G-XXXXXX-3', { 'groups': 'agency' });
239
+ gtag('config', 'G-XXXXXX-9', { 'groups': 'agency' });
240
+
241
+ // Sends only to G-XXXXXX-3 and G-XXXXXX-9
242
+ gtag('event', 'sign_in', { 'send_to': 'agency' });
243
+ ```
244
+
245
+ A target can belong to multiple groups:
246
+
247
+ ```javascript
248
+ gtag('config', 'G-XXXXXX-1', { 'groups': ['agency', 'internal'] });
249
+ ```
250
+
251
+ ### send_to with arrays
252
+
253
+ Route a single event to multiple specific targets:
254
+
255
+ ```javascript
256
+ gtag('event', 'add_to_cart', {
257
+ 'send_to': ['G-XXXXXX-1', 'AW-YYYYYY'],
258
+ 'items': [{ 'id': 'U1234', 'name': 'Widget', 'price': 9.99 }]
259
+ });
260
+ ```
261
+
262
+ ## Multi-Product Configuration
263
+
264
+ A single Google tag can send data to GA4, Google Ads, and Floodlight simultaneously:
265
+
266
+ ```html
267
+ <script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
268
+ <script>
269
+ window.dataLayer = window.dataLayer || [];
270
+ function gtag(){dataLayer.push(arguments);}
271
+ gtag('js', new Date());
272
+
273
+ gtag('config', 'G-XXXXXX'); // GA4
274
+ gtag('config', 'AW-YYYYYY'); // Google Ads
275
+ gtag('config', 'DC-ZZZZZZ'); // Floodlight
276
+
277
+ // GA4 + Ads get ecommerce
278
+ gtag('event', 'purchase', {
279
+ 'send_to': ['G-XXXXXX', 'AW-YYYYYY'],
280
+ 'transaction_id': 'T_123',
281
+ 'value': 29.99,
282
+ 'currency': 'USD'
283
+ });
284
+
285
+ // Ads-specific conversion
286
+ gtag('event', 'conversion', {
287
+ 'send_to': 'AW-YYYYYY/AbC-D_efG-h12_34-567',
288
+ 'value': 29.99,
289
+ 'currency': 'USD'
290
+ });
291
+ </script>
292
+ ```
293
+
294
+ ## Next.js / React Integration
295
+
296
+ ### Using next/script (App Router)
297
+
298
+ ```tsx
299
+ import Script from 'next/script';
300
+
301
+ const GA_ID = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;
302
+
303
+ export function GoogleAnalytics() {
304
+ if (!GA_ID) return null;
305
+ return (
306
+ <>
307
+ {/* Consent defaults + dataLayer stub (must run first) */}
308
+ <Script id="gtag-consent" strategy="beforeInteractive"
309
+ dangerouslySetInnerHTML={{ __html: `
310
+ window.dataLayer=window.dataLayer||[];
311
+ function gtag(){dataLayer.push(arguments);}
312
+ gtag('consent','default',{
313
+ 'ad_storage':'denied','ad_user_data':'denied',
314
+ 'ad_personalization':'denied','analytics_storage':'denied',
315
+ 'wait_for_update':500
316
+ });
317
+ `}} />
318
+
319
+ {/* Load gtag.js */}
320
+ <Script src={`https://www.googletagmanager.com/gtag/js?id=${GA_ID}`}
321
+ strategy="afterInteractive" />
322
+
323
+ {/* Configure */}
324
+ <Script id="gtag-config" strategy="afterInteractive"
325
+ dangerouslySetInnerHTML={{ __html: `
326
+ window.dataLayer=window.dataLayer||[];
327
+ function gtag(){dataLayer.push(arguments);}
328
+ gtag('js',new Date());
329
+ gtag('config','${GA_ID}');
330
+ `}} />
331
+ </>
332
+ );
333
+ }
334
+ ```
335
+
336
+ ### NEXT_PUBLIC_* in Docker builds
337
+
338
+ `NEXT_PUBLIC_*` variables are inlined at **build time**. For Docker deployments,
339
+ declare `ARG` + `ENV` in the builder stage before `npm run build`:
340
+
341
+ ```dockerfile
342
+ ARG NEXT_PUBLIC_GA_MEASUREMENT_ID
343
+ ENV NEXT_PUBLIC_GA_MEASUREMENT_ID=$NEXT_PUBLIC_GA_MEASUREMENT_ID
344
+ RUN npm run build
345
+ ```
346
+
347
+ ### trackEvent helper (TypeScript)
348
+
349
+ ```typescript
350
+ declare global {
351
+ interface Window { gtag?: (...args: unknown[]) => void; }
352
+ }
353
+
354
+ export function trackEvent(name: string, params?: Record<string, unknown>) {
355
+ if (typeof window === 'undefined') return;
356
+ if (typeof window.gtag !== 'function') return;
357
+ if (window.location.hostname === 'localhost') {
358
+ console.debug('[GA]', name, params);
359
+ return;
360
+ }
361
+ window.gtag('event', name, params);
362
+ }
363
+ ```
364
+
365
+ ### SPA page_view (App Router)
366
+
367
+ GA4 with enhanced measurement automatically tracks `page_view` via the History API
368
+ (`pushState`). Manual page views are only needed for hash routing (`#/path`).
369
+
370
+ If needed, send manual page views on route change:
371
+
372
+ ```typescript
373
+ 'use client';
374
+ import { usePathname } from 'next/navigation';
375
+ import { useEffect } from 'react';
376
+
377
+ export function usePageView() {
378
+ const pathname = usePathname();
379
+ useEffect(() => {
380
+ if (typeof window.gtag === 'function') {
381
+ window.gtag('event', 'page_view', {
382
+ page_path: pathname,
383
+ page_location: window.location.href,
384
+ page_title: document.title,
385
+ });
386
+ }
387
+ }, [pathname]);
388
+ }
389
+ ```
@@ -0,0 +1,103 @@
1
+ # Meta Pixel & LinkedIn — Reference
2
+
3
+ Moved out of `SKILL.md` when the body was 906 lines against a 500-line budget.
4
+ Everything here is detail the body used to carry inline; the body keeps the
5
+ setup snippet and the traps.
6
+
7
+ ## Contents
8
+
9
+ - [Parameter object properties](#parameter-object-properties) — what Meta accepts per event
10
+ - [Firing events](#firing-events) — the wrapper and its consent gate
11
+ - [Advanced matching](#advanced-matching) — hashed identifiers, and what must never be sent
12
+ - [Everything below](#) — LinkedIn conversion detail, deduplication with CAPI
13
+
14
+ ### Parameter Object Properties
15
+
16
+ | Property | Type | Description |
17
+ |---|---|---|
18
+ | `value` | float | **Required for Purchase.** Monetary amount. |
19
+ | `currency` | string | ISO 4217 code (e.g. `USD`, `EUR`). Required with `value`. |
20
+ | `content_name` | string | Name of the page/product |
21
+ | `content_category` | string | Category (e.g. `subscription`, `tokens`) |
22
+ | `content_type` | string | `product` or `product_group` |
23
+ | `content_ids` | string[] | Product IDs / SKUs |
24
+ | `contents` | object[] | Array of `{ id, quantity }` objects |
25
+ | `num_items` | integer | Item count at checkout |
26
+ | `predicted_ltv` | float | Predicted lifetime value (for Subscribe) |
27
+ | `status` | boolean | Registration status (for CompleteRegistration) |
28
+
29
+ ### Firing Events
30
+
31
+ ```javascript
32
+ // Standard event
33
+ fbq('track', 'Purchase', {
34
+ value: 30.00,
35
+ currency: 'USD',
36
+ content_name: 'Monthly Plan',
37
+ content_type: 'product',
38
+ contents: [{ id: 'plan_monthly', quantity: 1 }]
39
+ });
40
+
41
+ // Custom event
42
+ fbq('trackCustom', 'ShareDiscount', { promotion: 'share_10_percent' });
43
+ ```
44
+
45
+ ### Advanced Matching
46
+
47
+ Advanced Matching sends hashed user data (email, name, phone) to Meta for better conversion attribution. Two approaches:
48
+
49
+ **1. At init time (initial page load):**
50
+
51
+ ```javascript
52
+ fbq('init', 'PIXEL_ID', {
53
+ em: 'user@example.com', // email — Meta hashes automatically
54
+ fn: 'john', // first name (lowercase)
55
+ ln: 'doe', // last name (lowercase)
56
+ ph: '1234567890', // phone (digits only, no formatting)
57
+ ct: 'new york', // city (lowercase)
58
+ st: 'ny', // state (2-letter code)
59
+ zp: '10001', // zip code
60
+ country: 'us', // country (2-letter ISO)
61
+ });
62
+ ```
63
+
64
+ **2. After user identification (re-init):**
65
+
66
+ Call `fbq('init', PIXEL_ID, userData)` again after the user logs in. The pixel merges the data. This is the recommended approach for SPA/SSR apps where user data isn't available at first load.
67
+
68
+ ```typescript
69
+ export function setFbAdvancedMatching(data: { em?: string; fn?: string }) {
70
+ if (typeof window.fbq === "function" && PIXEL_ID) {
71
+ window.fbq("init", PIXEL_ID, data);
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### Meta Events Manager Verification
77
+
78
+ 1. Install the **Meta Pixel Helper** Chrome extension
79
+ 2. Go to Events Manager → Data Sources → select Pixel → **Test Events**
80
+ 3. Enter your site URL and walk through the funnel
81
+ 4. Verify events appear in real-time with correct parameters
82
+ 5. Check Advanced Matching: Events Manager → Settings → Advanced Matching tab
83
+
84
+ ### Best Practices
85
+
86
+ - Always include `value` and `currency` on Purchase events (required for ROAS optimisation)
87
+ - Use `predicted_ltv` on Subscribe events for better Value-Based Optimisation
88
+ - Fire `CompleteRegistration` immediately on signup, not after onboarding
89
+ - Use standard events over custom events when possible — Meta optimises ads for standard events
90
+ - Include `contents[]` array with product IDs for Advantage+ catalog campaigns
91
+ - The `PageView` event fires automatically from the base code — do not fire it manually
92
+ - For SPAs, the pixel tracks route changes automatically via pushState/replaceState
93
+
94
+ **Docs:**
95
+ - [Meta Pixel standard events specifications](https://www.facebook.com/business/help/402791146561655?id=1205376682832142)
96
+ - [Best practices for Meta Pixel setup](https://www.facebook.com/business/help/218844828315224?id=1205376682832142)
97
+ - [Conversion tracking & advanced matching](https://developers.facebook.com/docs/meta-pixel/implementation/conversion-tracking#advanced_match)
98
+ - [Meta Pixel reference](https://developers.facebook.com/docs/meta-pixel/reference)
99
+ - [Advanced Matching parameters](https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching)
100
+ - [Meta Pixel Helper extension](https://www.facebook.com/business/help/198460973553498)
101
+
102
+ ---
103
+