@inizioevoke/veeva-astroclm-core 1.1.0 → 1.1.1

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.
@@ -0,0 +1,274 @@
1
+ ---
2
+ name: analytics-auditor
3
+ description: >
4
+ Starts the Astro dev server, visits every page, clicks configurable CSS selectors,
5
+ captures all browser console messages, and writes a deduplication report of unique
6
+ log messages grouped by page. Use this skill whenever the user asks to audit,
7
+ record, or report on analytics, metrics, or events.
8
+ ---
9
+
10
+ # Analytics Auditor Skill
11
+
12
+ ## Purpose
13
+
14
+ Start the dev server, click interactive elements, harvest every `console.*` message,
15
+ and produce a report of **unique messages** (grouped by page) written to
16
+ `analytics-audit-report.md` in the project root.
17
+
18
+ ---
19
+
20
+ ## Instructions
21
+
22
+ ### Step 0 — Load the Playwright MCP tool schemas
23
+
24
+ Before doing anything else, call:
25
+ ```
26
+ ToolSearch({ query: "select:mcp__plugin_playwright_playwright__browser_navigate,mcp__plugin_playwright_playwright__browser_click,mcp__plugin_playwright_playwright__browser_console_messages,mcp__plugin_playwright_playwright__browser_snapshot,mcp__plugin_playwright_playwright__browser_wait_for,mcp__plugin_playwright_playwright__browser_evaluate,mcp__plugin_playwright_playwright__browser_handle_dialog,mcp__plugin_playwright_playwright__browser_close" })
27
+ ```
28
+
29
+ You will need all of those tools to be loaded and callable.
30
+
31
+ ---
32
+
33
+ ### Step 1 — Start the dev server and detect its port
34
+
35
+ Astro auto-increments the port when the default (4321) is already in use, so never
36
+ assume a fixed port. Instead, capture the server's own output to read the URL it
37
+ actually binds to.
38
+
39
+ Run this command to start the server and tee its output to a temp file:
40
+ ```bash
41
+ npm run dev > /tmp/astro-dev.log 2>&1 &
42
+ ```
43
+
44
+ Then poll the log file until Astro prints its ready URL. **Do not use `grep -P`** —
45
+ it is not supported on Windows. Use this portable polling loop instead:
46
+ ```bash
47
+ for i in $(seq 1 20); do
48
+ port=$(grep -o 'localhost:[0-9]*' /tmp/astro-dev.log | head -1 | grep -o '[0-9]*$')
49
+ if [ -n "$port" ]; then echo $port; break; fi
50
+ sleep 1
51
+ done
52
+ ```
53
+
54
+ Extract the port from that output and use it as `DEV_PORT` for all subsequent URLs
55
+ (e.g. `http://localhost:${DEV_PORT}/home/`).
56
+
57
+ If the log file already contains a port before you start the server, the server was
58
+ already running — use that port and skip the `npm run dev` step.
59
+
60
+ ---
61
+
62
+ ### Step 2 — Discover pages and define click selectors
63
+
64
+ #### Page URLs
65
+
66
+ Do **not** hardcode the page list. Instead, read the `src/pages` directory to discover
67
+ all `.astro` files:
68
+ ```bash
69
+ find src/pages -name "*.astro" | sort
70
+ ```
71
+
72
+ Convert each file path to a URL route using these rules:
73
+ - Strip the `src/pages/` prefix and `.astro` extension
74
+ - A file named `index.astro` maps to `/`
75
+ - All other files map to `/<name>/` (trailing slash)
76
+ - Nested files (e.g. `src/pages/about/moa.astro`) map to `/about/moa/`
77
+
78
+ Prepend `http://localhost:${DEV_PORT}` from Step 1 to form the full URL.
79
+
80
+ Example — `src/pages/home.astro` → `http://localhost:${DEV_PORT}/home/`
81
+
82
+ #### Click selectors
83
+
84
+ On every page, query for all elements matching the following selectors and click each
85
+ one that is visible and not disabled:
86
+
87
+ ```
88
+ a
89
+ button
90
+ [role="button"]
91
+ [role="link"]
92
+ [role="tab"]
93
+ input[type="checkbox"]
94
+ input[type="radio"]
95
+ [role="checkbox"]
96
+ [role="radio"]
97
+ ```
98
+
99
+ Use a single combined CSS selector string joined with commas when querying the page.
100
+ The user may supply additional or replacement selectors in their request — merge them
101
+ into this list rather than replacing it entirely unless the user says otherwise.
102
+
103
+ ---
104
+
105
+ ### Step 3 — Per-page procedure
106
+
107
+ For **each page URL** discovered in Step 2:
108
+
109
+ 1. Navigate to the page URL.
110
+ 2. Wait for the page to load (use `browser_wait_for` with a known selector like `h1`).
111
+ 3. **Inject a navigation guard** using `browser_evaluate` to prevent link clicks from
112
+ navigating away while still allowing the app's own click handlers (including
113
+ tracking) to run. Use a **bubble-phase** listener so the app's capture-phase and
114
+ bubble-phase handlers fire first:
115
+ ```js
116
+ () => {
117
+ document.addEventListener('click', (e) => {
118
+ const a = e.target.closest('a');
119
+ if (a) e.preventDefault();
120
+ });
121
+ }
122
+ ```
123
+ This approach ensures tracking events fire before navigation is cancelled.
124
+ **Do NOT add a `beforeunload` listener** — it causes a "Leave site?" browser dialog
125
+ that blocks every subsequent Playwright navigation.
126
+
127
+ 4. Take a `browser_snapshot` to get the current accessibility tree. Use the refs from
128
+ this snapshot for all subsequent clicks on this page.
129
+
130
+ 5. For **each matched element** (visible, not disabled):
131
+ a. Click it using `browser_click`.
132
+ b. Wait 500ms for async effects.
133
+ c. If the click opened a modal or significantly changed the DOM, take a new
134
+ `browser_snapshot` before proceeding — snapshot refs become stale after DOM
135
+ changes and will cause errors if reused.
136
+ d. If a dialog appears (check the snapshot for `Modal state`), dismiss it with
137
+ `browser_handle_dialog` before continuing.
138
+
139
+ 6. After all clicks on the page, call `browser_console_messages` **once** with
140
+ `level: "debug"`. Since `all` defaults to `false`, this returns only the messages
141
+ from the current page navigation — no need to diff between clicks.
142
+
143
+ 7. Store all messages with the page route (e.g. `/home/`) as their source.
144
+
145
+ ---
146
+
147
+ ### Step 4 — Parse, deduplicate, and structure the data
148
+
149
+ #### Identify tracking events
150
+
151
+ When an element is clicked the app emits a tracking log in this format:
152
+ ```
153
+ [HH:MM:SS.mmm] DEBUG: track {slide: 'home', type: 'button', name: 'button_evo_flip_card_trigger'}
154
+ ```
155
+
156
+ For every console message, check whether its text matches this pattern:
157
+ ```
158
+ DEBUG: track {…}
159
+ ```
160
+
161
+ If it matches, parse out the object payload `{ slide, type, name }` — these are the
162
+ primary data points of interest. Store them as structured tracking events separate from
163
+ general log messages.
164
+
165
+ #### Collect all messages
166
+
167
+ Gather every console message captured across all pages into a flat list:
168
+ ```
169
+ {
170
+ page: string, // route, e.g. "/home/"
171
+ level: "log"|"warn"|"error"|"info"|"debug",
172
+ text: string, // full raw message text
173
+ tracking: { // only present when the message is a tracking event
174
+ slide: string,
175
+ type: string,
176
+ name: string
177
+ } | null
178
+ }
179
+ ```
180
+
181
+ #### Deduplicate
182
+
183
+ Two messages are duplicates if they share the same `text`. When the same message
184
+ appears on multiple pages, record all pages it appeared on.
185
+
186
+ #### Tiers
187
+
188
+ Organize into four tiers:
189
+ 1. **Tracking Events** — messages matching the `DEBUG: track` pattern
190
+ 2. **Errors** — `console.error`
191
+ 3. **Warnings** — `console.warn`
192
+ 4. **Info / Log** — `console.log`, `console.info`, `console.debug` (excluding tracking events)
193
+
194
+ ---
195
+
196
+ ### Step 5 — Write the report
197
+
198
+ Write a Markdown file to `analytics-audit-report.md` in the project root with this structure:
199
+
200
+ ```markdown
201
+ # Browser Console Log Audit
202
+
203
+ **Date:** <today's date>
204
+ **Pages audited:** /home/, /about/, /about/moa/
205
+ **Total unique messages:** <N>
206
+
207
+ ---
208
+
209
+ ## Tracking Events (<count>)
210
+
211
+ | Slide | Type | Name | Pages |
212
+ |-------|------|------|-------|
213
+ | `home` | `button` | `button_evo_flip_card_trigger` | /home/ |
214
+
215
+ ## Errors (<count>)
216
+
217
+ | Message | Pages |
218
+ |---------|-------|
219
+ | `<message text>` | /home/, /about/ |
220
+
221
+ ## Warnings (<count>)
222
+
223
+ | Message | Pages |
224
+ |---------|-------|
225
+ | `<message text>` | /home/ |
226
+
227
+ ## Info / Log (<count>)
228
+
229
+ | Message | Pages |
230
+ |---------|-------|
231
+ | `<message text>` | /about/moa/ |
232
+
233
+ ---
234
+
235
+ *Generated by the analytics-auditor skill.*
236
+ ```
237
+
238
+ If a tier has zero messages, write `_None_` instead of a table.
239
+
240
+ After writing the file, tell the user where the report was saved and give a brief
241
+ summary (e.g. "Found 8 tracking events, 2 errors, 1 warning, 5 info messages across 3 pages").
242
+
243
+ ---
244
+
245
+ ### Step 6 — Close the browser and clean up
246
+
247
+ Call `browser_close` when done so the Playwright session is cleaned up.
248
+
249
+ Then delete the `.playwright-mcp` directory that Playwright creates for snapshots and
250
+ console logs:
251
+ ```bash
252
+ rm -rf .playwright-mcp
253
+ ```
254
+
255
+ Do **not** stop the dev server — the user likely wants to keep it running.
256
+
257
+ ---
258
+
259
+ ## Notes
260
+
261
+ - The Astro dev server defaults to port **4321** but increments on collision — always
262
+ read the actual port from the server output as described in Step 1.
263
+ - **`grep -P` is not supported on Windows** — use `grep -o` with basic regex patterns.
264
+ - **Snapshot refs go stale** after DOM mutations (modal open/close, tab switches). Always
265
+ re-snapshot after any click that visibly changes the page structure.
266
+ - **`browser_console_messages` fails if a dialog is showing** — check the snapshot for
267
+ `Modal state` and dismiss with `browser_handle_dialog` before calling it.
268
+ - **Call `browser_console_messages` once per page** (at the end), not after every click.
269
+ The default `all: false` scopes results to the current navigation, giving a clean
270
+ per-page log with no diffing needed.
271
+ - If the user provides their own list of selectors or pages, replace the defaults in
272
+ Step 2 before proceeding.
273
+ - If a selector does not match any element on a page, log a warning in the report's
274
+ header section rather than failing.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inizioevoke/veeva-astroclm-core",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "",
5
5
  "license": "ISC",
6
6
  "author": "",