crumbtrail 0.1.1 → 0.2.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Crumbtrail
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # crumbtrail
2
+
3
+ The setup wizard for [Crumbtrail](https://crumbtrail.dev). It finds your app, wires
4
+ in the SDK, and confirms the first event actually arrives — so you don't have to
5
+ read an integration guide to get started.
6
+
7
+ ```bash
8
+ npx crumbtrail
9
+ ```
10
+
11
+ That's the whole install. There's nothing to add to `package.json` first.
12
+
13
+ ## What it does
14
+
15
+ Running `npx crumbtrail` walks the full path in one pass:
16
+
17
+ 1. **Detects** your stack — Next.js, Vite, React, Vue, Svelte, Express, Hono, Node,
18
+ and non-JS services like Django, Rails, Go and .NET.
19
+ 2. **Logs you in** (opens a browser, or use `--no-browser` for a device code).
20
+ 3. **Provisions** a project and service, and mints an ingest key.
21
+ 4. **Installs** the right SDK package and **injects** the setup code into your entry
22
+ file. This is the only step that writes to your repo, and it always runs last.
23
+ 5. **Verifies** the wiring end to end, then waits for your first real event.
24
+
25
+ In a monorepo, run it from the repo root: it scans every workspace and service,
26
+ shows you what it found, and wires the ones you pick.
27
+
28
+ ## Usage
29
+
30
+ ```
31
+ crumbtrail [options] Run the setup wizard (detect → login → wire → verify)
32
+ crumbtrail login Log in and cache a token, nothing else
33
+ crumbtrail logout Delete the cached token
34
+ ```
35
+
36
+ | Option | Description |
37
+ | --- | --- |
38
+ | `--yes`, `-y` | Skip confirmations (required with `--project` in CI) |
39
+ | `--project <id>` | Attach to an existing project instead of creating one |
40
+ | `--only <name>` | Monorepo: wire only this service (repeatable) |
41
+ | `--all` | Monorepo: wire every service it can, no prompts |
42
+ | `--workspace <dir>` | Wire just one package dir instead of the whole repo |
43
+ | `--no-browser` | Use the device-code login flow |
44
+ | `--skip-verify` | Don't wait for the first event |
45
+ | `--endpoint <url>` | Cloud endpoint (else `$CRUMBTRAIL_BASE_URL`, else the default) |
46
+ | `--version`, `-v` | Print the version |
47
+
48
+ ### Non-interactive / CI
49
+
50
+ Outside a TTY the wizard refuses to guess. Pass `--yes` and an existing
51
+ `--project <id>`:
52
+
53
+ ```bash
54
+ npx crumbtrail --yes --project prj_1234abcd --only web --skip-verify
55
+ ```
56
+
57
+ ## What it writes
58
+
59
+ Only two kinds of change, both in the package it's wiring:
60
+
61
+ - the SDK import and `Crumbtrail.init(...)` call in your entry file
62
+ - `CRUMBTRAIL_KEY` appended to that package's `.env`
63
+
64
+ It won't touch a package that is already wired, and it never edits libraries or
65
+ config-only packages.
66
+
67
+ ## Prefer to wire it by hand?
68
+
69
+ Nothing here is magic — see [`crumbtrail-core`](https://www.npmjs.com/package/crumbtrail-core)
70
+ for the three-line manual setup.
71
+
72
+ ## Links
73
+
74
+ - **Website** — https://crumbtrail.dev
75
+ - **Docs** — https://crumbtrail.dev/docs
76
+ - **How it works** — https://crumbtrail.dev/how-it-works
77
+ - **Pricing** — https://crumbtrail.dev/pricing
78
+ - **Source** — https://github.com/crumbtrail-dev/crumbtrail-js
79
+ - **Issues** — https://github.com/crumbtrail-dev/crumbtrail-js/issues
80
+
81
+ ## License
82
+
83
+ MIT
@@ -0,0 +1,199 @@
1
+ // ../core/dist/bug-widget-LGIRLS76.js
2
+ var WIDGET_CSS = `
3
+ :host {
4
+ all: initial;
5
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
6
+ font-size: 14px;
7
+ color: #e0e0e0;
8
+ }
9
+
10
+ .bl-trigger {
11
+ position: fixed;
12
+ bottom: 20px;
13
+ right: 20px;
14
+ width: 48px;
15
+ height: 48px;
16
+ border-radius: 50%;
17
+ background: #dc2626;
18
+ border: none;
19
+ cursor: pointer;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3);
24
+ z-index: 2147483647;
25
+ transition: transform 0.15s ease, background 0.15s ease;
26
+ }
27
+ .bl-trigger:hover {
28
+ transform: scale(1.1);
29
+ background: #ef4444;
30
+ }
31
+ .bl-trigger svg {
32
+ width: 24px;
33
+ height: 24px;
34
+ fill: white;
35
+ }
36
+
37
+ .bl-popover {
38
+ position: fixed;
39
+ bottom: 80px;
40
+ right: 20px;
41
+ width: 320px;
42
+ background: #1e1e1e;
43
+ border: 1px solid #333;
44
+ border-radius: 12px;
45
+ box-shadow: 0 8px 32px rgba(0,0,0,0.4);
46
+ z-index: 2147483647;
47
+ padding: 16px;
48
+ display: none;
49
+ }
50
+ .bl-popover.open {
51
+ display: block;
52
+ }
53
+
54
+ .bl-popover h3 {
55
+ margin: 0 0 12px;
56
+ font-size: 15px;
57
+ font-weight: 600;
58
+ color: #f5f5f5;
59
+ }
60
+
61
+ .bl-note {
62
+ width: 100%;
63
+ min-height: 60px;
64
+ background: #2a2a2a;
65
+ border: 1px solid #444;
66
+ border-radius: 8px;
67
+ color: #e0e0e0;
68
+ padding: 8px 10px;
69
+ font-size: 13px;
70
+ font-family: inherit;
71
+ resize: vertical;
72
+ box-sizing: border-box;
73
+ }
74
+ .bl-note::placeholder {
75
+ color: #777;
76
+ }
77
+ .bl-note:focus {
78
+ outline: none;
79
+ border-color: #dc2626;
80
+ }
81
+
82
+ .bl-actions {
83
+ display: flex;
84
+ gap: 8px;
85
+ margin-top: 12px;
86
+ align-items: center;
87
+ }
88
+
89
+ .bl-btn {
90
+ padding: 8px 16px;
91
+ border-radius: 8px;
92
+ border: none;
93
+ cursor: pointer;
94
+ font-size: 13px;
95
+ font-weight: 500;
96
+ transition: background 0.15s ease;
97
+ }
98
+ .bl-submit {
99
+ background: #dc2626;
100
+ color: white;
101
+ flex: 1;
102
+ }
103
+ .bl-submit:hover {
104
+ background: #ef4444;
105
+ }
106
+ .bl-submit:disabled {
107
+ opacity: 0.5;
108
+ cursor: not-allowed;
109
+ }
110
+
111
+ .bl-status {
112
+ font-size: 11px;
113
+ color: #777;
114
+ margin-top: 8px;
115
+ }
116
+
117
+ .bl-hint {
118
+ font-size: 11px;
119
+ color: #555;
120
+ margin-top: 8px;
121
+ text-align: center;
122
+ }
123
+ `;
124
+ var BUG_SVG = `<svg viewBox="0 0 24 24"><path d="M20 8h-2.81a5.985 5.985 0 0 0-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5s-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/></svg>`;
125
+ function mountWidget(logger) {
126
+ const host = document.createElement("div");
127
+ host.id = "crumbtrail-widget";
128
+ const shadow = host.attachShadow({ mode: "closed" });
129
+ const style = document.createElement("style");
130
+ style.textContent = WIDGET_CSS;
131
+ shadow.appendChild(style);
132
+ const trigger = document.createElement("button");
133
+ trigger.className = "bl-trigger";
134
+ trigger.innerHTML = BUG_SVG;
135
+ trigger.title = "Flag a bug (Ctrl+Shift+B)";
136
+ shadow.appendChild(trigger);
137
+ const popover = document.createElement("div");
138
+ popover.className = "bl-popover";
139
+ popover.innerHTML = `
140
+ <h3>Flag a Bug</h3>
141
+ <textarea class="bl-note" placeholder="What went wrong? (optional)"></textarea>
142
+ <div class="bl-actions">
143
+ <button class="bl-btn bl-submit">Send Bug Report</button>
144
+ </div>
145
+ <div class="bl-status"></div>
146
+ <div class="bl-hint">Ctrl+Shift+B to toggle</div>
147
+ `;
148
+ shadow.appendChild(popover);
149
+ const noteInput = popover.querySelector(".bl-note");
150
+ const submitBtn = popover.querySelector(".bl-submit");
151
+ const statusEl = popover.querySelector(".bl-status");
152
+ let isOpen = false;
153
+ function toggle() {
154
+ isOpen = !isOpen;
155
+ popover.classList.toggle("open", isOpen);
156
+ if (isOpen) {
157
+ noteInput.focus();
158
+ } else {
159
+ reset();
160
+ }
161
+ }
162
+ function reset() {
163
+ noteInput.value = "";
164
+ statusEl.textContent = "";
165
+ }
166
+ trigger.addEventListener("click", toggle);
167
+ submitBtn.addEventListener("click", async () => {
168
+ submitBtn.disabled = true;
169
+ statusEl.textContent = "Sending...";
170
+ try {
171
+ const { bugId } = await logger.flagBug({
172
+ note: noteInput.value || void 0
173
+ });
174
+ statusEl.textContent = `Saved: ${bugId}`;
175
+ setTimeout(() => {
176
+ toggle();
177
+ submitBtn.disabled = false;
178
+ }, 1500);
179
+ } catch {
180
+ statusEl.textContent = "Failed to send";
181
+ submitBtn.disabled = false;
182
+ }
183
+ });
184
+ function onKeyDown(e) {
185
+ if (e.ctrlKey && e.shiftKey && e.key === "B") {
186
+ e.preventDefault();
187
+ toggle();
188
+ }
189
+ }
190
+ document.addEventListener("keydown", onKeyDown);
191
+ document.body.appendChild(host);
192
+ return () => {
193
+ document.removeEventListener("keydown", onKeyDown);
194
+ host.remove();
195
+ };
196
+ }
197
+ export {
198
+ mountWidget
199
+ };