@emblemvault/hustle-react 1.4.3 → 1.4.5

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/pluginRegistry.ts","../../src/hooks/usePlugins.ts","../../src/providers/HustleProvider.tsx"],"names":["useState","useEffect","useCallback","value","error"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Plugin Registry\n *\n * Manages plugin storage and state in localStorage.\n *\n * Storage model:\n * - Installed plugins are GLOBAL (hustle-plugins) - install once, available everywhere\n * - Enabled/disabled state is INSTANCE-SCOPED (hustle-plugin-state-{instanceId})\n *\n * Executor functions are serialized as strings (executorCode) and\n * reconstituted at runtime via new Function().\n *\n * SECURITY TODO: Add signature verification before executing stored code.\n * Plugins should be signed by trusted publishers and verified before\n * any eval/Function execution occurs.\n */\n\nimport type {\n StoredPlugin,\n HustlePlugin,\n HydratedPlugin,\n ToolExecutor,\n PluginHooks,\n SerializedToolDefinition,\n SerializedHooks,\n} from '../types';\n\n/**\n * Storage keys:\n * - PLUGINS_KEY: Global list of installed plugins (not instance-scoped)\n * - getEnabledStateKey: Per-instance enabled/disabled states\n */\nconst PLUGINS_KEY = 'hustle-plugins';\n\nfunction getEnabledStateKey(instanceId: string): string {\n return `hustle-plugin-state-${instanceId}`;\n}\n\ntype PluginChangeCallback = (plugins: StoredPlugin[]) => void;\n\n/** Stored enabled state per instance */\ntype EnabledState = Record<string, boolean>;\n\n/**\n * Serialize a function to a string for storage\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction serializeFunction(fn: (...args: any[]) => any): string {\n return fn.toString();\n}\n\n/**\n * Deserialize a function string back to executable function\n *\n * FIXME: Add signature verification before execution\n * This is a security-sensitive operation that executes stored code.\n */\nfunction deserializeExecutor(code: string): ToolExecutor {\n // Extract function body - handles arrow functions and regular functions\n // The stored code is the full function: \"(args) => { ... }\" or \"async (args) => { ... }\"\n // We wrap it in parentheses and eval to get the function reference\n try {\n // eslint-disable-next-line no-eval\n return eval(`(${code})`) as ToolExecutor;\n } catch (err) {\n console.error('[Hustle] Failed to deserialize executor:', err);\n // Return a no-op executor that reports the error\n return async () => ({ error: 'Failed to deserialize executor', code });\n }\n}\n\n/**\n * Deserialize a hook function string\n *\n * FIXME: Add signature verification before execution\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction deserializeHook<T extends (...args: any[]) => any>(code: string): T {\n try {\n // eslint-disable-next-line no-eval\n return eval(`(${code})`) as T;\n } catch (err) {\n console.error('[Hustle] Failed to deserialize hook:', err);\n return (() => {}) as T;\n }\n}\n\n/**\n * Serialize a plugin's executors to executorCode strings\n */\nfunction serializePluginTools(\n tools: HustlePlugin['tools'],\n executors: HustlePlugin['executors']\n): SerializedToolDefinition[] {\n if (!tools) return [];\n\n return tools.map((tool) => ({\n ...tool,\n executorCode: executors?.[tool.name]\n ? serializeFunction(executors[tool.name])\n : undefined,\n }));\n}\n\n/**\n * Serialize plugin hooks to code strings\n */\nfunction serializeHooks(hooks: PluginHooks | undefined): SerializedHooks | undefined {\n if (!hooks) return undefined;\n\n const serialized: SerializedHooks = {};\n\n if (hooks.onRegister) {\n serialized.onRegisterCode = serializeFunction(hooks.onRegister);\n }\n if (hooks.beforeRequest) {\n serialized.beforeRequestCode = serializeFunction(hooks.beforeRequest);\n }\n if (hooks.afterResponse) {\n serialized.afterResponseCode = serializeFunction(hooks.afterResponse);\n }\n if (hooks.onError) {\n serialized.onErrorCode = serializeFunction(hooks.onError);\n }\n\n return Object.keys(serialized).length > 0 ? serialized : undefined;\n}\n\n/**\n * Hydrate a stored plugin - reconstitute executors from executorCode\n *\n * FIXME: Add signature verification before execution\n */\nexport function hydratePlugin(stored: StoredPlugin): HydratedPlugin {\n // Reconstitute executors from executorCode strings\n const executors: Record<string, ToolExecutor> = {};\n\n if (stored.tools) {\n for (const tool of stored.tools) {\n if (tool.executorCode) {\n executors[tool.name] = deserializeExecutor(tool.executorCode);\n }\n }\n }\n\n // Reconstitute hooks from hooksCode strings\n let hooks: PluginHooks | undefined;\n\n if (stored.hooksCode) {\n hooks = {};\n if (stored.hooksCode.onRegisterCode) {\n hooks.onRegister = deserializeHook(stored.hooksCode.onRegisterCode);\n }\n if (stored.hooksCode.beforeRequestCode) {\n hooks.beforeRequest = deserializeHook(stored.hooksCode.beforeRequestCode);\n }\n if (stored.hooksCode.afterResponseCode) {\n hooks.afterResponse = deserializeHook(stored.hooksCode.afterResponseCode);\n }\n if (stored.hooksCode.onErrorCode) {\n hooks.onError = deserializeHook(stored.hooksCode.onErrorCode);\n }\n }\n\n return {\n ...stored,\n executors: Object.keys(executors).length > 0 ? executors : undefined,\n hooks,\n };\n}\n\n/**\n * Plugin Registry class\n *\n * Manages plugin persistence with:\n * - Global plugin installations (with serialized executorCode)\n * - Instance-scoped enabled/disabled state\n */\nclass PluginRegistry {\n private listeners: Map<string, Set<PluginChangeCallback>> = new Map();\n\n /**\n * Get listeners for a specific instance\n */\n private getListeners(instanceId: string): Set<PluginChangeCallback> {\n if (!this.listeners.has(instanceId)) {\n this.listeners.set(instanceId, new Set());\n }\n return this.listeners.get(instanceId)!;\n }\n\n /**\n * Load installed plugins (global)\n */\n private loadInstalledPlugins(): Omit<StoredPlugin, 'enabled'>[] {\n if (typeof window === 'undefined') return [];\n try {\n const stored = localStorage.getItem(PLUGINS_KEY);\n return stored ? JSON.parse(stored) : [];\n } catch {\n return [];\n }\n }\n\n /**\n * Save installed plugins (global)\n * Serializes executors as executorCode strings\n */\n private saveInstalledPlugins(plugins: Omit<StoredPlugin, 'enabled'>[]): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(PLUGINS_KEY, JSON.stringify(plugins));\n }\n\n /**\n * Load enabled state for an instance\n */\n private loadEnabledState(instanceId: string): EnabledState {\n if (typeof window === 'undefined') return {};\n try {\n const stored = localStorage.getItem(getEnabledStateKey(instanceId));\n return stored ? JSON.parse(stored) : {};\n } catch {\n return {};\n }\n }\n\n /**\n * Save enabled state for an instance\n */\n private saveEnabledState(state: EnabledState, instanceId: string): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(getEnabledStateKey(instanceId), JSON.stringify(state));\n }\n\n /**\n * Load plugins with instance-specific enabled state\n * Combines global plugin list with per-instance enabled state\n */\n loadFromStorage(instanceId: string = 'default'): StoredPlugin[] {\n const installed = this.loadInstalledPlugins();\n const enabledState = this.loadEnabledState(instanceId);\n\n return installed.map((plugin) => ({\n ...plugin,\n // Default to enabled if no state exists for this instance\n enabled: enabledState[plugin.name] ?? true,\n }));\n }\n\n /**\n * Register a new plugin (global - available to all instances)\n * Serializes executors as executorCode for persistence\n *\n * @param plugin The plugin to install\n * @param enabled Initial enabled state for this instance (default: true)\n * @param instanceId Instance to set initial enabled state for\n */\n register(plugin: HustlePlugin, enabled = true, instanceId: string = 'default'): void {\n // Add to global installed list with serialized executors\n const installed = this.loadInstalledPlugins();\n const existing = installed.findIndex((p) => p.name === plugin.name);\n\n const storedPlugin: Omit<StoredPlugin, 'enabled'> = {\n name: plugin.name,\n version: plugin.version,\n description: plugin.description,\n tools: serializePluginTools(plugin.tools, plugin.executors),\n hooksCode: serializeHooks(plugin.hooks),\n installedAt: new Date().toISOString(),\n };\n\n if (existing >= 0) {\n installed[existing] = storedPlugin;\n } else {\n installed.push(storedPlugin);\n }\n\n this.saveInstalledPlugins(installed);\n\n // Set initial enabled state for this instance\n const enabledState = this.loadEnabledState(instanceId);\n enabledState[plugin.name] = enabled;\n this.saveEnabledState(enabledState, instanceId);\n\n this.notifyListeners(instanceId);\n }\n\n /**\n * Unregister a plugin (global - removes from all instances)\n */\n unregister(pluginName: string, instanceId: string = 'default'): void {\n // Remove from global list\n const installed = this.loadInstalledPlugins().filter((p) => p.name !== pluginName);\n this.saveInstalledPlugins(installed);\n\n // Clean up enabled state for this instance\n const enabledState = this.loadEnabledState(instanceId);\n delete enabledState[pluginName];\n this.saveEnabledState(enabledState, instanceId);\n\n this.notifyListeners(instanceId);\n }\n\n /**\n * Enable or disable a plugin (instance-scoped)\n */\n setEnabled(pluginName: string, enabled: boolean, instanceId: string = 'default'): void {\n const enabledState = this.loadEnabledState(instanceId);\n enabledState[pluginName] = enabled;\n this.saveEnabledState(enabledState, instanceId);\n this.notifyListeners(instanceId);\n }\n\n /**\n * Check if a plugin is installed (global)\n */\n isRegistered(pluginName: string): boolean {\n return this.loadInstalledPlugins().some((p) => p.name === pluginName);\n }\n\n /**\n * Get a specific plugin with instance-specific enabled state\n */\n getPlugin(pluginName: string, instanceId: string = 'default'): StoredPlugin | undefined {\n return this.loadFromStorage(instanceId).find((p) => p.name === pluginName);\n }\n\n /**\n * Get all enabled plugins for an instance (hydrated with executors)\n */\n getEnabledPlugins(instanceId: string = 'default'): HydratedPlugin[] {\n return this.loadFromStorage(instanceId).filter((p) => p.enabled).map(hydratePlugin);\n }\n\n /**\n * Subscribe to plugin changes for a specific instance\n */\n onChange(callback: PluginChangeCallback, instanceId: string = 'default'): () => void {\n const listeners = this.getListeners(instanceId);\n listeners.add(callback);\n return () => listeners.delete(callback);\n }\n\n /**\n * Notify all listeners for a specific instance\n */\n private notifyListeners(instanceId: string = 'default'): void {\n const plugins = this.loadFromStorage(instanceId);\n const listeners = this.getListeners(instanceId);\n listeners.forEach((cb) => cb(plugins));\n }\n\n /**\n * Clear enabled state for an instance (plugins remain installed globally)\n */\n clear(instanceId: string = 'default'): void {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(getEnabledStateKey(instanceId));\n this.notifyListeners(instanceId);\n }\n\n /**\n * Clear all installed plugins globally\n */\n clearAll(): void {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(PLUGINS_KEY);\n // Note: This doesn't clear instance-specific enabled states\n }\n}\n\n// Singleton instance\nexport const pluginRegistry = new PluginRegistry();\n\nexport default pluginRegistry;\n","'use client';\n\n/**\n * usePlugins Hook\n *\n * Manages plugin state with localStorage persistence and cross-tab sync.\n * Supports instance-scoped storage for multiple HustleProviders.\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { pluginRegistry, hydratePlugin } from '../utils/pluginRegistry';\nimport type { StoredPlugin, HustlePlugin, HydratedPlugin } from '../types';\n\n// Re-export hydratePlugin for convenience\nexport { hydratePlugin };\n\n/**\n * Get the storage key for a given instance\n */\nfunction getStorageKey(instanceId: string): string {\n return `hustle-plugins-${instanceId}`;\n}\n\n/**\n * Return type for usePlugins hook\n */\nexport interface UsePluginsReturn {\n /** All registered plugins (with enabled state) */\n plugins: StoredPlugin[];\n /** Only enabled plugins (hydrated with executors) */\n enabledPlugins: HydratedPlugin[];\n /** Register a new plugin */\n registerPlugin: (plugin: HustlePlugin) => void;\n /** Unregister a plugin by name */\n unregisterPlugin: (name: string) => void;\n /** Enable a plugin */\n enablePlugin: (name: string) => void;\n /** Disable a plugin */\n disablePlugin: (name: string) => void;\n /** Check if a plugin is registered */\n isRegistered: (name: string) => boolean;\n /** Check if a plugin is enabled */\n isEnabled: (name: string) => boolean;\n}\n\n/**\n * Get the current instance ID from the global context or use fallback\n */\nfunction getInstanceId(providedId?: string): string {\n if (providedId) return providedId;\n // Check for global instanceId set by HustleProvider\n if (typeof window !== 'undefined') {\n const globalId = (window as unknown as { __hustleInstanceId?: string }).__hustleInstanceId;\n if (globalId) return globalId;\n }\n return 'default';\n}\n\n/**\n * Hook for managing plugins\n *\n * @param instanceId - Optional instance ID for scoping plugin storage. If not provided,\n * uses the global instanceId from HustleProvider, or 'default' as fallback.\n *\n * @example\n * ```tsx\n * const { plugins, registerPlugin, enabledPlugins } = usePlugins();\n *\n * // Install a plugin\n * registerPlugin(myPlugin);\n *\n * // Check enabled plugins\n * console.log('Active tools:', enabledPlugins.flatMap(p => p.tools));\n * ```\n */\nexport function usePlugins(instanceId?: string): UsePluginsReturn {\n // Resolve the instance ID once on initial render\n const [resolvedInstanceId] = useState(() => getInstanceId(instanceId));\n const [plugins, setPlugins] = useState<StoredPlugin[]>([]);\n\n // Load initial plugins and subscribe to changes\n useEffect(() => {\n // Load initial state\n setPlugins(pluginRegistry.loadFromStorage(resolvedInstanceId));\n\n // Subscribe to registry changes for this instance\n const unsubscribe = pluginRegistry.onChange(setPlugins, resolvedInstanceId);\n\n // Listen to storage events for cross-tab sync\n const storageKey = getStorageKey(resolvedInstanceId);\n const handleStorage = (e: StorageEvent) => {\n if (e.key === storageKey) {\n setPlugins(pluginRegistry.loadFromStorage(resolvedInstanceId));\n }\n };\n window.addEventListener('storage', handleStorage);\n\n // Listen for plugin-installed events (from plugin-builder install_plugin tool)\n const handlePluginInstalled = (e: Event) => {\n const customEvent = e as CustomEvent<{ plugin: StoredPlugin; instanceId: string }>;\n if (customEvent.detail.instanceId === resolvedInstanceId) {\n // Reload from storage to pick up the new plugin\n setPlugins(pluginRegistry.loadFromStorage(resolvedInstanceId));\n }\n };\n window.addEventListener('hustle-plugin-installed', handlePluginInstalled);\n\n return () => {\n unsubscribe();\n window.removeEventListener('storage', handleStorage);\n window.removeEventListener('hustle-plugin-installed', handlePluginInstalled);\n };\n }, [resolvedInstanceId]);\n\n // Register a new plugin\n const registerPlugin = useCallback((plugin: HustlePlugin) => {\n pluginRegistry.register(plugin, true, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Unregister a plugin\n const unregisterPlugin = useCallback((name: string) => {\n pluginRegistry.unregister(name, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Enable a plugin\n const enablePlugin = useCallback((name: string) => {\n pluginRegistry.setEnabled(name, true, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Disable a plugin\n const disablePlugin = useCallback((name: string) => {\n pluginRegistry.setEnabled(name, false, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Check if plugin is registered\n const isRegistered = useCallback(\n (name: string) => plugins.some(p => p.name === name),\n [plugins]\n );\n\n // Check if plugin is enabled\n const isEnabled = useCallback(\n (name: string) => plugins.some(p => p.name === name && p.enabled),\n [plugins]\n );\n\n // Get enabled plugins with hydrated executors\n const enabledPlugins = plugins.filter(p => p.enabled).map(hydratePlugin);\n\n return {\n plugins,\n enabledPlugins,\n registerPlugin,\n unregisterPlugin,\n enablePlugin,\n disablePlugin,\n isRegistered,\n isEnabled,\n };\n}\n\nexport default usePlugins;\n","'use client';\n\nimport React, {\n createContext,\n useContext,\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from 'react';\nimport { HustleIncognitoClient } from 'hustle-incognito';\nimport { useEmblemAuthOptional } from '@emblemvault/emblem-auth-react';\nimport { usePlugins, hydratePlugin } from '../hooks/usePlugins';\nimport { pluginRegistry } from '../utils/pluginRegistry';\nimport type {\n Model,\n ChatOptions,\n StreamOptions,\n StreamChunk,\n StreamWithResponse,\n ChatResponse,\n Attachment,\n HustleContextValue,\n HustleProviderProps,\n ChatMessage,\n HydratedPlugin,\n StoredPlugin,\n} from '../types';\n\n/**\n * Hustle context - undefined when not within provider\n */\nconst HustleContext = createContext<HustleContextValue | undefined>(undefined);\n\n/**\n * Default Hustle API URL\n */\nconst DEFAULT_HUSTLE_API_URL = 'https://agenthustle.ai';\n\n/**\n * Module-level counter for auto-generating instance IDs.\n * Resets on page load, but render order is deterministic.\n */\nlet instanceCounter = 0;\n\n/**\n * Track mounted instances without explicit IDs for dev warnings\n */\nconst mountedAutoInstances = new Set<string>();\n\n/**\n * HustleProvider - Provides Hustle SDK functionality to the app\n *\n * Supports two authentication modes:\n *\n * **Mode 1: Auth SDK (default)** - Uses EmblemAuthProvider context for authentication\n * ```tsx\n * <EmblemAuthProvider appId=\"your-app-id\">\n * <HustleProvider>\n * <App />\n * </HustleProvider>\n * </EmblemAuthProvider>\n * ```\n *\n * **Mode 2: Direct API Key** - Uses provided apiKey/vaultId (no EmblemAuthProvider needed)\n * ```tsx\n * <HustleProvider apiKey=\"your-key\" vaultId=\"your-vault\">\n * <App />\n * </HustleProvider>\n * ```\n */\nexport function HustleProvider({\n children,\n hustleApiUrl = DEFAULT_HUSTLE_API_URL,\n debug = false,\n instanceId: explicitInstanceId,\n apiKey,\n vaultId,\n}: HustleProviderProps) {\n // Generate stable instance ID - explicit or auto-generated based on mount order\n const [resolvedInstanceId] = useState(() => {\n if (explicitInstanceId) {\n return explicitInstanceId;\n }\n // Auto-generate based on mount order\n const autoId = `instance-${++instanceCounter}`;\n mountedAutoInstances.add(autoId);\n return autoId;\n });\n\n // Track if this is an auto-generated instance for cleanup\n const isAutoInstance = !explicitInstanceId;\n\n // Dev warning for multiple auto-generated instances\n useEffect(() => {\n if (isAutoInstance && mountedAutoInstances.size > 1 && process.env.NODE_ENV !== 'production') {\n console.warn(\n `[Hustle] Multiple HustleProviders detected without explicit instanceId. ` +\n `For stable settings persistence, consider adding instanceId prop:\\n` +\n ` <HustleProvider instanceId=\"my-chat-name\">`\n );\n }\n\n // Cleanup on unmount\n return () => {\n if (isAutoInstance) {\n mountedAutoInstances.delete(resolvedInstanceId);\n }\n };\n }, [isAutoInstance, resolvedInstanceId]);\n\n // Expose instanceId and plugin functions globally for plugin tools (e.g., install_plugin, uninstall_plugin)\n useEffect(() => {\n if (typeof window !== 'undefined') {\n const win = window as unknown as {\n __hustleInstanceId?: string;\n __hustleRegisterPlugin?: (plugin: StoredPlugin, enabled?: boolean) => Promise<void>;\n __hustleUnregisterPlugin?: (name: string) => Promise<void>;\n __hustleListPlugins?: () => Array<{ name: string; version: string; description: string; enabled: boolean }>;\n __hustleGetPlugin?: (name: string) => StoredPlugin | null;\n };\n win.__hustleInstanceId = resolvedInstanceId;\n\n // Expose registration function that uses pluginRegistry properly\n win.__hustleRegisterPlugin = async (plugin: StoredPlugin, enabled = true) => {\n // Hydrate the StoredPlugin and register it\n const hydrated = hydratePlugin(plugin);\n pluginRegistry.register(hydrated, enabled, resolvedInstanceId);\n };\n\n // Expose unregister function\n win.__hustleUnregisterPlugin = async (name: string) => {\n pluginRegistry.unregister(name, resolvedInstanceId);\n };\n\n // Expose list function\n win.__hustleListPlugins = () => {\n const plugins = pluginRegistry.loadFromStorage(resolvedInstanceId);\n return plugins.map(p => ({\n name: p.name,\n version: p.version,\n description: p.description || '',\n enabled: p.enabled,\n }));\n };\n\n // Expose get plugin function\n win.__hustleGetPlugin = (name: string) => {\n const plugins = pluginRegistry.loadFromStorage(resolvedInstanceId);\n return plugins.find(p => p.name === name) || null;\n };\n }\n return () => {\n if (typeof window !== 'undefined') {\n const win = window as unknown as {\n __hustleInstanceId?: string;\n __hustleRegisterPlugin?: unknown;\n __hustleUnregisterPlugin?: unknown;\n __hustleListPlugins?: unknown;\n __hustleGetPlugin?: unknown;\n };\n delete win.__hustleInstanceId;\n delete win.__hustleRegisterPlugin;\n delete win.__hustleUnregisterPlugin;\n delete win.__hustleListPlugins;\n delete win.__hustleGetPlugin;\n }\n };\n }, [resolvedInstanceId]);\n\n // Determine if we're using API key mode\n const isApiKeyMode = Boolean(apiKey && vaultId);\n\n // Get auth context - using optional hook that returns null when not in EmblemAuthProvider\n // This hook is always called (React rules) but returns null when outside provider\n const authContext = useEmblemAuthOptional();\n\n // Extract auth values - in API key mode, we don't need auth context\n const authSDK = isApiKeyMode ? null : authContext?.authSDK ?? null;\n const isAuthenticated = isApiKeyMode\n ? true // API key mode is always considered authenticated\n : authContext?.isAuthenticated ?? false;\n\n // Get plugins with instance scoping\n const { enabledPlugins } = usePlugins(resolvedInstanceId);\n\n // State\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [models, setModels] = useState<Model[]>([]);\n\n // Track registered plugins to avoid re-registering\n const registeredPluginsRef = useRef<Set<string>>(new Set());\n\n // Settings storage key - scoped to instance\n const SETTINGS_KEY = `hustle-settings-${resolvedInstanceId}`;\n\n // Load initial settings from localStorage\n const loadSettings = () => {\n if (typeof window === 'undefined') return { selectedModel: '', systemPrompt: '', skipServerPrompt: false };\n try {\n const stored = localStorage.getItem(SETTINGS_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n } catch {\n // Ignore parse errors\n }\n return { selectedModel: '', systemPrompt: '', skipServerPrompt: false };\n };\n\n const initialSettings = loadSettings();\n\n // Settings state (initialized from localStorage)\n const [selectedModel, setSelectedModelState] = useState<string>(initialSettings.selectedModel);\n const [systemPrompt, setSystemPromptState] = useState<string>(initialSettings.systemPrompt);\n const [skipServerPrompt, setSkipServerPromptState] = useState<boolean>(initialSettings.skipServerPrompt);\n\n // Persist settings to localStorage\n const saveSettings = useCallback((settings: { selectedModel: string; systemPrompt: string; skipServerPrompt: boolean }) => {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));\n } catch {\n // Ignore storage errors\n }\n }, []);\n\n // Wrapped setters that also persist\n const setSelectedModel = useCallback((value: string) => {\n setSelectedModelState(value);\n saveSettings({ selectedModel: value, systemPrompt, skipServerPrompt });\n }, [systemPrompt, skipServerPrompt, saveSettings]);\n\n const setSystemPrompt = useCallback((value: string) => {\n setSystemPromptState(value);\n saveSettings({ selectedModel, systemPrompt: value, skipServerPrompt });\n }, [selectedModel, skipServerPrompt, saveSettings]);\n\n const setSkipServerPrompt = useCallback((value: boolean) => {\n setSkipServerPromptState(value);\n saveSettings({ selectedModel, systemPrompt, skipServerPrompt: value });\n }, [selectedModel, systemPrompt, saveSettings]);\n\n // Debug logger\n const log = useCallback(\n (message: string, ...args: unknown[]) => {\n if (debug) {\n console.log(`[Hustle] ${message}`, ...args);\n }\n },\n [debug]\n );\n\n /**\n * Create the Hustle client\n * Supports two modes:\n * - Mode 1 (Auth SDK): Uses authSDK from EmblemAuthProvider context\n * - Mode 2 (API Key): Uses direct apiKey/vaultId props\n */\n const client = useMemo(() => {\n // Mode 2: API Key mode\n if (isApiKeyMode && apiKey && vaultId) {\n log('Creating HustleIncognitoClient with API key');\n\n try {\n const hustleClient = new HustleIncognitoClient({\n apiKey,\n vaultId,\n hustleApiUrl,\n debug,\n });\n\n // Subscribe to events\n hustleClient.on('tool_start', (event: unknown) => {\n log('Tool start:', event);\n });\n\n hustleClient.on('tool_end', (event: unknown) => {\n log('Tool end:', event);\n });\n\n hustleClient.on('stream_end', (event: unknown) => {\n log('Stream end:', event);\n });\n\n return hustleClient;\n } catch (err) {\n log('Failed to create client:', err);\n setError(err instanceof Error ? err : new Error('Failed to create Hustle client'));\n return null;\n }\n }\n\n // Mode 1: Auth SDK mode\n if (!authSDK || !isAuthenticated) {\n log('Client not created - auth not ready');\n return null;\n }\n\n log('Creating HustleIncognitoClient with auth SDK');\n\n try {\n const hustleClient = new HustleIncognitoClient({\n sdk: authSDK,\n hustleApiUrl,\n debug,\n });\n\n // Subscribe to events (use any for SDK event types)\n hustleClient.on('tool_start', (event: unknown) => {\n log('Tool start:', event);\n });\n\n hustleClient.on('tool_end', (event: unknown) => {\n log('Tool end:', event);\n });\n\n hustleClient.on('stream_end', (event: unknown) => {\n log('Stream end:', event);\n });\n\n return hustleClient;\n } catch (err) {\n log('Failed to create client:', err);\n setError(err instanceof Error ? err : new Error('Failed to create Hustle client'));\n return null;\n }\n }, [isApiKeyMode, apiKey, vaultId, authSDK, isAuthenticated, hustleApiUrl, debug, log]);\n\n // Is ready when client exists\n const isReady = client !== null;\n\n /**\n * Register enabled plugins with the client\n */\n useEffect(() => {\n if (!client) return;\n\n const registerPlugins = async () => {\n // Get the set of enabled plugin names\n const enabledNames = new Set(enabledPlugins.map(p => p.name));\n\n // Unregister plugins that were disabled\n for (const name of registeredPluginsRef.current) {\n if (!enabledNames.has(name)) {\n log('Unregistering plugin:', name);\n try {\n await client.unuse(name);\n registeredPluginsRef.current.delete(name);\n log('Plugin unregistered:', name);\n } catch (err) {\n log('Failed to unregister plugin:', name, err);\n }\n }\n }\n\n // Register new plugins\n for (const plugin of enabledPlugins) {\n if (!registeredPluginsRef.current.has(plugin.name)) {\n log('Registering plugin:', plugin.name);\n try {\n // The SDK's use() method registers the plugin\n if (plugin.executors || plugin.hooks) {\n // Cast to SDK's expected type (our types are compatible but TS is strict)\n await client.use({\n name: plugin.name,\n version: plugin.version,\n tools: plugin.tools,\n executors: plugin.executors,\n hooks: plugin.hooks,\n } as Parameters<typeof client.use>[0]);\n registeredPluginsRef.current.add(plugin.name);\n log('Plugin registered:', plugin.name);\n } else {\n log('Plugin has no executors/hooks, skipping registration:', plugin.name);\n }\n } catch (err) {\n log('Failed to register plugin:', plugin.name, err);\n }\n }\n }\n };\n\n registerPlugins();\n }, [client, enabledPlugins, log]);\n\n /**\n * Expose upload function globally for plugin tools (e.g., screenshot plugin)\n */\n useEffect(() => {\n if (typeof window !== 'undefined' && client) {\n const win = window as unknown as {\n __hustleUploadFile?: (file: File | Blob, fileName?: string) => Promise<Attachment>;\n };\n win.__hustleUploadFile = async (file: File | Blob, fileName?: string) => {\n return await client.uploadFile(file, fileName) as Attachment;\n };\n }\n return () => {\n if (typeof window !== 'undefined') {\n delete (window as unknown as { __hustleUploadFile?: unknown }).__hustleUploadFile;\n }\n };\n }, [client]);\n\n /**\n * Load available models\n */\n const loadModels = useCallback(async (): Promise<Model[]> => {\n if (!client) {\n log('Cannot load models - client not ready');\n return [];\n }\n\n log('Loading models');\n setIsLoading(true);\n\n try {\n const modelList = await client.getModels();\n setModels(modelList as Model[]);\n log('Loaded models:', modelList.length);\n return modelList as Model[];\n } catch (err) {\n log('Failed to load models:', err);\n setError(err instanceof Error ? err : new Error('Failed to load models'));\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [client, log]);\n\n /**\n * Load models when client becomes ready\n */\n useEffect(() => {\n if (client) {\n loadModels();\n }\n }, [client, loadModels]);\n\n /**\n * Send a chat message (non-streaming)\n */\n const chat = useCallback(\n async (options: ChatOptions): Promise<ChatResponse> => {\n if (!client) {\n throw new Error('Hustle client not ready. Please authenticate first.');\n }\n\n log('Chat request:', options.messages.length, 'messages');\n setIsLoading(true);\n setError(null);\n\n try {\n // Build the messages array, prepending system prompt if provided\n const effectiveSystemPrompt = options.systemPrompt || systemPrompt;\n const messagesWithSystem: ChatMessage[] = [];\n\n if (effectiveSystemPrompt) {\n messagesWithSystem.push({ role: 'system', content: effectiveSystemPrompt });\n }\n messagesWithSystem.push(...options.messages);\n\n // Build the options object for the SDK\n const sdkOptions: Record<string, unknown> = {\n messages: messagesWithSystem,\n processChunks: true,\n };\n\n // In API key mode, we need to pass vaultId with each request\n if (isApiKeyMode && vaultId) {\n sdkOptions.vaultId = vaultId;\n }\n\n if (options.model || selectedModel) {\n sdkOptions.model = options.model || selectedModel;\n }\n if (options.overrideSystemPrompt ?? skipServerPrompt) {\n sdkOptions.overrideSystemPrompt = true;\n }\n if (options.attachments) {\n sdkOptions.attachments = options.attachments;\n }\n\n // Call the SDK - it accepts an options object\n const response = await (client as unknown as { chat: (opts: Record<string, unknown>) => Promise<unknown> }).chat(sdkOptions);\n log('Chat response received');\n return response as ChatResponse;\n } catch (err) {\n log('Chat error:', err);\n const error = err instanceof Error ? err : new Error('Chat request failed');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [client, isApiKeyMode, vaultId, selectedModel, systemPrompt, skipServerPrompt, log]\n );\n\n /**\n * Send a chat message with streaming response\n */\n const chatStreamImpl = useCallback(\n (options: StreamOptions): StreamWithResponse => {\n if (!client) {\n // Return a stream with error that yields an error\n return {\n [Symbol.asyncIterator]: async function* () {\n yield { type: 'error', value: { message: 'Hustle client not ready. Please authenticate first.' } } as StreamChunk;\n },\n response: Promise.resolve({ content: '', messageId: undefined }),\n };\n }\n\n log('Chat stream request:', options.messages.length, 'messages');\n setError(null);\n\n // Build the messages array, prepending system prompt if provided\n const effectiveSystemPrompt = options.systemPrompt || systemPrompt;\n const messagesWithSystem: ChatMessage[] = [];\n\n if (effectiveSystemPrompt) {\n messagesWithSystem.push({ role: 'system', content: effectiveSystemPrompt });\n }\n messagesWithSystem.push(...options.messages);\n\n // Build the options object for the SDK\n const sdkOptions: Record<string, unknown> = {\n messages: messagesWithSystem,\n processChunks: options.processChunks ?? true,\n };\n\n // In API key mode, we need to pass vaultId with each request\n if (isApiKeyMode && vaultId) {\n sdkOptions.vaultId = vaultId;\n }\n\n if (options.model || selectedModel) {\n sdkOptions.model = options.model || selectedModel;\n }\n if (options.overrideSystemPrompt ?? skipServerPrompt) {\n sdkOptions.overrideSystemPrompt = true;\n }\n if (options.attachments) {\n sdkOptions.attachments = options.attachments;\n }\n\n // Get the stream from the client (cast through unknown for SDK compatibility)\n const stream = client.chatStream(sdkOptions as unknown as Parameters<typeof client.chatStream>[0]);\n\n // Wrap to add logging and type conversion, preserving .response property\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of stream) {\n // Type guard for chunk with type property\n const typedChunk = chunk as { type?: string; value?: unknown };\n\n if (typedChunk.type === 'text') {\n const textValue = typedChunk.value as string;\n log('Stream text chunk:', textValue?.substring(0, 50));\n yield { type: 'text', value: textValue } as StreamChunk;\n } else if (typedChunk.type === 'tool_call') {\n log('Stream tool call:', typedChunk.value);\n yield { type: 'tool_call', value: typedChunk.value } as StreamChunk;\n } else if (typedChunk.type === 'tool_result') {\n log('Stream tool result');\n yield { type: 'tool_result', value: typedChunk.value } as StreamChunk;\n } else if (typedChunk.type === 'error') {\n const errorValue = typedChunk.value as { message?: string };\n log('Stream error:', errorValue);\n setError(new Error(errorValue?.message || 'Stream error'));\n yield { type: 'error', value: { message: errorValue?.message || 'Stream error' } } as StreamChunk;\n } else {\n // Pass through unknown chunk types\n yield chunk as StreamChunk;\n }\n }\n } catch (err) {\n log('Stream error:', err);\n const error = err instanceof Error ? err : new Error('Stream failed');\n setError(error);\n yield { type: 'error', value: { message: error.message } } as StreamChunk;\n }\n },\n // Forward the response promise from the SDK stream (includes afterResponse hook modifications)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response: (stream as any).response as Promise<ChatResponse>,\n };\n },\n [client, isApiKeyMode, vaultId, selectedModel, systemPrompt, skipServerPrompt, log]\n );\n\n /**\n * Upload a file\n */\n const uploadFile = useCallback(\n async (file: File): Promise<Attachment> => {\n if (!client) {\n throw new Error('Hustle client not ready. Please authenticate first.');\n }\n\n log('Uploading file:', file.name);\n setIsLoading(true);\n\n try {\n const attachment = await client.uploadFile(file);\n log('File uploaded:', attachment);\n return attachment as Attachment;\n } catch (err) {\n log('Upload error:', err);\n const error = err instanceof Error ? err : new Error('File upload failed');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [client, log]\n );\n\n // Context value\n const value: HustleContextValue = {\n // Instance ID for scoped storage\n instanceId: resolvedInstanceId,\n\n // Auth mode\n isApiKeyMode,\n\n // State\n isReady,\n isLoading,\n error,\n models,\n\n // Client (for advanced use)\n client,\n\n // Chat methods\n chat,\n chatStream: chatStreamImpl,\n\n // File upload\n uploadFile,\n\n // Data fetching\n loadModels,\n\n // Settings\n selectedModel,\n setSelectedModel,\n systemPrompt,\n setSystemPrompt,\n skipServerPrompt,\n setSkipServerPrompt,\n };\n\n return (\n <HustleContext.Provider value={value}>\n {children}\n </HustleContext.Provider>\n );\n}\n\n/**\n * Hook to access Hustle context\n * Must be used within HustleProvider (which must be within EmblemAuthProvider)\n *\n * @example\n * ```tsx\n * function ChatComponent() {\n * const { isReady, chat, chatStream } = useHustle();\n *\n * if (!isReady) {\n * return <div>Please connect to start chatting</div>;\n * }\n *\n * // Use chat or chatStream...\n * }\n * ```\n */\nexport function useHustle(): HustleContextValue {\n const context = useContext(HustleContext);\n if (context === undefined) {\n throw new Error('useHustle must be used within a HustleProvider (which requires EmblemAuthProvider)');\n }\n return context;\n}\n"]}
1
+ {"version":3,"sources":["../../src/utils/pluginRegistry.ts","../../src/hooks/usePlugins.ts","../../src/providers/HustleProvider.tsx"],"names":["useState","useEffect","useCallback","value","error"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Plugin Registry\n *\n * Manages plugin storage and state in localStorage.\n *\n * Storage model:\n * - Installed plugins are GLOBAL (hustle-plugins) - install once, available everywhere\n * - Enabled/disabled state is INSTANCE-SCOPED (hustle-plugin-state-{instanceId})\n *\n * Executor functions are serialized as strings (executorCode) and\n * reconstituted at runtime via new Function().\n *\n * SECURITY TODO: Add signature verification before executing stored code.\n * Plugins should be signed by trusted publishers and verified before\n * any eval/Function execution occurs.\n */\n\nimport type {\n StoredPlugin,\n HustlePlugin,\n HydratedPlugin,\n ToolExecutor,\n PluginHooks,\n SerializedToolDefinition,\n SerializedHooks,\n} from '../types';\n\n/**\n * Storage keys:\n * - PLUGINS_KEY: Global list of installed plugins (not instance-scoped)\n * - getEnabledStateKey: Per-instance enabled/disabled states\n */\nconst PLUGINS_KEY = 'hustle-plugins';\n\nfunction getEnabledStateKey(instanceId: string): string {\n return `hustle-plugin-state-${instanceId}`;\n}\n\ntype PluginChangeCallback = (plugins: StoredPlugin[]) => void;\n\n/** Stored enabled state per instance */\ntype EnabledState = Record<string, boolean>;\n\n/**\n * Serialize a function to a string for storage\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction serializeFunction(fn: (...args: any[]) => any): string {\n return fn.toString();\n}\n\n/**\n * Deserialize a function string back to executable function\n *\n * FIXME: Add signature verification before execution\n * This is a security-sensitive operation that executes stored code.\n */\nfunction deserializeExecutor(code: string): ToolExecutor {\n // Extract function body - handles arrow functions and regular functions\n // The stored code is the full function: \"(args) => { ... }\" or \"async (args) => { ... }\"\n // We wrap it in parentheses and eval to get the function reference\n try {\n // eslint-disable-next-line no-eval\n return eval(`(${code})`) as ToolExecutor;\n } catch (err) {\n console.error('[Hustle] Failed to deserialize executor:', err);\n // Return a no-op executor that reports the error\n return async () => ({ error: 'Failed to deserialize executor', code });\n }\n}\n\n/**\n * Deserialize a hook function string\n *\n * FIXME: Add signature verification before execution\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction deserializeHook<T extends (...args: any[]) => any>(code: string): T {\n try {\n // eslint-disable-next-line no-eval\n return eval(`(${code})`) as T;\n } catch (err) {\n console.error('[Hustle] Failed to deserialize hook:', err);\n return (() => {}) as T;\n }\n}\n\n/**\n * Serialize a plugin's executors to executorCode strings\n */\nfunction serializePluginTools(\n tools: HustlePlugin['tools'],\n executors: HustlePlugin['executors']\n): SerializedToolDefinition[] {\n if (!tools) return [];\n\n return tools.map((tool) => ({\n ...tool,\n executorCode: executors?.[tool.name]\n ? serializeFunction(executors[tool.name])\n : undefined,\n }));\n}\n\n/**\n * Serialize plugin hooks to code strings\n */\nfunction serializeHooks(hooks: PluginHooks | undefined): SerializedHooks | undefined {\n if (!hooks) return undefined;\n\n const serialized: SerializedHooks = {};\n\n if (hooks.onRegister) {\n serialized.onRegisterCode = serializeFunction(hooks.onRegister);\n }\n if (hooks.beforeRequest) {\n serialized.beforeRequestCode = serializeFunction(hooks.beforeRequest);\n }\n if (hooks.afterResponse) {\n serialized.afterResponseCode = serializeFunction(hooks.afterResponse);\n }\n if (hooks.onError) {\n serialized.onErrorCode = serializeFunction(hooks.onError);\n }\n\n return Object.keys(serialized).length > 0 ? serialized : undefined;\n}\n\n/**\n * Hydrate a stored plugin - reconstitute executors from executorCode\n *\n * FIXME: Add signature verification before execution\n */\nexport function hydratePlugin(stored: StoredPlugin): HydratedPlugin {\n // Reconstitute executors from executorCode strings\n const executors: Record<string, ToolExecutor> = {};\n\n if (stored.tools) {\n for (const tool of stored.tools) {\n if (tool.executorCode) {\n executors[tool.name] = deserializeExecutor(tool.executorCode);\n }\n }\n }\n\n // Reconstitute hooks from hooksCode strings\n let hooks: PluginHooks | undefined;\n\n if (stored.hooksCode) {\n hooks = {};\n if (stored.hooksCode.onRegisterCode) {\n hooks.onRegister = deserializeHook(stored.hooksCode.onRegisterCode);\n }\n if (stored.hooksCode.beforeRequestCode) {\n hooks.beforeRequest = deserializeHook(stored.hooksCode.beforeRequestCode);\n }\n if (stored.hooksCode.afterResponseCode) {\n hooks.afterResponse = deserializeHook(stored.hooksCode.afterResponseCode);\n }\n if (stored.hooksCode.onErrorCode) {\n hooks.onError = deserializeHook(stored.hooksCode.onErrorCode);\n }\n }\n\n return {\n ...stored,\n executors: Object.keys(executors).length > 0 ? executors : undefined,\n hooks,\n };\n}\n\n/**\n * Plugin Registry class\n *\n * Manages plugin persistence with:\n * - Global plugin installations (with serialized executorCode)\n * - Instance-scoped enabled/disabled state\n */\nclass PluginRegistry {\n private listeners: Map<string, Set<PluginChangeCallback>> = new Map();\n\n /**\n * Get listeners for a specific instance\n */\n private getListeners(instanceId: string): Set<PluginChangeCallback> {\n if (!this.listeners.has(instanceId)) {\n this.listeners.set(instanceId, new Set());\n }\n return this.listeners.get(instanceId)!;\n }\n\n /**\n * Load installed plugins (global)\n */\n private loadInstalledPlugins(): Omit<StoredPlugin, 'enabled'>[] {\n if (typeof window === 'undefined') return [];\n try {\n const stored = localStorage.getItem(PLUGINS_KEY);\n return stored ? JSON.parse(stored) : [];\n } catch {\n return [];\n }\n }\n\n /**\n * Save installed plugins (global)\n * Serializes executors as executorCode strings\n */\n private saveInstalledPlugins(plugins: Omit<StoredPlugin, 'enabled'>[]): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(PLUGINS_KEY, JSON.stringify(plugins));\n }\n\n /**\n * Load enabled state for an instance\n */\n private loadEnabledState(instanceId: string): EnabledState {\n if (typeof window === 'undefined') return {};\n try {\n const stored = localStorage.getItem(getEnabledStateKey(instanceId));\n return stored ? JSON.parse(stored) : {};\n } catch {\n return {};\n }\n }\n\n /**\n * Save enabled state for an instance\n */\n private saveEnabledState(state: EnabledState, instanceId: string): void {\n if (typeof window === 'undefined') return;\n localStorage.setItem(getEnabledStateKey(instanceId), JSON.stringify(state));\n }\n\n /**\n * Load plugins with instance-specific enabled state\n * Combines global plugin list with per-instance enabled state\n */\n loadFromStorage(instanceId: string = 'default'): StoredPlugin[] {\n const installed = this.loadInstalledPlugins();\n const enabledState = this.loadEnabledState(instanceId);\n\n return installed.map((plugin) => ({\n ...plugin,\n // Default to enabled if no state exists for this instance\n enabled: enabledState[plugin.name] ?? true,\n }));\n }\n\n /**\n * Register a new plugin (global - available to all instances)\n * Serializes executors as executorCode for persistence\n *\n * @param plugin The plugin to install\n * @param enabled Initial enabled state for this instance (default: true)\n * @param instanceId Instance to set initial enabled state for\n */\n register(plugin: HustlePlugin, enabled = true, instanceId: string = 'default'): void {\n // Add to global installed list with serialized executors\n const installed = this.loadInstalledPlugins();\n const existing = installed.findIndex((p) => p.name === plugin.name);\n\n const storedPlugin: Omit<StoredPlugin, 'enabled'> = {\n name: plugin.name,\n version: plugin.version,\n description: plugin.description,\n tools: serializePluginTools(plugin.tools, plugin.executors),\n hooksCode: serializeHooks(plugin.hooks),\n installedAt: new Date().toISOString(),\n };\n\n if (existing >= 0) {\n installed[existing] = storedPlugin;\n } else {\n installed.push(storedPlugin);\n }\n\n this.saveInstalledPlugins(installed);\n\n // Set initial enabled state for this instance\n const enabledState = this.loadEnabledState(instanceId);\n enabledState[plugin.name] = enabled;\n this.saveEnabledState(enabledState, instanceId);\n\n this.notifyListeners(instanceId);\n }\n\n /**\n * Unregister a plugin (global - removes from all instances)\n */\n unregister(pluginName: string, instanceId: string = 'default'): void {\n // Remove from global list\n const installed = this.loadInstalledPlugins().filter((p) => p.name !== pluginName);\n this.saveInstalledPlugins(installed);\n\n // Clean up enabled state for this instance\n const enabledState = this.loadEnabledState(instanceId);\n delete enabledState[pluginName];\n this.saveEnabledState(enabledState, instanceId);\n\n this.notifyListeners(instanceId);\n }\n\n /**\n * Enable or disable a plugin (instance-scoped)\n */\n setEnabled(pluginName: string, enabled: boolean, instanceId: string = 'default'): void {\n const enabledState = this.loadEnabledState(instanceId);\n enabledState[pluginName] = enabled;\n this.saveEnabledState(enabledState, instanceId);\n this.notifyListeners(instanceId);\n }\n\n /**\n * Check if a plugin is installed (global)\n */\n isRegistered(pluginName: string): boolean {\n return this.loadInstalledPlugins().some((p) => p.name === pluginName);\n }\n\n /**\n * Get a specific plugin with instance-specific enabled state\n */\n getPlugin(pluginName: string, instanceId: string = 'default'): StoredPlugin | undefined {\n return this.loadFromStorage(instanceId).find((p) => p.name === pluginName);\n }\n\n /**\n * Get all enabled plugins for an instance (hydrated with executors)\n */\n getEnabledPlugins(instanceId: string = 'default'): HydratedPlugin[] {\n return this.loadFromStorage(instanceId).filter((p) => p.enabled).map(hydratePlugin);\n }\n\n /**\n * Subscribe to plugin changes for a specific instance\n */\n onChange(callback: PluginChangeCallback, instanceId: string = 'default'): () => void {\n const listeners = this.getListeners(instanceId);\n listeners.add(callback);\n return () => listeners.delete(callback);\n }\n\n /**\n * Notify all listeners for a specific instance\n */\n private notifyListeners(instanceId: string = 'default'): void {\n const plugins = this.loadFromStorage(instanceId);\n const listeners = this.getListeners(instanceId);\n listeners.forEach((cb) => cb(plugins));\n }\n\n /**\n * Clear enabled state for an instance (plugins remain installed globally)\n */\n clear(instanceId: string = 'default'): void {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(getEnabledStateKey(instanceId));\n this.notifyListeners(instanceId);\n }\n\n /**\n * Clear all installed plugins globally\n */\n clearAll(): void {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(PLUGINS_KEY);\n // Note: This doesn't clear instance-specific enabled states\n }\n}\n\n// Singleton instance\nexport const pluginRegistry = new PluginRegistry();\n\nexport default pluginRegistry;\n","'use client';\n\n/**\n * usePlugins Hook\n *\n * Manages plugin state with localStorage persistence and cross-tab sync.\n * Supports instance-scoped storage for multiple HustleProviders.\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { pluginRegistry, hydratePlugin } from '../utils/pluginRegistry';\nimport type { StoredPlugin, HustlePlugin, HydratedPlugin } from '../types';\n\n// Re-export hydratePlugin for convenience\nexport { hydratePlugin };\n\n/**\n * Get the storage key for a given instance\n */\nfunction getStorageKey(instanceId: string): string {\n return `hustle-plugins-${instanceId}`;\n}\n\n/**\n * Return type for usePlugins hook\n */\nexport interface UsePluginsReturn {\n /** All registered plugins (with enabled state) */\n plugins: StoredPlugin[];\n /** Only enabled plugins (hydrated with executors) */\n enabledPlugins: HydratedPlugin[];\n /** Register a new plugin */\n registerPlugin: (plugin: HustlePlugin) => void;\n /** Unregister a plugin by name */\n unregisterPlugin: (name: string) => void;\n /** Enable a plugin */\n enablePlugin: (name: string) => void;\n /** Disable a plugin */\n disablePlugin: (name: string) => void;\n /** Check if a plugin is registered */\n isRegistered: (name: string) => boolean;\n /** Check if a plugin is enabled */\n isEnabled: (name: string) => boolean;\n}\n\n/**\n * Get the current instance ID from the global context or use fallback\n */\nfunction getInstanceId(providedId?: string): string {\n if (providedId) return providedId;\n // Check for global instanceId set by HustleProvider\n if (typeof window !== 'undefined') {\n const globalId = (window as unknown as { __hustleInstanceId?: string }).__hustleInstanceId;\n if (globalId) return globalId;\n }\n return 'default';\n}\n\n/**\n * Hook for managing plugins\n *\n * @param instanceId - Optional instance ID for scoping plugin storage. If not provided,\n * uses the global instanceId from HustleProvider, or 'default' as fallback.\n *\n * @example\n * ```tsx\n * const { plugins, registerPlugin, enabledPlugins } = usePlugins();\n *\n * // Install a plugin\n * registerPlugin(myPlugin);\n *\n * // Check enabled plugins\n * console.log('Active tools:', enabledPlugins.flatMap(p => p.tools));\n * ```\n */\nexport function usePlugins(instanceId?: string): UsePluginsReturn {\n // Resolve the instance ID once on initial render\n const [resolvedInstanceId] = useState(() => getInstanceId(instanceId));\n const [plugins, setPlugins] = useState<StoredPlugin[]>([]);\n\n // Load initial plugins and subscribe to changes\n useEffect(() => {\n // Load initial state\n setPlugins(pluginRegistry.loadFromStorage(resolvedInstanceId));\n\n // Subscribe to registry changes for this instance\n const unsubscribe = pluginRegistry.onChange(setPlugins, resolvedInstanceId);\n\n // Listen to storage events for cross-tab sync\n const storageKey = getStorageKey(resolvedInstanceId);\n const handleStorage = (e: StorageEvent) => {\n if (e.key === storageKey) {\n setPlugins(pluginRegistry.loadFromStorage(resolvedInstanceId));\n }\n };\n window.addEventListener('storage', handleStorage);\n\n // Listen for plugin-installed events (from plugin-builder install_plugin tool)\n const handlePluginInstalled = (e: Event) => {\n const customEvent = e as CustomEvent<{ plugin: StoredPlugin; instanceId: string }>;\n if (customEvent.detail.instanceId === resolvedInstanceId) {\n // Reload from storage to pick up the new plugin\n setPlugins(pluginRegistry.loadFromStorage(resolvedInstanceId));\n }\n };\n window.addEventListener('hustle-plugin-installed', handlePluginInstalled);\n\n return () => {\n unsubscribe();\n window.removeEventListener('storage', handleStorage);\n window.removeEventListener('hustle-plugin-installed', handlePluginInstalled);\n };\n }, [resolvedInstanceId]);\n\n // Register a new plugin\n const registerPlugin = useCallback((plugin: HustlePlugin) => {\n pluginRegistry.register(plugin, true, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Unregister a plugin\n const unregisterPlugin = useCallback((name: string) => {\n pluginRegistry.unregister(name, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Enable a plugin\n const enablePlugin = useCallback((name: string) => {\n pluginRegistry.setEnabled(name, true, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Disable a plugin\n const disablePlugin = useCallback((name: string) => {\n pluginRegistry.setEnabled(name, false, resolvedInstanceId);\n }, [resolvedInstanceId]);\n\n // Check if plugin is registered\n const isRegistered = useCallback(\n (name: string) => plugins.some(p => p.name === name),\n [plugins]\n );\n\n // Check if plugin is enabled\n const isEnabled = useCallback(\n (name: string) => plugins.some(p => p.name === name && p.enabled),\n [plugins]\n );\n\n // Get enabled plugins with hydrated executors\n const enabledPlugins = plugins.filter(p => p.enabled).map(hydratePlugin);\n\n return {\n plugins,\n enabledPlugins,\n registerPlugin,\n unregisterPlugin,\n enablePlugin,\n disablePlugin,\n isRegistered,\n isEnabled,\n };\n}\n\nexport default usePlugins;\n","'use client';\n\nimport React, {\n createContext,\n useContext,\n useState,\n useEffect,\n useCallback,\n useMemo,\n useRef,\n} from 'react';\nimport { HustleIncognitoClient } from 'hustle-incognito';\nimport { useEmblemAuthOptional } from '@emblemvault/emblem-auth-react';\nimport { usePlugins, hydratePlugin } from '../hooks/usePlugins';\nimport { pluginRegistry } from '../utils/pluginRegistry';\nimport type {\n Model,\n ChatOptions,\n StreamOptions,\n StreamChunk,\n StreamWithResponse,\n ChatResponse,\n Attachment,\n HustleContextValue,\n HustleProviderProps,\n ChatMessage,\n HydratedPlugin,\n StoredPlugin,\n} from '../types';\n\n/**\n * Hustle context - undefined when not within provider\n */\nconst HustleContext = createContext<HustleContextValue | undefined>(undefined);\n\n/**\n * Default Hustle API URL\n */\nconst DEFAULT_HUSTLE_API_URL = 'https://agenthustle.ai';\n\n/**\n * Module-level counter for auto-generating instance IDs.\n * Resets on page load, but render order is deterministic.\n */\nlet instanceCounter = 0;\n\n/**\n * Track mounted instances without explicit IDs for dev warnings\n */\nconst mountedAutoInstances = new Set<string>();\n\n/**\n * HustleProvider - Provides Hustle SDK functionality to the app\n *\n * Supports two authentication modes:\n *\n * **Mode 1: Auth SDK (default)** - Uses EmblemAuthProvider context for authentication\n * ```tsx\n * <EmblemAuthProvider appId=\"your-app-id\">\n * <HustleProvider>\n * <App />\n * </HustleProvider>\n * </EmblemAuthProvider>\n * ```\n *\n * **Mode 2: Direct API Key** - Uses provided apiKey/vaultId (no EmblemAuthProvider needed)\n * ```tsx\n * <HustleProvider apiKey=\"your-key\" vaultId=\"your-vault\">\n * <App />\n * </HustleProvider>\n * ```\n */\nexport function HustleProvider({\n children,\n hustleApiUrl = DEFAULT_HUSTLE_API_URL,\n debug = false,\n instanceId: explicitInstanceId,\n apiKey,\n vaultId,\n}: HustleProviderProps) {\n // Generate stable instance ID - explicit or auto-generated based on mount order\n const [resolvedInstanceId] = useState(() => {\n if (explicitInstanceId) {\n return explicitInstanceId;\n }\n // Auto-generate based on mount order\n const autoId = `instance-${++instanceCounter}`;\n mountedAutoInstances.add(autoId);\n return autoId;\n });\n\n // Track if this is an auto-generated instance for cleanup\n const isAutoInstance = !explicitInstanceId;\n\n // Dev warning for multiple auto-generated instances\n useEffect(() => {\n if (isAutoInstance && mountedAutoInstances.size > 1 && process.env.NODE_ENV !== 'production') {\n console.warn(\n `[Hustle] Multiple HustleProviders detected without explicit instanceId. ` +\n `For stable settings persistence, consider adding instanceId prop:\\n` +\n ` <HustleProvider instanceId=\"my-chat-name\">`\n );\n }\n\n // Cleanup on unmount\n return () => {\n if (isAutoInstance) {\n mountedAutoInstances.delete(resolvedInstanceId);\n }\n };\n }, [isAutoInstance, resolvedInstanceId]);\n\n // Expose instanceId and plugin functions globally for plugin tools (e.g., install_plugin, uninstall_plugin)\n useEffect(() => {\n if (typeof window !== 'undefined') {\n const win = window as unknown as {\n __hustleInstanceId?: string;\n __hustleRegisterPlugin?: (plugin: StoredPlugin, enabled?: boolean) => Promise<void>;\n __hustleUnregisterPlugin?: (name: string) => Promise<void>;\n __hustleListPlugins?: () => Array<{ name: string; version: string; description: string; enabled: boolean }>;\n __hustleGetPlugin?: (name: string) => StoredPlugin | null;\n };\n win.__hustleInstanceId = resolvedInstanceId;\n\n // Expose registration function that uses pluginRegistry properly\n win.__hustleRegisterPlugin = async (plugin: StoredPlugin, enabled = true) => {\n // Hydrate the StoredPlugin and register it\n const hydrated = hydratePlugin(plugin);\n pluginRegistry.register(hydrated, enabled, resolvedInstanceId);\n };\n\n // Expose unregister function\n win.__hustleUnregisterPlugin = async (name: string) => {\n pluginRegistry.unregister(name, resolvedInstanceId);\n };\n\n // Expose list function\n win.__hustleListPlugins = () => {\n const plugins = pluginRegistry.loadFromStorage(resolvedInstanceId);\n return plugins.map(p => ({\n name: p.name,\n version: p.version,\n description: p.description || '',\n enabled: p.enabled,\n }));\n };\n\n // Expose get plugin function\n win.__hustleGetPlugin = (name: string) => {\n const plugins = pluginRegistry.loadFromStorage(resolvedInstanceId);\n return plugins.find(p => p.name === name) || null;\n };\n }\n return () => {\n if (typeof window !== 'undefined') {\n const win = window as unknown as {\n __hustleInstanceId?: string;\n __hustleRegisterPlugin?: unknown;\n __hustleUnregisterPlugin?: unknown;\n __hustleListPlugins?: unknown;\n __hustleGetPlugin?: unknown;\n };\n delete win.__hustleInstanceId;\n delete win.__hustleRegisterPlugin;\n delete win.__hustleUnregisterPlugin;\n delete win.__hustleListPlugins;\n delete win.__hustleGetPlugin;\n }\n };\n }, [resolvedInstanceId]);\n\n // Determine if we're using API key mode\n const isApiKeyMode = Boolean(apiKey && vaultId);\n\n // Get auth context - using optional hook that returns null when not in EmblemAuthProvider\n // This hook is always called (React rules) but returns null when outside provider\n const authContext = useEmblemAuthOptional();\n\n // Extract auth values - in API key mode, we don't need auth context\n const authSDK = isApiKeyMode ? null : authContext?.authSDK ?? null;\n const isAuthenticated = isApiKeyMode\n ? true // API key mode is always considered authenticated\n : authContext?.isAuthenticated ?? false;\n\n // Get plugins with instance scoping\n const { enabledPlugins } = usePlugins(resolvedInstanceId);\n\n // State\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [models, setModels] = useState<Model[]>([]);\n\n // Track registered plugins to avoid re-registering\n const registeredPluginsRef = useRef<Set<string>>(new Set());\n\n // Settings storage key - scoped to instance\n const SETTINGS_KEY = `hustle-settings-${resolvedInstanceId}`;\n\n // Load initial settings from localStorage\n const loadSettings = () => {\n if (typeof window === 'undefined') return { selectedModel: '', systemPrompt: '', skipServerPrompt: false };\n try {\n const stored = localStorage.getItem(SETTINGS_KEY);\n if (stored) {\n return JSON.parse(stored);\n }\n } catch {\n // Ignore parse errors\n }\n return { selectedModel: '', systemPrompt: '', skipServerPrompt: false };\n };\n\n const initialSettings = loadSettings();\n\n // Settings state (initialized from localStorage)\n const [selectedModel, setSelectedModelState] = useState<string>(initialSettings.selectedModel);\n const [systemPrompt, setSystemPromptState] = useState<string>(initialSettings.systemPrompt);\n const [skipServerPrompt, setSkipServerPromptState] = useState<boolean>(initialSettings.skipServerPrompt);\n\n // Persist settings to localStorage\n const saveSettings = useCallback((settings: { selectedModel: string; systemPrompt: string; skipServerPrompt: boolean }) => {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));\n } catch {\n // Ignore storage errors\n }\n }, []);\n\n // Wrapped setters that also persist\n const setSelectedModel = useCallback((value: string) => {\n setSelectedModelState(value);\n saveSettings({ selectedModel: value, systemPrompt, skipServerPrompt });\n }, [systemPrompt, skipServerPrompt, saveSettings]);\n\n const setSystemPrompt = useCallback((value: string) => {\n setSystemPromptState(value);\n saveSettings({ selectedModel, systemPrompt: value, skipServerPrompt });\n }, [selectedModel, skipServerPrompt, saveSettings]);\n\n const setSkipServerPrompt = useCallback((value: boolean) => {\n setSkipServerPromptState(value);\n saveSettings({ selectedModel, systemPrompt, skipServerPrompt: value });\n }, [selectedModel, systemPrompt, saveSettings]);\n\n // Debug logger\n const log = useCallback(\n (message: string, ...args: unknown[]) => {\n if (debug) {\n console.log(`[Hustle] ${message}`, ...args);\n }\n },\n [debug]\n );\n\n /**\n * Create the Hustle client\n * Supports two modes:\n * - Mode 1 (Auth SDK): Uses authSDK from EmblemAuthProvider context\n * - Mode 2 (API Key): Uses direct apiKey/vaultId props\n */\n const client = useMemo(() => {\n // Mode 2: API Key mode\n if (isApiKeyMode && apiKey && vaultId) {\n log('Creating HustleIncognitoClient with API key');\n\n try {\n const hustleClient = new HustleIncognitoClient({\n apiKey,\n vaultId,\n hustleApiUrl,\n debug,\n });\n\n // Subscribe to events\n hustleClient.on('tool_start', (event: unknown) => {\n log('Tool start:', event);\n });\n\n hustleClient.on('tool_end', (event: unknown) => {\n log('Tool end:', event);\n });\n\n hustleClient.on('stream_end', (event: unknown) => {\n log('Stream end:', event);\n });\n\n return hustleClient;\n } catch (err) {\n log('Failed to create client:', err);\n setError(err instanceof Error ? err : new Error('Failed to create Hustle client'));\n return null;\n }\n }\n\n // Mode 1: Auth SDK mode\n if (!authSDK || !isAuthenticated) {\n log('Client not created - auth not ready');\n return null;\n }\n\n log('Creating HustleIncognitoClient with auth SDK');\n\n try {\n const hustleClient = new HustleIncognitoClient({\n sdk: authSDK,\n hustleApiUrl,\n debug,\n });\n\n // Subscribe to events (use any for SDK event types)\n hustleClient.on('tool_start', (event: unknown) => {\n log('Tool start:', event);\n });\n\n hustleClient.on('tool_end', (event: unknown) => {\n log('Tool end:', event);\n });\n\n hustleClient.on('stream_end', (event: unknown) => {\n log('Stream end:', event);\n });\n\n return hustleClient;\n } catch (err) {\n log('Failed to create client:', err);\n setError(err instanceof Error ? err : new Error('Failed to create Hustle client'));\n return null;\n }\n }, [isApiKeyMode, apiKey, vaultId, authSDK, isAuthenticated, hustleApiUrl, debug, log]);\n\n // Is ready when client exists\n const isReady = client !== null;\n\n /**\n * Register enabled plugins with the client\n */\n useEffect(() => {\n if (!client) return;\n\n const registerPlugins = async () => {\n // Get the set of enabled plugin names\n const enabledNames = new Set(enabledPlugins.map(p => p.name));\n\n // Unregister plugins that were disabled\n for (const name of registeredPluginsRef.current) {\n if (!enabledNames.has(name)) {\n log('Unregistering plugin:', name);\n try {\n await client.unuse(name);\n registeredPluginsRef.current.delete(name);\n log('Plugin unregistered:', name);\n } catch (err) {\n log('Failed to unregister plugin:', name, err);\n }\n }\n }\n\n // Register new plugins\n for (const plugin of enabledPlugins) {\n if (!registeredPluginsRef.current.has(plugin.name)) {\n log('Registering plugin:', plugin.name);\n try {\n // The SDK's use() method registers the plugin\n if (plugin.executors || plugin.hooks) {\n // Cast to SDK's expected type (our types are compatible but TS is strict)\n await client.use({\n name: plugin.name,\n version: plugin.version,\n tools: plugin.tools,\n executors: plugin.executors,\n hooks: plugin.hooks,\n } as Parameters<typeof client.use>[0]);\n registeredPluginsRef.current.add(plugin.name);\n log('Plugin registered:', plugin.name);\n } else {\n log('Plugin has no executors/hooks, skipping registration:', plugin.name);\n }\n } catch (err) {\n log('Failed to register plugin:', plugin.name, err);\n }\n }\n }\n };\n\n registerPlugins();\n }, [client, enabledPlugins, log]);\n\n /**\n * Expose upload function globally for plugin tools (e.g., screenshot plugin)\n */\n useEffect(() => {\n if (typeof window !== 'undefined' && client) {\n const win = window as unknown as {\n __hustleUploadFile?: (file: File | Blob, fileName?: string) => Promise<Attachment>;\n };\n win.__hustleUploadFile = async (file: File | Blob, fileName?: string) => {\n return await client.uploadFile(file, fileName) as Attachment;\n };\n }\n return () => {\n if (typeof window !== 'undefined') {\n delete (window as unknown as { __hustleUploadFile?: unknown }).__hustleUploadFile;\n }\n };\n }, [client]);\n\n /**\n * Expose settings getters/setters globally for plugin tools\n * Allows plugins to read and modify model, system prompt, and skip server prompt settings\n */\n useEffect(() => {\n if (typeof window !== 'undefined') {\n const win = window as unknown as {\n __hustleGetModel?: () => string;\n __hustleSetModel?: (model: string) => void;\n __hustleGetSystemPrompt?: () => string;\n __hustleSetSystemPrompt?: (prompt: string) => void;\n __hustleGetSkipServerPrompt?: () => boolean;\n __hustleSetSkipServerPrompt?: (skip: boolean) => void;\n __hustleGetModels?: () => Model[];\n };\n\n // Model getters/setters\n win.__hustleGetModel = () => selectedModel;\n win.__hustleSetModel = (model: string) => setSelectedModel(model);\n\n // System prompt getters/setters\n win.__hustleGetSystemPrompt = () => systemPrompt;\n win.__hustleSetSystemPrompt = (prompt: string) => setSystemPrompt(prompt);\n\n // Skip server prompt getters/setters\n win.__hustleGetSkipServerPrompt = () => skipServerPrompt;\n win.__hustleSetSkipServerPrompt = (skip: boolean) => setSkipServerPrompt(skip);\n\n // Read-only access to available models list\n win.__hustleGetModels = () => models;\n }\n return () => {\n if (typeof window !== 'undefined') {\n const win = window as unknown as {\n __hustleGetModel?: unknown;\n __hustleSetModel?: unknown;\n __hustleGetSystemPrompt?: unknown;\n __hustleSetSystemPrompt?: unknown;\n __hustleGetSkipServerPrompt?: unknown;\n __hustleSetSkipServerPrompt?: unknown;\n __hustleGetModels?: unknown;\n };\n delete win.__hustleGetModel;\n delete win.__hustleSetModel;\n delete win.__hustleGetSystemPrompt;\n delete win.__hustleSetSystemPrompt;\n delete win.__hustleGetSkipServerPrompt;\n delete win.__hustleSetSkipServerPrompt;\n delete win.__hustleGetModels;\n }\n };\n }, [selectedModel, setSelectedModel, systemPrompt, setSystemPrompt, skipServerPrompt, setSkipServerPrompt, models]);\n\n /**\n * Load available models\n */\n const loadModels = useCallback(async (): Promise<Model[]> => {\n if (!client) {\n log('Cannot load models - client not ready');\n return [];\n }\n\n log('Loading models');\n setIsLoading(true);\n\n try {\n const modelList = await client.getModels();\n setModels(modelList as Model[]);\n log('Loaded models:', modelList.length);\n return modelList as Model[];\n } catch (err) {\n log('Failed to load models:', err);\n setError(err instanceof Error ? err : new Error('Failed to load models'));\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [client, log]);\n\n /**\n * Load models when client becomes ready\n */\n useEffect(() => {\n if (client) {\n loadModels();\n }\n }, [client, loadModels]);\n\n /**\n * Send a chat message (non-streaming)\n */\n const chat = useCallback(\n async (options: ChatOptions): Promise<ChatResponse> => {\n if (!client) {\n throw new Error('Hustle client not ready. Please authenticate first.');\n }\n\n log('Chat request:', options.messages.length, 'messages');\n setIsLoading(true);\n setError(null);\n\n try {\n // Build the messages array, prepending system prompt if provided\n const effectiveSystemPrompt = options.systemPrompt || systemPrompt;\n const messagesWithSystem: ChatMessage[] = [];\n\n if (effectiveSystemPrompt) {\n messagesWithSystem.push({ role: 'system', content: effectiveSystemPrompt });\n }\n messagesWithSystem.push(...options.messages);\n\n // Build the options object for the SDK\n const sdkOptions: Record<string, unknown> = {\n messages: messagesWithSystem,\n processChunks: true,\n };\n\n // In API key mode, we need to pass vaultId with each request\n if (isApiKeyMode && vaultId) {\n sdkOptions.vaultId = vaultId;\n }\n\n if (options.model || selectedModel) {\n sdkOptions.model = options.model || selectedModel;\n }\n if (options.overrideSystemPrompt ?? skipServerPrompt) {\n sdkOptions.overrideSystemPrompt = true;\n }\n if (options.attachments) {\n sdkOptions.attachments = options.attachments;\n }\n\n // Call the SDK - it accepts an options object\n const response = await (client as unknown as { chat: (opts: Record<string, unknown>) => Promise<unknown> }).chat(sdkOptions);\n log('Chat response received');\n return response as ChatResponse;\n } catch (err) {\n log('Chat error:', err);\n const error = err instanceof Error ? err : new Error('Chat request failed');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [client, isApiKeyMode, vaultId, selectedModel, systemPrompt, skipServerPrompt, log]\n );\n\n /**\n * Send a chat message with streaming response\n */\n const chatStreamImpl = useCallback(\n (options: StreamOptions): StreamWithResponse => {\n if (!client) {\n // Return a stream with error that yields an error\n return {\n [Symbol.asyncIterator]: async function* () {\n yield { type: 'error', value: { message: 'Hustle client not ready. Please authenticate first.' } } as StreamChunk;\n },\n response: Promise.resolve({ content: '', messageId: undefined }),\n };\n }\n\n log('Chat stream request:', options.messages.length, 'messages');\n setError(null);\n\n // Build the messages array, prepending system prompt if provided\n const effectiveSystemPrompt = options.systemPrompt || systemPrompt;\n const messagesWithSystem: ChatMessage[] = [];\n\n if (effectiveSystemPrompt) {\n messagesWithSystem.push({ role: 'system', content: effectiveSystemPrompt });\n }\n messagesWithSystem.push(...options.messages);\n\n // Build the options object for the SDK\n const sdkOptions: Record<string, unknown> = {\n messages: messagesWithSystem,\n processChunks: options.processChunks ?? true,\n };\n\n // In API key mode, we need to pass vaultId with each request\n if (isApiKeyMode && vaultId) {\n sdkOptions.vaultId = vaultId;\n }\n\n if (options.model || selectedModel) {\n sdkOptions.model = options.model || selectedModel;\n }\n if (options.overrideSystemPrompt ?? skipServerPrompt) {\n sdkOptions.overrideSystemPrompt = true;\n }\n if (options.attachments) {\n sdkOptions.attachments = options.attachments;\n }\n\n // Get the stream from the client (cast through unknown for SDK compatibility)\n const stream = client.chatStream(sdkOptions as unknown as Parameters<typeof client.chatStream>[0]);\n\n // Wrap to add logging and type conversion, preserving .response property\n return {\n [Symbol.asyncIterator]: async function* () {\n try {\n for await (const chunk of stream) {\n // Type guard for chunk with type property\n const typedChunk = chunk as { type?: string; value?: unknown };\n\n if (typedChunk.type === 'text') {\n const textValue = typedChunk.value as string;\n log('Stream text chunk:', textValue?.substring(0, 50));\n yield { type: 'text', value: textValue } as StreamChunk;\n } else if (typedChunk.type === 'tool_call') {\n log('Stream tool call:', typedChunk.value);\n yield { type: 'tool_call', value: typedChunk.value } as StreamChunk;\n } else if (typedChunk.type === 'tool_result') {\n log('Stream tool result');\n yield { type: 'tool_result', value: typedChunk.value } as StreamChunk;\n } else if (typedChunk.type === 'error') {\n const errorValue = typedChunk.value as { message?: string };\n log('Stream error:', errorValue);\n setError(new Error(errorValue?.message || 'Stream error'));\n yield { type: 'error', value: { message: errorValue?.message || 'Stream error' } } as StreamChunk;\n } else {\n // Pass through unknown chunk types\n yield chunk as StreamChunk;\n }\n }\n } catch (err) {\n log('Stream error:', err);\n const error = err instanceof Error ? err : new Error('Stream failed');\n setError(error);\n yield { type: 'error', value: { message: error.message } } as StreamChunk;\n }\n },\n // Forward the response promise from the SDK stream (includes afterResponse hook modifications)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n response: (stream as any).response as Promise<ChatResponse>,\n };\n },\n [client, isApiKeyMode, vaultId, selectedModel, systemPrompt, skipServerPrompt, log]\n );\n\n /**\n * Upload a file\n */\n const uploadFile = useCallback(\n async (file: File): Promise<Attachment> => {\n if (!client) {\n throw new Error('Hustle client not ready. Please authenticate first.');\n }\n\n log('Uploading file:', file.name);\n setIsLoading(true);\n\n try {\n const attachment = await client.uploadFile(file);\n log('File uploaded:', attachment);\n return attachment as Attachment;\n } catch (err) {\n log('Upload error:', err);\n const error = err instanceof Error ? err : new Error('File upload failed');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [client, log]\n );\n\n // Context value\n const value: HustleContextValue = {\n // Instance ID for scoped storage\n instanceId: resolvedInstanceId,\n\n // Auth mode\n isApiKeyMode,\n\n // State\n isReady,\n isLoading,\n error,\n models,\n\n // Client (for advanced use)\n client,\n\n // Chat methods\n chat,\n chatStream: chatStreamImpl,\n\n // File upload\n uploadFile,\n\n // Data fetching\n loadModels,\n\n // Settings\n selectedModel,\n setSelectedModel,\n systemPrompt,\n setSystemPrompt,\n skipServerPrompt,\n setSkipServerPrompt,\n };\n\n return (\n <HustleContext.Provider value={value}>\n {children}\n </HustleContext.Provider>\n );\n}\n\n/**\n * Hook to access Hustle context\n * Must be used within HustleProvider (which must be within EmblemAuthProvider)\n *\n * @example\n * ```tsx\n * function ChatComponent() {\n * const { isReady, chat, chatStream } = useHustle();\n *\n * if (!isReady) {\n * return <div>Please connect to start chatting</div>;\n * }\n *\n * // Use chat or chatStream...\n * }\n * ```\n */\nexport function useHustle(): HustleContextValue {\n const context = useContext(HustleContext);\n if (context === undefined) {\n throw new Error('useHustle must be used within a HustleProvider (which requires EmblemAuthProvider)');\n }\n return context;\n}\n"]}
package/dist/index.cjs CHANGED
@@ -601,6 +601,30 @@ function HustleProvider({
601
601
  }
602
602
  };
603
603
  }, [client]);
604
+ react.useEffect(() => {
605
+ if (typeof window !== "undefined") {
606
+ const win = window;
607
+ win.__hustleGetModel = () => selectedModel;
608
+ win.__hustleSetModel = (model) => setSelectedModel(model);
609
+ win.__hustleGetSystemPrompt = () => systemPrompt;
610
+ win.__hustleSetSystemPrompt = (prompt) => setSystemPrompt(prompt);
611
+ win.__hustleGetSkipServerPrompt = () => skipServerPrompt;
612
+ win.__hustleSetSkipServerPrompt = (skip) => setSkipServerPrompt(skip);
613
+ win.__hustleGetModels = () => models;
614
+ }
615
+ return () => {
616
+ if (typeof window !== "undefined") {
617
+ const win = window;
618
+ delete win.__hustleGetModel;
619
+ delete win.__hustleSetModel;
620
+ delete win.__hustleGetSystemPrompt;
621
+ delete win.__hustleSetSystemPrompt;
622
+ delete win.__hustleGetSkipServerPrompt;
623
+ delete win.__hustleSetSkipServerPrompt;
624
+ delete win.__hustleGetModels;
625
+ }
626
+ };
627
+ }, [selectedModel, setSelectedModel, systemPrompt, setSystemPrompt, skipServerPrompt, setSkipServerPrompt, models]);
604
628
  const loadModels = react.useCallback(async () => {
605
629
  if (!client) {
606
630
  log("Cannot load models - client not ready");
@@ -2200,6 +2224,15 @@ Executors run in the browser context with full access to:
2200
2224
  - **window.__hustleListPlugins()** - List all installed plugins
2201
2225
  - **window.__hustleGetPlugin(name)** - Get a specific plugin by name
2202
2226
 
2227
+ ### Hustle Settings Globals (Read/Write)
2228
+ - **window.__hustleGetModel()** - Get the current model override (empty string = server default)
2229
+ - **window.__hustleSetModel(model)** - Set the model override (e.g., "anthropic/claude-3-opus")
2230
+ - **window.__hustleGetSystemPrompt()** - Get the current system prompt override
2231
+ - **window.__hustleSetSystemPrompt(prompt)** - Set the system prompt override
2232
+ - **window.__hustleGetSkipServerPrompt()** - Get whether server prompt is skipped (boolean)
2233
+ - **window.__hustleSetSkipServerPrompt(skip)** - Set whether to skip server prompt
2234
+ - **window.__hustleGetModels()** - Get list of available models (read-only)
2235
+
2203
2236
  ### DOM Manipulation Examples
2204
2237
  Create a modal: document.createElement('div'), style it, append to document.body
2205
2238
  Add event listeners: element.addEventListener('click', handler)
@@ -4655,12 +4688,16 @@ function SettingsIcon() {
4655
4688
  function AttachIcon() {
4656
4689
  return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" }) });
4657
4690
  }
4691
+
4692
+ // src/constants/index.ts
4693
+ var AGENT_HUSTLE_ICON = "data:image/jpeg;base64,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";
4658
4694
  var sizeConfigs = {
4659
4695
  sm: { width: "320px", height: "400px" },
4660
4696
  md: { width: "380px", height: "520px" },
4661
4697
  lg: { width: "420px", height: "600px" },
4662
4698
  xl: { width: "480px", height: "700px" },
4663
- full: { width: "100vw", height: "100vh" }
4699
+ full: { width: "100vw", height: "100vh" },
4700
+ sideDock: { width: "380px", height: "100vh" }
4664
4701
  };
4665
4702
  var widgetStyles = {
4666
4703
  // Container for absolute positioning
@@ -4738,6 +4775,21 @@ var widgetStyles = {
4738
4775
  width: "100vw",
4739
4776
  height: "100vh"
4740
4777
  },
4778
+ // Side dock mode overrides
4779
+ panelSideDock: {
4780
+ position: "fixed",
4781
+ top: 0,
4782
+ right: 0,
4783
+ bottom: 0,
4784
+ borderRadius: 0,
4785
+ width: "380px",
4786
+ height: "100vh",
4787
+ borderLeft: `1px solid ${tokens.colors.borderPrimary}`,
4788
+ boxShadow: `-4px 0 24px rgba(0, 0, 0, 0.3)`
4789
+ },
4790
+ // Hustle avatar in launcher
4791
+ launcherAvatar: {
4792
+ borderRadius: tokens.radius.full},
4741
4793
  // Close button in panel header
4742
4794
  closeBtn: {
4743
4795
  width: "32px",
@@ -4757,23 +4809,35 @@ var widgetStyles = {
4757
4809
  color: tokens.colors.textPrimary
4758
4810
  }
4759
4811
  };
4760
- function ChatIcon() {
4761
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
4762
- }
4763
4812
  function CloseIcon() {
4764
4813
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
4765
4814
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
4766
4815
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
4767
4816
  ] });
4768
4817
  }
4769
- function MinimizeIcon() {
4818
+ function ExpandIcon() {
4770
4819
  return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
4771
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "4 14 10 14 10 20" }),
4772
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 10 14 10 14 4" }),
4773
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "14", y1: "10", x2: "21", y2: "3" }),
4820
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
4821
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 21 3 21 3 15" }),
4822
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
4774
4823
  /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
4775
4824
  ] });
