From jaan-to
Generates production-ready GTM tracking code with dataLayer pushes and HTML data attributes for clicks, impressions, and analytics. Use on PRD paths or tracking descriptions.
npx claudepluginhub parhumm/jaan-to --plugin jaan-toThis skill is limited to using the following tools:
> Generate production-ready GTM tracking code with enforced naming conventions.
Creates isolated Git worktrees for feature branches with prioritized directory selection, gitignore safety checks, auto project setup for Node/Python/Rust/Go, and baseline verification.
Executes implementation plans in current session by dispatching fresh subagents per independent task, with two-stage reviews: spec compliance then code quality.
Dispatches parallel agents to independently tackle 2+ tasks like separate test failures or subsystems without shared state or dependencies.
Generate production-ready GTM tracking code with enforced naming conventions.
$JAAN_LEARN_DIR/jaan-to-data-gtm-datalayer.learn.md - Past lessons (loaded in Pre-Execution)$JAAN_TEMPLATES_DIR/jaan-to-data-gtm-datalayer.template.md - Output template${CLAUDE_PLUGIN_ROOT}/docs/extending/language-protocol.md - Language resolution protocolTracking Request: $ARGUMENTS
MANDATORY — Read and execute ALL steps in: ${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md
Skill name: data-gtm-datalayer
Execute: Step 0 (Init Guard) → A (Load Lessons) → B (Resolve Template) → C (Offer Template Seeding)
Read and apply language protocol: ${CLAUDE_PLUGIN_ROOT}/docs/extending/language-protocol.md
Override field for this skill: language_data-gtm-datalayer
Check $ARGUMENTS:
Mode A - PRD Input:
If path to $JAAN_OUTPUTS_DIR/ or PRD text provided:
Mode B - Description Input: If text description of what to track:
Mode C - Interactive Wizard: If no arguments, ask questions in order:
"What type of tracking do you need?"
- click-html - HTML attributes (data-al-*) for simple clicks
- click-datalayer - dataLayer.push for flow-based clicks
- impression - dataLayer.push for visibility/exposure events
"What is the feature name? (e.g., player, checkout, onboarding)"
Apply naming rules:
"What is the item name? (e.g., play, pause, submit, modal-purchase)"
Apply same naming rules as feature.
"What is the action? (default: Click)"
If user provides custom action, apply naming rules. If empty/skipped, use "Click".
"Any additional params? Enter as key=value, one per line. (or 'skip')"
Example:
source=modal
count=3
active=true
Parse into object with ES5 type detection:
true / false → bool (no quotes): true3, 42) → int (no quotes): 3"modal"If none provided, omit params entirely from output.
Show full dataLayer preview before generating:
For click-html:
TRACKING SUMMARY
────────────────────────────────────────
<button data-al-feature="{feature}" data-al-item="{item}">...</button>
────────────────────────────────────────
For click-datalayer (without params):
TRACKING SUMMARY
────────────────────────────────────────
dataLayer.push({
event: "al_tracker_custom",
al: {
feature: "{feature}",
item: "{item}",
action: "{action}"
},
_clear: true
});
────────────────────────────────────────
For click-datalayer (with params):
TRACKING SUMMARY
────────────────────────────────────────
dataLayer.push({
event: "al_tracker_custom",
al: {
feature: "{feature}",
item: "{item}",
action: "{action}",
params: {
source: "modal",
count: 3,
active: true,
}
},
_clear: true
});
────────────────────────────────────────
Values are typed: strings in "quotes", ints/bools without quotes.
For impression (without params):
TRACKING SUMMARY
────────────────────────────────────────
dataLayer.push({
event: "al_tracker_impression",
al: {
feature: "{feature}",
item: "{item}"
},
_clear: true
});
────────────────────────────────────────
For impression (with params):
TRACKING SUMMARY
────────────────────────────────────────
dataLayer.push({
event: "al_tracker_impression",
al: {
feature: "{feature}",
item: "{item}",
params: {
variant: "A",
position: 1,
visible: true,
}
},
_clear: true
});
────────────────────────────────────────
"Generate tracking code with these values? [y/edit]"
Show the full dataLayer preview above (not just field summary).
"Proceed with code generation? [y/n/edit]"
Do NOT proceed to Phase 2 without explicit approval.
Based on tracking type, generate the appropriate code:
<element data-al-feature="{feature}" data-al-item="{item}">{element content}</element>
Example output:
<button data-al-feature="player" data-al-item="pause">Pause</button>
Without params:
dataLayer.push({
event: "al_tracker_custom",
al: {
feature: "{feature}",
item: "{item}",
action: "{action}"
},
_clear: true
});
With params (ES5 typed values):
dataLayer.push({
event: "al_tracker_custom",
al: {
feature: "{feature}",
item: "{item}",
action: "{action}",
params: {
{key1}: {value1}, // string: "value", int: 3, bool: true
{key2}: {value2},
}
},
_clear: true
});
Without params:
dataLayer.push({
event: "al_tracker_impression",
al: {
feature: "{feature}",
item: "{item}"
},
_clear: true
});
With params (ES5 typed values):
dataLayer.push({
event: "al_tracker_impression",
al: {
feature: "{feature}",
item: "{item}",
params: {
{key1}: {value1}, // string: "value", int: 3, bool: true
{key2}: {value2},
}
},
_clear: true
});
Before preview, verify:
event key present in all dataLayer pushes_clear: true included in all dataLayer pushesparams: {} (omit entirely if no params)"quotes", int/bool without)If any check fails, fix before preview.
Display the generated code in conversation:
GENERATED TRACKING CODE
───────────────────────
{code block}
EXAMPLE WITH VALUES
───────────────────
{example showing real values based on user input}
"Save tracking code to output? [y/n]"
If approved, set up the output structure:
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/id-generator.sh"
# Define subdomain directory
SUBDOMAIN_DIR="$JAAN_OUTPUTS_DIR/data/gtm"
mkdir -p "$SUBDOMAIN_DIR"
# Generate next ID
NEXT_ID=$(generate_next_id "$SUBDOMAIN_DIR")
# Create folder and file paths (slug from feature-item, e.g., "player-pause")
slug="{lowercase-hyphenated-feature-item}"
OUTPUT_FOLDER="${SUBDOMAIN_DIR}/${NEXT_ID}-${slug}"
MAIN_FILE="${OUTPUT_FOLDER}/${NEXT_ID}-gtm-${slug}.md"
Output Configuration
- ID: {NEXT_ID}
- Folder: $JAAN_OUTPUTS_DIR/data/gtm/{NEXT_ID}-{slug}/
- Main file: {NEXT_ID}-gtm-{slug}.md
mkdir -p "$OUTPUT_FOLDER"
# Use template from $JAAN_TEMPLATES_DIR/jaan-to-data-gtm-datalayer.template.md
cat > "$MAIN_FILE" <<'EOF'
{generated tracking documentation with Executive Summary}
EOF
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/index-updater.sh"
add_to_index \
"$SUBDOMAIN_DIR/README.md" \
"$NEXT_ID" \
"${NEXT_ID}-${slug}" \
"{Tracking Title}" \
"{1-2 sentence summary: feature-item tracking with event type}"
✓ Tracking code written to: $JAAN_OUTPUTS_DIR/data/gtm/{NEXT_ID}-{slug}/{NEXT_ID}-gtm-{slug}.md ✓ Index updated: $JAAN_OUTPUTS_DIR/data/gtm/README.md
"Any feedback? [y/n]"
If yes:
"[1] Fix now [2] Learn for future [3] Both"
/jaan-to:learn-add data-gtm-datalayer "{feedback}"$JAAN_OUTPUTS_DIR path$JAAN_OUTPUTS_DIR/data/gtm/{slug}/