@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.
- package/dist/browser/hustle-react.js +54 -1
- package/dist/browser/hustle-react.js.map +1 -1
- package/dist/components/index.cjs +57 -1
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +57 -1
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.cjs +3 -0
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +3 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +57 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +57 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.cjs +55 -1
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.js +55 -1
- package/dist/plugins/index.js.map +1 -1
- package/dist/providers/index.cjs +3 -0
- package/dist/providers/index.cjs.map +1 -1
- package/dist/providers/index.js +3 -0
- package/dist/providers/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -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
|
-
-
|
|
3797
|
+
- Sanitize any user-provided content before inserting into the DOM`,
|
|
3745
3798
|
parameters: {
|
|
3746
3799
|
type: "object",
|
|
3747
3800
|
properties: {
|