4776
4825
  }
4826
+ function AgentHustleAvatar({ size = 40 }) {
4827
+ return /* @__PURE__ */ jsxRuntime.jsx(
4828
+ "img",
4829
+ {
4830
+ src: AGENT_HUSTLE_ICON,
4831
+ alt: "Agent Hustle",
4832
+ style: {
4833
+ width: size,
4834
+ height: size,
4835
+ borderRadius: "50%",
4836
+ objectFit: "cover"
4837
+ }
4838
+ }
4839
+ );
4840
+ }
4777
4841
  function HustleChatWidget({
4778
4842
  config = {},
4779
4843
  ...chatProps
@@ -4781,7 +4845,7 @@ function HustleChatWidget({
4781
4845
  const {
4782
4846
  position = "bottom-right",
4783
4847
  size = "md",
4784
- title = "Chat",
4848
+ title = "Agent Hustle",
4785
4849
  defaultOpen = false,
4786
4850
  launcherIcon,
4787
4851
  offset = { x: 24, y: 24 },
@@ -4856,7 +4920,7 @@ function HustleChatWidget({
4856
4920
  style: {
4857
4921
  ...widgetStyles.panel,
4858
4922
  ...positionStyles.panel,
4859
- ...size === "full" ? widgetStyles.panelFull : {
4923
+ ...size === "full" ? widgetStyles.panelFull : size === "sideDock" ? widgetStyles.panelSideDock : {
4860
4924
  width: sizeConfig.width,
4861
4925
  height: sizeConfig.height
4862
4926
  },
@@ -4874,35 +4938,70 @@ function HustleChatWidget({
4874
4938
  padding: `${tokens.spacing.md} ${tokens.spacing.lg}`,
4875
4939
  background: tokens.colors.bgPrimary,
4876
4940
  borderBottom: `1px solid ${tokens.colors.borderPrimary}`,
4877
- borderRadius: `${tokens.radius.xl} ${tokens.radius.xl} 0 0`,
4941
+ borderRadius: size === "sideDock" || size === "full" ? 0 : `${tokens.radius.xl} ${tokens.radius.xl} 0 0`,
4878
4942
  flexShrink: 0
4879
4943
  },
4880
4944
  children: [
4881
- /* @__PURE__ */ jsxRuntime.jsx(
4882
- "span",
4883
- {
4884
- style: {
4885
- fontWeight: tokens.typography.fontWeightSemibold,
4886
- color: tokens.colors.textPrimary,
4887
- fontSize: tokens.typography.fontSizeMd
4888
- },
4889
- children: title
4890
- }
4891
- ),
4892
- /* @__PURE__ */ jsxRuntime.jsx(
4893
- "button",
4894
- {
4895
- onClick: toggle,
4896
- onMouseEnter: () => setCloseHovered(true),
4897
- onMouseLeave: () => setCloseHovered(false),
4898
- style: {
4899
- ...widgetStyles.closeBtn,
4900
- ...closeHovered ? widgetStyles.closeBtnHover : {}
4901
- },
4902
- title: "Close chat",
4903
- children: size === "full" ? /* @__PURE__ */ jsxRuntime.jsx(MinimizeIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
4904
- }
4905
- )
4945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.md }, children: [
4946
+ /* @__PURE__ */ jsxRuntime.jsx(AgentHustleAvatar, { size: 32 }),
4947
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4948
+ /* @__PURE__ */ jsxRuntime.jsx(
4949
+ "span",
4950
+ {
4951
+ style: {
4952
+ display: "block",
4953
+ fontWeight: tokens.typography.fontWeightSemibold,
4954
+ color: tokens.colors.textPrimary,
4955
+ fontSize: tokens.typography.fontSizeMd
4956
+ },
4957
+ children: title
4958
+ }
4959
+ ),
4960
+ /* @__PURE__ */ jsxRuntime.jsx(
4961
+ "span",
4962
+ {
4963
+ style: {
4964
+ display: "block",
4965
+ fontSize: tokens.typography.fontSizeXs,
4966
+ color: tokens.colors.textTertiary
4967
+ },
4968
+ children: "Protocol Companion"
4969
+ }
4970
+ )
4971
+ ] })
4972
+ ] }),
4973
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs }, children: [
4974
+ size === "sideDock" && /* @__PURE__ */ jsxRuntime.jsx(
4975
+ "button",
4976
+ {
4977
+ onClick: () => {
4978
+ },
4979
+ onMouseEnter: () => {
4980
+ },
4981
+ onMouseLeave: () => {
4982
+ },
4983
+ style: {
4984
+ ...widgetStyles.closeBtn
4985
+ },
4986
+ title: "Expand",
4987
+ children: /* @__PURE__ */ jsxRuntime.jsx(ExpandIcon, {})
4988
+ }
4989
+ ),
4990
+ /* @__PURE__ */ jsxRuntime.jsx(
4991
+ "button",
4992
+ {
4993
+ onClick: toggle,
4994
+ onMouseEnter: () => setCloseHovered(true),
4995
+ onMouseLeave: () => setCloseHovered(false),
4996
+ style: {
4997
+ ...widgetStyles.closeBtn,
4998
+ ...closeHovered ? widgetStyles.closeBtnHover : {}
4999
+ },
5000
+ title: "Close chat",
5001
+ children: size === "full" || size === "sideDock" ? /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
5002
+ }
5003
+ )
5004
+ ] })
4906
5005
  ]
4907
5006
  }
4908
5007
  ),
