- {#if currentView === 'plugin-manager'}
-
- {:else if currentView === 'workbench'}
-
- {:else if currentView === 'workspace'}
-
- {:else}
-
- {/if}
+
+
+ {#if currentView === 'plugin-manager'}
+
+ {:else if currentView === 'workbench'}
+
+ {:else if currentView === 'workspace'}
+
+ {:else}
+
+ {/if}
+
+
{/if}
@@ -460,6 +464,14 @@
overflow: hidden;
}
+ .content-shell {
+ flex: 1;
+ min-width: 0;
+ min-height: 0;
+ display: flex;
+ flex-direction: column;
+ }
+
.content {
flex: 1;
min-width: 0;
diff --git a/frontend/src/lib/shell/StatusBar.svelte b/frontend/src/lib/shell/StatusBar.svelte
new file mode 100644
index 0000000..527123c
--- /dev/null
+++ b/frontend/src/lib/shell/StatusBar.svelte
@@ -0,0 +1,102 @@
+
+
+
+
+
diff --git a/internal/api/app.go b/internal/api/app.go
index 6ef2312..37755bd 100644
--- a/internal/api/app.go
+++ b/internal/api/app.go
@@ -228,6 +228,14 @@ type FlatCommand struct {
Handler string `json:"handler,omitempty"`
}
+type FlatStatusBarItem struct {
+ PluginID string `json:"pluginId"`
+ ID string `json:"id"`
+ Label string `json:"label"`
+ Position string `json:"position,omitempty"`
+ Handler string `json:"handler,omitempty"`
+}
+
type FlatOpenProviderSupport struct {
Kind string `json:"kind"`
Mime []string `json:"mime,omitempty"`
@@ -258,6 +266,7 @@ type ContributionSummary struct {
Commands []FlatCommand `json:"commands"`
SettingsPanels []FlatSettingsPanel `json:"settingsPanels"`
SidebarItems []FlatSidebarItem `json:"sidebarItems"`
+ StatusBarItems []FlatStatusBarItem `json:"statusBarItems"`
OpenProviders []FlatOpenProvider `json:"openProviders"`
WorkspaceItems []FlatWorkspaceItem `json:"workspaceItems"`
}
@@ -271,6 +280,7 @@ func buildContributionSummary(r *contribution.Registry) ContributionSummary {
regCmds := r.Commands()
regPanels := r.SettingsPanels()
regSidebar := r.SidebarItems()
+ regStatusBar := r.StatusBarItems()
regOpenProviders := r.OpenProviders()
regWorkspaceItems := r.WorkspaceItems()
@@ -290,6 +300,10 @@ func buildContributionSummary(r *contribution.Registry) ContributionSummary {
for i, v := range regSidebar {
sidebar[i] = FlatSidebarItem{PluginID: v.PluginID, ID: v.Item.ID, Title: v.Item.Title, Icon: v.Item.Icon, View: v.Item.View, Position: v.Item.Position}
}
+ statusBarItems := make([]FlatStatusBarItem, len(regStatusBar))
+ for i, v := range regStatusBar {
+ statusBarItems[i] = FlatStatusBarItem{PluginID: v.PluginID, ID: v.Item.ID, Label: v.Item.Label, Position: v.Item.Position, Handler: v.Item.Handler}
+ }
openProviders := make([]FlatOpenProvider, len(regOpenProviders))
for i, v := range regOpenProviders {
supports := make([]FlatOpenProviderSupport, len(v.Item.Supports))
@@ -309,7 +323,7 @@ func buildContributionSummary(r *contribution.Registry) ContributionSummary {
for i, v := range regWorkspaceItems {
workspaceItems[i] = FlatWorkspaceItem{PluginID: v.PluginID, ID: v.Item.ID, Title: v.Item.Title, Icon: v.Item.Icon, Component: v.Item.Component}
}
- return ContributionSummary{Views: views, Commands: cmds, SettingsPanels: panels, SidebarItems: sidebar, OpenProviders: openProviders, WorkspaceItems: workspaceItems}
+ return ContributionSummary{Views: views, Commands: cmds, SettingsPanels: panels, SidebarItems: sidebar, StatusBarItems: statusBarItems, OpenProviders: openProviders, WorkspaceItems: workspaceItems}
}
// GetContributions returns all registered contributions flattened for the frontend.
@@ -322,8 +336,8 @@ func (a *App) GetContributions() ContributionSummary {
}
summary := buildContributionSummary(a.contribRegistry)
if a.debug {
- debug.Logf("[api] GetContributions: returning views=%d commands=%d sidebar=%d settings=%d openProviders=%d",
- len(summary.Views), len(summary.Commands), len(summary.SidebarItems), len(summary.SettingsPanels), len(summary.OpenProviders))
+ debug.Logf("[api] GetContributions: returning views=%d commands=%d sidebar=%d statusBar=%d settings=%d openProviders=%d",
+ len(summary.Views), len(summary.Commands), len(summary.SidebarItems), len(summary.StatusBarItems), len(summary.SettingsPanels), len(summary.OpenProviders))
}
return summary
}
diff --git a/internal/api/app_test.go b/internal/api/app_test.go
index eee8910..5cd30ea 100644
--- a/internal/api/app_test.go
+++ b/internal/api/app_test.go
@@ -924,6 +924,9 @@ func newBridgeTestApp(t *testing.T) *App {
Commands: []plugin.ContributionCommand{
{ID: "bridge.command", Title: "Bridge Command", Handler: "runBridgeCommand"},
},
+ StatusBarItems: []plugin.ContributionStatusBarItem{
+ {ID: "bridge.status", Label: "Bridge Ready", Position: "right", Handler: "openBridgeStatus"},
+ },
OpenProviders: []plugin.ContributionOpenProvider{
{
ID: "bridge.markdown",
@@ -998,6 +1001,19 @@ func TestContributionSummaryIncludesOpenProviders(t *testing.T) {
}
}
+func TestContributionSummaryIncludesStatusBarItems(t *testing.T) {
+ app := newBridgeTestApp(t)
+
+ summary := app.GetContributions()
+ if len(summary.StatusBarItems) != 1 {
+ t.Fatalf("StatusBarItems count = %d, want 1", len(summary.StatusBarItems))
+ }
+ item := summary.StatusBarItems[0]
+ if item.PluginID != "bridge.plugin" || item.ID != "bridge.status" || item.Label != "Bridge Ready" || item.Position != "right" || item.Handler != "openBridgeStatus" {
+ t.Fatalf("status item = %+v", item)
+ }
+}
+
func TestWorkbenchOpenAndEditResourceRouteToProvider(t *testing.T) {
app := newBridgeTestApp(t)
app.contribRegistry.Register("disabled.plugin", &plugin.Contributions{
diff --git a/internal/core/contribution/registry.go b/internal/core/contribution/registry.go
index d90340c..e22a419 100644
--- a/internal/core/contribution/registry.go
+++ b/internal/core/contribution/registry.go
@@ -280,6 +280,15 @@ func (r *Registry) SidebarItems() []ContributionSidebarItem {
return result
}
+func (r *Registry) StatusBarItems() []ContributionStatusBarItem {
+ r.mu.RLock()
+ defer r.mu.RUnlock()
+ result := make([]ContributionStatusBarItem, len(r.statusBarItems))
+ copy(result, r.statusBarItems)
+ sort.Slice(result, func(i, j int) bool { return result[i].Item.ID < result[j].Item.ID })
+ return result
+}
+
func (r *Registry) FileActions() []ContributionAction {
r.mu.RLock()
defer r.mu.RUnlock()