diff --git a/src/apps/officer-web/App.tsx b/src/apps/officer-web/App.tsx
index 68734820..4bfc259f 100644
--- a/src/apps/officer-web/App.tsx
+++ b/src/apps/officer-web/App.tsx
@@ -46,7 +46,7 @@ export function App() {
} />
} />
} />
- } />
+ } />
} />
} />
} />
diff --git a/src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx b/src/apps/officer-web/Screens/Dashboard/CapabilityPage.tsx
similarity index 96%
rename from src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx
rename to src/apps/officer-web/Screens/Dashboard/CapabilityPage.tsx
index e1f79145..c540513b 100644
--- a/src/apps/officer-web/Screens/Dashboard/ResourcePage.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/CapabilityPage.tsx
@@ -13,27 +13,27 @@ import { Card } from '@/components/Card';
import type { ChatMessage } from 'widgets/Chat';
import { useClaude } from '@/Screens/Dashboard/Chat/useClaude';
import { EmbeddableChat } from '@/Screens/Dashboard/Chat/EmbeddableChat';
-type ResourceSummary = {
+type CapabilitySummary = {
dirName: string;
name: string;
description: string;
scope: 'global' | 'user';
};
-type ResourceDetail = ResourceSummary & {
+type CapabilityDetail = CapabilitySummary & {
body: string;
rawFrontmatter: string;
filePath: string;
chatSessionId: string | null;
};
-type ResourcePageProps = {
+type CapabilityPageProps = {
kind: string;
endpoint: string;
queryKey: string;
};
-type ResourceChatProps = {
+type CapabilityChatProps = {
kind: string;
endpoint: string;
dirName: string;
@@ -44,7 +44,7 @@ type ResourceChatProps = {
onResponseEnd?: () => void;
};
-const ResourceChat = ({
+const CapabilityChat = ({
kind,
endpoint,
dirName,
@@ -53,7 +53,7 @@ const ResourceChat = ({
chatSessionId,
isNew,
onResponseEnd,
-}: ResourceChatProps) => {
+}: CapabilityChatProps) => {
const client = useClient();
const claudeModels = useVisibleClaudeModels();
const seedFile = `${kind.toUpperCase()}.md`;
@@ -129,7 +129,7 @@ const FrontmatterBlock = ({ yaml }: { yaml: string }) => {
);
};
-export const ResourcePage = ({ kind, endpoint, queryKey }: ResourcePageProps) => {
+export const CapabilityPage = ({ kind, endpoint, queryKey }: CapabilityPageProps) => {
const client = useClient();
const qc = useQueryClient();
const [selected, setSelected] = useState(null);
@@ -142,9 +142,9 @@ export const ResourcePage = ({ kind, endpoint, queryKey }: ResourcePageProps) =>
const [showDetail, setShowDetail] = useState(false);
const newNameRef = useRef(null);
- const { data: items = [] } = useQuery({
+ const { data: items = [] } = useQuery({
queryKey: [queryKey],
- queryFn: () => client.get(endpoint),
+ queryFn: () => client.get(endpoint),
});
useEffect(() => {
@@ -153,9 +153,9 @@ export const ResourcePage = ({ kind, endpoint, queryKey }: ResourcePageProps) =>
}
}, [items, selected]);
- const { data: detail } = useQuery({
+ const { data: detail } = useQuery({
queryKey: [queryKey, selected],
- queryFn: () => client.get(`${endpoint}/${selected}`),
+ queryFn: () => client.get(`${endpoint}/${selected}`),
enabled: !!selected,
});
@@ -369,7 +369,7 @@ export const ResourcePage = ({ kind, endpoint, queryKey }: ResourcePageProps) =>
- {
return (
<>
-
-
+
(
+
+
+
+
+
+);
+
export { FileBrowser as FileBrowserWidget } from './Widget';
diff --git a/src/apps/officer-web/Screens/Dashboard/Home/index.tsx b/src/apps/officer-web/Screens/Dashboard/Home/index.tsx
index 8626b3a1..c7e28f23 100644
--- a/src/apps/officer-web/Screens/Dashboard/Home/index.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Home/index.tsx
@@ -15,7 +15,7 @@ const DEFAULT_HOME_LAYOUT: LayoutNode = {
id: 'home-left',
direction: 'vertical',
children: [
- { size: 50, node: { type: 'panel', id: 'home-tl', widgetType: 'chat-launcher' } },
+ { size: 50, node: { type: 'panel', id: 'home-tl', widgetType: 'chat' } },
{ size: 50, node: { type: 'panel', id: 'home-bl', widgetType: 'file-browser' } },
],
},
diff --git a/src/apps/officer-web/Screens/Dashboard/Processes/index.tsx b/src/apps/officer-web/Screens/Dashboard/Processes/index.tsx
index b32ef319..ab0144e5 100644
--- a/src/apps/officer-web/Screens/Dashboard/Processes/index.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Processes/index.tsx
@@ -1,3 +1,3 @@
-import { ResourcePage } from '../ResourcePage';
+import { CapabilityPage } from '../CapabilityPage';
-export const Processes = () => ;
+export const Processes = () => ;
diff --git a/src/apps/officer-web/Screens/Dashboard/Skills/index.tsx b/src/apps/officer-web/Screens/Dashboard/Skills/index.tsx
index b93b0d64..930ddd9c 100644
--- a/src/apps/officer-web/Screens/Dashboard/Skills/index.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Skills/index.tsx
@@ -1,3 +1,3 @@
-import { ResourcePage } from '../ResourcePage';
+import { CapabilityPage } from '../CapabilityPage';
-export const Skills = () => ;
+export const Skills = () => ;
diff --git a/src/apps/officer-web/Screens/Dashboard/Tasks/index.tsx b/src/apps/officer-web/Screens/Dashboard/Tasks/index.tsx
index 269f320d..0792f22c 100644
--- a/src/apps/officer-web/Screens/Dashboard/Tasks/index.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Tasks/index.tsx
@@ -1,3 +1,3 @@
-import { ResourcePage } from '../ResourcePage';
+import { CapabilityPage } from '../CapabilityPage';
-export const Tasks = () => ;
+export const Tasks = () => ;
diff --git a/src/apps/officer-web/Screens/Dashboard/Workspaces/widget-registry.tsx b/src/apps/officer-web/Screens/Dashboard/Workspaces/widget-registry.tsx
index 6c0caeec..39a661ae 100644
--- a/src/apps/officer-web/Screens/Dashboard/Workspaces/widget-registry.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Workspaces/widget-registry.tsx
@@ -1,20 +1,45 @@
+import { useState } from 'react';
import { MessageSquare, FolderOpen, History, Music, Code, TerminalSquare, LayoutGrid } from 'lucide-react';
import type { WidgetRegistry } from '@/components/Workspace';
import { CodeEditorView } from 'widgets/CodeEditor';
import { TerminalView } from 'widgets/Terminal';
-import { ChatLauncher } from '../Home/ChatLauncher';
+import { useClaude } from '../Chat/useClaude';
+import { useOpenCode } from '../Chat/useOpenCode';
+import { ChatPanel } from '../Chat/ChatPanel';
+import { useVisibleClaudeModels, useVisibleOpenCodeModels } from '@/state/useModels';
import { ChatHistoryWidget as ChatHistory } from '../ChatHistory';
-import { FileBrowserWidget as FileBrowser } from '../Files';
+import { Files } from '../Files';
import { Catalog } from 'sounds';
import { WorkspaceListWidget } from './WorkspaceListWidget';
+const ChatWidget = () => {
+ const [provider, setProvider] = useState<'claude' | 'opencode'>('claude');
+ return provider === 'claude' ? (
+
+ ) : (
+
+ );
+};
+
+const ClaudeChatWidget = ({ onProviderChange }: { onProviderChange: (p: 'claude' | 'opencode') => void }) => {
+ const claude = useClaude();
+ const models = useVisibleClaudeModels();
+ return ;
+};
+
+const OpenCodeChatWidget = ({ onProviderChange }: { onProviderChange: (p: 'claude' | 'opencode') => void }) => {
+ const opencode = useOpenCode();
+ const models = useVisibleOpenCodeModels();
+ return ;
+};
+
const CodeEditorWrapper = () => ;
const TerminalWrapper = () => ;
export const widgetRegistry: WidgetRegistry = {
- 'chat-launcher': { name: 'Chat', icon: MessageSquare, component: () => },
- 'file-browser': { name: 'File Browser', icon: FolderOpen, component: () => },
+ 'chat': { name: 'Chat', icon: MessageSquare, component: ChatWidget },
+ 'file-browser': { name: 'File Browser', icon: FolderOpen, component: () => },
'chat-history': { name: 'Chat History', icon: History, component: () => },
'sound-library': { name: 'Sound Library', icon: Music, component: () => },
'code-editor': { name: 'Code Editor', icon: Code, component: CodeEditorWrapper },
diff --git a/src/apps/officer-web/Screens/Dashboard/index.tsx b/src/apps/officer-web/Screens/Dashboard/index.tsx
index 5b236c8c..98edc0b2 100644
--- a/src/apps/officer-web/Screens/Dashboard/index.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/index.tsx
@@ -5,7 +5,7 @@ export * from './OnboardingAdmin';
export * from './PasskeyGate';
export * from './Plans';
export * from './Processes';
-export * from './ResourcePage';
+export * from './CapabilityPage';
export * from './Settings';
export * from './Skills';
export * from './TaskLogs';
diff --git a/src/workspaces/components/Workspace/PanelSlot.tsx b/src/workspaces/components/Workspace/PanelSlot.tsx
index 02e3f948..3f8541b4 100644
--- a/src/workspaces/components/Workspace/PanelSlot.tsx
+++ b/src/workspaces/components/Workspace/PanelSlot.tsx
@@ -1,4 +1,5 @@
import type { LayoutPanel, WidgetRegistry } from './types';
+import { Card } from '../Card';
import { WidgetPicker } from './WidgetPicker';
import { LayoutEditor } from './LayoutEditor';
@@ -20,10 +21,7 @@ export const PanelSlot = ({ panel, registry, editing, isLastPanel, onSetWidget,
if (!WidgetComponent) {
return (
-
+
onSetWidget(panel.id, type)} />
-
+
);
}
return (