Use the Settings modal action order across plugin settings and related edit/create modals so primary actions appear before Cancel while preserving existing handlers and state logic.
Surface the active Agent Profile beside the model preset switcher and let users switch profiles through the existing settings flow.
- add agent profile metadata to state snapshots
- list available profiles in the chat composer profile dropdown
- persist profile changes via settings_get/settings_set
- add a Create new Agent Profile action that opens a guided a0-create-agent chat
- rename the agent-profile creation skill/docs from a0-new-agent to a0-create-agent
- clean up fetchApi imports for related WebUI modules
- Populate plugin settings modal title from selected plugin metadata instead of static `"Plugin Settings"`.
- Keep the modal title aligned with the currently opened plugin (`display_name`/`name` fallback).
- Remove the non-functional **Open Model Settings** action from `_browser_agent` UI.
- Remove the now-unused `openModelSettings()` handler from `browser-agent-store`.
- Preserve and retain only **Open Presets** and **Open API Keys** in Browser Agent actions.
Redesign the three messaging integration panels with a clearer, more guided
setup flow and polished user experience.
- simplify the email panel by surfacing the essentials first, moving
advanced scheduling behind Advanced, and making connection checks more
visible
- redesign Telegram and WhatsApp as step-based setup flows with clearer
status states, safer access warnings, richer test feedback, and more
responsive layouts
- add shared plugin-settings wizard footer support, extract WhatsApp state
into its own store, and align test-connection messages with the new UX
ux: ease Email connector setup and refresh copy
- Redesign the Email connector settings around a guided first-run flow with a clearer empty state, provider presets, and much friendlier copy
- Move server, routing, and scheduling power-user controls into an `Advanced` section while keeping the existing config model compatible
- Improve connection-test messaging, add Exchange inbound validation, and refresh the dashboard Email card copy while keeping the card visible
- Verify the updated setup flow in the browser on desktop and mobile
update and simplify x-data based on established frontend patterns
Update 10_discovery_cards.py
further polishing and first-draft no-click model for email and telegram
update whatsapp
Update telegram-config-store.js
Add the always-enabled `_discovery` plugin to turn the welcome screen into a discovery surface for the Plugin Hub and A0 integrations.
Includes a hero card plus Telegram, Email, and WhatsApp feature cards, with persistent dismiss/restore state, CTA routing to plugin config screens, and self-contained placeholder artwork. Implemented entirely through the existing WebUI extension mechanism with no core welcome-screen changes.
stores cleanup
layout polish and onboarding integration
Move feature card titles beside thumbnails for better space efficiency
and visibility. Restructure card markup and styles to support a fluid
grid layout and horizontal alignment.
Integrate discovery cards into the final onboarding step via a new
'onboarding-success-end' extension point, ensuring new users see
extension opportunities immediately after setup.
Hide discovery cards on the dashboard while the missing API key
onboarding banner is visible to reduce UI noise and user confusion during initial config.
update discovery card initialization and loading logic
Enhance the discovery store to fetch cards from the API, improving the dynamic loading of discovery cards based on user context. This change optimizes the user experience by ensuring relevant cards are displayed immediately after onboarding and when modals are closed.
And on top of that, there's a proper backend for these new cards.
Add a shared safe markdown pipeline for plugin READMEs and docs.
- vendor DOMPurify and introduce a shared safe-markdown helper
- centralize GitHub README link/image rebasing, including repo routes like `releases`
- sanitize rendered HTML before all plugin-related x-html sinks
- apply the shared renderer to Plugin Hub README, installed plugin README, and markdown modal docs
- preserve target/rel handling for external links
- Normalize plugin paths using files.normalize_a0_path in get_enhanced_plugins_list
- Add collapsible README section to plugin info modal with loading/error states
- Implement loadPluginReadme function to fetch and render plugin documentation
- Update plugin hub pagination from 20 to 24 items per page
- Change popular filter threshold from >0 to >=3 stars
- Add comprehensive README styling with support
Surface repository metadata for installed custom plugins and add quick actions from the plugin info modal to open plugin files or jump back into the Plugin Hub. Refresh Plugin Hub card/status styling and modal spacing.
Move plugin config modal initialization into pluginSettingsStore.openConfig(), so callers only pass plugin name and optional scope. Resolve invalid project/agent scopes inside the store, initialize toggle state on the resolved scope, remove the old saveMode/core-save path, and delete stale saveMode guidance from docs and plugin skills.
Add a new per-plugin actions dropdown to the plugin list and expose new HTML extension points inside it so plugins can inject custom dropdown entries while empty menus stay hidden.
Also add a fire-and-forget JS hook after `plugins_list` loads, with `_plugin_installer` owning the cached marketplace index fetch and deep-link helper so matching installed plugins get a Marketplace action that opens the exact marketplace detail.
Make marketplace discovery easier to find from the main Plugins screen and tighten the plugin detail layout so metadata and actions stay readable across breakpoints.
- add a Browse tab to the main plugin list by reusing the existing marketplace component and matching its store icon
- refresh marketplace data after detail/install actions when that tab is active
- keep title, installed state, metadata, and tags grouped together while letting detail actions wrap in their own column
- add the repository "Give a star" link and move screenshots below the description
Align plugin installer and plugin settings UI with the frontend component/store patterns.
- compose plugin_installer main.html from install-index/install-git/install-zip components instead of duplicating tab markup
- restore shared plugin window CSS in main.html while keeping tab content delegated to dedicated components
- replace remaining direct cross-store/template calls with store methods and module imports
- route installer screenshot opening through pluginInstallStore and rewire plugin init opening through pluginListStore
- extract settings/plugins subsection logic from inline x-data into a dedicated store-backed context
- remove touched plugin/settings Alpine.store lookups in favor of explicit store imports
- fix advanced toggle behavior so the switch can create a rule immediately for the selected scope
- restore installer success/result state used by the git/zip tab UIs
Refactor plugin settings to use a per-modal prototype/context instead of binding directly to the global store. Introduces pluginSettingsPrototype (renamed export) and a lightweight instantiate helper (Alpine.magic('instantiate')) to clone the prototype into a modal-local context. Plugin config HTMLs (code_execution, infection_check, memory, text_editor) now bind UI fields to config.* and use context.* for modal-level state and actions; plugin settings components (plugin-settings.html, plugin-configs.html, plugin-settings-store.js, pluginListStore.js) were updated to create and consume the local context and to pass context into nested modals. Documentation and the SKILL guide were updated to describe the new modal contract and usage. This change scopes settings UI state to modal instances, enabling safer local state and easier integration with core-setting wrappers (use context.saveMode = 'core').
- Updated the plugin installation API to fetch and augment plugin discussions from GitHub, improving the index response with discussion links.
- Refactored the plugin installation UI to include better handling of plugin details, including management buttons for installed plugins.
- Improved the layout and styling of the plugin browsing interface, including search and sort functionalities, and added a summary of available plugins.
Replaced the "delete_work_dir_file" API call with a "delete_plugin" action in the plugins API. This bypasses the dev container file browser conversion and directly uses the runtime's absolute path to securely remove custom plugins using the files.delete_dir utility.
When you close a modal, the DOM element is physically removed from the document tree, which is what triggers x-destroy. Using Alpine's $dispatch('event'), the event fires from the detached element and cannot bubble up to the window where our x-on:plugin-modal-closed.window listener is waiting to refresh the list of plugins.
To fix this so it works 100% of the time, I've bypassed the bubbling entirely by explicitly dispatching the event directly on the window object using native JS inside the x-destroy directive.
Now, the moment the modal closes the listener catches it, and the list refreshes automatically, showing the "Advanced" button right away, so you can go back to the Advanced toggling modal to do edits without having to refresh.
- Added a shortcut "Open Advanced" icon next to the dropdown (visible only in Advanced mode) to quickly open the Switch modal.
- Fixed the Switch modal so the "Configure Plugin" button only appears if the plugin actually has settings.
- Redesigned scope rule creation in the Switch modal: switching project/agent profiles no longer auto-creates .toggle-1 files silently. Users must now intentionally click a + button to create a rule for that scope before the switch becomes active.
When you close a modal, the DOM element is physically removed from the document tree, which is what triggers x-destroy. Using Alpine's $dispatch('event'), the event fires from the detached element and cannot bubble up to the window where our x-on:plugin-modal-closed.window listener is waiting to refresh the list of plugins.
To fix this so it works 100% of the time, I've bypassed the bubbling entirely by explicitly dispatching the event directly on the window object using native JS inside the x-destroy directive.
Now, the moment the modal closes the listener catches it, and the list refreshes automatically, showing the "Advanced" button right away, so you can go back to the Advanced toggling modal to do edits without having to refresh.
- Added a shortcut "Open Advanced" icon next to the dropdown (visible only in Advanced mode) to quickly open the Switch modal.
- Fixed the Switch modal so the "Configure Plugin" button only appears if the plugin actually has settings.
- Redesigned scope rule creation in the Switch modal: switching project/agent profiles no longer auto-creates .toggle-1 files silently. Users must now intentionally click a + button to create a rule for that scope before the switch becomes active.
Backend: Update toggle_plugin signature to match API
Frontend: use x-on:modal-closed in the Plugin List to auto-refresh state, ensuring the "Advanced" dropdown status updates immediately without manual store calls
- Updated documentation to reflect the new plugin structure and activation rules.
- Refactored activation rules related code in the API and frontend to accommodate the new plugin settings and activation logic.
- Added support for clearing per-scope overrides when toggling plugins.
Use json.dumps when writing plugin settings to disk instead of yaml_helper.dumps to serialize plugin configuration as JSON. Also add an <x-extension id="plugins-list-header-buttons"> slot to the plugin list header so extra header buttons or controls can be injected by extensions.
Remove a temporary test extension and add UI and Python support for plugin toggles/settings. Highlights:
- Deleted plugins/memory/extensions/webui/.../testingext.js (temporary test code removed).
- API: python/api/plugins.py: add asset_type input to list_configs and route to toggle asset pattern when requested.
- Helpers: python/helpers/plugins.py: add typing for toggle state, TOGGLE_FILE_PATTERN, always_enabled metadata flag, stub get_toggle_state/toggle_plugin, and small refactor in get_enabled_plugins to import subagents only when needed.
- Subagents: python/helpers/subagents.py: iterate over get_plugins_list() and adjust path usage.
- Web UI: add new components under webui/components/plugins/toggle: plugin-toggle-advanced.html (plugin settings modal), plugin-toggle-store.js (Alpine store for plugin settings), and plugin-toggles.html (list of existing plugin configurations).
These changes add the front-end modal and store for per-project/agent plugin settings and introduce backend patterns/constants and stubs to support toggles (get_toggle_state/toggle_plugin) and listing toggle assets. Further implementation is needed to persist toggle state and fully integrate TOGGLE_FILE_PATTERN handling.
Removed the memory_subdir attribute from AgentConfig and related settings, transitioning to a project-based memory isolation approach. Updated the memory plugin configuration to default to an empty string for agent_memory_subdir. Enhanced the get_context_memory_subdir function to support project-specific memory directories. Removed the project-edit-memory component and adjusted the UI to reflect these changes. Added a new memory configuration file for better management of memory settings.
Expose plugin config management and improve UI/UX. Backend: add plugins API actions list_configs and delete_config (with validation and file deletion), and refine find_plugin_assets to infer project/agent from paths when wildcards are used. Frontend: update download endpoints to /api/download_work_dir_file, redesign plugin-configs list layout, add delete confirmation and show action, and adjust styles. Enhance plugin-settings-store with unsaved-changes detection, scope-change confirmation, config listing and deletion via the new API, and settings snapshot lifecycle. Also update message path replacement to use the /api prefix.
Introduce support for scoped plugin configurations and a small WebUI to list/switch them. Rename plugin memory config to config.default.json and set memory plugin per_agent_config to false. API changes: Plugins.get_config now searches project/agent-specific configs, falls back to config.default.json, and returns loaded_path/loaded_project_name/loaded_agent_profile metadata. Helper updates: add CONFIG_DEFAULT_FILE_NAME, enhance get_plugin_config to consider project and agent profile, replace/find wrapper with find_plugin_assets which returns matching paths and scope metadata, and minor refactors in plugin path handling. WebUI: add plugin-configs.html and update plugin-settings-store.js and plugin-settings.html to expose scope info, config listing modal, and scope-mismatch messaging.