guideagent 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -1 +1,196 @@
1
- http://127.0.0.1:5500/guideagent/test.html
1
+ # 🧭 GuideAgent
2
+
3
+ <p align="center">
4
+ <b>Lightweight user onboarding & product tour library for modern web apps</b><br/>
5
+ Guide users step-by-step with multi-language support.
6
+ </p>
7
+
8
+ <p align="center">
9
+ <a href="https://www.npmjs.com/package/guideagent">📦 NPM</a> •
10
+ <a href="#installation">⚙️ Installation</a> •
11
+ <a href="#usage">🚀 Usage</a> •
12
+ <a href="#api-reference">📚 API</a>
13
+ </p>
14
+
15
+ ---
16
+
17
+ ## ✨ Features
18
+
19
+ * 🧭 Step-by-step guided tours
20
+ * 🌐 Multi-language support (English, Tamil, Hindi)
21
+ * ⚡ Lightweight & fast
22
+ * 🧩 Works with React, Vue, Angular, or plain HTML
23
+ * 🎯 Flexible selector targeting
24
+ * 🔄 Auto start on first visit
25
+
26
+ ---
27
+
28
+ ## ⚙️ Installation
29
+
30
+ ```bash
31
+ npm install guideagent
32
+ ```
33
+
34
+ ---
35
+
36
+ ## 🚀 Usage
37
+
38
+ ### React / Next.js
39
+
40
+ ```jsx
41
+ import GuideAgent from 'guideagent'
42
+
43
+ setTimeout(() => {
44
+ GuideAgent.initFromUrl('/guide.json')
45
+ }, 800)
46
+ ```
47
+
48
+ ---
49
+
50
+ ### Vue.js
51
+
52
+ ```js
53
+ import GuideAgent from 'guideagent'
54
+
55
+ app.mount('#app')
56
+
57
+ setTimeout(() => {
58
+ GuideAgent.initFromUrl('/guide.json')
59
+ }, 800)
60
+ ```
61
+
62
+ ---
63
+
64
+ ### Angular
65
+
66
+ ```ts
67
+ import GuideAgent from 'guideagent'
68
+
69
+ platformBrowserDynamic().bootstrapModule(AppModule).then(() => {
70
+ setTimeout(() => {
71
+ GuideAgent.initFromUrl('/guide.json')
72
+ }, 800)
73
+ })
74
+ ```
75
+
76
+ ---
77
+
78
+ ### Plain HTML (No Install)
79
+
80
+ ```html
81
+ <script type="module">
82
+ import GuideAgent from 'https://unpkg.com/guideagent/dist/index.mjs'
83
+ await GuideAgent.initFromUrl('./guide.json')
84
+ </script>
85
+ ```
86
+
87
+ ---
88
+
89
+ ## 🧩 Step 2 — Add Guide Targets
90
+
91
+ Add `data-guide-id` to elements you want to highlight:
92
+
93
+ ```html
94
+ <header data-guide-id="navbar"></header>
95
+ <section data-guide-id="hero"></section>
96
+ <div data-guide-id="features"></div>
97
+ <section data-guide-id="contact"></section>
98
+ ```
99
+
100
+ ---
101
+
102
+ ## 📄 Step 3 — Create guide.json
103
+
104
+ ```json
105
+ {
106
+ "page": "home",
107
+ "steps": [
108
+ {
109
+ "selector": "[data-guide-id='hero']",
110
+ "order": 1,
111
+ "translations": {
112
+ "en": {
113
+ "title": "Welcome!",
114
+ "description": "Let me walk you through this app."
115
+ },
116
+ "ta": {
117
+ "title": "Vanakkam!",
118
+ "description": "Ithai pathi kaattukirein."
119
+ },
120
+ "hi": {
121
+ "title": "Swagat!",
122
+ "description": "Main aapko guide karunga."
123
+ }
124
+ }
125
+ }
126
+ ]
127
+ }
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 🎯 Selector Options
133
+
134
+ ```html
135
+ <!-- Recommended -->
136
+ <div data-guide-id="dashboard"></div>
137
+
138
+ <!-- ID selector -->
139
+ <div id="dashboard"></div>
140
+
141
+ <!-- Class selector -->
142
+ <div class="hero-section"></div>
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 📚 API Reference
148
+
149
+ | Method | Description |
150
+ | --------------------------------------- | -------------------- |
151
+ | `GuideAgent.initFromUrl('/guide.json')` | Load guide from JSON |
152
+ | `GuideAgent.init({ steps })` | Load guide from JS |
153
+ | `GuideAgent.start()` | Start guide manually |
154
+ | `GuideAgent.stop()` | Stop guide |
155
+ | `GuideAgent.setLang('ta')` | Change language |
156
+ | `GuideAgent.getStrings()` | Get current strings |
157
+
158
+ ---
159
+
160
+ ## 🌐 Supported Languages
161
+
162
+ | Code | Language |
163
+ | ---- | -------- |
164
+ | en | English |
165
+ | ta | Tamil |
166
+ | hi | Hindi |
167
+
168
+ ---
169
+
170
+ ## ⚡ How It Works
171
+
172
+ ```
173
+ Page Load
174
+
175
+ Welcome Popup (first visit)
176
+
177
+ Start Guide / Maybe Later
178
+
179
+ Guide Runs
180
+
181
+ Floating Button (bottom-right)
182
+
183
+ Stop Anytime (top-right ✕)
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 📦 NPM Package
189
+
190
+ 👉 https://www.npmjs.com/package/guideagent
191
+
192
+ ---
193
+
194
+ ## 💡 Author
195
+
196
+ Built with ❤️ for better onboarding experiences
package/dist/index.d.mts CHANGED
@@ -6,6 +6,11 @@ interface LanguageStrings {
6
6
  guide_me_btn: string;
7
7
  guide_complete: string;
8
8
  step_of: string;
9
+ welcome_title: string;
10
+ welcome_desc: string;
11
+ welcome_start: string;
12
+ welcome_cancel: string;
13
+ select_language: string;
9
14
  }
10
15
 
11
16
  interface StepTranslation {
@@ -27,10 +32,12 @@ declare const GuideAgent: {
27
32
  version: string;
28
33
  init(config: GuideConfig): void;
29
34
  initFromUrl(configUrl: string): Promise<void>;
35
+ showWelcomeOnFirstVisit(): void;
30
36
  start(): void;
31
37
  stop(): void;
32
38
  setLang(lang: string): void;
33
39
  getStrings(): LanguageStrings;
40
+ updateFloatingButtonText(): void;
34
41
  createFloatingButton(): void;
35
42
  };
36
43
 
package/dist/index.d.ts CHANGED
@@ -6,6 +6,11 @@ interface LanguageStrings {
6
6
  guide_me_btn: string;
7
7
  guide_complete: string;
8
8
  step_of: string;
9
+ welcome_title: string;
10
+ welcome_desc: string;
11
+ welcome_start: string;
12
+ welcome_cancel: string;
13
+ select_language: string;
9
14
  }
10
15
 
11
16
  interface StepTranslation {
@@ -27,10 +32,12 @@ declare const GuideAgent: {
27
32
  version: string;
28
33
  init(config: GuideConfig): void;
29
34
  initFromUrl(configUrl: string): Promise<void>;
35
+ showWelcomeOnFirstVisit(): void;
30
36
  start(): void;
31
37
  stop(): void;
32
38
  setLang(lang: string): void;
33
39
  getStrings(): LanguageStrings;
40
+ updateFloatingButtonText(): void;
34
41
  createFloatingButton(): void;
35
42
  };
36
43
 
package/dist/index.js CHANGED
@@ -98,7 +98,12 @@ var en_default = {
98
98
  finish_btn: "Finish \u2713",
99
99
  guide_me_btn: "\u{1F9ED} Guide Me",
100
100
  guide_complete: "\u2713 Guide Complete!",
101
- step_of: "Step {current} of {total}"
101
+ step_of: "Step {current} of {total}",
102
+ welcome_title: "Welcome! \u{1F44B}",
103
+ welcome_desc: "Would you like a quick tour of this page? I'll guide you through everything in just a few steps.",
104
+ welcome_start: "Start Guide \u{1F9ED}",
105
+ welcome_cancel: "Maybe Later",
106
+ select_language: "Choose your language"
102
107
  };
103
108
 
104
109
  // src/i18n/ta.json
@@ -109,7 +114,12 @@ var ta_default = {
109
114
  finish_btn: "Mudinthathu \u2713",
110
115
  guide_me_btn: "\u{1F9ED} Vazhi Kaattu",
111
116
  guide_complete: "\u2713 Vazhi Kaattal Mudinthathu!",
112
- step_of: "Padi {current} / {total}"
117
+ step_of: "Padi {current} / {total}",
118
+ welcome_title: "Vanakkam! \u{1F44B}",
119
+ welcome_desc: "Indha page-ai pathi oru siriya vilakkam venum? Sila padikalil ellaam kaattukirein.",
120
+ welcome_start: "Thoda Thottangu \u{1F9ED}",
121
+ welcome_cancel: "Pinbu Paarkiren",
122
+ select_language: "Mozhi Theru"
113
123
  };
114
124
 
115
125
  // src/i18n/hi.json
@@ -120,7 +130,12 @@ var hi_default = {
120
130
  finish_btn: "Khatam \u2713",
121
131
  guide_me_btn: "\u{1F9ED} Mujhe Guide Karo",
122
132
  guide_complete: "\u2713 Guide Poora Hua!",
123
- step_of: "Kadam {current} / {total}"
133
+ step_of: "Kadam {current} / {total}",
134
+ welcome_title: "Swagat Hai! \u{1F44B}",
135
+ welcome_desc: "Kya aap is page ka ek chhota tour lena chahte hain? Main kuch steps mein sab dikhata hoon.",
136
+ welcome_start: "Guide Shuru Karo \u{1F9ED}",
137
+ welcome_cancel: "Baad Mein",
138
+ select_language: "Bhasha Chunein"
124
139
  };
125
140
 
126
141
  // src/config/i18n.ts
@@ -445,6 +460,317 @@ var GuideEngine = class {
445
460
  }
446
461
  };
447
462
 
463
+ // src/renderer/welcome.ts
464
+ var welcomeEl = null;
465
+ var closeBtn = null;
466
+ function showWelcomeDialog(onStart, onCancel) {
467
+ removeWelcomeDialog();
468
+ renderDialog(onStart, onCancel);
469
+ }
470
+ function showLanguagePicker(onContinue, onCancel) {
471
+ var _a, _b, _c, _d, _e;
472
+ removeWelcomeDialog();
473
+ const s = getStrings();
474
+ welcomeEl = document.createElement("div");
475
+ Object.assign(welcomeEl.style, {
476
+ position: "fixed",
477
+ inset: "0",
478
+ background: "rgba(0,0,0,0.7)",
479
+ zIndex: "10002",
480
+ display: "flex",
481
+ alignItems: "center",
482
+ justifyContent: "center",
483
+ fontFamily: "sans-serif"
484
+ });
485
+ const dialog = document.createElement("div");
486
+ Object.assign(dialog.style, {
487
+ background: "#1e1e2e",
488
+ border: "1px solid #6366f1",
489
+ borderRadius: "16px",
490
+ padding: "28px",
491
+ width: "90%",
492
+ maxWidth: "340px",
493
+ boxShadow: "0 24px 64px rgba(0,0,0,0.6)",
494
+ color: "#ffffff",
495
+ textAlign: "center",
496
+ position: "relative"
497
+ });
498
+ dialog.innerHTML = `
499
+ <!-- Close X -->
500
+ <button id="ga-picker-close" style="
501
+ position: absolute;
502
+ top: 12px; right: 14px;
503
+ background: transparent;
504
+ border: none;
505
+ color: #64748b;
506
+ font-size: 18px;
507
+ cursor: pointer;
508
+ line-height: 1;
509
+ ">\u2715</button>
510
+
511
+ <!-- Title -->
512
+ <div style="
513
+ font-size: 12px;
514
+ color: #a5b4fc;
515
+ font-weight: 700;
516
+ text-transform: uppercase;
517
+ letter-spacing: 1px;
518
+ margin-bottom: 16px;
519
+ ">\u{1F9ED} GUIDEAGENT</div>
520
+
521
+ <h3 id="ga-picker-title" style="
522
+ font-size: 18px;
523
+ font-weight: 800;
524
+ margin-bottom: 20px;
525
+ color: #ffffff;
526
+ ">${s.select_language}</h3>
527
+
528
+ <!-- Language Buttons -->
529
+ <div style="display: flex; gap: 10px; justify-content: center; margin-bottom: 24px;">
530
+ <button id="ga-lang-en" style="
531
+ padding: 10px 20px;
532
+ border-radius: 8px;
533
+ border: 1px solid #6366f1;
534
+ background: #6366f1;
535
+ color: white;
536
+ font-size: 13px;
537
+ font-weight: 700;
538
+ cursor: pointer;
539
+ transition: all 0.2s;
540
+ ">EN</button>
541
+
542
+ <button id="ga-lang-ta" style="
543
+ padding: 10px 20px;
544
+ border-radius: 8px;
545
+ border: 1px solid #334155;
546
+ background: transparent;
547
+ color: #94a3b8;
548
+ font-size: 13px;
549
+ font-weight: 700;
550
+ cursor: pointer;
551
+ ">TA</button>
552
+
553
+ <button id="ga-lang-hi" style="
554
+ padding: 10px 20px;
555
+ border-radius: 8px;
556
+ border: 1px solid #334155;
557
+ background: transparent;
558
+ color: #94a3b8;
559
+ font-size: 13px;
560
+ font-weight: 700;
561
+ cursor: pointer;
562
+ ">HI</button>
563
+ </div>
564
+
565
+ <!-- Continue Button -->
566
+ <button id="ga-continue-btn" style="
567
+ width: 100%;
568
+ padding: 12px;
569
+ background: #6366f1;
570
+ color: white;
571
+ border: none;
572
+ border-radius: 10px;
573
+ font-size: 14px;
574
+ font-weight: 700;
575
+ cursor: pointer;
576
+ ">${s.welcome_start}</button>
577
+ `;
578
+ welcomeEl.appendChild(dialog);
579
+ document.body.appendChild(welcomeEl);
580
+ const setActiveLang = (lang) => {
581
+ setLanguage(lang);
582
+ ["en", "ta", "hi"].forEach((l) => {
583
+ const btn = document.getElementById(`ga-lang-${l}`);
584
+ if (!btn) return;
585
+ if (l === lang) {
586
+ Object.assign(btn.style, {
587
+ background: "#6366f1",
588
+ color: "white",
589
+ border: "1px solid #6366f1"
590
+ });
591
+ } else {
592
+ Object.assign(btn.style, {
593
+ background: "transparent",
594
+ color: "#94a3b8",
595
+ border: "1px solid #334155"
596
+ });
597
+ }
598
+ });
599
+ const continueBtn = document.getElementById("ga-continue-btn");
600
+ if (continueBtn) continueBtn.textContent = getStrings().welcome_start;
601
+ };
602
+ (_a = document.getElementById("ga-lang-en")) == null ? void 0 : _a.addEventListener("click", () => setActiveLang("en"));
603
+ (_b = document.getElementById("ga-lang-ta")) == null ? void 0 : _b.addEventListener("click", () => setActiveLang("ta"));
604
+ (_c = document.getElementById("ga-lang-hi")) == null ? void 0 : _c.addEventListener("click", () => setActiveLang("hi"));
605
+ (_d = document.getElementById("ga-continue-btn")) == null ? void 0 : _d.addEventListener("click", () => {
606
+ removeWelcomeDialog();
607
+ onContinue();
608
+ });
609
+ (_e = document.getElementById("ga-picker-close")) == null ? void 0 : _e.addEventListener("click", () => {
610
+ removeWelcomeDialog();
611
+ onCancel();
612
+ });
613
+ }
614
+ function showCloseButton(onClose) {
615
+ removeCloseButton();
616
+ closeBtn = document.createElement("button");
617
+ closeBtn.textContent = "\u2715 Stop Guide";
618
+ Object.assign(closeBtn.style, {
619
+ position: "fixed",
620
+ top: "20px",
621
+ right: "20px",
622
+ background: "rgba(30,30,46,0.95)",
623
+ color: "#f87171",
624
+ border: "1px solid #f87171",
625
+ padding: "8px 16px",
626
+ borderRadius: "999px",
627
+ fontSize: "13px",
628
+ fontWeight: "700",
629
+ fontFamily: "sans-serif",
630
+ cursor: "pointer",
631
+ zIndex: "10003",
632
+ boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
633
+ transition: "all 0.2s ease"
634
+ });
635
+ closeBtn.addEventListener("mouseenter", () => {
636
+ closeBtn.style.background = "#f87171";
637
+ closeBtn.style.color = "white";
638
+ });
639
+ closeBtn.addEventListener("mouseleave", () => {
640
+ closeBtn.style.background = "rgba(30,30,46,0.95)";
641
+ closeBtn.style.color = "#f87171";
642
+ });
643
+ closeBtn.addEventListener("click", () => {
644
+ removeCloseButton();
645
+ onClose();
646
+ });
647
+ document.body.appendChild(closeBtn);
648
+ }
649
+ function removeCloseButton() {
650
+ closeBtn == null ? void 0 : closeBtn.remove();
651
+ closeBtn = null;
652
+ }
653
+ function removeWelcomeDialog() {
654
+ welcomeEl == null ? void 0 : welcomeEl.remove();
655
+ welcomeEl = null;
656
+ }
657
+ function renderDialog(onStart, onCancel) {
658
+ var _a, _b, _c, _d, _e, _f;
659
+ const s = getStrings();
660
+ welcomeEl = document.createElement("div");
661
+ Object.assign(welcomeEl.style, {
662
+ position: "fixed",
663
+ inset: "0",
664
+ background: "rgba(0,0,0,0.7)",
665
+ zIndex: "10002",
666
+ display: "flex",
667
+ alignItems: "center",
668
+ justifyContent: "center",
669
+ fontFamily: "sans-serif"
670
+ });
671
+ const dialog = document.createElement("div");
672
+ Object.assign(dialog.style, {
673
+ background: "#1e1e2e",
674
+ border: "1px solid #6366f1",
675
+ borderRadius: "16px",
676
+ padding: "32px",
677
+ width: "90%",
678
+ maxWidth: "420px",
679
+ boxShadow: "0 24px 64px rgba(0,0,0,0.6)",
680
+ color: "#ffffff",
681
+ textAlign: "center",
682
+ position: "relative"
683
+ });
684
+ dialog.innerHTML = `
685
+ <button id="ga-welcome-close" style="
686
+ position: absolute; top: 12px; right: 14px;
687
+ background: transparent; border: none;
688
+ color: #64748b; font-size: 18px; cursor: pointer;
689
+ ">\u2715</button>
690
+
691
+ <div style="
692
+ display: inline-flex; align-items: center; gap: 8px;
693
+ background: #6366f1; padding: 8px 16px;
694
+ border-radius: 999px; font-size: 12px;
695
+ font-weight: 700; color: white; margin-bottom: 20px;
696
+ ">\u{1F9ED} GUIDEAGENT</div>
697
+
698
+ <h2 id="ga-welcome-title" style="
699
+ font-size: 22px; font-weight: 800;
700
+ margin-bottom: 12px; color: #ffffff;
701
+ ">${s.welcome_title}</h2>
702
+
703
+ <p id="ga-welcome-desc" style="
704
+ font-size: 14px; color: #94a3b8;
705
+ line-height: 1.6; margin-bottom: 24px;
706
+ ">${s.welcome_desc}</p>
707
+
708
+ <p id="ga-select-lang" style="
709
+ font-size: 11px; color: #64748b;
710
+ text-transform: uppercase; letter-spacing: 1px;
711
+ margin-bottom: 10px; font-weight: 600;
712
+ ">${s.select_language}</p>
713
+
714
+ <div style="display:flex; gap:8px; justify-content:center; margin-bottom:24px;">
715
+ <button id="ga-lang-en" style="padding:6px 16px; border-radius:6px; border:1px solid #6366f1; background:#6366f1; color:white; font-size:12px; font-weight:600; cursor:pointer;">EN</button>
716
+ <button id="ga-lang-ta" style="padding:6px 16px; border-radius:6px; border:1px solid #334155; background:transparent; color:#94a3b8; font-size:12px; font-weight:600; cursor:pointer;">TA</button>
717
+ <button id="ga-lang-hi" style="padding:6px 16px; border-radius:6px; border:1px solid #334155; background:transparent; color:#94a3b8; font-size:12px; font-weight:600; cursor:pointer;">HI</button>
718
+ </div>
719
+
720
+ <button id="ga-start-btn" style="
721
+ width:100%; padding:12px; background:#6366f1;
722
+ color:white; border:none; border-radius:10px;
723
+ font-size:15px; font-weight:700; cursor:pointer; margin-bottom:10px;
724
+ ">${s.welcome_start}</button>
725
+
726
+ <button id="ga-cancel-btn" style="
727
+ width:100%; padding:10px; background:transparent;
728
+ color:#64748b; border:1px solid #1e293b;
729
+ border-radius:10px; font-size:13px; cursor:pointer;
730
+ ">${s.welcome_cancel}</button>
731
+ `;
732
+ welcomeEl.appendChild(dialog);
733
+ document.body.appendChild(welcomeEl);
734
+ const setActiveLang = (lang) => {
735
+ setLanguage(lang);
736
+ ["en", "ta", "hi"].forEach((l2) => {
737
+ const btn = document.getElementById(`ga-lang-${l2}`);
738
+ if (!btn) return;
739
+ if (l2 === lang) {
740
+ Object.assign(btn.style, { background: "#6366f1", color: "white", border: "1px solid #6366f1" });
741
+ } else {
742
+ Object.assign(btn.style, { background: "transparent", color: "#94a3b8", border: "1px solid #334155" });
743
+ }
744
+ });
745
+ const ns = getStrings();
746
+ const t = document.getElementById("ga-welcome-title");
747
+ const d = document.getElementById("ga-welcome-desc");
748
+ const l = document.getElementById("ga-select-lang");
749
+ const s2 = document.getElementById("ga-start-btn");
750
+ const c = document.getElementById("ga-cancel-btn");
751
+ if (t) t.textContent = ns.welcome_title;
752
+ if (d) d.textContent = ns.welcome_desc;
753
+ if (l) l.textContent = ns.select_language;
754
+ if (s2) s2.textContent = ns.welcome_start;
755
+ if (c) c.textContent = ns.welcome_cancel;
756
+ };
757
+ (_a = document.getElementById("ga-lang-en")) == null ? void 0 : _a.addEventListener("click", () => setActiveLang("en"));
758
+ (_b = document.getElementById("ga-lang-ta")) == null ? void 0 : _b.addEventListener("click", () => setActiveLang("ta"));
759
+ (_c = document.getElementById("ga-lang-hi")) == null ? void 0 : _c.addEventListener("click", () => setActiveLang("hi"));
760
+ (_d = document.getElementById("ga-start-btn")) == null ? void 0 : _d.addEventListener("click", () => {
761
+ removeWelcomeDialog();
762
+ onStart();
763
+ });
764
+ (_e = document.getElementById("ga-cancel-btn")) == null ? void 0 : _e.addEventListener("click", () => {
765
+ removeWelcomeDialog();
766
+ onCancel();
767
+ });
768
+ (_f = document.getElementById("ga-welcome-close")) == null ? void 0 : _f.addEventListener("click", () => {
769
+ removeWelcomeDialog();
770
+ onCancel();
771
+ });
772
+ }
773
+
448
774
  // src/index.ts
449
775
  var engine = null;
450
776
  var floatingBtn = null;
@@ -453,7 +779,7 @@ var GuideAgent = {
453
779
  init(config) {
454
780
  engine = new GuideEngine(config);
455
781
  this.createFloatingButton();
456
- console.log("GuideAgent initialized \u2705");
782
+ this.showWelcomeOnFirstVisit();
457
783
  },
458
784
  async initFromUrl(configUrl) {
459
785
  try {
@@ -461,27 +787,49 @@ var GuideAgent = {
461
787
  const config = await loadConfig2(configUrl);
462
788
  engine = new GuideEngine({ steps: config.steps });
463
789
  this.createFloatingButton();
464
- console.log("GuideAgent initialized from URL \u2705");
790
+ this.showWelcomeOnFirstVisit();
465
791
  } catch (error) {
466
792
  console.error("GuideAgent: initFromUrl failed:", error);
467
793
  }
468
794
  },
795
+ showWelcomeOnFirstVisit() {
796
+ const hasVisited = sessionStorage.getItem("ga_visited");
797
+ if (hasVisited) return;
798
+ setTimeout(() => {
799
+ showWelcomeDialog(
800
+ () => {
801
+ sessionStorage.setItem("ga_visited", "true");
802
+ this.updateFloatingButtonText();
803
+ showCloseButton(() => this.stop());
804
+ engine == null ? void 0 : engine.start();
805
+ },
806
+ () => {
807
+ sessionStorage.setItem("ga_visited", "true");
808
+ }
809
+ );
810
+ }, 1e3);
811
+ },
469
812
  start() {
470
813
  engine == null ? void 0 : engine.start();
814
+ showCloseButton(() => this.stop());
471
815
  },
472
816
  stop() {
473
817
  engine == null ? void 0 : engine.stop();
818
+ removeCloseButton();
819
+ removeWelcomeDialog();
474
820
  },
475
821
  setLang(lang) {
476
822
  setLanguage(lang);
477
- if (floatingBtn) {
478
- floatingBtn.textContent = getStrings().guide_me_btn;
479
- }
823
+ this.updateFloatingButtonText();
480
824
  },
481
- // Expose getStrings so HTML can read page content keys
482
825
  getStrings() {
483
826
  return getStrings();
484
827
  },
828
+ updateFloatingButtonText() {
829
+ if (floatingBtn) {
830
+ floatingBtn.textContent = getStrings().guide_me_btn;
831
+ }
832
+ },
485
833
  createFloatingButton() {
486
834
  floatingBtn == null ? void 0 : floatingBtn.remove();
487
835
  floatingBtn = document.createElement("button");
@@ -510,7 +858,15 @@ var GuideAgent = {
510
858
  floatingBtn.style.transform = "scale(1)";
511
859
  });
512
860
  floatingBtn.addEventListener("click", () => {
513
- engine == null ? void 0 : engine.start();
861
+ showLanguagePicker(
862
+ () => {
863
+ this.updateFloatingButtonText();
864
+ showCloseButton(() => this.stop());
865
+ engine == null ? void 0 : engine.start();
866
+ },
867
+ () => {
868
+ }
869
+ );
514
870
  });
515
871
  document.body.appendChild(floatingBtn);
516
872
  }
package/dist/index.mjs CHANGED
@@ -6,7 +6,12 @@ var en_default = {
6
6
  finish_btn: "Finish \u2713",
7
7
  guide_me_btn: "\u{1F9ED} Guide Me",
8
8
  guide_complete: "\u2713 Guide Complete!",
9
- step_of: "Step {current} of {total}"
9
+ step_of: "Step {current} of {total}",
10
+ welcome_title: "Welcome! \u{1F44B}",
11
+ welcome_desc: "Would you like a quick tour of this page? I'll guide you through everything in just a few steps.",
12
+ welcome_start: "Start Guide \u{1F9ED}",
13
+ welcome_cancel: "Maybe Later",
14
+ select_language: "Choose your language"
10
15
  };
11
16
 
12
17
  // src/i18n/ta.json
@@ -17,7 +22,12 @@ var ta_default = {
17
22
  finish_btn: "Mudinthathu \u2713",
18
23
  guide_me_btn: "\u{1F9ED} Vazhi Kaattu",
19
24
  guide_complete: "\u2713 Vazhi Kaattal Mudinthathu!",
20
- step_of: "Padi {current} / {total}"
25
+ step_of: "Padi {current} / {total}",
26
+ welcome_title: "Vanakkam! \u{1F44B}",
27
+ welcome_desc: "Indha page-ai pathi oru siriya vilakkam venum? Sila padikalil ellaam kaattukirein.",
28
+ welcome_start: "Thoda Thottangu \u{1F9ED}",
29
+ welcome_cancel: "Pinbu Paarkiren",
30
+ select_language: "Mozhi Theru"
21
31
  };
22
32
 
23
33
  // src/i18n/hi.json
@@ -28,7 +38,12 @@ var hi_default = {
28
38
  finish_btn: "Khatam \u2713",
29
39
  guide_me_btn: "\u{1F9ED} Mujhe Guide Karo",
30
40
  guide_complete: "\u2713 Guide Poora Hua!",
31
- step_of: "Kadam {current} / {total}"
41
+ step_of: "Kadam {current} / {total}",
42
+ welcome_title: "Swagat Hai! \u{1F44B}",
43
+ welcome_desc: "Kya aap is page ka ek chhota tour lena chahte hain? Main kuch steps mein sab dikhata hoon.",
44
+ welcome_start: "Guide Shuru Karo \u{1F9ED}",
45
+ welcome_cancel: "Baad Mein",
46
+ select_language: "Bhasha Chunein"
32
47
  };
33
48
 
34
49
  // src/config/i18n.ts
@@ -353,6 +368,317 @@ var GuideEngine = class {
353
368
  }
354
369
  };
355
370
 
371
+ // src/renderer/welcome.ts
372
+ var welcomeEl = null;
373
+ var closeBtn = null;
374
+ function showWelcomeDialog(onStart, onCancel) {
375
+ removeWelcomeDialog();
376
+ renderDialog(onStart, onCancel);
377
+ }
378
+ function showLanguagePicker(onContinue, onCancel) {
379
+ var _a, _b, _c, _d, _e;
380
+ removeWelcomeDialog();
381
+ const s = getStrings();
382
+ welcomeEl = document.createElement("div");
383
+ Object.assign(welcomeEl.style, {
384
+ position: "fixed",
385
+ inset: "0",
386
+ background: "rgba(0,0,0,0.7)",
387
+ zIndex: "10002",
388
+ display: "flex",
389
+ alignItems: "center",
390
+ justifyContent: "center",
391
+ fontFamily: "sans-serif"
392
+ });
393
+ const dialog = document.createElement("div");
394
+ Object.assign(dialog.style, {
395
+ background: "#1e1e2e",
396
+ border: "1px solid #6366f1",
397
+ borderRadius: "16px",
398
+ padding: "28px",
399
+ width: "90%",
400
+ maxWidth: "340px",
401
+ boxShadow: "0 24px 64px rgba(0,0,0,0.6)",
402
+ color: "#ffffff",
403
+ textAlign: "center",
404
+ position: "relative"
405
+ });
406
+ dialog.innerHTML = `
407
+ <!-- Close X -->
408
+ <button id="ga-picker-close" style="
409
+ position: absolute;
410
+ top: 12px; right: 14px;
411
+ background: transparent;
412
+ border: none;
413
+ color: #64748b;
414
+ font-size: 18px;
415
+ cursor: pointer;
416
+ line-height: 1;
417
+ ">\u2715</button>
418
+
419
+ <!-- Title -->
420
+ <div style="
421
+ font-size: 12px;
422
+ color: #a5b4fc;
423
+ font-weight: 700;
424
+ text-transform: uppercase;
425
+ letter-spacing: 1px;
426
+ margin-bottom: 16px;
427
+ ">\u{1F9ED} GUIDEAGENT</div>
428
+
429
+ <h3 id="ga-picker-title" style="
430
+ font-size: 18px;
431
+ font-weight: 800;
432
+ margin-bottom: 20px;
433
+ color: #ffffff;
434
+ ">${s.select_language}</h3>
435
+
436
+ <!-- Language Buttons -->
437
+ <div style="display: flex; gap: 10px; justify-content: center; margin-bottom: 24px;">
438
+ <button id="ga-lang-en" style="
439
+ padding: 10px 20px;
440
+ border-radius: 8px;
441
+ border: 1px solid #6366f1;
442
+ background: #6366f1;
443
+ color: white;
444
+ font-size: 13px;
445
+ font-weight: 700;
446
+ cursor: pointer;
447
+ transition: all 0.2s;
448
+ ">EN</button>
449
+
450
+ <button id="ga-lang-ta" style="
451
+ padding: 10px 20px;
452
+ border-radius: 8px;
453
+ border: 1px solid #334155;
454
+ background: transparent;
455
+ color: #94a3b8;
456
+ font-size: 13px;
457
+ font-weight: 700;
458
+ cursor: pointer;
459
+ ">TA</button>
460
+
461
+ <button id="ga-lang-hi" style="
462
+ padding: 10px 20px;
463
+ border-radius: 8px;
464
+ border: 1px solid #334155;
465
+ background: transparent;
466
+ color: #94a3b8;
467
+ font-size: 13px;
468
+ font-weight: 700;
469
+ cursor: pointer;
470
+ ">HI</button>
471
+ </div>
472
+
473
+ <!-- Continue Button -->
474
+ <button id="ga-continue-btn" style="
475
+ width: 100%;
476
+ padding: 12px;
477
+ background: #6366f1;
478
+ color: white;
479
+ border: none;
480
+ border-radius: 10px;
481
+ font-size: 14px;
482
+ font-weight: 700;
483
+ cursor: pointer;
484
+ ">${s.welcome_start}</button>
485
+ `;
486
+ welcomeEl.appendChild(dialog);
487
+ document.body.appendChild(welcomeEl);
488
+ const setActiveLang = (lang) => {
489
+ setLanguage(lang);
490
+ ["en", "ta", "hi"].forEach((l) => {
491
+ const btn = document.getElementById(`ga-lang-${l}`);
492
+ if (!btn) return;
493
+ if (l === lang) {
494
+ Object.assign(btn.style, {
495
+ background: "#6366f1",
496
+ color: "white",
497
+ border: "1px solid #6366f1"
498
+ });
499
+ } else {
500
+ Object.assign(btn.style, {
501
+ background: "transparent",
502
+ color: "#94a3b8",
503
+ border: "1px solid #334155"
504
+ });
505
+ }
506
+ });
507
+ const continueBtn = document.getElementById("ga-continue-btn");
508
+ if (continueBtn) continueBtn.textContent = getStrings().welcome_start;
509
+ };
510
+ (_a = document.getElementById("ga-lang-en")) == null ? void 0 : _a.addEventListener("click", () => setActiveLang("en"));
511
+ (_b = document.getElementById("ga-lang-ta")) == null ? void 0 : _b.addEventListener("click", () => setActiveLang("ta"));
512
+ (_c = document.getElementById("ga-lang-hi")) == null ? void 0 : _c.addEventListener("click", () => setActiveLang("hi"));
513
+ (_d = document.getElementById("ga-continue-btn")) == null ? void 0 : _d.addEventListener("click", () => {
514
+ removeWelcomeDialog();
515
+ onContinue();
516
+ });
517
+ (_e = document.getElementById("ga-picker-close")) == null ? void 0 : _e.addEventListener("click", () => {
518
+ removeWelcomeDialog();
519
+ onCancel();
520
+ });
521
+ }
522
+ function showCloseButton(onClose) {
523
+ removeCloseButton();
524
+ closeBtn = document.createElement("button");
525
+ closeBtn.textContent = "\u2715 Stop Guide";
526
+ Object.assign(closeBtn.style, {
527
+ position: "fixed",
528
+ top: "20px",
529
+ right: "20px",
530
+ background: "rgba(30,30,46,0.95)",
531
+ color: "#f87171",
532
+ border: "1px solid #f87171",
533
+ padding: "8px 16px",
534
+ borderRadius: "999px",
535
+ fontSize: "13px",
536
+ fontWeight: "700",
537
+ fontFamily: "sans-serif",
538
+ cursor: "pointer",
539
+ zIndex: "10003",
540
+ boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
541
+ transition: "all 0.2s ease"
542
+ });
543
+ closeBtn.addEventListener("mouseenter", () => {
544
+ closeBtn.style.background = "#f87171";
545
+ closeBtn.style.color = "white";
546
+ });
547
+ closeBtn.addEventListener("mouseleave", () => {
548
+ closeBtn.style.background = "rgba(30,30,46,0.95)";
549
+ closeBtn.style.color = "#f87171";
550
+ });
551
+ closeBtn.addEventListener("click", () => {
552
+ removeCloseButton();
553
+ onClose();
554
+ });
555
+ document.body.appendChild(closeBtn);
556
+ }
557
+ function removeCloseButton() {
558
+ closeBtn == null ? void 0 : closeBtn.remove();
559
+ closeBtn = null;
560
+ }
561
+ function removeWelcomeDialog() {
562
+ welcomeEl == null ? void 0 : welcomeEl.remove();
563
+ welcomeEl = null;
564
+ }
565
+ function renderDialog(onStart, onCancel) {
566
+ var _a, _b, _c, _d, _e, _f;
567
+ const s = getStrings();
568
+ welcomeEl = document.createElement("div");
569
+ Object.assign(welcomeEl.style, {
570
+ position: "fixed",
571
+ inset: "0",
572
+ background: "rgba(0,0,0,0.7)",
573
+ zIndex: "10002",
574
+ display: "flex",
575
+ alignItems: "center",
576
+ justifyContent: "center",
577
+ fontFamily: "sans-serif"
578
+ });
579
+ const dialog = document.createElement("div");
580
+ Object.assign(dialog.style, {
581
+ background: "#1e1e2e",
582
+ border: "1px solid #6366f1",
583
+ borderRadius: "16px",
584
+ padding: "32px",
585
+ width: "90%",
586
+ maxWidth: "420px",
587
+ boxShadow: "0 24px 64px rgba(0,0,0,0.6)",
588
+ color: "#ffffff",
589
+ textAlign: "center",
590
+ position: "relative"
591
+ });
592
+ dialog.innerHTML = `
593
+ <button id="ga-welcome-close" style="
594
+ position: absolute; top: 12px; right: 14px;
595
+ background: transparent; border: none;
596
+ color: #64748b; font-size: 18px; cursor: pointer;
597
+ ">\u2715</button>
598
+
599
+ <div style="
600
+ display: inline-flex; align-items: center; gap: 8px;
601
+ background: #6366f1; padding: 8px 16px;
602
+ border-radius: 999px; font-size: 12px;
603
+ font-weight: 700; color: white; margin-bottom: 20px;
604
+ ">\u{1F9ED} GUIDEAGENT</div>
605
+
606
+ <h2 id="ga-welcome-title" style="
607
+ font-size: 22px; font-weight: 800;
608
+ margin-bottom: 12px; color: #ffffff;
609
+ ">${s.welcome_title}</h2>
610
+
611
+ <p id="ga-welcome-desc" style="
612
+ font-size: 14px; color: #94a3b8;
613
+ line-height: 1.6; margin-bottom: 24px;
614
+ ">${s.welcome_desc}</p>
615
+
616
+ <p id="ga-select-lang" style="
617
+ font-size: 11px; color: #64748b;
618
+ text-transform: uppercase; letter-spacing: 1px;
619
+ margin-bottom: 10px; font-weight: 600;
620
+ ">${s.select_language}</p>
621
+
622
+ <div style="display:flex; gap:8px; justify-content:center; margin-bottom:24px;">
623
+ <button id="ga-lang-en" style="padding:6px 16px; border-radius:6px; border:1px solid #6366f1; background:#6366f1; color:white; font-size:12px; font-weight:600; cursor:pointer;">EN</button>
624
+ <button id="ga-lang-ta" style="padding:6px 16px; border-radius:6px; border:1px solid #334155; background:transparent; color:#94a3b8; font-size:12px; font-weight:600; cursor:pointer;">TA</button>
625
+ <button id="ga-lang-hi" style="padding:6px 16px; border-radius:6px; border:1px solid #334155; background:transparent; color:#94a3b8; font-size:12px; font-weight:600; cursor:pointer;">HI</button>
626
+ </div>
627
+
628
+ <button id="ga-start-btn" style="
629
+ width:100%; padding:12px; background:#6366f1;
630
+ color:white; border:none; border-radius:10px;
631
+ font-size:15px; font-weight:700; cursor:pointer; margin-bottom:10px;
632
+ ">${s.welcome_start}</button>
633
+
634
+ <button id="ga-cancel-btn" style="
635
+ width:100%; padding:10px; background:transparent;
636
+ color:#64748b; border:1px solid #1e293b;
637
+ border-radius:10px; font-size:13px; cursor:pointer;
638
+ ">${s.welcome_cancel}</button>
639
+ `;
640
+ welcomeEl.appendChild(dialog);
641
+ document.body.appendChild(welcomeEl);
642
+ const setActiveLang = (lang) => {
643
+ setLanguage(lang);
644
+ ["en", "ta", "hi"].forEach((l2) => {
645
+ const btn = document.getElementById(`ga-lang-${l2}`);
646
+ if (!btn) return;
647
+ if (l2 === lang) {
648
+ Object.assign(btn.style, { background: "#6366f1", color: "white", border: "1px solid #6366f1" });
649
+ } else {
650
+ Object.assign(btn.style, { background: "transparent", color: "#94a3b8", border: "1px solid #334155" });
651
+ }
652
+ });
653
+ const ns = getStrings();
654
+ const t = document.getElementById("ga-welcome-title");
655
+ const d = document.getElementById("ga-welcome-desc");
656
+ const l = document.getElementById("ga-select-lang");
657
+ const s2 = document.getElementById("ga-start-btn");
658
+ const c = document.getElementById("ga-cancel-btn");
659
+ if (t) t.textContent = ns.welcome_title;
660
+ if (d) d.textContent = ns.welcome_desc;
661
+ if (l) l.textContent = ns.select_language;
662
+ if (s2) s2.textContent = ns.welcome_start;
663
+ if (c) c.textContent = ns.welcome_cancel;
664
+ };
665
+ (_a = document.getElementById("ga-lang-en")) == null ? void 0 : _a.addEventListener("click", () => setActiveLang("en"));
666
+ (_b = document.getElementById("ga-lang-ta")) == null ? void 0 : _b.addEventListener("click", () => setActiveLang("ta"));
667
+ (_c = document.getElementById("ga-lang-hi")) == null ? void 0 : _c.addEventListener("click", () => setActiveLang("hi"));
668
+ (_d = document.getElementById("ga-start-btn")) == null ? void 0 : _d.addEventListener("click", () => {
669
+ removeWelcomeDialog();
670
+ onStart();
671
+ });
672
+ (_e = document.getElementById("ga-cancel-btn")) == null ? void 0 : _e.addEventListener("click", () => {
673
+ removeWelcomeDialog();
674
+ onCancel();
675
+ });
676
+ (_f = document.getElementById("ga-welcome-close")) == null ? void 0 : _f.addEventListener("click", () => {
677
+ removeWelcomeDialog();
678
+ onCancel();
679
+ });
680
+ }
681
+
356
682
  // src/index.ts
357
683
  var engine = null;
358
684
  var floatingBtn = null;
@@ -361,7 +687,7 @@ var GuideAgent = {
361
687
  init(config) {
362
688
  engine = new GuideEngine(config);
363
689
  this.createFloatingButton();
364
- console.log("GuideAgent initialized \u2705");
690
+ this.showWelcomeOnFirstVisit();
365
691
  },
366
692
  async initFromUrl(configUrl) {
367
693
  try {
@@ -369,27 +695,49 @@ var GuideAgent = {
369
695
  const config = await loadConfig(configUrl);
370
696
  engine = new GuideEngine({ steps: config.steps });
371
697
  this.createFloatingButton();
372
- console.log("GuideAgent initialized from URL \u2705");
698
+ this.showWelcomeOnFirstVisit();
373
699
  } catch (error) {
374
700
  console.error("GuideAgent: initFromUrl failed:", error);
375
701
  }
376
702
  },
703
+ showWelcomeOnFirstVisit() {
704
+ const hasVisited = sessionStorage.getItem("ga_visited");
705
+ if (hasVisited) return;
706
+ setTimeout(() => {
707
+ showWelcomeDialog(
708
+ () => {
709
+ sessionStorage.setItem("ga_visited", "true");
710
+ this.updateFloatingButtonText();
711
+ showCloseButton(() => this.stop());
712
+ engine == null ? void 0 : engine.start();
713
+ },
714
+ () => {
715
+ sessionStorage.setItem("ga_visited", "true");
716
+ }
717
+ );
718
+ }, 1e3);
719
+ },
377
720
  start() {
378
721
  engine == null ? void 0 : engine.start();
722
+ showCloseButton(() => this.stop());
379
723
  },
380
724
  stop() {
381
725
  engine == null ? void 0 : engine.stop();
726
+ removeCloseButton();
727
+ removeWelcomeDialog();
382
728
  },
383
729
  setLang(lang) {
384
730
  setLanguage(lang);
385
- if (floatingBtn) {
386
- floatingBtn.textContent = getStrings().guide_me_btn;
387
- }
731
+ this.updateFloatingButtonText();
388
732
  },
389
- // Expose getStrings so HTML can read page content keys
390
733
  getStrings() {
391
734
  return getStrings();
392
735
  },
736
+ updateFloatingButtonText() {
737
+ if (floatingBtn) {
738
+ floatingBtn.textContent = getStrings().guide_me_btn;
739
+ }
740
+ },
393
741
  createFloatingButton() {
394
742
  floatingBtn == null ? void 0 : floatingBtn.remove();
395
743
  floatingBtn = document.createElement("button");
@@ -418,7 +766,15 @@ var GuideAgent = {
418
766
  floatingBtn.style.transform = "scale(1)";
419
767
  });
420
768
  floatingBtn.addEventListener("click", () => {
421
- engine == null ? void 0 : engine.start();
769
+ showLanguagePicker(
770
+ () => {
771
+ this.updateFloatingButtonText();
772
+ showCloseButton(() => this.stop());
773
+ engine == null ? void 0 : engine.start();
774
+ },
775
+ () => {
776
+ }
777
+ );
422
778
  });
423
779
  document.body.appendChild(floatingBtn);
424
780
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "guideagent",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Contextual in-app guidance SDK for web apps — multilingual, config-driven, developer-first",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",