@friedbotstudio/create-baseline 0.5.0 → 0.7.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 (55) hide show
  1. package/README.md +14 -10
  2. package/bin/cli.js +46 -15
  3. package/obj/template/.claude/commands/init-project-doctor.md +74 -0
  4. package/obj/template/.claude/hooks/lib/resume_writer.py +14 -1
  5. package/obj/template/.claude/hooks/track_guard.sh +11 -1
  6. package/obj/template/.claude/manifest.json +848 -230
  7. package/obj/template/.claude/schemas/workflow-track.v1.json +64 -0
  8. package/obj/template/.claude/skills/audit-baseline/audit.sh +6 -3
  9. package/obj/template/.claude/skills/chore/SKILL.md +2 -2
  10. package/obj/template/.claude/skills/harness/SKILL.md +15 -6
  11. package/obj/template/.claude/skills/intake/SKILL.md +1 -1
  12. package/obj/template/.claude/skills/swarm-plan/SKILL.md +2 -0
  13. package/obj/template/.claude/skills/tdd/SKILL.md +2 -2
  14. package/obj/template/.claude/skills/triage/SKILL.md +29 -6
  15. package/obj/template/.claude/skills/triage/seed-tasklist.mjs +107 -0
  16. package/obj/template/.claude/skills/upgrade-project/SKILL.md +121 -0
  17. package/obj/template/.claude/workflows.jsonl +6 -0
  18. package/obj/template/CLAUDE.md +14 -19
  19. package/obj/template/docs/init/seed.md +152 -7
  20. package/package.json +1 -1
  21. package/src/.claude/workflows.template.jsonl +6 -0
  22. package/src/CLAUDE.template.md +14 -19
  23. package/src/cli/diff-render.js +54 -0
  24. package/src/cli/install.js +38 -3
  25. package/src/cli/manifest.js +7 -3
  26. package/src/cli/merge.js +107 -13
  27. package/src/cli/track-tasklist-materializer.js +223 -0
  28. package/src/cli/tui/upgrade.js +130 -27
  29. package/src/cli/upgrade-tiers.js +256 -0
  30. package/src/cli/workflow-migrator.js +40 -0
  31. package/src/cli/workflows-validator-invariants.js +417 -0
  32. package/src/cli/workflows-validator-predicates.js +19 -0
  33. package/src/cli/workflows-validator.js +156 -0
  34. package/src/seed.template.md +152 -7
  35. package/obj/template/.claude/skills/google-analytics/SKILL.md +0 -129
  36. package/obj/template/.claude/skills/google-analytics/references/audiences.md +0 -389
  37. package/obj/template/.claude/skills/google-analytics/references/bigquery.md +0 -470
  38. package/obj/template/.claude/skills/google-analytics/references/custom-dimensions.md +0 -355
  39. package/obj/template/.claude/skills/google-analytics/references/custom-events.md +0 -383
  40. package/obj/template/.claude/skills/google-analytics/references/data-management.md +0 -416
  41. package/obj/template/.claude/skills/google-analytics/references/debugview.md +0 -364
  42. package/obj/template/.claude/skills/google-analytics/references/events-fundamentals.md +0 -398
  43. package/obj/template/.claude/skills/google-analytics/references/gtag.md +0 -502
  44. package/obj/template/.claude/skills/google-analytics/references/gtm-integration.md +0 -483
  45. package/obj/template/.claude/skills/google-analytics/references/measurement-protocol.md +0 -519
  46. package/obj/template/.claude/skills/google-analytics/references/privacy.md +0 -441
  47. package/obj/template/.claude/skills/google-analytics/references/recommended-events.md +0 -464
  48. package/obj/template/.claude/skills/google-analytics/references/reporting.md +0 -397
  49. package/obj/template/.claude/skills/google-analytics/references/setup.md +0 -344
  50. package/obj/template/.claude/skills/google-analytics/references/user-tracking.md +0 -417
  51. package/obj/template/.claude/skills/optimize-seo/SKILL.md +0 -313
  52. package/obj/template/.claude/skills/optimize-seo/scripts/pagespeed.mjs +0 -197
  53. package/obj/template/.claude/skills/pagespeed-insights/LICENSE.md +0 -37
  54. package/obj/template/.claude/skills/pagespeed-insights/SKILL.md +0 -446
  55. package/obj/template/.claude/skills/pagespeed-insights/reference.md +0 -50
