instruckt 0.4.27 → 0.4.28

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
@@ -10,13 +10,9 @@ Framework-agnostic JS core with adapters for Livewire, Vue, Svelte, and React.
10
10
  npm install instruckt
11
11
  ```
12
12
 
13
- Or load via CDN:
13
+ ## Quick Start
14
14
 
15
- ```html
16
- <script src="https://cdn.jsdelivr.net/npm/instruckt/dist/instruckt.iife.js"></script>
17
- ```
18
-
19
- ## Quick Start: Vite Plugin
15
+ ### Vite Plugin
20
16
 
21
17
  The easiest way to use instruckt is with the Vite plugin. It handles client injection and provides a built-in dev API server — no backend required.
22
18
 
@@ -31,27 +27,19 @@ export default defineConfig({
31
27
 
32
28
  That's it for SPA apps (Vue, React, Svelte with Vite). The plugin auto-injects the client via `transformIndexHtml`.
33
29
 
34
- ### SSR Frameworks (SvelteKit, Nuxt, etc.)
35
-
36
- For frameworks that don't use `index.html`, import the virtual module in your layout:
30
+ ### Laravel
37
31
 
38
- ```js
39
- // SvelteKit: src/routes/+layout.svelte
40
- import 'virtual:instruckt'
32
+ 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:
41
33
 
42
- // Nuxt: plugins/instruckt.client.ts
43
- import 'virtual:instruckt'
34
+ ```bash
35
+ composer require joshcirre/instruckt-laravel --dev
36
+ php artisan instruckt:install
44
37
  ```
45
38
 
46
- The virtual module is SSR-safe it only initializes in the browser.
47
-
48
- ### Laravel
49
-
50
- The Vite plugin works alongside the Laravel package. Set `server: false` so Laravel handles the backend:
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.
51
40
 
52
41
  ```js
53
- // vite.config.ts
54
- import laravel from 'laravel-vite-plugin'
42
+ // vite.config.js (added automatically by install command)
55
43
  import instruckt from 'instruckt/vite'
56
44
 
57
45
  export default defineConfig({
@@ -66,14 +54,25 @@ export default defineConfig({
66
54
  })
67
55
  ```
68
56
 
69
- Then in your app entry:
57
+ ### SSR Frameworks (SvelteKit, Nuxt, etc.)
58
+
59
+ For frameworks that don't use `index.html`, import the virtual module in your layout:
70
60
 
71
61
  ```js
72
- // resources/js/app.js
62
+ // SvelteKit: src/routes/+layout.svelte
63
+ import 'virtual:instruckt'
64
+
65
+ // Nuxt: plugins/instruckt.client.ts
73
66
  import 'virtual:instruckt'
74
67
  ```
75
68
 
