@ssheleg/sheleg-dev 0.11.5 → 0.11.7

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,35 @@
1
+ ## v0.11.7 — the fifth version surface is retired, and one audit finding is refused by a guard that already knew
2
+
3
+ > **v0.11.6 is a burned tag.** It was pushed before the release PR merged, in a repository
4
+ > that squash-merges — so it points beside `main` at `7088752`, the release run refused it
5
+ > at *The tag must be reachable from the default branch*, and the remote forbids tag
6
+ > deletion. Nothing shipped under it; this version is the same tree, tagged on `main`.
7
+
8
+ A family audit (2026-09-06, `sshlg-skills` wave `AUDIT-WAVE-0906`) read all seven skills
9
+ against the standard. What it found here, closed:
10
+
11
+ - **`error-tracking` carried `metadata.version: 0.9.2` under a release whose every other
12
+ surface said 0.11.5** — the only skill in the member carrying the key, a fifth version
13
+ surface the ×4 sync never read. The key is dropped rather than synced: four surfaces
14
+ move together under a guard, and a fifth existed only to drift.
15
+ - **Five skills declared no `license:`** while their two siblings did — `ad-tracking`,
16
+ `crypto-payments`, `frontend-performance`, `google-auth`, `google-signin` all say MIT now.
17
+ - **`error-tracking`'s NOT-for clause named `triage-issue`**, an id that resolves only on
18
+ machines carrying one specific tracker plugin; it names the class now.
19
+ - **`heleket-provider.md` pointed at a bare `references/price-integrity.md`**, which
20
+ resolves only in the sibling skill; the pointer carries `../stripe-billing/` now.
21
+ - **`ad-tracking`'s troubleshooting table moved into `references/performance-security.md`**
22
+ (~285 body tokens), and `stripe-billing`'s cancellation bullets compressed against their
23
+ own reference (~65) — headroom bought by moving depth, never by deleting it. What still
24
+ sits near the ceiling is `B-106` on the board.
25
+
26
+ One finding was refused, and the refusal is the record: the audit asked for the shared
27
+ `webhook signature` literal to be qualified per provider, and `test/validate.py` already
28
+ carries `TRIGGERS_SHARED_BY_DESIGN` saying both rails own that seam — the attempted
29
+ removal turned the gate red, which is the exemption doing its job.
30
+
31
+ Board: `B-106` filed. Source: family audit 2026-09-06.
32
+
1
33
  ## v0.11.5 — the card is the umbrella's render, and the eyebrow stops painting past the canvas
2
34
 
3
35
  The committed social preview is now generated by the umbrella with the CORRECTED fit
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ssheleg/sheleg-dev",
3
- "version": "0.11.5",
3
+ "version": "0.11.7",
4
4
  "description": "Seven integration skills for the layer a product reaches once it has users: Stripe subscription billing and cancellation retention, crypto payments, ad and conversion tracking under Consent Mode v2, Google sign-in and the wider Google auth surface, error tracking, and Core Web Vitals. This package is the installer CLI.",
