diff --git a/packages/cli/src/commands/workspaces/update/command.ts b/packages/cli/src/commands/workspaces/update/command.ts new file mode 100644 index 00000000000..8889c956e21 --- /dev/null +++ b/packages/cli/src/commands/workspaces/update/command.ts @@ -0,0 +1,31 @@ +import { CLIError, positional, string } from "@superset/cli-framework"; +import { command } from "../../../lib/command"; + +export default command({ + description: "Update a workspace", + args: [positional("id").required().desc("Workspace UUID")], + options: { + name: string().desc("Workspace name"), + }, + run: async ({ ctx, args, options }) => { + const id = args.id as string; + const organizationId = ctx.config.organizationId; + if (!organizationId) { + throw new CLIError("No active organization", "Run: superset auth login"); + } + + if (options.name === undefined) { + throw new CLIError("No fields to update", "Pass --name "); + } + + const updated = await ctx.api.v2Workspace.update.mutate({ + id, + name: options.name, + }); + + return { + data: updated, + message: `Updated workspace ${id}`, + }; + }, +}); diff --git a/packages/mcp-v2/src/tools/register.ts b/packages/mcp-v2/src/tools/register.ts index 555d4c624b6..3d40aa6081a 100644 --- a/packages/mcp-v2/src/tools/register.ts +++ b/packages/mcp-v2/src/tools/register.ts @@ -27,6 +27,7 @@ import * as tasksUpdate from "./tasks/update"; import * as workspacesCreate from "./workspaces/create"; import * as workspacesDelete from "./workspaces/delete"; import * as workspacesList from "./workspaces/list"; +import * as workspacesUpdate from "./workspaces/update"; const REGISTRARS = [ tasksList, @@ -47,6 +48,7 @@ const REGISTRARS = [ automationsLogs, workspacesList, workspacesCreate, + workspacesUpdate, workspacesDelete, agentsRun, agentsList, diff --git a/packages/mcp-v2/src/tools/workspaces/update.ts b/packages/mcp-v2/src/tools/workspaces/update.ts new file mode 100644 index 00000000000..283f7ab54d7 --- /dev/null +++ b/packages/mcp-v2/src/tools/workspaces/update.ts @@ -0,0 +1,20 @@ +import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; +import { createMcpCaller } from "../../caller"; +import { defineTool } from "../../define-tool"; + +export function register(server: McpServer): void { + defineTool(server, { + name: "workspaces_update", + description: + "Update fields on an existing workspace. At least one field is required.", + inputSchema: { + id: z.string().uuid().describe("Workspace UUID."), + name: z.string().min(1).optional().describe("New workspace name."), + }, + handler: async (input, ctx) => { + const caller = createMcpCaller(ctx); + return caller.v2Workspace.update(input); + }, + }); +} diff --git a/packages/sdk/src/resources/workspaces.ts b/packages/sdk/src/resources/workspaces.ts index fb29d323bf8..8013a1a7437 100644 --- a/packages/sdk/src/resources/workspaces.ts +++ b/packages/sdk/src/resources/workspaces.ts @@ -58,6 +58,25 @@ export class Workspaces extends APIResource { ); } + /** + * Update fields on a workspace. At least one field is required. Currently + * only `name` is exposed — branch and host moves require host-side + * orchestration and aren't safe to set directly. + * + * Mirrors `superset workspaces update`. + */ + update( + id: string, + params: WorkspaceUpdateParams, + options?: RequestOptions, + ): APIPromise { + return this._client.mutation( + "v2Workspace.update", + { id, ...params }, + options, + ); + } + /** * Delete a workspace by id. Looks up the host the workspace lives on (via * the cloud index) and routes the delete to that host's service through @@ -179,6 +198,26 @@ export interface WorkspaceCreateResult { alreadyExists: boolean; } +export interface WorkspaceUpdateParams { + /** New workspace name. */ + name?: string; +} + +export interface WorkspaceUpdateResult { + id: string; + name: string; + branch: string; + organizationId: string; + projectId: string; + hostId: string; + type: "main" | "worktree"; + createdByUserId: string | null; + taskId: string | null; + createdAt: Date; + updatedAt: Date; + txid: number; +} + export interface WorkspaceDeleteResult { [key: string]: unknown; } @@ -193,6 +232,8 @@ export declare namespace Workspaces { WorkspaceAgentLaunch, WorkspaceCreateAgentResult, WorkspaceCreateResult, + WorkspaceUpdateParams, + WorkspaceUpdateResult, WorkspaceDeleteResult, }; } diff --git a/skills/superset/SKILL.md b/skills/superset/SKILL.md index f46ea9e514d..02ef88b2914 100644 --- a/skills/superset/SKILL.md +++ b/skills/superset/SKILL.md @@ -32,6 +32,7 @@ If `$SUPERSET_WORKSPACE_ID` is unset, you're not inside a Superset workspace — superset workspaces create --project --host --name "..." --branch superset workspaces create --project --local --name "..." --pr superset workspaces list [--host | --local] +superset workspaces update --name "..." superset workspaces delete [...] ```