76
- ### Vite Plugin Options
69
+ The virtual module is SSR-safe — it only initializes in the browser.
70
+
71
+ ### Astro
72
+
73
+ See **[instruckt-astro](https://github.com/sgasser/instruckt-astro)** for a community-maintained Astro integration.
74
+
75
+ ## Vite Plugin Options
77
76
 
78
77
  ```js
79
78
  instruckt({
@@ -120,15 +119,6 @@ const instruckt = new Instruckt({
120
119
  })
121
120
  ```
122
121
 
123
- Or with the IIFE build:
124
-
125
- ```html
126
- <script src="/path/to/instruckt.iife.js"></script>
127
- <script>
128
- Instruckt.init({ endpoint: '/instruckt' })
129
- </script>
130
- ```
131
-
132
122
  ### Framework-Specific Manual Setup
133
123
 
134
124
  instruckt is a browser-only library. In SSR frameworks without the Vite plugin, make sure it only loads on the client.
@@ -237,10 +227,6 @@ export default function RootLayout({ children }) {
237
227
 
238
228
  </details>
239
229
 
240
- ### Astro
241
-
242
- See **[instruckt-astro](https://github.com/sgasser/instruckt-astro)** for a community-maintained Astro integration.
243
-
244
230
  ## How It Works
245
231
 
246
232
  1. A floating toolbar appears in your app
@@ -355,7 +341,7 @@ The Vite plugin includes a dev API server that saves annotations and screenshots
355
341
 
356
342
  ### Laravel
357
343
 
358
- **[instruckt-laravel](https://github.com/joshcirre/instruckt-laravel)** — Laravel package with JSON file storage, MCP tools, Blade component, and API routes.
344
+ **[instruckt-laravel](https://github.com/joshcirre/instruckt-laravel)** — Laravel package with JSON file storage, MCP tools, Blade component, and API routes. Includes `artisan instruckt:install` which auto-configures the Vite plugin, MCP, and agent skills.
359
345
 
360
346
  ### Custom Backend
361
347
 
@@ -549,7 +549,7 @@ var ICONS = {
549
549
  logo: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4 12.5-12.5z"/></svg>`
550
550
  };
551
551
  var Toolbar = class {
552
- constructor(position, callbacks, keys) {
552
+ constructor(position, callbacks, keys, tools) {
553
553
  this.position = position;
554
554
  this.callbacks = callbacks;
555
555
  this.fabBadge = null;
@@ -560,9 +560,15 @@ var Toolbar = class {
560
560
  this.dragging = false;
561
561
  this.dragOffset = { x: 0, y: 0 };
562
562
  this.keys = keys != null ? keys : {};
563
+ this.tools = tools != null ? tools : {};
563
564
  this.build();
564
565
  this.setupDrag();
565
566
  }
567
+ /** Whether a built-in tool should be shown (default true if not specified). */
568
+ show(id) {
569
+ const v = this.tools[id];
570
+ return v !== false;
571
+ }
566
572
  build() {
567
573
  var _a2, _b, _c, _d, _e;
568
574
  this.host = document.createElement("div");
@@ -621,17 +627,18 @@ var Toolbar = class {
621
627
  d.className = "divider";
622
628
  return d;
623
629
  };
624
- this.toolbarEl.append(
625
- this.annotateBtn,
626
- screenshotBtn,
627
- mkDiv(),
628
- this.freezeBtn,
629
- mkDiv(),
630
- this.copyBtn,
631
- clearWrap,
632
- mkDiv(),
633
- minimizeBtn
634
- );
630
+ const toAppend = [];
631
+ const add = (el) => {
632
+ if (toAppend.length > 0) toAppend.push(mkDiv());
633
+ toAppend.push(el);
634
+ };
635
+ if (this.show("annotate")) add(this.annotateBtn);
636
+ if (this.show("screenshot")) add(screenshotBtn);
637
+ if (this.show("freeze")) add(this.freezeBtn);
638
+ if (this.show("copy")) add(this.copyBtn);
639
+ if (this.show("clear_page") || this.show("clear_all")) add(clearWrap);
640
+ if (this.show("minimize")) add(minimizeBtn);
641
+ this.toolbarEl.append(...toAppend);
635
642
  this.shadow.appendChild(this.toolbarEl);
636
643
  this.fab = document.createElement("button");
637
644
  this.fab.className = "fab";
@@ -3305,7 +3312,7 @@ var _Instruckt = class _Instruckt {
3305
3312
  onClearPage: () => this.clearPage(),
3306
3313
  onClearAll: () => this.clearEverything(),
3307
3314
  onMinimize: (min) => this.onMinimize(min)
3308
- }, this.config.keys);
3315
+ }, this.config.keys, this.config.tools);
3309
3316
  this.highlight = new ElementHighlight();
3310
3317
  this.popup = new AnnotationPopup();
3311
3318
  this.markers = new AnnotationMarkers((annotation) => this.onMarkerClick(annotation));
@@ -3344,7 +3351,7 @@ var _Instruckt = class _Instruckt {
3344
3351
  this.isAnnotating = false;
3345
3352
  this.isFrozen = false;
3346
3353
  document.querySelectorAll("[data-instruckt]").forEach((el) => el.remove());
3347
- this.toolbar = new Toolbar(this.config.position, this.makeToolbarCallbacks());
3354
+ this.toolbar = new Toolbar(this.config.position, this.makeToolbarCallbacks(), this.config.keys, this.config.tools);
3348
3355
  if (wasMinimized) this.toolbar.minimize();
3349
3356
  this.markers = new AnnotationMarkers((annotation) => this.onMarkerClick(annotation));
3350
3357
  this.highlight = new ElementHighlight();