5
5
  "bin": {
6
6
  "sheleg-dev": "bin/sheleg-dev.js"
@@ -3,7 +3,7 @@
3
3
  "name": "sheleg-dev",
4
4
  "displayName": "Sheleg Dev",
5
5
  "description": "The integration layer a product needs once it has users: Stripe subscription billing reconciled into your own database, crypto payments that survive over-payment and duplicate webhooks, ad and conversion tracking under Consent Mode v2, Google sign-in with the account-linking guards, the wider Google auth surface, and Core Web Vitals work that moves the score, and Sentry error tracking wired so it does not forward your own credentials to a third party and so a stack trace names the commit that caused it.",
6
- "version": "0.11.5",
6
+ "version": "0.11.7",
7
7
  "author": {
8
8
  "name": "ssheleg",
9
9
  "url": "https://x.com/sshlg93"
@@ -11,6 +11,7 @@ description: >-
11
11
  "enhanced conversions", "retargeting", "purchase event", "CAPI", "gclid", "UTM",
12
12
  "attribution", "отслеживание конверсий", "пиксель Meta", "согласие на куки", "ретаргетинг",
13
13
  "аналитика рекламы". Not for running the ad campaigns themselves.
14
+ license: MIT
14
15
  ---
15
16
 
16
17
  # Advertising Analytics & Conversion Tracking Integration
@@ -364,31 +365,11 @@ failure this whole skill exists to prevent, and it looks fine in every test
364
365
  that starts by accepting.
365
366
  ## Troubleshooting
366
367
 
367
- ### Common Issues
368
-
369
- | Problem | Cause | Fix |
370
- |---|---|---|
371
- | No events in GA4 | Consent defaults not set before gtag.js loads | Ensure consent `default` call is **before** the script tag |
372
- | CSP violations in console | Missing domain in CSP header | Add the domain to the correct CSP directive |
373
- | Meta Pixel not firing | Consent-gated component not rendering | Check localStorage consent value, check CustomEvent listener |
374
- | Duplicate `PageView` events | Multiple pixel instances or route change listeners | Ensure pixel init code has `if(f.fbq)return;` guard |
375
- | Purchase events without value | Missing `value`/`currency` params | Both GA4 and Meta **require** these for conversion optimisation |
376
- | Advanced Matching not working | `fbq('init')` called before pixel SDK loads | Ensure `fbevents.js` is loaded before calling `setFbAdvancedMatching()` |
377
- | Enhanced Conversions not matching | `user_data` set after conversion event | Call `setEnhancedConversionData()` **before** the conversion event fires |
378
- | gclid lost after Stripe redirect | — (shouldn't happen) | `_gcl_aw` cookie is first-party, persists across redirects |
379
- | Events firing on localhost | Missing `isLocal` guard | Add `if (window.location.hostname === 'localhost') return;` |
380
-
381
- ### Debug Mode
382
-
383
- Enable debug logging for local development:
384
-
385
- ```typescript
386
- const isLocal = window.location.hostname === "localhost";
387
- if (isLocal) {
388
- console.debug("[Analytics]", eventName, params);
389
- return; // don't fire real events
390
- }
391
- ```
368
+ Read `references/performance-security.md` → **Troubleshooting** for the
369
+ common-issues table (consent ordering, duplicate `PageView`, Advanced/Enhanced
370
+ Matching timing, the localhost guard) and the debug-mode snippet. The two seen
371
+ most: consent `default` must run **before** gtag.js loads, and a purchase
372
+ without `value`/`currency` cannot be optimised against by either platform.
392
373
 
393
374
  ---
394
375
 
@@ -13,6 +13,7 @@
13
13
  - [Debug & Testing](#debug--testing)
14
14
  - [Common Mistakes](#common-mistakes)
15
15
  - [Multi-Page Consistency](#multi-page-consistency)
16
+ - [Troubleshooting](#troubleshooting)
16
17
 
17
18
  ## Table of Contents
18
19
 
@@ -22,6 +23,7 @@
22
23
  - [Debug & Testing](#debug--testing)
23
24
  - [Common Mistakes](#common-mistakes)
24
25
  - [Multi-Page Consistency](#multi-page-consistency)
26
+ - [Troubleshooting](#troubleshooting)
25
27
 
26
28
  ## Script Loading Strategies
27
29
 
@@ -288,3 +290,34 @@ terser js/consent.js -o js/consent.min.js -c -m
288
290
  ```
289
291
 
290
292
  Use the minified version in production, source version in development.
293
+
294
+ ## Troubleshooting
295
+
296
+ Moved here from `SKILL.md` — the lookup table for symptoms whose causes are
297
+ covered in the sections above.
298
+
299
+ ### Common Issues
300
+
301
+ | Problem | Cause | Fix |
302
+ |---|---|---|
303
+ | No events in GA4 | Consent defaults not set before gtag.js loads | Ensure consent `default` call is **before** the script tag |
304
+ | CSP violations in console | Missing domain in CSP header | Add the domain to the correct CSP directive |
305
+ | Meta Pixel not firing | Consent-gated component not rendering | Check localStorage consent value, check CustomEvent listener |
306
+ | Duplicate `PageView` events | Multiple pixel instances or route change listeners | Ensure pixel init code has `if(f.fbq)return;` guard |
307
+ | Purchase events without value | Missing `value`/`currency` params | Both GA4 and Meta **require** these for conversion optimisation |
308
+ | Advanced Matching not working | `fbq('init')` called before pixel SDK loads | Ensure `fbevents.js` is loaded before calling `setFbAdvancedMatching()` |
309
+ | Enhanced Conversions not matching | `user_data` set after conversion event | Call `setEnhancedConversionData()` **before** the conversion event fires |
310
+ | gclid lost after Stripe redirect | — (shouldn't happen) | `_gcl_aw` cookie is first-party, persists across redirects |
311
+ | Events firing on localhost | Missing `isLocal` guard | Add `if (window.location.hostname === 'localhost') return;` |
312
+
313
+ ### Debug Mode
314
+
315
+ Enable debug logging for local development:
316
+
317
+ ```typescript
318
+ const isLocal = window.location.hostname === "localhost";
319
+ if (isLocal) {
320
+ console.debug("[Analytics]", eventName, params);
321
+ return; // don't fire real events
322
+ }
323
+ ```
@@ -11,6 +11,7 @@ description: >-
11
11
  checkout", "pay with crypto", "USDT payment", "TRC20", "payment webhook", "IPN", "webhook
12
12
  signature", "underpayment", "Heleket", "NOWPayments", "приём криптоплатежей", "оплата
13
13
  криптой", "вебхук платежа", "недоплата". Not for card billing — use stripe-billing.
14
+ license: MIT
14
15
  ---
15
16
 
16
17
  # Crypto payments
@@ -174,8 +174,9 @@ than Stripe's and the difference decides the design:
174
174
  | Key also signs webhooks | no, a separate `whsec_` | **yes, the same value** |
175
175
 
176
176
  So the house pattern — declare the environment in a variable separate from the secret,
177
- then assert at boot that the two agree (the `stripe-billing` skill, `references/price-integrity.md`,
178
- *Test and live mode*) — applies, but its Stripe implementation does not: there is no key
177
+ then assert at boot that the two agree (the `stripe-billing` skill,
178
+ `../stripe-billing/references/price-integrity.md`, *Test and live mode*) — applies, but its
179
+ Stripe implementation does not: there is no key
179
180
  prefix to read. The comparison has to be made against something else, and Heleket gives
180
181
  exactly two candidates, both non-secret:
181
182
 
@@ -10,11 +10,9 @@ description: >-
10
10
  "set up error tracking", "SENTRY_DSN", "sentry-cli", "sentry mcp", "scrub secrets from
11
11
  errors", "release tracking", "suspect commits", "why is Sentry empty", "подключить Sentry",
12
12
  "трекинг ошибок", "секреты в Sentry", "релизы в Sentry", "наблюдаемость". NOT for judging an
13
- agent's trajectory (agent-evals), triaging tickets in a tracker (triage-issue), or choosing an
14
- uptime vendor.
13
+ agent's trajectory (agent-evals), triaging tickets in a tracker (your tracker's own triage
14
+ skill), or choosing an uptime vendor.
15
15
  license: MIT
16
- metadata:
17
- version: 0.9.2
18
16
  ---
19
17
 
20
18
  # error-tracking — Sentry wired so it does not leak, and so a stack trace names a commit
@@ -11,6 +11,7 @@ description: >-
11
11
  "render-blocking", "bundle size", "code splitting", "lazy loading", "cache headers",
12
12
  "performance budget", "ускорить сайт", "медленно грузится", "оптимизация скорости", "вес
13
13
  бандла". Not for visual design or conversion work.
14
+ license: MIT
14
15
  ---
15
16
 
16
17
  # Frontend Performance
@@ -11,6 +11,7 @@ description: >-
11
11
  "GOOGLE_APPLICATION_CREDENTIALS", "Google SSO", "авторизация Google", "сервисный аккаунт",
12
12
  "ключи сервисного аккаунта", "проверить ID-токен". For end-user web sign-in only, use the
13
13
  google-signin skill instead.
14
+ license: MIT
14
15
  ---
15
16
 
16
17
  # Google Authentication for Node.js & Python
@@ -10,6 +10,7 @@ description: >-
10
10
  "google.accounts.id", "gsi/client", "verify google token", "one tap", "account linking",
11
11
  "login csrf", "g_csrf_token", "вход через Google", "кнопка входа Google", "связать аккаунты",
12
12
  "проверить токен Google". For the broader library surface use google-auth instead.
13
+ license: MIT
13
14
  ---
14
15
 
15
16
  # Google Sign-In (GIS) — production web login
@@ -314,18 +314,15 @@ product decision `stripe-best-practices` owns.
314
314
 
315
315
  - **At period end is the default** — the user keeps what they paid for and
316
316
  `status` stays `active`. Under **flexible** `billing_mode` a portal
317
- cancellation sets `cancel_at` and leaves `cancel_at_period_end` **false**, so a
318
- banner reading that boolean tells a customer who cancelled ten seconds ago that
319
- their plan renews. Store the timestamp, derived from both fields.
317
+ cancellation sets `cancel_at` and leaves `cancel_at_period_end` **false** —
318
+ derive "is cancelling" from both fields, never from the boolean alone.
320
319
  - **Do the teardown in `customer.subscription.deleted`**, never beside the API
321
320
  call, so one path serves your UI, the portal and dunning alike.
322
321
  - On `invoice.payment_failed`, mark `past_due` and notify — do not cancel.
323
322
  Stripe's dunning decides the retries and the terminal state.
324
- - **A save offer's eligibility is yours.** Stripe's cancel page shows a coupon
325
- card when you pass `flow_data.subscription_cancel.retention`, but a coupon
326
- cannot be restricted to one customer and a `duration=once` discount leaves
327
- `subscription.discounts` once its invoice finalizes. Ask Stripe whether this
328
- customer was already discounted and the answer is no, every month, forever.
323
+ - **A save offer's eligibility is yours.** Stripe cannot answer "was this
324
+ customer already discounted" — a `duration=once` discount leaves
325
+ `subscription.discounts` at finalization — so track eligibility yourself.
329
326
 
330
327
  Both, with the code:
331
328
  [`references/cancellation-and-retention.md`](references/cancellation-and-retention.md).