@@ -4910,7 +5009,7 @@ function HustleChatWidget({
4910
5009
  ]
4911
5010
  }
4912
5011
  ),
4913
- (size !== "full" || !isOpen) && /* @__PURE__ */ jsxRuntime.jsxs(
5012
+ (size !== "full" && size !== "sideDock" || !isOpen) && /* @__PURE__ */ jsxRuntime.jsxs(
4914
5013
  "button",
4915
5014
  {
4916
5015
  onClick: toggle,
@@ -4926,7 +5025,7 @@ function HustleChatWidget({
4926
5025
  title: isOpen ? "Close chat" : "Open chat",
4927
5026
  "aria-label": isOpen ? "Close chat" : "Open chat",
4928
5027
  children: [
4929
- launcherIcon || /* @__PURE__ */ jsxRuntime.jsx(ChatIcon, {}),
5028
+ launcherIcon || /* @__PURE__ */ jsxRuntime.jsx(AgentHustleAvatar, { size: 40 }),
4930
5029
  showBadge && badgeContent && !isOpen && /* @__PURE__ */ jsxRuntime.jsx("span", { style: widgetStyles.badge, children: badgeContent })
4931
5030
  ]
4932
5031
  }
@@ -5020,6 +5119,7 @@ var DEFAULTS = {
5020
5119
  EMBLEM_MODAL_URL: "https://emblemvault.ai/connect"
5021
5120
  };
5022
5121
 
5122
+ exports.AGENT_HUSTLE_ICON = AGENT_HUSTLE_ICON;
5023
5123
  exports.DEFAULTS = DEFAULTS;
5024
5124
  exports.HustleChat = HustleChat;
5025
5125
  exports.HustleChatWidget = HustleChatWidget;