diff --git a/apps/web/app/components/sidebar.tsx b/apps/web/app/components/sidebar.tsx
index 83c7b15b3b6..c0a6b42dd33 100644
--- a/apps/web/app/components/sidebar.tsx
+++ b/apps/web/app/components/sidebar.tsx
@@ -351,7 +351,7 @@ export function Sidebar({
const [mainMemory, setMainMemory] = useState(null);
const [dailyLogs, setDailyLogs] = useState([]);
const [workspaceTree, setWorkspaceTree] = useState([]);
- const [activeProfile, setActiveProfile] = useState("default");
+ const [activeWorkspace, setActiveWorkspace] = useState(null);
const [loading, setLoading] = useState(true);
const toggleSection = (section: SidebarSection) => {
@@ -368,19 +368,19 @@ export function Sidebar({
async function load() {
setLoading(true);
try {
- const [webSessionsRes, skillsRes, memoriesRes, workspaceRes, profilesRes] = await Promise.all([
+ const [webSessionsRes, skillsRes, memoriesRes, workspaceRes, workspaceListRes] = await Promise.all([
fetch("/api/web-sessions").then((r) => r.json()),
fetch("/api/skills").then((r) => r.json()),
fetch("/api/memories").then((r) => r.json()),
fetch("/api/workspace/tree").then((r) => r.json()).catch(() => ({ tree: [] })),
- fetch("/api/profiles").then((r) => r.json()).catch(() => ({ activeProfile: "default" })),
+ fetch("/api/workspace/list").then((r) => r.json()).catch(() => ({ activeWorkspace: null })),
]);
setWebSessions(webSessionsRes.sessions ?? []);
setSkills(skillsRes.skills ?? []);
setMainMemory(memoriesRes.mainMemory ?? null);
setDailyLogs(memoriesRes.dailyLogs ?? []);
setWorkspaceTree(workspaceRes.tree ?? []);
- setActiveProfile(String(profilesRes.activeProfile || "default"));
+ setActiveWorkspace((workspaceListRes.activeWorkspace ?? null) as string | null);
} catch (err) {
console.error("Failed to load sidebar data:", err);
} finally {
@@ -428,7 +428,9 @@ export function Sidebar({
- Profile: {activeProfile}
+
+ Workspace: {activeWorkspace ?? "none"}
+
{/* Content */}
diff --git a/apps/web/app/components/workspace/create-workspace-dialog.tsx b/apps/web/app/components/workspace/create-workspace-dialog.tsx
index 731b262d2d8..e8f61ae32e5 100644
--- a/apps/web/app/components/workspace/create-workspace-dialog.tsx
+++ b/apps/web/app/components/workspace/create-workspace-dialog.tsx
@@ -1,7 +1,6 @@
"use client";
import { useState, useRef, useEffect } from "react";
-import { DirectoryPickerModal } from "./directory-picker-modal";
type CreateWorkspaceDialogProps = {
isOpen: boolean;
@@ -16,17 +15,9 @@ function shortenPath(p: string): string {
.replace(/^[A-Za-z]:[/\\]Users[/\\][^/\\]+/, "~");
}
-function pathBasename(p: string): string {
- return p.replaceAll("\\", "/").split("/").pop() || p;
-}
-
export function CreateWorkspaceDialog({ isOpen, onClose, onCreated }: CreateWorkspaceDialogProps) {
- const [profileName, setProfileName] = useState("");
- const [customPath, setCustomPath] = useState("");
- const [useCustomPath, setUseCustomPath] = useState(false);
- const [showDirPicker, setShowDirPicker] = useState(false);
+ const [workspaceName, setWorkspaceName] = useState("");
const [seedBootstrap, setSeedBootstrap] = useState(true);
- const [copyConfigAuth, setCopyConfigAuth] = useState(true);
const [creating, setCreating] = useState(false);
const [error, setError] = useState(null);
const [result, setResult] = useState<{ workspaceDir: string; seededFiles: string[] } | null>(null);
@@ -36,30 +27,26 @@ export function CreateWorkspaceDialog({ isOpen, onClose, onCreated }: CreateWork
// Focus input on open
useEffect(() => {
if (isOpen) {
- setProfileName("");
- setCustomPath("");
- setUseCustomPath(false);
- setShowDirPicker(false);
- setCopyConfigAuth(true);
+ setWorkspaceName("");
setError(null);
setResult(null);
setTimeout(() => inputRef.current?.focus(), 100);
}
}, [isOpen]);
- // Close on Escape (only if dir picker is not open)
+ // Close on Escape.
useEffect(() => {
function handleKey(e: KeyboardEvent) {
- if (e.key === "Escape" && !showDirPicker) {onClose();}
+ if (e.key === "Escape") {onClose();}
}
if (isOpen) {
document.addEventListener("keydown", handleKey);
return () => document.removeEventListener("keydown", handleKey);
}
- }, [isOpen, onClose, showDirPicker]);
+ }, [isOpen, onClose]);
const handleCreate = async () => {
- const name = profileName.trim();
+ const name = workspaceName.trim();
if (!name) {
setError("Please enter a workspace name.");
return;
@@ -74,13 +61,9 @@ export function CreateWorkspaceDialog({ isOpen, onClose, onCreated }: CreateWork
try {
const body: Record = {
- profile: name,
+ workspace: name,
seedBootstrap,
- copyConfigAuth,
};
- if (useCustomPath && customPath.trim()) {
- body.path = customPath.trim();
- }
const res = await fetch("/api/workspace/init", {
method: "POST",
@@ -196,9 +179,9 @@ export function CreateWorkspaceDialog({ isOpen, onClose, onCreated }: CreateWork
{
- setProfileName(e.target.value);
+ setWorkspaceName(e.target.value);
setError(null);
}}
onKeyDown={(e) => {
@@ -216,91 +199,10 @@ export function CreateWorkspaceDialog({ isOpen, onClose, onCreated }: CreateWork
className="text-xs mt-1"
style={{ color: "var(--color-text-muted)" }}
>
- This creates a new profile with its own workspace directory.
+ This creates a workspace under ~/.openclaw-ironclaw/workspace-{"{name}"}.
- {/* Custom path toggle */}
-
-
-
- {useCustomPath && (
-
- {customPath ? (
-
-
-
-
- {pathBasename(customPath)}
-
-
- {shortenPath(customPath)}
-
-
-
-
-
- ) : (
-
- )}
-
- )}
-
-
{/* Bootstrap toggle */}
-
-
{error && (