@emblemvault/hustle-react 1.1.1 → 1.2.0

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.
@@ -3621,6 +3621,21 @@ var buildPluginTool = {
3621
3621
  name: "build_plugin",
3622
3622
  description: `Build a Hustle plugin definition. Use this tool to construct a plugin based on user requirements.
3623
3623
 
3624
+ ## Testing Before Building (IMPORTANT)
3625
+
3626
+ If the execute_javascript tool is available, use it to prototype and test code BEFORE building the plugin. This allows rapid iteration without the overhead of building/installing/uninstalling.
3627
+
3628
+ **Workflow:**
3629
+ 1. When a user describes what they want, first test the core logic using execute_javascript
3630
+ 2. Iterate on the code until it works correctly
3631
+ 3. Ask the user: "Would you like to test this further, or should I build it into a plugin?"
3632
+ 4. Only call build_plugin once the code is validated and the user confirms
3633
+
3634
+ **Example:** If building a weather plugin, first test the API call:
3635
+ execute_javascript({ code: "fetch('https://api.example.com/weather?city=London').then(r => r.json()).then(console.log)" })
3636
+
3637
+ This catches errors early and lets users see results before committing to a plugin.
3638
+
3624
3639
  ## Plugin Structure
3625
3640
 
3626
3641
  A plugin consists of:
@@ -3737,11 +3752,49 @@ Hooks also have full access to the browser scope described above.
3737
3752
  2. **Namespace console logs** with [PluginName] prefix for easy identification
3738
3753
  3. **Handle errors gracefully** in executors - return { error: message } instead of throwing
3739
3754
 
3755
+ ## Building Plugin UI
3756
+
3757
+ Plugins can embed custom UI elements in two ways:
3758
+
3759
+ ### Persistent UI (via onRegister hook)
3760
+ Use the onRegister hook to embed UI that persists across the chat session. Check if your element already exists to avoid duplicates on re-registration:
3761
+
3762
+ "async () => {
3763
+ console.log('[MyPlugin] v1.0.0 registered');
3764
+ if (document.getElementById('my-plugin-panel')) return; // Already exists
3765
+
3766
+ const panel = document.createElement('div');
3767
+ panel.id = 'my-plugin-panel';
3768
+ Object.assign(panel.style, { position: 'fixed', bottom: '20px', right: '20px', padding: '10px', background: '#333', color: '#fff' });
3769
+ panel.textContent = 'My Panel';
3770
+ document.body.appendChild(panel);
3771
+ }"
3772
+
3773
+ ### On-Demand UI (via tool executors)
3774
+ Embed UI just-in-time when a tool is invoked. Useful for tools like show_clock, display_chart, etc.:
3775
+
3776
+ "async (args) => {
3777
+ const modal = document.createElement('div');
3778
+ modal.id = 'clock-modal';
3779
+ Object.assign(modal.style, { position: 'fixed', inset: '0', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.5)' });
3780
+ modal.textContent = 'Current time: ' + new Date().toLocaleTimeString();
3781
+ modal.onclick = () => modal.remove(); // Click to dismiss
3782
+ document.body.appendChild(modal);
3783
+ return { success: true, message: 'Clock displayed' };
3784
+ }"
3785
+
3786
+ ### UI Best Practices
3787
+ - Always use unique IDs with your plugin name prefix (e.g., "myplugin-modal")
3788
+ - For persistent UI, check existence in onRegister before creating
3789
+ - Provide a way to dismiss/close UI elements (click handler, close button)
3790
+ - Use Object.assign(el.style, {...}) for inline styles or inject a <style> tag
3791
+ - Clean up UI in tool executors if appropriate (e.g., remove after timeout)
3792
+
3740
3793
  ## Security Notes
3741
3794
  - Code runs in browser sandbox with same-origin policy
3742
3795
  - fetch() is subject to CORS restrictions
3743
3796
  - No direct filesystem access (use File API with user interaction)
3744
- - Be careful with eval() on user input`,
3797
+ - Sanitize any user-provided content before inserting into the DOM`,
3745
3798
  parameters: {
3746
3799
  type: "object",
3747
3800
  properties: {