@@ -1,502 +0,0 @@
1
- # GA4 gtag.js Direct Implementation
2
-
3
- Expert guidance for implementing GA4 using gtag.js directly without Google Tag Manager.
4
-
5
- ## Overview
6
-
7
- gtag.js (Google Tag) is the official JavaScript library for implementing GA4 tracking directly on websites. This reference covers installation, gtag commands, event tracking, user properties, and framework integration patterns.
8
-
9
- ## When to Use gtag.js
10
-
11
- **Choose gtag.js when:**
12
- - Only need Google products (GA4, Google Ads)
13
- - Want lightweight implementation
14
- - Have code access to website
15
- - No tag management system required
16
- - Simple tracking needs
17
-
18
- **Choose GTM instead when:**
19
- - Need multiple tracking tags
20
- - Team collaboration required
21
- - Frequent changes expected
22
- - Want version control for tags
23
-
24
- ## Installation
25
-
26
- ### Basic Installation
27
-
28
- Place in `<head>` section, before all other scripts:
29
-
30
- ```html
31
- <!-- Google tag (gtag.js) -->
32
- <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
33
- <script>
34
- window.dataLayer = window.dataLayer || [];
35
- function gtag(){dataLayer.push(arguments);}
36
- gtag('js', new Date());
37
- gtag('config', 'G-XXXXXXXXXX');
38
- </script>
39
- ```
40
-
41
- ### Placement Requirements
42
-
43
- | Requirement | Description |
44
- |-------------|-------------|
45
- | Location | `<head>` section |
46
- | Position | Before all other scripts |
47
- | Async | Script loaded asynchronously |
48
- | Every page | Must be on all pages |
49
-
50
- ## gtag Commands
51
-
52
- ### gtag('js', new Date())
53
-
54
- Initialises the library with timestamp.
55
-
56
- ```javascript
57
- gtag('js', new Date());
58
- ```
59
-
60
- **Required:** Yes, must be called first
61
-
62
- ### gtag('config', 'G-ID')
63
-
64
- Configures GA4 with Measurement ID.
65
-
66
- **Basic:**
67
- ```javascript
68
- gtag('config', 'G-XXXXXXXXXX');
69
- ```
70
-
71
- **With Options:**
72
- ```javascript
73
- gtag('config', 'G-XXXXXXXXXX', {
74
- 'page_title': 'Custom Page Title',
75
- 'page_location': window.location.href,
76
- 'send_page_view': true,
77
- 'allow_google_signals': true,
78
- 'allow_ad_personalization_signals': true,
79
- 'user_id': 'USER_12345'
80
- });
81
- ```
82
-
83
- ### gtag('event', 'name', {params})
84
-
85
- Sends events to GA4.
86
-
87
- **Simple Event:**
88
- ```javascript
89
- gtag('event', 'button_click', {
90
- 'button_name': 'Subscribe',
91
- 'button_location': 'header'
92
- });
93
- ```
94
-
95
- **Recommended Event:**
96
- ```javascript
97
- gtag('event', 'purchase', {
98
- 'transaction_id': 'TXN_12345',
99
- 'value': 99.99,
100
- 'currency': 'USD',
101
- 'items': [{
102
- 'item_id': 'SKU_001',
103
- 'item_name': 'Product Name',
104
- 'price': 99.99,
105
- 'quantity': 1
106
- }]
107
- });
108
- ```
109
-
110
- ### gtag('set', {properties})
111
-
112
- Sets user properties and User ID.
113
-
114
- **User ID:**
115
- ```javascript
116
- // On login
117
- gtag('set', 'user_id', 'USER_12345');
118
-
119
- // On logout - MUST use null, never empty string
120
- gtag('set', 'user_id', null);
121
- ```
122
-
123
- **User Properties:**
124
- ```javascript
125
- gtag('set', 'user_properties', {
126
- 'subscription_tier': 'premium',
127
- 'customer_segment': 'enterprise',
128
- 'account_age_days': 365
129
- });
130
- ```
131
-
132
- ### gtag('consent', 'default/update', {})
133
-
134
- Manages consent state.
135
-
136
- **Default (Before Consent):**
137
- ```javascript
138
- gtag('consent', 'default', {
139
- 'ad_storage': 'denied',
140
- 'analytics_storage': 'denied',
141
- 'ad_user_data': 'denied',
142
- 'ad_personalization': 'denied'
143
- });
144
- ```
145
-
146
- **Update (After Consent):**
147
- ```javascript
148
- gtag('consent', 'update', {
149
- 'ad_storage': 'granted',
150
- 'analytics_storage': 'granted',
151
- 'ad_user_data': 'granted',
152
- 'ad_personalization': 'granted'
153
- });
154
- ```
155
-
156
- ## Common Implementation Patterns
157
-
158
- ### Button Click Tracking
159
-
160
- ```html
161
- <button id="subscribe-btn">Subscribe</button>
162
-
163
- <script>
164
- document.getElementById('subscribe-btn').addEventListener('click', function() {
165
- gtag('event', 'button_click', {
166
- 'button_name': 'Subscribe',
167
- 'button_location': 'homepage_hero',
168
- 'button_id': 'subscribe-btn'
169
- });
170
- });
171
- </script>
172
- ```
173
-
174
- ### Form Submission Tracking
175
-
176
- ```html
177
- <form id="contact-form">
178
- <input type="email" name="email" required>
179
- <button type="submit">Submit</button>
180
- </form>
181
-
182
- <script>
183
- document.getElementById('contact-form').addEventListener('submit', function(e) {
184
- gtag('event', 'form_submit', {
185
- 'form_name': 'Contact Form',
186
- 'form_id': 'contact-form',
187
- 'form_destination': '/thank-you'
188
- });
189
- });
190
- </script>
191
- ```
192
-
193
- ### Video Tracking
194
-
195
- ```javascript
196
- // Video start
197
- gtag('event', 'video_start', {
198
- 'video_title': 'Getting Started Guide',
199
- 'video_id': 'VID_001',
200
- 'video_duration': 180
201
- });
202
-
203
- // Video progress
204
- gtag('event', 'video_progress', {
205
- 'video_title': 'Getting Started Guide',
206
- 'video_id': 'VID_001',
207
- 'video_percent': 50
208
- });
209
-
210
- // Video complete
211
- gtag('event', 'video_complete', {
212
- 'video_title': 'Getting Started Guide',
213
- 'video_id': 'VID_001'
214
- });
215
- ```
216
-
217
- ### Ecommerce Purchase
218
-
219
- ```javascript
220
- gtag('event', 'purchase', {
221
- 'transaction_id': 'TXN_' + Date.now(),
222
- 'value': 149.99,
223
- 'currency': 'USD',
224
- 'tax': 10.00,
225
- 'shipping': 5.99,
226
- 'coupon': 'SUMMER20',
227
- 'items': [
228
- {
229
- 'item_id': 'SKU_001',
230
- 'item_name': 'Premium Widget',
231
- 'item_brand': 'Acme',
232
- 'item_category': 'Electronics',
233
- 'item_variant': 'Blue',
234
- 'price': 149.99,
235
- 'quantity': 1
236
- }
237
- ]
238
- });
239
- ```
240
-
241
- ### User Authentication
242
-
243
- ```javascript
244
- // On login
245
- function handleLogin(userId, method) {
246
- // Set User ID
247
- gtag('set', 'user_id', userId);
248
-
249
- // Send login event
250
- gtag('event', 'login', {
251
- 'method': method
252
- });
253
-
254
- // Set user properties
255
- gtag('set', 'user_properties', {
256
- 'account_type': 'registered',
257
- 'login_method': method
258
- });
259
- }
260
-
261
- // On logout
262
- function handleLogout() {
263
- // Clear User ID
264
- gtag('set', 'user_id', null);
265
-
266
- // Optional: track logout
267
- gtag('event', 'logout');
268
- }
269
- ```
270
-
271
- ## Single Page Applications
272
-
273
- ### Manual Page View Tracking
274
-
275
- SPAs don't trigger traditional page loads. Track manually:
276
-
277
- ```javascript
278
- // Call on route change
279
- function trackPageView(path, title) {
280
- gtag('config', 'G-XXXXXXXXXX', {
281
- 'page_path': path,
282
- 'page_title': title
283
- });
284
- }
285
-
286
- // Example with router
287
- router.afterEach((to) => {
288
- trackPageView(to.path, to.meta.title);
289
- });
290
- ```
291
-
292
- ### Disable Automatic Page View
293
-
294
- If handling manually:
295
-
296
- ```javascript
297
- gtag('config', 'G-XXXXXXXXXX', {
298
- 'send_page_view': false
299
- });
300
-
301
- // Then send manually
302
- gtag('event', 'page_view', {
303
- 'page_title': 'Custom Title',
304
- 'page_location': window.location.href,
305
- 'page_path': '/custom-path'
306
- });
307
- ```
308
-
309
- ## Framework Integration
310
-
311
- ### React / Next.js
312
-
313
- ```javascript
314
- // lib/gtag.js
315
- export const GA_MEASUREMENT_ID = 'G-XXXXXXXXXX';
316
-
317
- export const pageview = (url) => {
318
- window.gtag('config', GA_MEASUREMENT_ID, {
319
- page_path: url,
320
- });
321
- };
322
-
323
- export const event = (action, params) => {
324
- window.gtag('event', action, params);
325
- };
326
- ```
327
-
328
- ```javascript
329
- // In _app.js or layout
330
- import { useEffect } from 'react';
331
- import { useRouter } from 'next/router';
332
- import * as gtag from '../lib/gtag';
333
-
334
- export default function App({ Component, pageProps }) {
335
- const router = useRouter();
336
-
337
- useEffect(() => {
338
- const handleRouteChange = (url) => {
339
- gtag.pageview(url);
340
- };
341
- router.events.on('routeChangeComplete', handleRouteChange);
342
- return () => {
343
- router.events.off('routeChangeComplete', handleRouteChange);
344
- };
345
- }, [router.events]);
346
-
347
- return <Component {...pageProps} />;
348
- }
349
- ```
350
-
351
- ### Vue.js
352
-
353
- ```javascript
354
- // plugins/gtag.js
355
- export default {
356
- install(app) {
357
- app.config.globalProperties.$gtag = (action, params) => {
358
- window.gtag('event', action, params);
359
- };
360
- }
361
- };
362
- ```
363
-
364
- ```javascript
365
- // In router
366
- router.afterEach((to, from) => {
367
- gtag('config', 'G-XXXXXXXXXX', {
368
- page_path: to.fullPath,
369
- page_title: to.meta.title
370
- });
371
- });
372
- ```
373
-
374
- ### Angular
375
-
376
- ```typescript
377
- // analytics.service.ts
378
- import { Injectable } from '@angular/core';
379
-
380
- declare let gtag: Function;
381
-
382
- @Injectable({
383
- providedIn: 'root'
384
- })
385
- export class AnalyticsService {
386
- event(action: string, params: object) {
387
- gtag('event', action, params);
388
- }
389
-
390
- pageView(path: string, title: string) {
391
- gtag('config', 'G-XXXXXXXXXX', {
392
- page_path: path,
393
- page_title: title
394
- });
395
- }
396
- }
397
- ```
398
-
399
- ## Multiple Properties
400
-
401
- Track to multiple GA4 properties:
402
-
403
- ```javascript
404
- // Configure both
405
- gtag('config', 'G-XXXXXXXXXX'); // Property 1
406
- gtag('config', 'G-YYYYYYYYYY'); // Property 2
407
-
408
- // Events sent to both automatically
409
- gtag('event', 'purchase', {
410
- 'value': 99.99,
411
- 'currency': 'USD'
412
- });
413
-
414
- // Send to specific property only
415
- gtag('event', 'purchase', {
416
- 'send_to': 'G-XXXXXXXXXX',
417
- 'value': 99.99,
418
- 'currency': 'USD'
419
- });
420
- ```
421
-
422
- ## Debug Mode
423
-
424
- Enable debug mode for testing:
425
-
426
- ```javascript
427
- gtag('config', 'G-XXXXXXXXXX', {
428
- 'debug_mode': true
429
- });
430
- ```
431
-
432
- **Important:** Remove for production.
433
-
434
- ## Common Pitfalls
435
-
436
- ### 1. gtag Called Before Initialisation
437
-
438
- **Problem:** Events called before gtag snippet
439
- **Solution:** Ensure snippet loads first in `<head>`
440
-
441
- ### 2. Multiple gtag Snippets
442
-
443
- **Problem:** Duplicate events
444
- **Solution:** Single snippet, multiple config calls
445
-
446
- ### 3. Empty String for User ID
447
-
448
- **Problem:** User ID not cleared properly
449
- **Solution:** Use `null`, never empty string `""`
450
-
451
- ### 4. Missing Currency
452
-
453
- **Problem:** Monetary events without currency
454
- **Solution:** Always include `currency` with `value`
455
-
456
- ### 5. Unregistered Parameters
457
-
458
- **Problem:** Parameters not in reports
459
- **Solution:** Register as custom dimensions
460
-
461
- ## Critical Rules
462
-
463
- | Rule | Value |
464
- |------|-------|
465
- | Event name max | 40 characters |
466
- | Parameter name max | 40 characters |
467
- | Parameter value max | 100 characters |
468
- | Parameters per event | 25 |
469
- | Event names | snake_case |
470
-
471
- ## Quick Reference
472
-
473
- ### Initialise
474
-
475
- ```javascript
476
- gtag('js', new Date());
477
- gtag('config', 'G-XXXXXXXXXX');
478
- ```
479
-
480
- ### Send Event
481
-
482
- ```javascript
483
- gtag('event', 'event_name', {params});
484
- ```
485
-
486
- ### Set User ID
487
-
488
- ```javascript
489
- gtag('set', 'user_id', 'USER_123');
490
- ```
491
-
492
- ### Set User Properties
493
-
494
- ```javascript
495
- gtag('set', 'user_properties', {key: 'value'});
496
- ```
497
-
498
- ### Clear User ID
499
-
500
- ```javascript
501
- gtag('set', 'user_id', null);
502
- ```