instruckt 0.4.28 → 0.4.30
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 +122 -139
- package/dist/instruckt.cjs.js +87 -24
- package/dist/instruckt.cjs.js.map +1 -1
- package/dist/instruckt.d.cts +14 -1
- package/dist/instruckt.d.ts +14 -1
- package/dist/instruckt.esm.js +87 -24
- package/dist/instruckt.esm.js.map +1 -1
- package/dist/instruckt.iife.js +53 -23
- package/dist/instruckt.iife.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -12,9 +12,22 @@ npm install instruckt
|
|
|
12
12
|
|
|
13
13
|
## Quick Start
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
> **Pick your framework below** -- each section is self-contained.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
| Framework | Setup |
|
|
18
|
+
|-----------|-------|
|
|
19
|
+
| [SPA (Vue, React, Svelte)](#spa-vue-react-svelte-with-vite) | Vite plugin only |
|
|
20
|
+
| [SvelteKit](#sveltekit) | Vite plugin + virtual import |
|
|
21
|
+
| [Nuxt](#nuxt) | Vite plugin + virtual import |
|
|
22
|
+
| [Next.js](#nextjs) | Client component |
|
|
23
|
+
| [Laravel](#laravel) | Composer package |
|
|
24
|
+
| [Astro](#astro) | Community integration |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
### SPA (Vue, React, Svelte with Vite)
|
|
29
|
+
|
|
30
|
+
Add the Vite plugin — it handles client injection and provides a built-in dev API server. No backend required.
|
|
18
31
|
|
|
19
32
|
```js
|
|
20
33
|
// vite.config.ts
|
|
@@ -25,165 +38,59 @@ export default defineConfig({
|
|
|
25
38
|
})
|
|
26
39
|
```
|
|
27
40
|
|
|
28
|
-
That's it
|
|
41
|
+
That's it. The plugin auto-injects the client via `transformIndexHtml`.
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
---
|
|
31
44
|
|
|
32
|
-
|
|
45
|
+
### SvelteKit
|
|
33
46
|
|
|
34
|
-
|
|
35
|
-
composer require joshcirre/instruckt-laravel --dev
|
|
36
|
-
php artisan instruckt:install
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
The install command adds the Vite plugin to your `vite.config.js` with `server: false` (Laravel owns the backend), configures MCP for your AI agent, and adds the virtual import to your JS entry point.
|
|
47
|
+
Two steps — add the Vite plugin, then import the virtual module in your layout:
|
|
40
48
|
|
|
41
49
|
```js
|
|
42
|
-
// vite.config.
|
|
50
|
+
// vite.config.ts
|
|
43
51
|
import instruckt from 'instruckt/vite'
|
|
44
52
|
|
|
45
53
|
export default defineConfig({
|
|
46
|
-
plugins: [
|
|
47
|
-
laravel({ input: ['resources/js/app.js'] }),
|
|
48
|
-
instruckt({
|
|
49
|
-
server: false,
|
|
50
|
-
adapters: ['livewire', 'blade'],
|
|
51
|
-
mcp: true,
|
|
52
|
-
}),
|
|
53
|
-
],
|
|
54
|
+
plugins: [sveltekit(), instruckt()],
|
|
54
55
|
})
|
|
55
56
|
```
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
// SvelteKit: src/routes/+layout.svelte
|
|
63
|
-
import 'virtual:instruckt'
|
|
64
|
-
|
|
65
|
-
// Nuxt: plugins/instruckt.client.ts
|
|
66
|
-
import 'virtual:instruckt'
|
|
58
|
+
```svelte
|
|
59
|
+
<!-- src/routes/+layout.svelte -->
|
|
60
|
+
<script>
|
|
61
|
+
import 'virtual:instruckt'
|
|
62
|
+
</script>
|
|
67
63
|
```
|
|
68
64
|
|
|
69
65
|
The virtual module is SSR-safe — it only initializes in the browser.
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
See **[instruckt-astro](https://github.com/sgasser/instruckt-astro)** for a community-maintained Astro integration.
|
|
74
|
-
|
|
75
|
-
## Vite Plugin Options
|
|
76
|
-
|
|
77
|
-
```js
|
|
78
|
-
instruckt({
|
|
79
|
-
// Framework adapters to activate (default: auto-detect)
|
|
80
|
-
adapters: ['svelte'],
|
|
81
|
-
|
|
82
|
-
// Theme: 'light' | 'dark' | 'auto' (default: 'auto')
|
|
83
|
-
theme: 'auto',
|
|
67
|
+
---
|
|
84
68
|
|
|
85
|
-
|
|
86
|
-
position: 'bottom-right',
|
|
69
|
+
### Nuxt
|
|
87
70
|
|
|
88
|
-
|
|
89
|
-
colors: { default: '#6366f1', screenshot: '#22c55e', dismissed: '#71717a' },
|
|
90
|
-
|
|
91
|
-
// Customize keyboard shortcuts
|
|
92
|
-
keys: { annotate: 'a', freeze: 'f', screenshot: 'c', clearPage: 'x' },
|
|
93
|
-
|
|
94
|
-
// Storage directory for annotations + screenshots (default: '.instruckt')
|
|
95
|
-
dir: '.instruckt',
|
|
96
|
-
|
|
97
|
-
// API endpoint prefix (default: '/instruckt')
|
|
98
|
-
endpoint: '/instruckt',
|
|
99
|
-
|
|
100
|
-
// Enable built-in dev API server (default: true)
|
|
101
|
-
// Set to false when your framework provides its own backend (e.g. Laravel)
|
|
102
|
-
server: true,
|
|
103
|
-
|
|
104
|
-
// Show MCP tool instructions in clipboard markdown (default: false)
|
|
105
|
-
// Set to true when using with a backend that registers MCP tools
|
|
106
|
-
mcp: false,
|
|
107
|
-
})
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Manual Setup
|
|
111
|
-
|
|
112
|
-
If you're not using Vite, you can initialize instruckt directly:
|
|
71
|
+
Same idea — add the Vite plugin, then import the virtual module in a client plugin:
|
|
113
72
|
|
|
114
73
|
```js
|
|
115
|
-
|
|
74
|
+
// nuxt.config.ts — add the Vite plugin
|
|
75
|
+
import instruckt from 'instruckt/vite'
|
|
116
76
|
|
|
117
|
-
|
|
118
|
-
|
|
77
|
+
export default defineNuxtConfig({
|
|
78
|
+
vite: {
|
|
79
|
+
plugins: [instruckt()],
|
|
80
|
+
},
|
|
119
81
|
})
|
|
120
82
|
```
|
|
121
83
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
instruckt
|
|
125
|
-
|
|
126
|
-
<details>
|
|
127
|
-
<summary>SvelteKit</summary>
|
|
128
|
-
|
|
129
|
-
```svelte
|
|
130
|
-
<!-- src/lib/InstrucktProvider.svelte -->
|
|
131
|
-
<script>
|
|
132
|
-
import { onMount } from 'svelte';
|
|
133
|
-
|
|
134
|
-
onMount(async () => {
|
|
135
|
-
const { Instruckt } = await import('instruckt');
|
|
136
|
-
const instruckt = new Instruckt({
|
|
137
|
-
endpoint: '/api/annotations',
|
|
138
|
-
adapters: ['svelte'],
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
return () => instruckt.destroy();
|
|
142
|
-
});
|
|
143
|
-
</script>
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
```svelte
|
|
147
|
-
<!-- src/routes/+layout.svelte -->
|
|
148
|
-
<script>
|
|
149
|
-
import { browser } from '$app/environment';
|
|
150
|
-
|
|
151
|
-
let { children } = $props();
|
|
152
|
-
</script>
|
|
153
|
-
|
|
154
|
-
{#if browser}
|
|
155
|
-
{#await import('$lib/InstrucktProvider.svelte') then { default: InstrucktProvider }}
|
|
156
|
-
<InstrucktProvider />
|
|
157
|
-
{/await}
|
|
158
|
-
{/if}
|
|
159
|
-
|
|
160
|
-
{@render children()}
|
|
84
|
+
```ts
|
|
85
|
+
// plugins/instruckt.client.ts
|
|
86
|
+
import 'virtual:instruckt'
|
|
161
87
|
```
|
|
162
88
|
|
|
163
|
-
|
|
89
|
+
---
|
|
164
90
|
|
|
165
|
-
|
|
166
|
-
<summary>Nuxt</summary>
|
|
91
|
+
### Next.js
|
|
167
92
|
|
|
168
|
-
|
|
169
|
-
<!-- plugins/instruckt.client.ts -->
|
|
170
|
-
<script>
|
|
171
|
-
// The .client.ts suffix ensures Nuxt only runs this in the browser
|
|
172
|
-
export default defineNuxtPlugin(async () => {
|
|
173
|
-
const { Instruckt } = await import('instruckt')
|
|
174
|
-
|
|
175
|
-
const instruckt = new Instruckt({
|
|
176
|
-
endpoint: '/api/annotations',
|
|
177
|
-
adapters: ['vue'],
|
|
178
|
-
})
|
|
179
|
-
})
|
|
180
|
-
</script>
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
</details>
|
|
184
|
-
|
|
185
|
-
<details>
|
|
186
|
-
<summary>Next.js (App Router)</summary>
|
|
93
|
+
Next.js doesn't use Vite, so initialize instruckt directly in a client component:
|
|
187
94
|
|
|
188
95
|
```tsx
|
|
189
96
|
// components/InstrucktProvider.tsx
|
|
@@ -225,7 +132,77 @@ export default function RootLayout({ children }) {
|
|
|
225
132
|
}
|
|
226
133
|
```
|
|
227
134
|
|
|
228
|
-
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Laravel
|
|
138
|
+
|
|
139
|
+
Use the **[instruckt-laravel](https://github.com/joshcirre/instruckt-laravel)** package — it provides the backend API, MCP tools, JSON file storage, and handles install/uninstall automatically:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
composer require joshcirre/instruckt-laravel --dev
|
|
143
|
+
php artisan instruckt:install
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
The install command adds the Vite plugin to your `vite.config.js` with `server: false` (Laravel owns the backend), configures MCP for your AI agent, and adds the virtual import to your JS entry point.
|
|
147
|
+
|
|
148
|
+
```js
|
|
149
|
+
// vite.config.js (added automatically by install command)
|
|
150
|
+
import instruckt from 'instruckt/vite'
|
|
151
|
+
|
|
152
|
+
export default defineConfig({
|
|
153
|
+
plugins: [
|
|
154
|
+
laravel({ input: ['resources/js/app.js'] }),
|
|
155
|
+
instruckt({
|
|
156
|
+
server: false,
|
|
157
|
+
adapters: ['livewire', 'blade'],
|
|
158
|
+
mcp: true,
|
|
159
|
+
}),
|
|
160
|
+
],
|
|
161
|
+
})
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### Astro
|
|
167
|
+
|
|
168
|
+
See **[instruckt-astro](https://github.com/sgasser/instruckt-astro)** for a community-maintained Astro integration.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Vite Plugin Options
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
instruckt({
|
|
176
|
+
// Framework adapters to activate (default: auto-detect)
|
|
177
|
+
adapters: ['svelte'],
|
|
178
|
+
|
|
179
|
+
// Theme: 'light' | 'dark' | 'auto' (default: 'auto')
|
|
180
|
+
theme: 'auto',
|
|
181
|
+
|
|
182
|
+
// Toolbar position (default: 'bottom-right')
|
|
183
|
+
position: 'bottom-right',
|
|
184
|
+
|
|
185
|
+
// Customize marker pin colors
|
|
186
|
+
colors: { default: '#6366f1', screenshot: '#22c55e', dismissed: '#71717a' },
|
|
187
|
+
|
|
188
|
+
// Customize keyboard shortcuts
|
|
189
|
+
keys: { annotate: 'a', freeze: 'f', screenshot: 'c', clearPage: 'x' },
|
|
190
|
+
|
|
191
|
+
// Storage directory for annotations + screenshots (default: '.instruckt')
|
|
192
|
+
dir: '.instruckt',
|
|
193
|
+
|
|
194
|
+
// API endpoint prefix (default: '/instruckt')
|
|
195
|
+
endpoint: '/instruckt',
|
|
196
|
+
|
|
197
|
+
// Enable built-in dev API server (default: true)
|
|
198
|
+
// Set to false when your framework provides its own backend (e.g. Laravel)
|
|
199
|
+
server: true,
|
|
200
|
+
|
|
201
|
+
// Show MCP tool instructions in clipboard markdown (default: false)
|
|
202
|
+
// Set to true when using with a backend that registers MCP tools
|
|
203
|
+
mcp: false,
|
|
204
|
+
})
|
|
205
|
+
```
|
|
229
206
|
|
|
230
207
|
## How It Works
|
|
231
208
|
|
|
@@ -242,16 +219,22 @@ export default function RootLayout({ children }) {
|
|
|
242
219
|
### Example Output
|
|
243
220
|
|
|
244
221
|
```markdown
|
|
245
|
-
# UI Feedback: /
|
|
222
|
+
# UI Feedback: /dashboard
|
|
246
223
|
|
|
247
224
|
## 1. Change the submit button color to green
|
|
248
|
-
- Element: `button.btn-primary` in `
|
|
225
|
+
- Element: `button.btn-primary` in `LoginForm`
|
|
226
|
+
- Source: `src/components/LoginForm.tsx:42:5`
|
|
227
|
+
- Component stack:
|
|
228
|
+
- LoginForm `src/components/LoginForm.tsx:42:5`
|
|
229
|
+
- AuthPage `src/pages/AuthPage.tsx:18:3`
|
|
230
|
+
- App `src/App.tsx:8:7`
|
|
249
231
|
- Classes: `btn btn-primary`
|
|
250
232
|
- Text: "Submit Login"
|
|
251
233
|
- Screenshot: `.instruckt/screenshots/01JWXYZ.png`
|
|
252
234
|
|
|
253
235
|
## 2. Make the login card have rounded corners
|
|
254
|
-
- Element: `div.bg-white` in `
|
|
236
|
+
- Element: `div.bg-white` in `LoginCard`
|
|
237
|
+
- Source: `src/components/LoginCard.tsx:15:3`
|
|
255
238
|
- Classes: `bg-white dark:bg-white/10 border`
|
|
256
239
|
```
|
|
257
240
|
|
|
@@ -309,7 +292,7 @@ Default shortcuts (customizable via `keys` config):
|
|
|
309
292
|
|
|
310
293
|
## Features
|
|
311
294
|
|
|
312
|
-
- **Framework detection** — automatically identifies Livewire, Vue, Svelte, and React components
|
|
295
|
+
- **Framework detection** — automatically identifies Livewire, Vue, Svelte, and React components with full component stacks and precise source locations (file:line:column) via [element-source](https://github.com/aidenybai/element-source)
|
|
313
296
|
- **Screenshots** — capture element or region screenshots; uses DOM-to-image on standard apps, automatically falls back to Screen Capture API on shadow DOM frameworks (Flux UI, etc.)
|
|
314
297
|
- **Shadow DOM isolation** — all UI renders in shadow roots so it never conflicts with your styles
|
|
315
298
|
- **Copy as markdown** — annotations auto-copy as structured markdown optimized for AI agents
|
package/dist/instruckt.cjs.js
CHANGED
|
@@ -2951,6 +2951,9 @@ function getPageBoundingBox(el) {
|
|
|
2951
2951
|
};
|
|
2952
2952
|
}
|
|
2953
2953
|
|
|
2954
|
+
// src/instruckt.ts
|
|
2955
|
+
var import_element_source = require("element-source");
|
|
2956
|
+
|
|
2954
2957
|
// src/adapters/livewire.ts
|
|
2955
2958
|
function isAvailable() {
|
|
2956
2959
|
return typeof window.Livewire !== "undefined";
|
|
@@ -3250,7 +3253,7 @@ var _Instruckt = class _Instruckt {
|
|
|
3250
3253
|
e.stopImmediatePropagation();
|
|
3251
3254
|
};
|
|
3252
3255
|
this.boundClick = (e) => {
|
|
3253
|
-
var _a2, _b
|
|
3256
|
+
var _a2, _b;
|
|
3254
3257
|
const target = e.target;
|
|
3255
3258
|
if (this.isInstruckt(target)) return;
|
|
3256
3259
|
e.preventDefault();
|
|
@@ -3263,23 +3266,24 @@ var _Instruckt = class _Instruckt {
|
|
|
3263
3266
|
const cssClasses = getCssClasses(target);
|
|
3264
3267
|
const nearbyText = getNearbyText(target) || void 0;
|
|
3265
3268
|
const boundingBox = getPageBoundingBox(target);
|
|
3266
|
-
|
|
3267
|
-
(_c = this.highlight) == null ? void 0 : _c.show(target);
|
|
3269
|
+
(_b = this.highlight) == null ? void 0 : _b.show(target);
|
|
3268
3270
|
this.highlightLocked = true;
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3271
|
+
this.detectFramework(target).then((framework) => {
|
|
3272
|
+
const pending = {
|
|
3273
|
+
element: target,
|
|
3274
|
+
elementPath,
|
|
3275
|
+
elementName,
|
|
3276
|
+
elementLabel,
|
|
3277
|
+
cssClasses,
|
|
3278
|
+
boundingBox,
|
|
3279
|
+
x: e.clientX,
|
|
3280
|
+
y: e.clientY,
|
|
3281
|
+
selectedText,
|
|
3282
|
+
nearbyText,
|
|
3283
|
+
framework: framework != null ? framework : void 0
|
|
3284
|
+
};
|
|
3285
|
+
this.showAnnotationPopup(pending);
|
|
3286
|
+
});
|
|
3283
3287
|
};
|
|
3284
3288
|
this.config = __spreadValues({
|
|
3285
3289
|
adapters: ["livewire", "vue", "svelte", "react", "blade"],
|
|
@@ -3685,7 +3689,7 @@ var _Instruckt = class _Instruckt {
|
|
|
3685
3689
|
}
|
|
3686
3690
|
// ── Region screenshot ────────────────────────────────────────
|
|
3687
3691
|
async startRegionCapture() {
|
|
3688
|
-
var _a2
|
|
3692
|
+
var _a2;
|
|
3689
3693
|
const wasAnnotating = this.isAnnotating;
|
|
3690
3694
|
if (wasAnnotating) this.setAnnotating(false);
|
|
3691
3695
|
const rect = await selectRegion();
|
|
@@ -3701,6 +3705,7 @@ var _Instruckt = class _Instruckt {
|
|
|
3701
3705
|
const centerX = rect.x + rect.width / 2;
|
|
3702
3706
|
const centerY = rect.y + rect.height / 2;
|
|
3703
3707
|
const target = (_a2 = document.elementFromPoint(centerX, centerY)) != null ? _a2 : document.body;
|
|
3708
|
+
const framework = await this.detectFramework(target);
|
|
3704
3709
|
const pending = {
|
|
3705
3710
|
element: target,
|
|
3706
3711
|
elementPath: getElementSelector(target),
|
|
@@ -3712,18 +3717,60 @@ var _Instruckt = class _Instruckt {
|
|
|
3712
3717
|
y: centerY,
|
|
3713
3718
|
nearbyText: getNearbyText(target) || void 0,
|
|
3714
3719
|
screenshot,
|
|
3715
|
-
framework:
|
|
3720
|
+
framework: framework != null ? framework : void 0
|
|
3716
3721
|
};
|
|
3717
3722
|
this.showAnnotationPopup(pending);
|
|
3718
3723
|
}
|
|
3719
3724
|
// ── Framework detection ───────────────────────────────────────
|
|
3720
|
-
|
|
3721
|
-
|
|
3725
|
+
/**
|
|
3726
|
+
* Use element-source as the primary resolver for React/Vue/Svelte,
|
|
3727
|
+
* then layer our adapters on top for props/state/framework-specific metadata.
|
|
3728
|
+
* Livewire and Blade are handled by our adapters only (element-source doesn't support them).
|
|
3729
|
+
*/
|
|
3730
|
+
async detectFramework(el) {
|
|
3731
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
3722
3732
|
const adapters = (_a2 = this.config.adapters) != null ? _a2 : [];
|
|
3723
3733
|
if (adapters.includes("livewire")) {
|
|
3724
3734
|
const ctx = getContext(el);
|
|
3725
3735
|
if (ctx) return ctx;
|
|
3726
3736
|
}
|
|
3737
|
+
const esAdapters = ["vue", "svelte", "react"];
|
|
3738
|
+
if (esAdapters.some((a) => adapters.includes(a))) {
|
|
3739
|
+
try {
|
|
3740
|
+
const info = await (0, import_element_source.resolveElementInfo)(el);
|
|
3741
|
+
if (info.source) {
|
|
3742
|
+
const stack = info.stack.map((f) => ({
|
|
3743
|
+
filePath: f.filePath,
|
|
3744
|
+
lineNumber: f.lineNumber,
|
|
3745
|
+
columnNumber: f.columnNumber,
|
|
3746
|
+
componentName: f.componentName
|
|
3747
|
+
}));
|
|
3748
|
+
let adapterCtx = null;
|
|
3749
|
+
if (adapters.includes("vue")) adapterCtx = getContext2(el);
|
|
3750
|
+
if (!adapterCtx && adapters.includes("svelte")) adapterCtx = getContext3(el);
|
|
3751
|
+
if (!adapterCtx && adapters.includes("react")) adapterCtx = getContext4(el);
|
|
3752
|
+
if (adapterCtx) {
|
|
3753
|
+
return __spreadProps(__spreadValues({}, adapterCtx), {
|
|
3754
|
+
component: (_b = info.componentName) != null ? _b : adapterCtx.component,
|
|
3755
|
+
source_file: info.source.filePath,
|
|
3756
|
+
source_line: (_c = info.source.lineNumber) != null ? _c : adapterCtx.source_line,
|
|
3757
|
+
source_column: (_d = info.source.columnNumber) != null ? _d : void 0,
|
|
3758
|
+
component_stack: stack.length > 0 ? stack : void 0
|
|
3759
|
+
});
|
|
3760
|
+
}
|
|
3761
|
+
return {
|
|
3762
|
+
framework: "react",
|
|
3763
|
+
// element-source defaults to React resolver
|
|
3764
|
+
component: (_e = info.componentName) != null ? _e : "Component",
|
|
3765
|
+
source_file: info.source.filePath,
|
|
3766
|
+
source_line: (_f = info.source.lineNumber) != null ? _f : void 0,
|
|
3767
|
+
source_column: (_g = info.source.columnNumber) != null ? _g : void 0,
|
|
3768
|
+
component_stack: stack.length > 0 ? stack : void 0
|
|
3769
|
+
};
|
|
3770
|
+
}
|
|
3771
|
+
} catch (e) {
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3727
3774
|
if (adapters.includes("vue")) {
|
|
3728
3775
|
const ctx = getContext2(el);
|
|
3729
3776
|
if (ctx) return ctx;
|
|
@@ -3915,17 +3962,33 @@ No open annotations.`;
|
|
|
3915
3962
|
lines.push("");
|
|
3916
3963
|
const hPrefix = multiPage ? "###" : "##";
|
|
3917
3964
|
annotations.forEach((a, i) => {
|
|
3918
|
-
var _a2, _b, _c, _d, _e;
|
|
3965
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
3919
3966
|
const componentSuffix = ((_a2 = a.framework) == null ? void 0 : _a2.component) ? ` in \`${a.framework.component}\`` : "";
|
|
3920
3967
|
lines.push(`${hPrefix} ${i + 1}. ${a.comment}`);
|
|
3921
3968
|
lines.push(`- ID: \`${a.id}\``);
|
|
3922
3969
|
lines.push(`- Element: \`${a.element}\`${componentSuffix}`);
|
|
3923
3970
|
if ((_b = a.framework) == null ? void 0 : _b.source_file) {
|
|
3924
|
-
|
|
3971
|
+
let loc = a.framework.source_file;
|
|
3972
|
+
if (a.framework.source_line) {
|
|
3973
|
+
loc += `:${a.framework.source_line}`;
|
|
3974
|
+
if (a.framework.source_column) loc += `:${a.framework.source_column}`;
|
|
3975
|
+
}
|
|
3925
3976
|
lines.push(`- Source: \`${loc}\``);
|
|
3926
3977
|
} else if ((_d = (_c = a.framework) == null ? void 0 : _c.data) == null ? void 0 : _d.file) {
|
|
3927
3978
|
lines.push(`- File: \`${a.framework.data.file}\``);
|
|
3928
3979
|
}
|
|
3980
|
+
if (((_e = a.framework) == null ? void 0 : _e.component_stack) && a.framework.component_stack.length > 1) {
|
|
3981
|
+
lines.push(`- Component stack:`);
|
|
3982
|
+
for (const frame of a.framework.component_stack) {
|
|
3983
|
+
let frameLoc = frame.filePath;
|
|
3984
|
+
if (frame.lineNumber) {
|
|
3985
|
+
frameLoc += `:${frame.lineNumber}`;
|
|
3986
|
+
if (frame.columnNumber) frameLoc += `:${frame.columnNumber}`;
|
|
3987
|
+
}
|
|
3988
|
+
const name = frame.componentName ? `${frame.componentName} ` : "";
|
|
3989
|
+
lines.push(` - ${name}\`${frameLoc}\``);
|
|
3990
|
+
}
|
|
3991
|
+
}
|
|
3929
3992
|
if (a.cssClasses) {
|
|
3930
3993
|
lines.push(`- Classes: \`${a.cssClasses}\``);
|
|
3931
3994
|
}
|
|
@@ -3936,7 +3999,7 @@ No open annotations.`;
|
|
|
3936
3999
|
}
|
|
3937
4000
|
if (a.screenshot) {
|
|
3938
4001
|
if (!a.screenshot.startsWith("data:")) {
|
|
3939
|
-
const screenshotPath = (
|
|
4002
|
+
const screenshotPath = (_f = this.config.screenshotPath) != null ? _f : "storage/app/_instruckt/";
|
|
3940
4003
|
lines.push(`- Screenshot: \`${screenshotPath}${a.screenshot}\``);
|
|
3941
4004
|
} else {
|
|
3942
4005
|
lines.push(`- Screenshot: `);
|