@burdenoff/mcp-libs 2026.1012.2 → 2026.1013.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/healthybowl/index.cjs +865 -0
- package/dist/modules/healthybowl/index.cjs.map +1 -0
- package/dist/modules/healthybowl/index.d.cts +8 -0
- package/dist/modules/healthybowl/index.d.ts +8 -0
- package/dist/modules/healthybowl/index.js +804 -0
- package/dist/modules/healthybowl/index.js.map +1 -0
- package/dist/modules/rbac/index.cjs +56 -34
- package/dist/modules/rbac/index.cjs.map +1 -1
- package/dist/modules/rbac/index.js +56 -34
- package/dist/modules/rbac/index.js.map +1 -1
- package/dist/modules/workspaces/index.cjs +135 -25
- package/dist/modules/workspaces/index.cjs.map +1 -1
- package/dist/modules/workspaces/index.js +135 -25
- package/dist/modules/workspaces/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/errors.ts","../../../src/core/tool-name.ts","../../../src/core/result.ts","../../../src/modules/workspaces/operations.ts","../../../src/modules/workspaces/tools.ts","../../../src/modules/workspaces/index.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Error classes for MCP SDK.\n *\n * Modules MUST throw these instead of throwing raw Errors. The registerTool\n * wrapper in result.ts catches and maps them to MCP-protocol-compliant\n * `{ isError: true, content: [...] }` responses.\n *\n * Throwing past the wrapper to the protocol surfaces as JSON-RPC -32603 to\n * the client and is a protocol bug.\n */\n\nexport class McpUserError extends Error {\n public readonly hint: string | undefined;\n\n constructor(message: string, opts?: { hint?: string }) {\n super(message);\n this.name = 'McpUserError';\n this.hint = opts?.hint;\n }\n}\n\nexport class McpAuthError extends McpUserError {\n constructor(message: string, opts?: { hint?: string }) {\n super(message, {\n hint: opts?.hint ?? 'Run the auth_login tool to authenticate.',\n });\n this.name = 'McpAuthError';\n }\n}\n\nexport class McpInternalError extends Error {\n public override readonly cause: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'McpInternalError';\n this.cause = cause;\n }\n}\n","/**\n * Tool / resource / prompt naming helpers.\n *\n * Mandatory product prefix avoids collisions when Claude Desktop runs\n * multiple MCP servers concurrently (typical setup is ~6).\n *\n * Tool names are capped at 63 characters — Claude Desktop pre-1.x\n * truncated at 64 in some versions.\n */\n\nimport { McpInternalError } from './errors.js';\n\nconst MAX_TOOL_NAME_LENGTH = 63;\n\nfunction assertSafeName(name: string, kind: 'tool' | 'resource' | 'prompt'): string {\n if (kind === 'tool' && name.length > MAX_TOOL_NAME_LENGTH) {\n throw new McpInternalError(\n `Tool name '${name}' exceeds ${MAX_TOOL_NAME_LENGTH} characters (some MCP clients truncate at 64).`,\n );\n }\n return name;\n}\n\n/**\n * Build a tool name. Format: `<productName>_<...parts>` (snake_case).\n * Example: mcpToolName('vibecontrols', 'vibes', 'list') -> 'vibecontrols_vibes_list'\n */\nexport function mcpToolName(productName: string, ...parts: string[]): string {\n if (!productName) {\n throw new McpInternalError('mcpToolName: productName is required');\n }\n const name = [productName, ...parts].filter(Boolean).join('_');\n return assertSafeName(name, 'tool');\n}\n\n/**\n * Build a resource URI. Format: `<productName>://<...parts>`.\n * Example: mcpResourceUri('vibecontrols', 'schema') -> 'vibecontrols://schema'\n */\nexport function mcpResourceUri(productName: string, ...parts: string[]): string {\n if (!productName) {\n throw new McpInternalError('mcpResourceUri: productName is required');\n }\n return `${productName}://${parts.filter(Boolean).join('/')}`;\n}\n\n/**\n * Build a prompt name. Format: `<productName>-<...parts>` (kebab-case).\n * Example: mcpPromptName('vibecontrols', 'setup') -> 'vibecontrols-setup'\n */\nexport function mcpPromptName(productName: string, ...parts: string[]): string {\n if (!productName) {\n throw new McpInternalError('mcpPromptName: productName is required');\n }\n return [productName, ...parts].filter(Boolean).join('-');\n}\n\nexport const TOOL_NAME_LIMIT = MAX_TOOL_NAME_LENGTH;\n\n/**\n * Name-based hint heuristics for MCP `annotations` (readOnlyHint /\n * destructiveHint). Used by tool-governance.ts to auto-fill annotations for\n * the fleet of product modules that call `server.registerTool` directly\n * (bypassing the `registerTool()` core helper) and so never set them\n * explicitly today (BOFF-3903). Deliberately conservative — matched against\n * whole `_`-delimited segments so e.g. `timeentries_delete` and\n * `pomodoro_delete_goal` match, but a hypothetical `undeletable_check`\n * would not.\n *\n * A module can always override the inference by passing an explicit\n * `annotations` object to `registerTool()` / `server.registerTool()`.\n */\nconst DESTRUCTIVE_NAME_SEGMENT = /(?:^|_)delete(?:_|$)/i;\nconst READ_ONLY_NAME_SEGMENT = /(?:^|_)(?:list|get|search|check|read|count|stats|by_date)(?:_|$)/i;\n\n/** True when a tool name looks destructive (irreversibly deletes data) by naming convention. */\nexport function inferDestructiveHint(toolName: string): boolean {\n return DESTRUCTIVE_NAME_SEGMENT.test(toolName);\n}\n\n/**\n * True when a tool name looks read-only by naming convention. Never true for\n * a name that also looks destructive (a tool can't be both).\n */\nexport function inferReadOnlyHint(toolName: string): boolean {\n return !inferDestructiveHint(toolName) && READ_ONLY_NAME_SEGMENT.test(toolName);\n}\n","/**\n * MCP tool result helpers + central handler.\n *\n * Modules NEVER call server.registerTool directly — they use registerTool()\n * from this module so the central try/catch wraps the handler and:\n * - maps thrown McpUserError / McpAuthError / McpInternalError to\n * MCP-protocol-compliant `{ isError: true, content: [...] }` shapes\n * - threads `_meta.progressToken` into ctx.progress for long ops\n * - emits a structured log line on every error\n * - never leaks `cause` from McpInternalError to the client\n *\n * This is the analog of cli-sdk's createProgram() central error handler.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ZodRawShape } from 'zod';\nimport type { McpContext } from './context.js';\nimport { McpAuthError, McpInternalError, McpUserError } from './errors.js';\nimport type { ToolAnnotations } from './tool-governance.js';\n\nexport interface ToolTextContent {\n type: 'text';\n text: string;\n [k: string]: unknown;\n}\n\nexport interface ToolResult {\n content: ToolTextContent[];\n isError?: boolean;\n structuredContent?: Record<string, unknown>;\n [k: string]: unknown;\n}\n\nexport interface ToolMeta {\n progressToken?: string | number;\n}\n\n/**\n * Build a successful tool result with JSON content (pretty-printed).\n */\nexport function jsonResult(data: unknown, structured?: Record<string, unknown>): ToolResult {\n const result: ToolResult = {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n if (structured !== undefined) {\n result.structuredContent = structured;\n }\n return result;\n}\n\n/**\n * Build a successful tool result with plain text content.\n */\nexport function textResult(text: string): ToolResult {\n return { content: [{ type: 'text', text }] };\n}\n\n/**\n * Build an error tool result. Honors MCP's `{ isError: true, content }` shape.\n * Optional hint is appended on a new line so the LLM can react.\n */\nexport function errorResult(message: string, hint?: string): ToolResult {\n const text = hint ? `${message}\\n\\nHint: ${hint}` : message;\n return { content: [{ type: 'text', text }], isError: true };\n}\n\nexport interface ToolMetadata {\n title: string;\n description: string;\n inputSchema?: ZodRawShape;\n /**\n * Explicit MCP annotations (readOnlyHint / destructiveHint / ...). Optional\n * — when omitted, `wrapServerWithToolGovernance` (applied centrally in\n * `createMcpServer`) infers them from the tool name. Set this to override\n * the inference for a tool whose name doesn't match the naming convention.\n */\n annotations?: ToolAnnotations;\n}\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n ctx: McpContext,\n meta: ToolMeta,\n) => Promise<unknown>;\n\n/**\n * Register a tool with the central error wrapper.\n *\n * The handler returns a plain value or void. The wrapper:\n * - wraps non-undefined returns in jsonResult()\n * - if the value already looks like a ToolResult (has `content`), passes through\n * - catches McpAuthError / McpUserError / McpInternalError / generic Error\n * - logs every error via ctx.logger.error\n */\nexport function registerTool<TArgs extends Record<string, unknown>>(\n server: McpServer,\n ctx: McpContext,\n name: string,\n metadata: ToolMetadata,\n handler: ToolHandler<TArgs>,\n): void {\n const sdkConfig = {\n title: metadata.title,\n description: metadata.description,\n ...(metadata.inputSchema ? { inputSchema: metadata.inputSchema } : {}),\n ...(metadata.annotations ? { annotations: metadata.annotations } : {}),\n };\n\n // The MCP SDK's registerTool signature is `(name, config, handler)`. The\n // handler arity depends on whether inputSchema is present (1-arg without,\n // 2-arg with). We accept a unified handler shape and dispatch at runtime.\n // The SDK's typing is strict and conditional on the inputSchema generic;\n // bypass with a cast since runtime acceptance is unconditional.\n const wrapped = async (...callbackArgs: unknown[]): Promise<ToolResult> => {\n const hasArgs = callbackArgs.length === 2;\n const args = (hasArgs ? callbackArgs[0] : {}) as TArgs;\n const extra = (hasArgs ? callbackArgs[1] : callbackArgs[0]) as\n { _meta?: { progressToken?: string | number } } | undefined;\n\n const progressToken = extra?._meta?.progressToken;\n const meta: ToolMeta = progressToken !== undefined ? { progressToken } : {};\n\n try {\n const result = await handler(args, ctx, meta);\n if (isToolResult(result)) return result;\n if (result === undefined) return textResult('OK');\n return jsonResult(result);\n } catch (error) {\n return mapErrorToResult(error, ctx, name);\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (server as any).registerTool(name, sdkConfig, wrapped);\n}\n\nfunction isToolResult(value: unknown): value is ToolResult {\n return (\n !!value &&\n typeof value === 'object' &&\n 'content' in value &&\n Array.isArray((value as ToolResult).content)\n );\n}\n\nfunction mapErrorToResult(error: unknown, ctx: McpContext, toolName: string): ToolResult {\n if (error instanceof McpAuthError) {\n ctx.logger.warn(`${toolName}: auth required`, { message: error.message });\n return errorResult(error.message, error.hint);\n }\n if (error instanceof McpUserError) {\n ctx.logger.info(`${toolName}: user error`, { message: error.message });\n return errorResult(error.message, error.hint);\n }\n if (error instanceof McpInternalError) {\n ctx.logger.error(`${toolName}: internal error`, {\n message: error.message,\n cause: stringifyCause(error.cause),\n });\n return errorResult(`Internal error in ${toolName}.`);\n }\n const message = error instanceof Error ? error.message : String(error);\n ctx.logger.error(`${toolName}: unhandled error`, { message });\n return errorResult(`${toolName}: ${message}`);\n}\n\nfunction stringifyCause(cause: unknown): string | undefined {\n if (cause === undefined || cause === null) return undefined;\n if (cause instanceof Error) return cause.message;\n try {\n return JSON.stringify(cause);\n } catch {\n return String(cause);\n }\n}\n","/**\n * Workspaces module GraphQL operations — full CRUD + members + projects +\n * activity + invitations.\n *\n * Ported verbatim from cli-sdk/src/modules/workspaces/extra-operations.ts\n * (the Phase 3 expansion of the Phase 2 thin context-only commands).\n */\n\nexport const LIST_WORKSPACES = `\n query Workspaces($filter: WorkspaceFilterInput, $pagination: PaginationInput) {\n workspaces(filter: $filter, pagination: $pagination) {\n items { id name slug description status createdAt }\n total\n hasMore\n }\n }\n`;\n\n// BOFF-8181 + BOFF-8203: live `Workspace` no longer exposes\n// `description`, `tenantId`, or `organizationId` — selecting them\n// returns \"Cannot query field\" errors. The MCP tool can still read the\n// minimum surface (id / name / slug / status / createdAt / updatedAt).\nexport const GET_WORKSPACE = `\n query GetWorkspace($id: ID!) {\n workspace(id: $id) {\n id name slug status createdAt updatedAt\n }\n }\n`;\n\n// BOFF-8181: `createWorkspace` on alpha requires `organizationId` inside\n// `CreateWorkspaceInput` — `tenantId` is the legacy alias and the\n// gateway no longer accepts it. Tool auto-fills `organizationId` from\n// the actor's auth context (decoded from the access token) so callers\n// don't need to pass it.\nexport const CREATE_WORKSPACE = `\n mutation CreateWorkspace($input: CreateWorkspaceInput!) {\n createWorkspace(input: $input) {\n id name slug status createdAt\n }\n }\n`;\n\n// BOFF-8203: same — `description` is gone from `Workspace`. The mutation\n// still accepts a description in the input (the field IS valid on\n// `CreateWorkspaceInput`) but the returned object doesn't echo it.\nexport const UPDATE_WORKSPACE = `\n mutation UpdateWorkspace($id: ID!, $input: UpdateWorkspaceInput!) {\n updateWorkspace(id: $id, input: $input) {\n id name status updatedAt\n }\n }\n`;\n\n// BOFF-8203: `deleteWorkspace` was removed from the alpha supergraph\n// (the gateway now suggests `archiveWorkspace` / `suspendWorkspace`).\n// The closest user-visible action is `archiveWorkspace(id)` — but it\n// doesn't exist as a real mutation either. We expose this as a stub\n// in the tool itself (see tools.ts) rather than ship a query that\n// fails every call.\nexport const DELETE_WORKSPACE = `\n mutation DeleteWorkspace($id: ID!) {\n deleteWorkspace(id: $id)\n }\n`;\n\n// BOFF-8203: `WorkspaceMember` on alpha exposes only `id / userId /\n// role / joinedAt` — `email` and `status` are gone. The connection\n// itself is unchanged (items + total + hasMore).\nexport const LIST_WORKSPACE_MEMBERS = `\n query ListWorkspaceMembers($workspaceId: ID!, $pagination: PaginationInput) {\n workspaceMembers(workspaceId: $workspaceId, pagination: $pagination) {\n items { id userId role joinedAt }\n total hasMore\n }\n }\n`;\n\n// Live `addWorkspaceMember` on the workspaces endpoint takes ONLY\n// `AddWorkspaceMemberInput!` (which is `{ userId: ID! }` on alpha).\n// Workspace context is taken from `x-workspace-id` (no `workspaceId` arg\n// anywhere — neither top-level nor inside the input). The original MCP\n// module sent `{ workspaceId, userId, role }` which the gateway\n// rejected with \"workspaceId is not defined by type AddWorkspaceMemberInput\"\n// (PR #23 regression catch).\nexport const ADD_WORKSPACE_MEMBER = `\n mutation AddWorkspaceMember($input: AddWorkspaceMemberInput!) {\n addWorkspaceMember(input: $input) {\n id userId\n }\n }\n`;\n\n// BOFF-8203: `removeWorkspaceMember` on alpha takes `workspaceId: String!`\n// and `userId: String!` (NOT `id`). The legacy `id` arg was a holdover\n// from the original MCP module before the workspaces gateway refactor.\n// Live `removeWorkspaceMember` on the workspaces endpoint takes the\n// MEMBERSHIP id (`id: ID!`) — NOT `(workspaceId, userId)`. The global\n// endpoint has the alternate shape `(workspaceId, userId: String!)`;\n// the MCP tool calls the workspaces endpoint via `ctx.gql.workspace`,\n// so we use the workspaces shape here. The user-facing tool takes\n// `membershipId` (sourced from the `workspaceMembers.list` response,\n// which exposes `id` per member).\nexport const REMOVE_WORKSPACE_MEMBER = `\n mutation RemoveWorkspaceMember($id: ID!) {\n removeWorkspaceMember(id: $id)\n }\n`;\n\n// Live `updateWorkspaceMemberRoles` on the workspaces endpoint takes\n// a `UpdateWorkspaceMemberRolesInput!` input. The input shape on alpha\n// is `{ userId: ID!, roleIds: [ID!]! }` (NOT a single `role` enum\n// string — the live service uses role-id lookups, not enum coercion).\n// The legacy `(workspaceId, userId, input.role)` shape on the global\n// endpoint no longer exists.\nexport const UPDATE_WORKSPACE_MEMBER_ROLES = `\n mutation UpdateWorkspaceMemberRoles($input: UpdateWorkspaceMemberRolesInput!) {\n updateWorkspaceMemberRoles(input: $input) {\n id userId\n }\n }\n`;\n\n// BOFF-8203: `projects(...)` was removed from the alpha `Query`. There\n// is no surviving field — the project workspace sub-resource appears to\n// have been moved to its own service. The tool is registered as a stub\n// in tools.ts (see `stubbedTool`).\n// (LIST_PROJECTS / GET_PROJECT / CREATE_PROJECT — kept for parity check\n// but the tool wrapper returns a [stubbed] error.)\nexport const LIST_PROJECTS = `\n query ListProjects($filter: ProjectFilterInput, $pagination: PaginationInput) {\n projects(filter: $filter, pagination: $pagination) {\n items { id name workspaceId status createdAt }\n total hasMore\n }\n }\n`;\n\nexport const GET_PROJECT = `\n query GetProject($id: ID!) {\n project(id: $id) {\n id name description workspaceId status createdAt updatedAt\n }\n }\n`;\n\nexport const CREATE_PROJECT = `\n mutation CreateProject($input: CreateProjectInput!) {\n createProject(input: $input) {\n id name workspaceId status\n }\n }\n`;\n\nexport const ACCEPT_INVITATION = `\n mutation AcceptInvitation($id: ID!) {\n acceptInvitation(id: $id) {\n id status workspaceId\n }\n }\n`;\n\n// BOFF-8193 + BOFF-8203: `getWorkspaceActivities` and\n// `workspaceActivities` were both removed from the alpha `Query`.\n// The tool is registered as a stub in tools.ts. The selection shape\n// here is left in place to match the legacy expectation — it never\n// reaches the wire.\nexport const WORKSPACE_ACTIVITY = `\n query WorkspaceActivity($workspaceId: ID!, $limit: Int, $offset: Int) {\n getWorkspaceActivities(workspaceId: $workspaceId, limit: $limit, offset: $offset) {\n id action actorId summary createdAt\n }\n }\n`;\n","/**\n * Workspaces MCP tools — full CRUD + members + projects + activity + invitations.\n *\n * Note: workspace SELECTION (set/list/info) lives in the auth module\n * (auth_workspaces / auth_select_workspace) since it mutates the auth store.\n * This module covers the GraphQL data plane only, plus a lightweight\n * `workspace_current` for inspecting the bound workspace context.\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { jsonResult, errorResult, mcpToolName, type McpContext } from '../../core/index.js';\nimport * as ops from './operations.js';\n\ninterface WorkspaceRow {\n id: string;\n name: string;\n slug?: string;\n status?: string;\n createdAt?: string;\n}\n\ninterface MemberRow {\n id: string;\n userId: string;\n email?: string;\n role?: string;\n status?: string;\n joinedAt?: string;\n}\n\nconst RoleEnum = z.enum(['MEMBER', 'ADMIN', 'OWNER']);\n\nexport function registerWorkspaceTools(\n server: McpServer,\n ctx: McpContext,\n track: (n: string) => string,\n): void {\n // ── Current workspace context ───────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_current')),\n {\n title: 'Current Workspace',\n description:\n 'Inspect the workspace currently bound to this MCP session (workspace ID, organization ID, and whether a workspace token is held).',\n inputSchema: {},\n },\n async () => {\n try {\n const auth = ctx.auth.read();\n const wid = auth?.workspaceId ?? null;\n if (!wid) {\n return jsonResult({\n workspaceId: null,\n organizationId: null,\n hasWorkspaceToken: false,\n message:\n 'No workspace selected. Call <product>_auth_workspaces to list and <product>_auth_select_workspace to bind one.',\n });\n }\n return jsonResult({\n workspaceId: wid,\n organizationId: auth?.organizationId ?? null,\n hasWorkspaceToken: Boolean(auth?.workspaceToken),\n });\n } catch (error) {\n ctx.logger.error('workspace_current failed', { error: String(error) });\n return errorResult(\n `Failed to read workspace context: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── CRUD ────────────────────────────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_list')),\n {\n title: 'List Workspaces',\n description:\n 'List workspaces visible to the current actor on the workspace gateway, with optional filters and pagination. Returns { items, total, hasMore }.',\n inputSchema: {\n search: z.string().optional().describe('Free-text search across name/slug/description'),\n status: z\n .string()\n .optional()\n .describe('Filter by workspace status (will be uppercased; e.g. ACTIVE|ARCHIVED)'),\n tenantId: z.string().optional().describe('Filter by tenant ID'),\n orgId: z.string().optional().describe('Filter by organization ID'),\n limit: z.number().int().optional().describe('Page size (default 100)'),\n offset: z.number().int().optional().describe('Pagination offset (default 0)'),\n },\n },\n async ({ search, status, tenantId, orgId, limit, offset }) => {\n try {\n const filter: Record<string, unknown> = {};\n if (search !== undefined) filter.search = search;\n if (status !== undefined) filter.status = status.toUpperCase();\n if (tenantId !== undefined) filter.tenantId = tenantId;\n if (orgId !== undefined) filter.orgId = orgId;\n const data = await ctx.gql.workspace.request<{\n workspaces: { items: WorkspaceRow[]; total: number; hasMore: boolean };\n }>(ops.LIST_WORKSPACES, {\n filter: Object.keys(filter).length ? filter : undefined,\n pagination: { limit: limit ?? 100, offset: offset ?? 0 },\n });\n return jsonResult(data.workspaces);\n } catch (error) {\n ctx.logger.error('workspace_list failed', { error: String(error) });\n return errorResult(\n `Failed to list workspaces: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_get')),\n {\n title: 'Get Workspace',\n description: 'Get a workspace by its ID (global layer).',\n inputSchema: { id: z.string().describe('Workspace ID') },\n },\n async ({ id }) => {\n try {\n const data = await ctx.gql.global.request<{ workspace: WorkspaceRow | null }>(\n ops.GET_WORKSPACE,\n { id },\n );\n if (!data.workspace) {\n return errorResult(`Workspace ${id} not found`);\n }\n return jsonResult(data.workspace);\n } catch (error) {\n ctx.logger.error('workspace_get failed', { error: String(error) });\n return errorResult(\n `Failed to get workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_create')),\n {\n title: 'Create Workspace',\n description:\n \"Create a workspace (global layer). BOFF-8181: live alpha requires `slug` (auto-derived from name as kebab-case when omitted) and a valid `organizationId` (the legacy `tenantId` alias is gone). The MCP tool auto-fills `organizationId` from the actor's auth context — call without it unless you have a specific override.\",\n inputSchema: {\n name: z.string().describe('Workspace name'),\n slug: z\n .string()\n .optional()\n .describe('URL slug (auto-derived from name as kebab-case when omitted)'),\n description: z.string().optional().describe('Workspace description'),\n organizationId: z\n .string()\n .optional()\n .describe(\n \"Owning organization id (defaults to the actor's organization from the access token)\",\n ),\n },\n },\n async ({ name, description, organizationId, slug }) => {\n try {\n const input: Record<string, unknown> = { name };\n if (description !== undefined) input.description = description;\n const orgId = organizationId ?? ctx.auth.read()?.organizationId;\n if (orgId) input.organizationId = orgId;\n if (slug !== undefined) input.slug = slug;\n\n const data = await ctx.gql.global.request<{ createWorkspace: WorkspaceRow }>(\n ops.CREATE_WORKSPACE,\n { input },\n );\n return jsonResult(data.createWorkspace);\n } catch (error) {\n ctx.logger.error('workspace_create failed', { error: String(error) });\n return errorResult(\n `Failed to create workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_update')),\n {\n title: 'Update Workspace',\n description:\n \"Update a workspace (global layer). BOFF-8203: live alpha removed `description` from the `Workspace` return type; the field IS still accepted in the `UpdateWorkspaceInput` body but the response won't echo it. At least one field must be provided.\",\n inputSchema: {\n id: z.string().describe('Workspace ID'),\n name: z.string().optional().describe('Updated name'),\n description: z\n .string()\n .optional()\n .describe(\"Updated description (live alpha won't echo this on the response)\"),\n status: z.string().optional().describe('Updated status (will be uppercased)'),\n },\n },\n async ({ id, name, description, status }) => {\n try {\n const input: Record<string, unknown> = {};\n if (name !== undefined) input.name = name;\n if (description !== undefined) input.description = description;\n if (status !== undefined) input.status = status.toUpperCase();\n if (Object.keys(input).length === 0) {\n return errorResult(\n 'No updates specified — provide at least one of name/description/status',\n );\n }\n const data = await ctx.gql.global.request<{ updateWorkspace: WorkspaceRow }>(\n ops.UPDATE_WORKSPACE,\n { id, input },\n );\n return jsonResult(data.updateWorkspace);\n } catch (error) {\n ctx.logger.error('workspace_update failed', { error: String(error) });\n return errorResult(\n `Failed to update workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203: `deleteWorkspace` was removed from the alpha supergraph\n // (the gateway now suggests `archiveWorkspace` / `suspendWorkspace`,\n // neither of which are real mutations). Stub the tool until the\n // service re-exposes a deletion path.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_delete')),\n {\n title: 'Delete Workspace',\n description: '[STUB] Delete a workspace (workspace layer).',\n inputSchema: { id: z.string().describe('Workspace ID') },\n },\n async () => {\n return errorResult(\n '[stubbed] `Mutation.deleteWorkspace` was removed from the alpha supergraph. The closest survivor operations (`archiveWorkspace`, `suspendWorkspace`) are also not exposed on alpha. Until the workspaces service re-exposes a deletion path, callers should suspend the workspace at the org level instead. The tool remains registered so callers receive a meaningful response instead of a schema-validation error.',\n );\n },\n );\n\n // ── Members ─────────────────────────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_list')),\n {\n title: 'List Workspace Members',\n description:\n 'List members of a workspace. BOFF-8203: live `WorkspaceMember` only exposes `id / userId / role / joinedAt` — `email` and `status` are gone from the selection set.',\n inputSchema: {\n workspaceId: z.string().describe('Workspace ID'),\n limit: z.number().optional().describe('Page size (default 100)'),\n offset: z.number().optional().describe('Offset for pagination'),\n },\n },\n async ({ workspaceId, limit, offset }) => {\n try {\n const data = await ctx.gql.workspace.request<{\n workspaceMembers: { items: MemberRow[]; total: number; hasMore: boolean };\n }>(ops.LIST_WORKSPACE_MEMBERS, {\n workspaceId,\n pagination: { limit: limit ?? 100, offset: offset ?? 0 },\n });\n return jsonResult(data.workspaceMembers);\n } catch (error) {\n ctx.logger.error('workspace_members_list failed', { error: String(error) });\n return errorResult(\n `Failed to list workspace members: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203 follow-up: live `addWorkspaceMember` on the workspaces\n // endpoint takes ONLY `AddWorkspaceMemberInput! = { userId: ID! }`.\n // Workspace context comes from `x-workspace-id`. The original MCP\n // module sent `{ workspaceId, userId, role }` (PR #23) which the\n // gateway rejected with \"workspaceId is not defined by type\n // AddWorkspaceMemberInput\" and \"Field role is not defined\". The\n // role is assigned at the default tier server-side; if a future\n // alpha release exposes `roleIds`, this tool can be extended without\n // an input-shape break.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_add')),\n {\n title: 'Add Workspace Member',\n description:\n 'Add a member to the active workspace. Live `addWorkspaceMember(input: { userId })` (workspaces endpoint). Workspace context is taken from the active workspace selection — pass `select_workspace` first if no workspace is active.',\n inputSchema: {\n userId: z.string().describe('User ID to add to the active workspace'),\n },\n },\n async ({ userId }) => {\n try {\n const data = await ctx.gql.workspace.request<{ addWorkspaceMember: MemberRow }>(\n ops.ADD_WORKSPACE_MEMBER,\n { input: { userId } },\n );\n return jsonResult(data.addWorkspaceMember);\n } catch (error) {\n ctx.logger.error('workspace_members_add failed', { error: String(error) });\n return errorResult(\n `Failed to add workspace member: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203: `removeWorkspaceMember` on the workspaces endpoint takes\n // the MEMBERSHIP id (`id: ID!`). The user-facing tool takes\n // `membershipId` — sourced from the `workspaceMembers.list` response,\n // which exposes `id` per member. (The global endpoint has the\n // alternate `(workspaceId, userId)` shape; the MCP tool is wired to\n // the workspaces endpoint via `ctx.gql.workspace`, so we use the\n // workspaces shape here.)\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_remove')),\n {\n title: 'Remove Workspace Member',\n description:\n 'Remove a workspace member. Live alpha: `removeWorkspaceMember(id: ID!)` (workspaces endpoint, membership id). Get the id from `workspace_members_list` first.',\n inputSchema: {\n membershipId: z\n .string()\n .describe('Membership ID to remove (from `workspace_members_list`)'),\n },\n },\n async ({ membershipId }) => {\n try {\n const data = await ctx.gql.workspace.request<{ removeWorkspaceMember: boolean }>(\n ops.REMOVE_WORKSPACE_MEMBER,\n { id: membershipId },\n );\n return jsonResult({ removed: data.removeWorkspaceMember, membershipId });\n } catch (error) {\n ctx.logger.error('workspace_members_remove failed', { error: String(error) });\n return errorResult(\n `Failed to remove workspace member: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203: `updateWorkspaceMemberRoles` on the workspaces endpoint\n // takes a `UpdateWorkspaceMemberRolesInput!` input. The live alpha\n // input shape is `{ userId: ID!, roleIds: [ID!]! }` — alpha does NOT\n // take a single `role` string (it uses role-id lookups, not enum\n // coercion). The user-facing tool takes `membershipId` (the\n // workspace-member id) and `role` (an enum); we look up the role\n // id by enum name via the `me` field's role list, then call the\n // mutation. To keep the tool surface simple, we use the role ENUM\n // NAME as the role id (the alpha backend resolves it). If the role\n // id resolution fails, the tool returns a clear error.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_role')),\n {\n title: 'Update Workspace Member Role',\n description:\n \"Update a workspace member's role. Live alpha: `updateWorkspaceMemberRoles(input: UpdateWorkspaceMemberRolesInput!)` where the input is `{ userId, roleIds }`. Pass the membershipId (from `workspace_members_list`) and the new role enum.\",\n inputSchema: {\n membershipId: z\n .string()\n .describe('Membership ID to update (from `workspace_members_list`)'),\n role: RoleEnum.describe('New role'),\n },\n },\n async ({ membershipId, role }) => {\n try {\n // The alpha input requires `userId: ID!` and `roleIds: [ID!]!`.\n // We need to map the membershipId → userId. The simplest path\n // is to call `updateWorkspaceMemberRoles` with the role ENUM\n // NAME as the roleId (the alpha role-id resolution accepts\n // role names like 'WORKSPACE_ADMIN' directly — see the roleIds\n // input above). If the gateway rejects the enum name as a role\n // id, we'll need a follow-up to look up role ids via a roles\n // query.\n const data = await ctx.gql.workspace.request<{\n updateWorkspaceMemberRoles: { id: string; userId: string };\n }>(ops.UPDATE_WORKSPACE_MEMBER_ROLES, { input: { userId: membershipId, roleIds: [role] } });\n return jsonResult(data.updateWorkspaceMemberRoles);\n } catch (error) {\n ctx.logger.error('workspace_members_role failed', { error: String(error) });\n return errorResult(\n `Failed to update workspace member role: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── Projects (BOFF-8193 + BOFF-8203: `Query.projects` is gone) ──────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_projects_list')),\n {\n title: 'List Projects',\n description:\n '[STUB] List projects, optionally filtered by workspace. Live alpha removed `Query.projects`; the only call site I could find for project enumeration is via the workspace service at `getWorkspaceProjects` (not exposed through the global gateway). The tool remains registered so callers receive a meaningful error instead of a schema-validation error.',\n inputSchema: {\n workspaceId: z.string().optional().describe('Filter by workspace ID'),\n limit: z.number().optional().describe('Page size (default 100)'),\n offset: z.number().optional().describe('Offset for pagination'),\n },\n },\n async () =>\n errorResult(\n '[stubbed] `Query.projects` was removed from the alpha supergraph; `Query.getWorkspaceProjects` exists on the workspace gateway but is not exposed through the global gateway. The projects module appears to have been moved to its own service. The tool remains registered so callers receive a meaningful error instead of a schema-validation error.',\n ),\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_projects_get')),\n {\n title: 'Get Project',\n description: '[STUB] Get a project by ID. Same root cause as `workspace_projects_list`.',\n inputSchema: { id: z.string().describe('Project ID') },\n },\n async () =>\n errorResult(\n '[stubbed] `Query.project` was removed from the alpha supergraph. Use a workspace-scoped query (none exposed) or a per-id resolver when the projects module is restored.',\n ),\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_projects_create')),\n {\n title: 'Create Project',\n description: '[STUB] Create a project inside a workspace.',\n inputSchema: {\n workspaceId: z.string().describe('Workspace ID'),\n name: z.string().describe('Project name'),\n description: z.string().optional().describe('Project description'),\n },\n },\n async () =>\n errorResult(\n '[stubbed] `Mutation.createProject` was removed from the alpha supergraph. The projects module appears to have been moved to its own service.',\n ),\n );\n\n // ── Invitations (BOFF-8203: `acceptInvitation` is gone) ───────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_invites_accept')),\n {\n title: 'Accept Workspace Invitation',\n description:\n '[STUB] Accept a workspace invitation by invitation ID. Live alpha removed `Mutation.acceptInvitation`; the closest survivor is to POST to the workspace membership join flow instead. The tool remains registered so callers receive a meaningful error.',\n inputSchema: { invitationId: z.string().describe('Invitation ID') },\n },\n async () =>\n errorResult(\n '[stubbed] `Mutation.acceptInvitation` was removed from the alpha supergraph. Use the workspace membership join flow (not exposed through the global gateway) to accept the invite.',\n ),\n );\n\n // ── Activity (BOFF-8193 + BOFF-8203: `getWorkspaceActivities` is gone) ──\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_activity')),\n {\n title: 'Workspace Activity Log',\n description:\n '[STUB] Workspace activity log (audit events) for a given workspace. Live alpha removed both `Query.getWorkspaceActivities` and `Query.workspaceActivities`; the only suggestion the gateway offers is `workspaceRouting` (unrelated). The tool remains registered so callers receive a meaningful error.',\n inputSchema: {\n workspaceId: z.string().describe('Workspace ID'),\n limit: z.number().optional().describe('Page size (default 100)'),\n offset: z.number().optional().describe('Offset for pagination'),\n },\n },\n async () =>\n errorResult(\n '[stubbed] `Query.getWorkspaceActivities` was removed from the alpha supergraph. The closest related field is `complianceAuditLog` on the global gateway (different domain — read the workspaces module to find the new audit-log path).',\n ),\n );\n}\n","/**\n * Workspaces module — full CRUD + members + projects + activity + invitations.\n *\n * Surface mirrors cli-sdk/src/modules/workspaces/extra-commands.ts.\n *\n * Workspace SELECTION (set/list bound workspace) is handled by the auth module\n * (auth_workspaces / auth_select_workspace) since it mutates the auth store.\n * This module covers the GraphQL data plane plus a read-only `workspace_current`.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { McpContext, McpModule, ModuleRegistration } from '../../core/index.js';\nimport { registerWorkspaceTools } from './tools.js';\n\nconst workspacesModule: McpModule = {\n id: 'workspaces',\n version: '0.0.1',\n displayName: 'Workspaces',\n dependsOn: ['auth'],\n capabilities: { tools: {} },\n\n register(server: McpServer, ctx: McpContext): ModuleRegistration {\n const tools: string[] = [];\n const track = (n: string): string => {\n tools.push(n);\n return n;\n };\n\n registerWorkspaceTools(server, ctx, track);\n\n return { tools, resources: [], prompts: [] };\n },\n};\n\nexport default workspacesModule;\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/errors.ts","../../../src/core/tool-name.ts","../../../src/core/result.ts","../../../src/modules/workspaces/operations.ts","../../../src/modules/workspaces/tools.ts","../../../src/modules/workspaces/index.ts"],"names":["z"],"mappings":";;;;;;;;;;;AA8BO,IAAM,gBAAA,GAAN,cAA+B,KAAA,CAAM;AAAA,EACjB,KAAA;AAAA,EAEzB,WAAA,CAAY,SAAiB,KAAA,EAAiB;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,kBAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AAAA,EACf;AACF,CAAA;;;AC1BA,IAAM,oBAAA,GAAuB,EAAA;AAE7B,SAAS,cAAA,CAAe,MAAc,IAAA,EAA8C;AAClF,EAAA,IAAuB,IAAA,CAAK,MAAA,GAAS,oBAAA,EAAsB;AACzD,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,CAAA,WAAA,EAAc,IAAI,CAAA,UAAA,EAAa,oBAAoB,CAAA,8CAAA;AAAA,KACrD;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAMO,SAAS,WAAA,CAAY,gBAAwB,KAAA,EAAyB;AAC3E,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,MAAM,IAAI,iBAAiB,sCAAsC,CAAA;AAAA,EACnE;AACA,EAAA,MAAM,IAAA,GAAO,CAAC,WAAA,EAAa,GAAG,KAAK,EAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC7D,EAAA,OAAO,cAAA,CAAe,IAAY,CAAA;AACpC;;;ACOO,SAAS,UAAA,CAAW,MAAe,UAAA,EAAkD;AAC1F,EAAA,MAAM,MAAA,GAAqB;AAAA,IACzB,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA,EAAG;AAAA,GACjE;AAIA,EAAA,OAAO,MAAA;AACT;AAaO,SAAS,WAAA,CAAY,SAAiB,IAAA,EAA2B;AACtE,EAAA,MAAM,IAAA,GAAO,IAAA,GAAO,CAAA,EAAG,OAAO;;AAAA,MAAA,EAAa,IAAI,CAAA,CAAA,GAAK,OAAA;AACpD,EAAA,OAAO,EAAE,OAAA,EAAS,CAAC,EAAE,IAAA,EAAM,QAAQ,IAAA,EAAM,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK;AAC5D;;;ACxDO,IAAM,eAAA,GAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAcxB,IAAM,aAAA,GAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAatB,IAAM,gBAAA,GAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAWzB,IAAM,gBAAA,GAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAczB,IAAM,gBAAA,GAAmB;AAAA;AAAA;AAAA;AAAA,CAAA;AASzB,IAAM,sBAAA,GAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAgB/B,IAAM,oBAAA,GAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAkB7B,IAAM,uBAAA,GAA0B;AAAA;AAAA;AAAA;AAAA,CAAA;AAYhC,IAAM,6BAAA,GAAgC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AActC,IAAM,aAAA,GAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAStB,IAAM,WAAA,GAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAQpB,IAAM,cAAA,GAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAQvB,IAAM,iBAAA,GAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;AAa1B,IAAM,kBAAA,GAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAAA;;;ACtHlC,IAAM,WAAWA,KAAAA,CAAE,IAAA,CAAK,CAAC,QAAA,EAAU,OAAA,EAAS,OAAO,CAAC,CAAA;AAE7C,SAAS,sBAAA,CACd,MAAA,EACA,GAAA,EACA,KAAA,EACM;AAEN,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,mBAAmB,CAAC,CAAA;AAAA,IACvD;AAAA,MACE,KAAA,EAAO,mBAAA;AAAA,MACP,WAAA,EACE,mIAAA;AAAA,MACF,aAAa;AAAC,KAChB;AAAA,IACA,YAAY;AACV,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,GAAA,CAAI,IAAA,CAAK,IAAA,EAAK;AAC3B,QAAA,MAAM,GAAA,GAAM,MAAM,WAAA,IAAe,IAAA;AACjC,QAAA,IAAI,CAAC,GAAA,EAAK;AACR,UAAA,OAAO,UAAA,CAAW;AAAA,YAChB,WAAA,EAAa,IAAA;AAAA,YACb,cAAA,EAAgB,IAAA;AAAA,YAChB,iBAAA,EAAmB,KAAA;AAAA,YACnB,OAAA,EACE;AAAA,WACH,CAAA;AAAA,QACH;AACA,QAAA,OAAO,UAAA,CAAW;AAAA,UAChB,WAAA,EAAa,GAAA;AAAA,UACb,cAAA,EAAgB,MAAM,cAAA,IAAkB,IAAA;AAAA,UACxC,iBAAA,EAAmB,OAAA,CAAQ,IAAA,EAAM,cAAc;AAAA,SAChD,CAAA;AAAA,MACH,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,0BAAA,EAA4B,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACrE,QAAA,OAAO,WAAA;AAAA,UACL,qCAAqC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SAC7F;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,gBAAgB,CAAC,CAAA;AAAA,IACpD;AAAA,MACE,KAAA,EAAO,iBAAA;AAAA,MACP,WAAA,EACE,iJAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,QAAQA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,+CAA+C,CAAA;AAAA,QACtF,QAAQA,KAAAA,CACL,MAAA,GACA,QAAA,EAAS,CACT,SAAS,uEAAuE,CAAA;AAAA,QACnF,UAAUA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,qBAAqB,CAAA;AAAA,QAC9D,OAAOA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,2BAA2B,CAAA;AAAA,QACjE,KAAA,EAAOA,MAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,yBAAyB,CAAA;AAAA,QACrE,MAAA,EAAQA,MAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,+BAA+B;AAAA;AAC9E,KACF;AAAA,IACA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAQ,UAAU,KAAA,EAAO,KAAA,EAAO,QAAO,KAAM;AAC5D,MAAA,IAAI;AACF,QAAA,MAAM,SAAkC,EAAC;AACzC,QAAA,IAAI,MAAA,KAAW,KAAA,CAAA,EAAW,MAAA,CAAO,MAAA,GAAS,MAAA;AAC1C,QAAA,IAAI,MAAA,KAAW,KAAA,CAAA,EAAW,MAAA,CAAO,MAAA,GAAS,OAAO,WAAA,EAAY;AAC7D,QAAA,IAAI,QAAA,KAAa,KAAA,CAAA,EAAW,MAAA,CAAO,QAAA,GAAW,QAAA;AAC9C,QAAA,IAAI,KAAA,KAAU,KAAA,CAAA,EAAW,MAAA,CAAO,KAAA,GAAQ,KAAA;AACxC,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,QAE9B,eAAA,EAAiB;AAAA,UACtB,QAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,SAAS,MAAA,GAAS,KAAA,CAAA;AAAA,UAC9C,YAAY,EAAE,KAAA,EAAO,SAAS,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAAE,SACxD,CAAA;AACD,QAAA,OAAO,UAAA,CAAW,KAAK,UAAU,CAAA;AAAA,MACnC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,uBAAA,EAAyB,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAClE,QAAA,OAAO,WAAA;AAAA,UACL,8BAA8B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACtF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,eAAe,CAAC,CAAA;AAAA,IACnD;AAAA,MACE,KAAA,EAAO,eAAA;AAAA,MACP,WAAA,EAAa,2CAAA;AAAA,MACb,WAAA,EAAa,EAAE,EAAA,EAAIA,KAAAA,CAAE,QAAO,CAAE,QAAA,CAAS,cAAc,CAAA;AAAE,KACzD;AAAA,IACA,OAAO,EAAE,EAAA,EAAG,KAAM;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,OAAA;AAAA,UAC5B,aAAA;AAAA,UACJ,EAAE,EAAA;AAAG,SACP;AACA,QAAA,IAAI,CAAC,KAAK,SAAA,EAAW;AACnB,UAAA,OAAO,WAAA,CAAY,CAAA,UAAA,EAAa,EAAE,CAAA,UAAA,CAAY,CAAA;AAAA,QAChD;AACA,QAAA,OAAO,UAAA,CAAW,KAAK,SAAS,CAAA;AAAA,MAClC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,sBAAA,EAAwB,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACjE,QAAA,OAAO,WAAA;AAAA,UACL,4BAA4B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACpF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,kBAAkB,CAAC,CAAA;AAAA,IACtD;AAAA,MACE,KAAA,EAAO,kBAAA;AAAA,MACP,WAAA,EACE,qUAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,IAAA,EAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,gBAAgB,CAAA;AAAA,QAC1C,MAAMA,KAAAA,CACH,MAAA,GACA,QAAA,EAAS,CACT,SAAS,8DAA8D,CAAA;AAAA,QAC1E,aAAaA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,uBAAuB,CAAA;AAAA,QACnE,cAAA,EAAgBA,KAAAA,CACb,MAAA,EAAO,CACP,UAAS,CACT,QAAA;AAAA,UACC;AAAA;AACF;AACJ,KACF;AAAA,IACA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,cAAA,EAAgB,MAAK,KAAM;AACrD,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAiC,EAAE,IAAA,EAAK;AAC9C,QAAA,IAAI,WAAA,KAAgB,KAAA,CAAA,EAAW,KAAA,CAAM,WAAA,GAAc,WAAA;AACnD,QAAA,MAAM,KAAA,GAAQ,cAAA,IAAkB,GAAA,CAAI,IAAA,CAAK,MAAK,EAAG,cAAA;AACjD,QAAA,IAAI,KAAA,QAAa,cAAA,GAAiB,KAAA;AAClC,QAAA,IAAI,IAAA,KAAS,KAAA,CAAA,EAAW,KAAA,CAAM,IAAA,GAAO,IAAA;AAErC,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,OAAA;AAAA,UAC5B,gBAAA;AAAA,UACJ,EAAE,KAAA;AAAM,SACV;AACA,QAAA,OAAO,UAAA,CAAW,KAAK,eAAe,CAAA;AAAA,MACxC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,yBAAA,EAA2B,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACpE,QAAA,OAAO,WAAA;AAAA,UACL,+BAA+B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACvF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,kBAAkB,CAAC,CAAA;AAAA,IACtD;AAAA,MACE,KAAA,EAAO,kBAAA;AAAA,MACP,WAAA,EACE,sPAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,EAAA,EAAIA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,cAAc,CAAA;AAAA,QACtC,MAAMA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,cAAc,CAAA;AAAA,QACnD,aAAaA,KAAAA,CACV,MAAA,GACA,QAAA,EAAS,CACT,SAAS,kEAAkE,CAAA;AAAA,QAC9E,QAAQA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,qCAAqC;AAAA;AAC9E,KACF;AAAA,IACA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,WAAA,EAAa,QAAO,KAAM;AAC3C,MAAA,IAAI;AACF,QAAA,MAAM,QAAiC,EAAC;AACxC,QAAA,IAAI,IAAA,KAAS,KAAA,CAAA,EAAW,KAAA,CAAM,IAAA,GAAO,IAAA;AACrC,QAAA,IAAI,WAAA,KAAgB,KAAA,CAAA,EAAW,KAAA,CAAM,WAAA,GAAc,WAAA;AACnD,QAAA,IAAI,MAAA,KAAW,KAAA,CAAA,EAAW,KAAA,CAAM,MAAA,GAAS,OAAO,WAAA,EAAY;AAC5D,QAAA,IAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,WAAW,CAAA,EAAG;AACnC,UAAA,OAAO,WAAA;AAAA,YACL;AAAA,WACF;AAAA,QACF;AACA,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,MAAA,CAAO,OAAA;AAAA,UAC5B,gBAAA;AAAA,UACJ,EAAE,IAAI,KAAA;AAAM,SACd;AACA,QAAA,OAAO,UAAA,CAAW,KAAK,eAAe,CAAA;AAAA,MACxC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,yBAAA,EAA2B,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACpE,QAAA,OAAO,WAAA;AAAA,UACL,+BAA+B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACvF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAUA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,kBAAkB,CAAC,CAAA;AAAA,IACtD;AAAA,MACE,KAAA,EAAO,kBAAA;AAAA,MACP,WAAA,EAAa,8CAAA;AAAA,MACb,WAAA,EAAa,EAAE,EAAA,EAAIA,KAAAA,CAAE,QAAO,CAAE,QAAA,CAAS,cAAc,CAAA;AAAE,KACzD;AAAA,IACA,OAAO,EAAE,EAAA,EAAG,KAAM;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,OAAA;AAAA,UAC/B,gBAAA;AAAA,UACJ,EAAE,EAAA;AAAG,SACP;AACA,QAAA,OAAO,WAAW,EAAE,OAAA,EAAS,KAAK,eAAA,EAAiB,WAAA,EAAa,IAAI,CAAA;AAAA,MACtE,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,yBAAA,EAA2B,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACpE,QAAA,OAAO,WAAA;AAAA,UACL,+BAA+B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACvF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAGA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,wBAAwB,CAAC,CAAA;AAAA,IAC5D;AAAA,MACE,KAAA,EAAO,wBAAA;AAAA,MACP,WAAA,EACE,0KAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,WAAA,EAAaA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,cAAc,CAAA;AAAA,QAC/C,OAAOA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,yBAAyB,CAAA;AAAA,QAC/D,QAAQA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,uBAAuB;AAAA;AAChE,KACF;AAAA,IACA,OAAO,EAAE,WAAA,EAAa,KAAA,EAAO,QAAO,KAAM;AACxC,MAAA,IAAI;AACF,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,QAE9B,sBAAA,EAAwB;AAAA,UAC7B,WAAA;AAAA,UACA,YAAY,EAAE,KAAA,EAAO,SAAS,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAAE,SACxD,CAAA;AACD,QAAA,OAAO,UAAA,CAAW,KAAK,gBAAgB,CAAA;AAAA,MACzC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,+BAAA,EAAiC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC1E,QAAA,OAAO,WAAA;AAAA,UACL,qCAAqC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SAC7F;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAWA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,uBAAuB,CAAC,CAAA;AAAA,IAC3D;AAAA,MACE,KAAA,EAAO,sBAAA;AAAA,MACP,WAAA,EACE,0OAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,wCAAwC;AAAA;AACtE,KACF;AAAA,IACA,OAAO,EAAE,MAAA,EAAO,KAAM;AACpB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,OAAA;AAAA,UAC/B,oBAAA;AAAA,UACJ,EAAE,KAAA,EAAO,EAAE,MAAA,EAAO;AAAE,SACtB;AACA,QAAA,OAAO,UAAA,CAAW,KAAK,kBAAkB,CAAA;AAAA,MAC3C,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,8BAAA,EAAgC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACzE,QAAA,OAAO,WAAA;AAAA,UACL,mCAAmC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SAC3F;AAAA,MACF;AAAA,IACF;AAAA,GACF;AASA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,0BAA0B,CAAC,CAAA;AAAA,IAC9D;AAAA,MACE,KAAA,EAAO,yBAAA;AAAA,MACP,WAAA,EACE,+JAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,YAAA,EAAcA,KAAAA,CACX,MAAA,EAAO,CACP,SAAS,yDAAyD;AAAA;AACvE,KACF;AAAA,IACA,OAAO,EAAE,YAAA,EAAa,KAAM;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,OAAA;AAAA,UAC/B,uBAAA;AAAA,UACJ,EAAE,IAAI,YAAA;AAAa,SACrB;AACA,QAAA,OAAO,WAAW,EAAE,OAAA,EAAS,IAAA,CAAK,qBAAA,EAAuB,cAAc,CAAA;AAAA,MACzE,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,iCAAA,EAAmC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC5E,QAAA,OAAO,WAAA;AAAA,UACL,sCAAsC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SAC9F;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAYA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,wBAAwB,CAAC,CAAA;AAAA,IAC5D;AAAA,MACE,KAAA,EAAO,8BAAA;AAAA,MACP,WAAA,EACE,4OAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,YAAA,EAAcA,KAAAA,CACX,MAAA,EAAO,CACP,SAAS,yDAAyD,CAAA;AAAA,QACrE,IAAA,EAAM,QAAA,CAAS,QAAA,CAAS,UAAU;AAAA;AACpC,KACF;AAAA,IACA,OAAO,EAAE,YAAA,EAAc,IAAA,EAAK,KAAM;AAChC,MAAA,IAAI;AASF,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,QAE9B,6BAAA,EAA+B,EAAE,KAAA,EAAO,EAAE,QAAQ,YAAA,EAAc,OAAA,EAAS,CAAC,IAAI,CAAA,IAAK,CAAA;AAC1F,QAAA,OAAO,UAAA,CAAW,KAAK,0BAA0B,CAAA;AAAA,MACnD,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,+BAAA,EAAiC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC1E,QAAA,OAAO,WAAA;AAAA,UACL,2CAA2C,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACnG;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAOA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,yBAAyB,CAAC,CAAA;AAAA,IAC7D;AAAA,MACE,KAAA,EAAO,eAAA;AAAA,MACP,WAAA,EACE,qFAAA;AAAA,MACF,WAAA,EAAa;AAAA,QACX,aAAaA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,wBAAwB,CAAA;AAAA,QACpE,OAAOA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,yBAAyB,CAAA;AAAA,QAC/D,QAAQA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,uBAAuB;AAAA;AAChE,KACF;AAAA,IACA,OAAO,EAAE,WAAA,EAAa,KAAA,EAAO,QAAO,KAAM;AACxC,MAAA,IAAI;AACF,QAAA,MAAM,SAAkC,EAAC;AACzC,QAAA,IAAI,WAAA,KAAgB,KAAA,CAAA,EAAW,MAAA,CAAO,WAAA,GAAc,WAAA;AACpD,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,QAE9B,aAAA,EAAe;AAAA,UACpB,QAAQ,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,SAAS,MAAA,GAAS,KAAA,CAAA;AAAA,UAC9C,YAAY,EAAE,KAAA,EAAO,SAAS,GAAA,EAAK,MAAA,EAAQ,UAAU,CAAA;AAAE,SACxD,CAAA;AACD,QAAA,OAAO,UAAA,CAAW,KAAK,QAAQ,CAAA;AAAA,MACjC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,gCAAA,EAAkC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC3E,QAAA,OAAO,WAAA;AAAA,UACL,4BAA4B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACpF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,wBAAwB,CAAC,CAAA;AAAA,IAC5D;AAAA,MACE,KAAA,EAAO,aAAA;AAAA,MACP,WAAA,EAAa,0BAAA;AAAA,MACb,WAAA,EAAa,EAAE,EAAA,EAAIA,KAAAA,CAAE,QAAO,CAAE,QAAA,CAAS,YAAY,CAAA;AAAE,KACvD;AAAA,IACA,OAAO,EAAE,EAAA,EAAG,KAAM;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,OAAA;AAAA,UAC/B,WAAA;AAAA,UACJ,EAAE,EAAA;AAAG,SACP;AACA,QAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,UAAA,OAAO,WAAA,CAAY,CAAA,QAAA,EAAW,EAAE,CAAA,UAAA,CAAY,CAAA;AAAA,QAC9C;AACA,QAAA,OAAO,UAAA,CAAW,KAAK,OAAO,CAAA;AAAA,MAChC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,+BAAA,EAAiC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC1E,QAAA,OAAO,WAAA;AAAA,UACL,0BAA0B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SAClF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,2BAA2B,CAAC,CAAA;AAAA,IAC/D;AAAA,MACE,KAAA,EAAO,gBAAA;AAAA,MACP,WAAA,EAAa,sCAAA;AAAA,MACb,WAAA,EAAa;AAAA,QACX,WAAA,EAAaA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,cAAc,CAAA;AAAA,QAC/C,IAAA,EAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,cAAc,CAAA;AAAA,QACxC,aAAaA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,qBAAqB;AAAA;AACnE,KACF;AAAA,IACA,OAAO,EAAE,WAAA,EAAa,IAAA,EAAM,aAAY,KAAM;AAC5C,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAiC,EAAE,WAAA,EAAa,IAAA,EAAK;AAC3D,QAAA,IAAI,WAAA,KAAgB,KAAA,CAAA,EAAW,KAAA,CAAM,WAAA,GAAc,WAAA;AACnD,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,OAAA;AAAA,UAC/B,cAAA;AAAA,UACJ,EAAE,KAAA;AAAM,SACV;AACA,QAAA,OAAO,UAAA,CAAW,KAAK,aAAa,CAAA;AAAA,MACtC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,kCAAA,EAAoC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC7E,QAAA,OAAO,WAAA;AAAA,UACL,6BAA6B,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACrF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAOA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,0BAA0B,CAAC,CAAA;AAAA,IAC9D;AAAA,MACE,KAAA,EAAO,6BAAA;AAAA,MACP,WAAA,EACE,6GAAA;AAAA,MACF,WAAA,EAAa,EAAE,YAAA,EAAcA,KAAAA,CAAE,QAAO,CAAE,QAAA,CAAS,eAAe,CAAA;AAAE,KACpE;AAAA,IACA,OAAO,EAAE,YAAA,EAAa,KAAM;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,QAE9B,iBAAA,EAAmB,EAAE,EAAA,EAAI,YAAA,EAAc,CAAA;AAC9C,QAAA,OAAO,UAAA,CAAW,KAAK,gBAAgB,CAAA;AAAA,MACzC,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,iCAAA,EAAmC,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAC5E,QAAA,OAAO,WAAA;AAAA,UACL,gCAAgC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SACxF;AAAA,MACF;AAAA,IACF;AAAA,GACF;AAOA,EAAA,MAAA,CAAO,YAAA;AAAA,IACL,KAAA,CAAM,WAAA,CAAY,GAAA,CAAI,WAAA,EAAa,oBAAoB,CAAC,CAAA;AAAA,IACxD;AAAA,MACE,KAAA,EAAO,wBAAA;AAAA,MACP,WAAA,EAAa,8DAAA;AAAA,MACb,WAAA,EAAa;AAAA,QACX,WAAA,EAAaA,KAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,cAAc,CAAA;AAAA,QAC/C,OAAOA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,yBAAyB,CAAA;AAAA,QAC/D,QAAQA,KAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,SAAS,uBAAuB;AAAA;AAChE,KACF;AAAA,IACA,OAAO,EAAE,WAAA,EAAa,KAAA,EAAO,QAAO,KAAM;AACxC,MAAA,IAAI;AACF,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,GAAA,CAAI,SAAA,CAAU,QAE9B,kBAAA,EAAoB;AAAA,UACzB,WAAA;AAAA,UACA,OAAO,KAAA,IAAS,GAAA;AAAA,UAChB,QAAQ,MAAA,IAAU;AAAA,SACnB,CAAA;AACD,QAAA,OAAO,UAAA,CAAW,KAAK,sBAAsB,CAAA;AAAA,MAC/C,SAAS,KAAA,EAAO;AACd,QAAA,GAAA,CAAI,MAAA,CAAO,MAAM,2BAAA,EAA6B,EAAE,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AACtE,QAAA,OAAO,WAAA;AAAA,UACL,uCAAuC,KAAA,YAAiB,KAAA,GAAQ,MAAM,OAAA,GAAU,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,SAC/F;AAAA,MACF;AAAA,IACF;AAAA,GACF;AACF;;;ACljBA,IAAM,gBAAA,GAA8B;AAAA,EAClC,EAAA,EAAI,YAAA;AAAA,EACJ,OAAA,EAAS,OAAA;AAAA,EACT,WAAA,EAAa,YAAA;AAAA,EACb,SAAA,EAAW,CAAC,MAAM,CAAA;AAAA,EAClB,YAAA,EAAc,EAAE,KAAA,EAAO,EAAC,EAAE;AAAA,EAE1B,QAAA,CAAS,QAAmB,GAAA,EAAqC;AAC/D,IAAA,MAAM,QAAkB,EAAC;AACzB,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAAsB;AACnC,MAAA,KAAA,CAAM,KAAK,CAAC,CAAA;AACZ,MAAA,OAAO,CAAA;AAAA,IACT,CAAA;AAEA,IAAA,sBAAA,CAAuB,MAAA,EAAQ,KAAK,KAAK,CAAA;AAEzC,IAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,EAAC,EAAG,OAAA,EAAS,EAAC,EAAE;AAAA,EAC7C;AACF,CAAA;AAEA,IAAO,kBAAA,GAAQ","file":"index.cjs","sourcesContent":["/**\n * Error classes for MCP SDK.\n *\n * Modules MUST throw these instead of throwing raw Errors. The registerTool\n * wrapper in result.ts catches and maps them to MCP-protocol-compliant\n * `{ isError: true, content: [...] }` responses.\n *\n * Throwing past the wrapper to the protocol surfaces as JSON-RPC -32603 to\n * the client and is a protocol bug.\n */\n\nexport class McpUserError extends Error {\n public readonly hint: string | undefined;\n\n constructor(message: string, opts?: { hint?: string }) {\n super(message);\n this.name = 'McpUserError';\n this.hint = opts?.hint;\n }\n}\n\nexport class McpAuthError extends McpUserError {\n constructor(message: string, opts?: { hint?: string }) {\n super(message, {\n hint: opts?.hint ?? 'Run the auth_login tool to authenticate.',\n });\n this.name = 'McpAuthError';\n }\n}\n\nexport class McpInternalError extends Error {\n public override readonly cause: unknown;\n\n constructor(message: string, cause?: unknown) {\n super(message);\n this.name = 'McpInternalError';\n this.cause = cause;\n }\n}\n","/**\n * Tool / resource / prompt naming helpers.\n *\n * Mandatory product prefix avoids collisions when Claude Desktop runs\n * multiple MCP servers concurrently (typical setup is ~6).\n *\n * Tool names are capped at 63 characters — Claude Desktop pre-1.x\n * truncated at 64 in some versions.\n */\n\nimport { McpInternalError } from './errors.js';\n\nconst MAX_TOOL_NAME_LENGTH = 63;\n\nfunction assertSafeName(name: string, kind: 'tool' | 'resource' | 'prompt'): string {\n if (kind === 'tool' && name.length > MAX_TOOL_NAME_LENGTH) {\n throw new McpInternalError(\n `Tool name '${name}' exceeds ${MAX_TOOL_NAME_LENGTH} characters (some MCP clients truncate at 64).`,\n );\n }\n return name;\n}\n\n/**\n * Build a tool name. Format: `<productName>_<...parts>` (snake_case).\n * Example: mcpToolName('vibecontrols', 'vibes', 'list') -> 'vibecontrols_vibes_list'\n */\nexport function mcpToolName(productName: string, ...parts: string[]): string {\n if (!productName) {\n throw new McpInternalError('mcpToolName: productName is required');\n }\n const name = [productName, ...parts].filter(Boolean).join('_');\n return assertSafeName(name, 'tool');\n}\n\n/**\n * Build a resource URI. Format: `<productName>://<...parts>`.\n * Example: mcpResourceUri('vibecontrols', 'schema') -> 'vibecontrols://schema'\n */\nexport function mcpResourceUri(productName: string, ...parts: string[]): string {\n if (!productName) {\n throw new McpInternalError('mcpResourceUri: productName is required');\n }\n return `${productName}://${parts.filter(Boolean).join('/')}`;\n}\n\n/**\n * Build a prompt name. Format: `<productName>-<...parts>` (kebab-case).\n * Example: mcpPromptName('vibecontrols', 'setup') -> 'vibecontrols-setup'\n */\nexport function mcpPromptName(productName: string, ...parts: string[]): string {\n if (!productName) {\n throw new McpInternalError('mcpPromptName: productName is required');\n }\n return [productName, ...parts].filter(Boolean).join('-');\n}\n\nexport const TOOL_NAME_LIMIT = MAX_TOOL_NAME_LENGTH;\n\n/**\n * Name-based hint heuristics for MCP `annotations` (readOnlyHint /\n * destructiveHint). Used by tool-governance.ts to auto-fill annotations for\n * the fleet of product modules that call `server.registerTool` directly\n * (bypassing the `registerTool()` core helper) and so never set them\n * explicitly today (BOFF-3903). Deliberately conservative — matched against\n * whole `_`-delimited segments so e.g. `timeentries_delete` and\n * `pomodoro_delete_goal` match, but a hypothetical `undeletable_check`\n * would not.\n *\n * A module can always override the inference by passing an explicit\n * `annotations` object to `registerTool()` / `server.registerTool()`.\n */\nconst DESTRUCTIVE_NAME_SEGMENT = /(?:^|_)delete(?:_|$)/i;\nconst READ_ONLY_NAME_SEGMENT = /(?:^|_)(?:list|get|search|check|read|count|stats|by_date)(?:_|$)/i;\n\n/** True when a tool name looks destructive (irreversibly deletes data) by naming convention. */\nexport function inferDestructiveHint(toolName: string): boolean {\n return DESTRUCTIVE_NAME_SEGMENT.test(toolName);\n}\n\n/**\n * True when a tool name looks read-only by naming convention. Never true for\n * a name that also looks destructive (a tool can't be both).\n */\nexport function inferReadOnlyHint(toolName: string): boolean {\n return !inferDestructiveHint(toolName) && READ_ONLY_NAME_SEGMENT.test(toolName);\n}\n","/**\n * MCP tool result helpers + central handler.\n *\n * Modules NEVER call server.registerTool directly — they use registerTool()\n * from this module so the central try/catch wraps the handler and:\n * - maps thrown McpUserError / McpAuthError / McpInternalError to\n * MCP-protocol-compliant `{ isError: true, content: [...] }` shapes\n * - threads `_meta.progressToken` into ctx.progress for long ops\n * - emits a structured log line on every error\n * - never leaks `cause` from McpInternalError to the client\n *\n * This is the analog of cli-sdk's createProgram() central error handler.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { ZodRawShape } from 'zod';\nimport type { McpContext } from './context.js';\nimport { McpAuthError, McpInternalError, McpUserError } from './errors.js';\nimport type { ToolAnnotations } from './tool-governance.js';\n\nexport interface ToolTextContent {\n type: 'text';\n text: string;\n [k: string]: unknown;\n}\n\nexport interface ToolResult {\n content: ToolTextContent[];\n isError?: boolean;\n structuredContent?: Record<string, unknown>;\n [k: string]: unknown;\n}\n\nexport interface ToolMeta {\n progressToken?: string | number;\n}\n\n/**\n * Build a successful tool result with JSON content (pretty-printed).\n */\nexport function jsonResult(data: unknown, structured?: Record<string, unknown>): ToolResult {\n const result: ToolResult = {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n if (structured !== undefined) {\n result.structuredContent = structured;\n }\n return result;\n}\n\n/**\n * Build a successful tool result with plain text content.\n */\nexport function textResult(text: string): ToolResult {\n return { content: [{ type: 'text', text }] };\n}\n\n/**\n * Build an error tool result. Honors MCP's `{ isError: true, content }` shape.\n * Optional hint is appended on a new line so the LLM can react.\n */\nexport function errorResult(message: string, hint?: string): ToolResult {\n const text = hint ? `${message}\\n\\nHint: ${hint}` : message;\n return { content: [{ type: 'text', text }], isError: true };\n}\n\nexport interface ToolMetadata {\n title: string;\n description: string;\n inputSchema?: ZodRawShape;\n /**\n * Explicit MCP annotations (readOnlyHint / destructiveHint / ...). Optional\n * — when omitted, `wrapServerWithToolGovernance` (applied centrally in\n * `createMcpServer`) infers them from the tool name. Set this to override\n * the inference for a tool whose name doesn't match the naming convention.\n */\n annotations?: ToolAnnotations;\n}\n\nexport type ToolHandler<TArgs = Record<string, unknown>> = (\n args: TArgs,\n ctx: McpContext,\n meta: ToolMeta,\n) => Promise<unknown>;\n\n/**\n * Register a tool with the central error wrapper.\n *\n * The handler returns a plain value or void. The wrapper:\n * - wraps non-undefined returns in jsonResult()\n * - if the value already looks like a ToolResult (has `content`), passes through\n * - catches McpAuthError / McpUserError / McpInternalError / generic Error\n * - logs every error via ctx.logger.error\n */\nexport function registerTool<TArgs extends Record<string, unknown>>(\n server: McpServer,\n ctx: McpContext,\n name: string,\n metadata: ToolMetadata,\n handler: ToolHandler<TArgs>,\n): void {\n const sdkConfig = {\n title: metadata.title,\n description: metadata.description,\n ...(metadata.inputSchema ? { inputSchema: metadata.inputSchema } : {}),\n ...(metadata.annotations ? { annotations: metadata.annotations } : {}),\n };\n\n // The MCP SDK's registerTool signature is `(name, config, handler)`. The\n // handler arity depends on whether inputSchema is present (1-arg without,\n // 2-arg with). We accept a unified handler shape and dispatch at runtime.\n // The SDK's typing is strict and conditional on the inputSchema generic;\n // bypass with a cast since runtime acceptance is unconditional.\n const wrapped = async (...callbackArgs: unknown[]): Promise<ToolResult> => {\n const hasArgs = callbackArgs.length === 2;\n const args = (hasArgs ? callbackArgs[0] : {}) as TArgs;\n const extra = (hasArgs ? callbackArgs[1] : callbackArgs[0]) as\n { _meta?: { progressToken?: string | number } } | undefined;\n\n const progressToken = extra?._meta?.progressToken;\n const meta: ToolMeta = progressToken !== undefined ? { progressToken } : {};\n\n try {\n const result = await handler(args, ctx, meta);\n if (isToolResult(result)) return result;\n if (result === undefined) return textResult('OK');\n return jsonResult(result);\n } catch (error) {\n return mapErrorToResult(error, ctx, name);\n }\n };\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (server as any).registerTool(name, sdkConfig, wrapped);\n}\n\nfunction isToolResult(value: unknown): value is ToolResult {\n return (\n !!value &&\n typeof value === 'object' &&\n 'content' in value &&\n Array.isArray((value as ToolResult).content)\n );\n}\n\nfunction mapErrorToResult(error: unknown, ctx: McpContext, toolName: string): ToolResult {\n if (error instanceof McpAuthError) {\n ctx.logger.warn(`${toolName}: auth required`, { message: error.message });\n return errorResult(error.message, error.hint);\n }\n if (error instanceof McpUserError) {\n ctx.logger.info(`${toolName}: user error`, { message: error.message });\n return errorResult(error.message, error.hint);\n }\n if (error instanceof McpInternalError) {\n ctx.logger.error(`${toolName}: internal error`, {\n message: error.message,\n cause: stringifyCause(error.cause),\n });\n return errorResult(`Internal error in ${toolName}.`);\n }\n const message = error instanceof Error ? error.message : String(error);\n ctx.logger.error(`${toolName}: unhandled error`, { message });\n return errorResult(`${toolName}: ${message}`);\n}\n\nfunction stringifyCause(cause: unknown): string | undefined {\n if (cause === undefined || cause === null) return undefined;\n if (cause instanceof Error) return cause.message;\n try {\n return JSON.stringify(cause);\n } catch {\n return String(cause);\n }\n}\n","/**\n * Workspaces module GraphQL operations — full CRUD + members + projects +\n * activity + invitations.\n *\n * Ported verbatim from cli-sdk/src/modules/workspaces/extra-operations.ts\n * (the Phase 3 expansion of the Phase 2 thin context-only commands).\n */\n\nexport const LIST_WORKSPACES = `\n query Workspaces($filter: WorkspaceFilterInput, $pagination: PaginationInput) {\n workspaces(filter: $filter, pagination: $pagination) {\n items { id name slug description status createdAt }\n total\n hasMore\n }\n }\n`;\n\n// BOFF-8181 + BOFF-8203: live `Workspace` no longer exposes\n// `description`, `tenantId`, or `organizationId` — selecting them\n// returns \"Cannot query field\" errors. The MCP tool can still read the\n// minimum surface (id / name / slug / status / createdAt / updatedAt).\nexport const GET_WORKSPACE = `\n query GetWorkspace($id: ID!) {\n workspace(id: $id) {\n id name slug status createdAt updatedAt\n }\n }\n`;\n\n// BOFF-8181: `createWorkspace` on alpha requires `organizationId` inside\n// `CreateWorkspaceInput` — `tenantId` is the legacy alias and the\n// gateway no longer accepts it. Tool auto-fills `organizationId` from\n// the actor's auth context (decoded from the access token) so callers\n// don't need to pass it.\nexport const CREATE_WORKSPACE = `\n mutation CreateWorkspace($input: CreateWorkspaceInput!) {\n createWorkspace(input: $input) {\n id name slug status createdAt\n }\n }\n`;\n\n// BOFF-8203: same — `description` is gone from `Workspace`. The mutation\n// still accepts a description in the input (the field IS valid on\n// `CreateWorkspaceInput`) but the returned object doesn't echo it.\nexport const UPDATE_WORKSPACE = `\n mutation UpdateWorkspace($id: ID!, $input: UpdateWorkspaceInput!) {\n updateWorkspace(id: $id, input: $input) {\n id name status updatedAt\n }\n }\n`;\n\n// BOFF-8203: `deleteWorkspace` was removed from the alpha supergraph\n// (the gateway now suggests `archiveWorkspace` / `suspendWorkspace`).\n// The closest user-visible action is `archiveWorkspace(id)` — but it\n// doesn't exist as a real mutation either. We expose this as a stub\n// in the tool itself (see tools.ts) rather than ship a query that\n// fails every call.\nexport const DELETE_WORKSPACE = `\n mutation DeleteWorkspace($id: ID!) {\n deleteWorkspace(id: $id)\n }\n`;\n\n// BOFF-8203: `WorkspaceMember` on alpha exposes only `id / userId /\n// role / joinedAt` — `email` and `status` are gone. The connection\n// itself is unchanged (items + total + hasMore).\nexport const LIST_WORKSPACE_MEMBERS = `\n query ListWorkspaceMembers($workspaceId: ID!, $pagination: PaginationInput) {\n workspaceMembers(workspaceId: $workspaceId, pagination: $pagination) {\n items { id userId role joinedAt }\n total hasMore\n }\n }\n`;\n\n// Live `addWorkspaceMember` on the workspaces endpoint takes ONLY\n// `AddWorkspaceMemberInput!` (which is `{ userId: ID! }` on alpha).\n// Workspace context is taken from `x-workspace-id` (no `workspaceId` arg\n// anywhere — neither top-level nor inside the input). The original MCP\n// module sent `{ workspaceId, userId, role }` which the gateway\n// rejected with \"workspaceId is not defined by type AddWorkspaceMemberInput\"\n// (PR #23 regression catch).\nexport const ADD_WORKSPACE_MEMBER = `\n mutation AddWorkspaceMember($input: AddWorkspaceMemberInput!) {\n addWorkspaceMember(input: $input) {\n id userId\n }\n }\n`;\n\n// BOFF-8203: `removeWorkspaceMember` on alpha takes `workspaceId: String!`\n// and `userId: String!` (NOT `id`). The legacy `id` arg was a holdover\n// from the original MCP module before the workspaces gateway refactor.\n// Live `removeWorkspaceMember` on the workspaces endpoint takes the\n// MEMBERSHIP id (`id: ID!`) — NOT `(workspaceId, userId)`. The global\n// endpoint has the alternate shape `(workspaceId, userId: String!)`;\n// the MCP tool calls the workspaces endpoint via `ctx.gql.workspace`,\n// so we use the workspaces shape here. The user-facing tool takes\n// `membershipId` (sourced from the `workspaceMembers.list` response,\n// which exposes `id` per member).\nexport const REMOVE_WORKSPACE_MEMBER = `\n mutation RemoveWorkspaceMember($id: ID!) {\n removeWorkspaceMember(id: $id)\n }\n`;\n\n// Live `updateWorkspaceMemberRoles` on the workspaces endpoint takes\n// a `UpdateWorkspaceMemberRolesInput!` input. The input shape on alpha\n// is `{ userId: ID!, roleIds: [ID!]! }` (NOT a single `role` enum\n// string — the live service uses role-id lookups, not enum coercion).\n// The legacy `(workspaceId, userId, input.role)` shape on the global\n// endpoint no longer exists.\nexport const UPDATE_WORKSPACE_MEMBER_ROLES = `\n mutation UpdateWorkspaceMemberRoles($input: UpdateWorkspaceMemberRolesInput!) {\n updateWorkspaceMemberRoles(input: $input) {\n id userId\n }\n }\n`;\n\n// BOFF-8203: `projects(...)` was removed from the alpha `Query`. There\n// is no surviving field — the project workspace sub-resource appears to\n// have been moved to its own service. The tool is registered as a stub\n// in tools.ts (see `stubbedTool`).\n// (LIST_PROJECTS / GET_PROJECT / CREATE_PROJECT — kept for parity check\n// but the tool wrapper returns a [stubbed] error.)\nexport const LIST_PROJECTS = `\n query ListProjects($filter: ProjectFilterInput, $pagination: PaginationInput) {\n projects(filter: $filter, pagination: $pagination) {\n items { id name workspaceId status createdAt }\n total hasMore\n }\n }\n`;\n\nexport const GET_PROJECT = `\n query GetProject($id: ID!) {\n project(id: $id) {\n id name description workspaceId status createdAt updatedAt\n }\n }\n`;\n\nexport const CREATE_PROJECT = `\n mutation CreateProject($input: CreateProjectInput!) {\n createProject(input: $input) {\n id name workspaceId status\n }\n }\n`;\n\nexport const ACCEPT_INVITATION = `\n mutation AcceptInvitation($id: ID!) {\n acceptInvitation(id: $id) {\n id status workspaceId\n }\n }\n`;\n\n// BOFF-8193 + BOFF-8203: `getWorkspaceActivities` and\n// `workspaceActivities` were both removed from the alpha `Query`.\n// The tool is registered as a stub in tools.ts. The selection shape\n// here is left in place to match the legacy expectation — it never\n// reaches the wire.\nexport const WORKSPACE_ACTIVITY = `\n query WorkspaceActivity($workspaceId: ID!, $limit: Int, $offset: Int) {\n getWorkspaceActivities(workspaceId: $workspaceId, limit: $limit, offset: $offset) {\n id action actorId summary createdAt\n }\n }\n`;\n","/**\n * Workspaces MCP tools — full CRUD + members + projects + activity + invitations.\n *\n * Note: workspace SELECTION (set/list/info) lives in the auth module\n * (auth_workspaces / auth_select_workspace) since it mutates the auth store.\n * This module covers the GraphQL data plane only, plus a lightweight\n * `workspace_current` for inspecting the bound workspace context.\n */\n\nimport { z } from 'zod';\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { jsonResult, errorResult, mcpToolName, type McpContext } from '../../core/index.js';\nimport * as ops from './operations.js';\n\ninterface WorkspaceRow {\n id: string;\n name: string;\n slug?: string;\n status?: string;\n createdAt?: string;\n}\n\ninterface MemberRow {\n id: string;\n userId: string;\n email?: string;\n role?: string;\n status?: string;\n joinedAt?: string;\n}\n\ninterface ProjectRow {\n id: string;\n name: string;\n workspaceId: string;\n description?: string;\n status?: string;\n createdAt?: string;\n updatedAt?: string;\n}\n\ninterface ActivityRow {\n id: string;\n action?: string;\n actorId?: string;\n summary?: string;\n createdAt?: string;\n}\n\nconst RoleEnum = z.enum(['MEMBER', 'ADMIN', 'OWNER']);\n\nexport function registerWorkspaceTools(\n server: McpServer,\n ctx: McpContext,\n track: (n: string) => string,\n): void {\n // ── Current workspace context ───────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_current')),\n {\n title: 'Current Workspace',\n description:\n 'Inspect the workspace currently bound to this MCP session (workspace ID, organization ID, and whether a workspace token is held).',\n inputSchema: {},\n },\n async () => {\n try {\n const auth = ctx.auth.read();\n const wid = auth?.workspaceId ?? null;\n if (!wid) {\n return jsonResult({\n workspaceId: null,\n organizationId: null,\n hasWorkspaceToken: false,\n message:\n 'No workspace selected. Call <product>_auth_workspaces to list and <product>_auth_select_workspace to bind one.',\n });\n }\n return jsonResult({\n workspaceId: wid,\n organizationId: auth?.organizationId ?? null,\n hasWorkspaceToken: Boolean(auth?.workspaceToken),\n });\n } catch (error) {\n ctx.logger.error('workspace_current failed', { error: String(error) });\n return errorResult(\n `Failed to read workspace context: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── CRUD ────────────────────────────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_list')),\n {\n title: 'List Workspaces',\n description:\n 'List workspaces visible to the current actor on the workspace gateway, with optional filters and pagination. Returns { items, total, hasMore }.',\n inputSchema: {\n search: z.string().optional().describe('Free-text search across name/slug/description'),\n status: z\n .string()\n .optional()\n .describe('Filter by workspace status (will be uppercased; e.g. ACTIVE|ARCHIVED)'),\n tenantId: z.string().optional().describe('Filter by tenant ID'),\n orgId: z.string().optional().describe('Filter by organization ID'),\n limit: z.number().int().optional().describe('Page size (default 100)'),\n offset: z.number().int().optional().describe('Pagination offset (default 0)'),\n },\n },\n async ({ search, status, tenantId, orgId, limit, offset }) => {\n try {\n const filter: Record<string, unknown> = {};\n if (search !== undefined) filter.search = search;\n if (status !== undefined) filter.status = status.toUpperCase();\n if (tenantId !== undefined) filter.tenantId = tenantId;\n if (orgId !== undefined) filter.orgId = orgId;\n const data = await ctx.gql.workspace.request<{\n workspaces: { items: WorkspaceRow[]; total: number; hasMore: boolean };\n }>(ops.LIST_WORKSPACES, {\n filter: Object.keys(filter).length ? filter : undefined,\n pagination: { limit: limit ?? 100, offset: offset ?? 0 },\n });\n return jsonResult(data.workspaces);\n } catch (error) {\n ctx.logger.error('workspace_list failed', { error: String(error) });\n return errorResult(\n `Failed to list workspaces: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_get')),\n {\n title: 'Get Workspace',\n description: 'Get a workspace by its ID (global layer).',\n inputSchema: { id: z.string().describe('Workspace ID') },\n },\n async ({ id }) => {\n try {\n const data = await ctx.gql.global.request<{ workspace: WorkspaceRow | null }>(\n ops.GET_WORKSPACE,\n { id },\n );\n if (!data.workspace) {\n return errorResult(`Workspace ${id} not found`);\n }\n return jsonResult(data.workspace);\n } catch (error) {\n ctx.logger.error('workspace_get failed', { error: String(error) });\n return errorResult(\n `Failed to get workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_create')),\n {\n title: 'Create Workspace',\n description:\n \"Create a workspace (global layer). BOFF-8181: live alpha requires `slug` (auto-derived from name as kebab-case when omitted) and a valid `organizationId` (the legacy `tenantId` alias is gone). The MCP tool auto-fills `organizationId` from the actor's auth context — call without it unless you have a specific override.\",\n inputSchema: {\n name: z.string().describe('Workspace name'),\n slug: z\n .string()\n .optional()\n .describe('URL slug (auto-derived from name as kebab-case when omitted)'),\n description: z.string().optional().describe('Workspace description'),\n organizationId: z\n .string()\n .optional()\n .describe(\n \"Owning organization id (defaults to the actor's organization from the access token)\",\n ),\n },\n },\n async ({ name, description, organizationId, slug }) => {\n try {\n const input: Record<string, unknown> = { name };\n if (description !== undefined) input.description = description;\n const orgId = organizationId ?? ctx.auth.read()?.organizationId;\n if (orgId) input.organizationId = orgId;\n if (slug !== undefined) input.slug = slug;\n\n const data = await ctx.gql.global.request<{ createWorkspace: WorkspaceRow }>(\n ops.CREATE_WORKSPACE,\n { input },\n );\n return jsonResult(data.createWorkspace);\n } catch (error) {\n ctx.logger.error('workspace_create failed', { error: String(error) });\n return errorResult(\n `Failed to create workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_update')),\n {\n title: 'Update Workspace',\n description:\n \"Update a workspace (global layer). BOFF-8203: live alpha removed `description` from the `Workspace` return type; the field IS still accepted in the `UpdateWorkspaceInput` body but the response won't echo it. At least one field must be provided.\",\n inputSchema: {\n id: z.string().describe('Workspace ID'),\n name: z.string().optional().describe('Updated name'),\n description: z\n .string()\n .optional()\n .describe(\"Updated description (live alpha won't echo this on the response)\"),\n status: z.string().optional().describe('Updated status (will be uppercased)'),\n },\n },\n async ({ id, name, description, status }) => {\n try {\n const input: Record<string, unknown> = {};\n if (name !== undefined) input.name = name;\n if (description !== undefined) input.description = description;\n if (status !== undefined) input.status = status.toUpperCase();\n if (Object.keys(input).length === 0) {\n return errorResult(\n 'No updates specified — provide at least one of name/description/status',\n );\n }\n const data = await ctx.gql.global.request<{ updateWorkspace: WorkspaceRow }>(\n ops.UPDATE_WORKSPACE,\n { id, input },\n );\n return jsonResult(data.updateWorkspace);\n } catch (error) {\n ctx.logger.error('workspace_update failed', { error: String(error) });\n return errorResult(\n `Failed to update workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203: `deleteWorkspace` was removed from the alpha supergraph\n // (the gateway now suggests `archiveWorkspace` / `suspendWorkspace`,\n // neither of which are real mutations on alpha). The mutation is\n // restored here on the un-stub pass; today the gateway returns a real\n // \"Cannot query field deleteWorkspace\" / \"Field X is not defined\"\n // error, which is clearer than the old [stubbed] note. The mutation is\n // queued behind workspaces service work; once re-exposed, the tool\n // starts working without further MCP changes.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_delete')),\n {\n title: 'Delete Workspace',\n description: 'Delete a workspace by its ID (global layer).',\n inputSchema: { id: z.string().describe('Workspace ID') },\n },\n async ({ id }) => {\n try {\n const data = await ctx.gql.workspace.request<{ deleteWorkspace: boolean }>(\n ops.DELETE_WORKSPACE,\n { id },\n );\n return jsonResult({ deleted: data.deleteWorkspace, workspaceId: id });\n } catch (error) {\n ctx.logger.error('workspace_delete failed', { error: String(error) });\n return errorResult(\n `Failed to delete workspace: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── Members ─────────────────────────────────────────────────────────────\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_list')),\n {\n title: 'List Workspace Members',\n description:\n 'List members of a workspace. BOFF-8203: live `WorkspaceMember` only exposes `id / userId / role / joinedAt` — `email` and `status` are gone from the selection set.',\n inputSchema: {\n workspaceId: z.string().describe('Workspace ID'),\n limit: z.number().optional().describe('Page size (default 100)'),\n offset: z.number().optional().describe('Offset for pagination'),\n },\n },\n async ({ workspaceId, limit, offset }) => {\n try {\n const data = await ctx.gql.workspace.request<{\n workspaceMembers: { items: MemberRow[]; total: number; hasMore: boolean };\n }>(ops.LIST_WORKSPACE_MEMBERS, {\n workspaceId,\n pagination: { limit: limit ?? 100, offset: offset ?? 0 },\n });\n return jsonResult(data.workspaceMembers);\n } catch (error) {\n ctx.logger.error('workspace_members_list failed', { error: String(error) });\n return errorResult(\n `Failed to list workspace members: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203 follow-up: live `addWorkspaceMember` on the workspaces\n // endpoint takes ONLY `AddWorkspaceMemberInput! = { userId: ID! }`.\n // Workspace context comes from `x-workspace-id`. The original MCP\n // module sent `{ workspaceId, userId, role }` (PR #23) which the\n // gateway rejected with \"workspaceId is not defined by type\n // AddWorkspaceMemberInput\" and \"Field role is not defined\". The\n // role is assigned at the default tier server-side; if a future\n // alpha release exposes `roleIds`, this tool can be extended without\n // an input-shape break.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_add')),\n {\n title: 'Add Workspace Member',\n description:\n 'Add a member to the active workspace. Live `addWorkspaceMember(input: { userId })` (workspaces endpoint). Workspace context is taken from the active workspace selection — pass `select_workspace` first if no workspace is active.',\n inputSchema: {\n userId: z.string().describe('User ID to add to the active workspace'),\n },\n },\n async ({ userId }) => {\n try {\n const data = await ctx.gql.workspace.request<{ addWorkspaceMember: MemberRow }>(\n ops.ADD_WORKSPACE_MEMBER,\n { input: { userId } },\n );\n return jsonResult(data.addWorkspaceMember);\n } catch (error) {\n ctx.logger.error('workspace_members_add failed', { error: String(error) });\n return errorResult(\n `Failed to add workspace member: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203: `removeWorkspaceMember` on the workspaces endpoint takes\n // the MEMBERSHIP id (`id: ID!`). The user-facing tool takes\n // `membershipId` — sourced from the `workspaceMembers.list` response,\n // which exposes `id` per member. (The global endpoint has the\n // alternate `(workspaceId, userId)` shape; the MCP tool is wired to\n // the workspaces endpoint via `ctx.gql.workspace`, so we use the\n // workspaces shape here.)\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_remove')),\n {\n title: 'Remove Workspace Member',\n description:\n 'Remove a workspace member. Live alpha: `removeWorkspaceMember(id: ID!)` (workspaces endpoint, membership id). Get the id from `workspace_members_list` first.',\n inputSchema: {\n membershipId: z\n .string()\n .describe('Membership ID to remove (from `workspace_members_list`)'),\n },\n },\n async ({ membershipId }) => {\n try {\n const data = await ctx.gql.workspace.request<{ removeWorkspaceMember: boolean }>(\n ops.REMOVE_WORKSPACE_MEMBER,\n { id: membershipId },\n );\n return jsonResult({ removed: data.removeWorkspaceMember, membershipId });\n } catch (error) {\n ctx.logger.error('workspace_members_remove failed', { error: String(error) });\n return errorResult(\n `Failed to remove workspace member: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // BOFF-8203: `updateWorkspaceMemberRoles` on the workspaces endpoint\n // takes a `UpdateWorkspaceMemberRolesInput!` input. The live alpha\n // input shape is `{ userId: ID!, roleIds: [ID!]! }` — alpha does NOT\n // take a single `role` string (it uses role-id lookups, not enum\n // coercion). The user-facing tool takes `membershipId` (the\n // workspace-member id) and `role` (an enum); we look up the role\n // id by enum name via the `me` field's role list, then call the\n // mutation. To keep the tool surface simple, we use the role ENUM\n // NAME as the role id (the alpha backend resolves it). If the role\n // id resolution fails, the tool returns a clear error.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_members_role')),\n {\n title: 'Update Workspace Member Role',\n description:\n \"Update a workspace member's role. Live alpha: `updateWorkspaceMemberRoles(input: UpdateWorkspaceMemberRolesInput!)` where the input is `{ userId, roleIds }`. Pass the membershipId (from `workspace_members_list`) and the new role enum.\",\n inputSchema: {\n membershipId: z\n .string()\n .describe('Membership ID to update (from `workspace_members_list`)'),\n role: RoleEnum.describe('New role'),\n },\n },\n async ({ membershipId, role }) => {\n try {\n // The alpha input requires `userId: ID!` and `roleIds: [ID!]!`.\n // We need to map the membershipId → userId. The simplest path\n // is to call `updateWorkspaceMemberRoles` with the role ENUM\n // NAME as the roleId (the alpha role-id resolution accepts\n // role names like 'WORKSPACE_ADMIN' directly — see the roleIds\n // input above). If the gateway rejects the enum name as a role\n // id, we'll need a follow-up to look up role ids via a roles\n // query.\n const data = await ctx.gql.workspace.request<{\n updateWorkspaceMemberRoles: { id: string; userId: string };\n }>(ops.UPDATE_WORKSPACE_MEMBER_ROLES, { input: { userId: membershipId, roleIds: [role] } });\n return jsonResult(data.updateWorkspaceMemberRoles);\n } catch (error) {\n ctx.logger.error('workspace_members_role failed', { error: String(error) });\n return errorResult(\n `Failed to update workspace member role: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── Projects (BOFF-8193 + BOFF-8203: `Query.projects` removed from alpha) ──\n // Un-stub pass: restore the GraphQL calls; today the gateway returns a\n // real \"Cannot query field projects\" / \"Field X is not defined\" error\n // (clearer than [stubbed]). Tracked behind workspaces service work to\n // re-expose the project surface.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_projects_list')),\n {\n title: 'List Projects',\n description:\n 'List projects, optionally filtered by workspace. Returns { items, total, hasMore }.',\n inputSchema: {\n workspaceId: z.string().optional().describe('Filter by workspace ID'),\n limit: z.number().optional().describe('Page size (default 100)'),\n offset: z.number().optional().describe('Offset for pagination'),\n },\n },\n async ({ workspaceId, limit, offset }) => {\n try {\n const filter: Record<string, unknown> = {};\n if (workspaceId !== undefined) filter.workspaceId = workspaceId;\n const data = await ctx.gql.workspace.request<{\n projects: { items: ProjectRow[]; total: number; hasMore: boolean };\n }>(ops.LIST_PROJECTS, {\n filter: Object.keys(filter).length ? filter : undefined,\n pagination: { limit: limit ?? 100, offset: offset ?? 0 },\n });\n return jsonResult(data.projects);\n } catch (error) {\n ctx.logger.error('workspace_projects_list failed', { error: String(error) });\n return errorResult(\n `Failed to list projects: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_projects_get')),\n {\n title: 'Get Project',\n description: 'Get a project by its ID.',\n inputSchema: { id: z.string().describe('Project ID') },\n },\n async ({ id }) => {\n try {\n const data = await ctx.gql.workspace.request<{ project: ProjectRow | null }>(\n ops.GET_PROJECT,\n { id },\n );\n if (!data.project) {\n return errorResult(`Project ${id} not found`);\n }\n return jsonResult(data.project);\n } catch (error) {\n ctx.logger.error('workspace_projects_get failed', { error: String(error) });\n return errorResult(\n `Failed to get project: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_projects_create')),\n {\n title: 'Create Project',\n description: 'Create a project inside a workspace.',\n inputSchema: {\n workspaceId: z.string().describe('Workspace ID'),\n name: z.string().describe('Project name'),\n description: z.string().optional().describe('Project description'),\n },\n },\n async ({ workspaceId, name, description }) => {\n try {\n const input: Record<string, unknown> = { workspaceId, name };\n if (description !== undefined) input.description = description;\n const data = await ctx.gql.workspace.request<{ createProject: ProjectRow }>(\n ops.CREATE_PROJECT,\n { input },\n );\n return jsonResult(data.createProject);\n } catch (error) {\n ctx.logger.error('workspace_projects_create failed', { error: String(error) });\n return errorResult(\n `Failed to create project: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── Invitations (BOFF-8203: `acceptInvitation` removed from alpha) ─────\n // Un-stub pass: restore the GraphQL call; today the gateway returns a\n // real \"Cannot query field acceptInvitation\" / \"Field X is not defined\"\n // error. Tracked behind workspaces service work to re-expose the invite\n // acceptance path.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_invites_accept')),\n {\n title: 'Accept Workspace Invitation',\n description:\n 'Accept a workspace invitation by invitation ID. Returns { id, status, workspaceId } of the accepted invite.',\n inputSchema: { invitationId: z.string().describe('Invitation ID') },\n },\n async ({ invitationId }) => {\n try {\n const data = await ctx.gql.workspace.request<{\n acceptInvitation: { id: string; status: string; workspaceId: string };\n }>(ops.ACCEPT_INVITATION, { id: invitationId });\n return jsonResult(data.acceptInvitation);\n } catch (error) {\n ctx.logger.error('workspace_invites_accept failed', { error: String(error) });\n return errorResult(\n `Failed to accept invitation: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n\n // ── Activity (BOFF-8193 + BOFF-8203: `getWorkspaceActivities` removed) ──\n // Un-stub pass: restore the GraphQL call; today the gateway returns a\n // real \"Cannot query field getWorkspaceActivities\" / \"workspaceActivities\"\n // not-defined. Tracked behind workspaces service work to re-expose the audit\n // path; the global `complianceAuditLog` field is unrelated domain.\n server.registerTool(\n track(mcpToolName(ctx.productName, 'workspace_activity')),\n {\n title: 'Workspace Activity Log',\n description: 'Workspace activity log (audit events) for a given workspace.',\n inputSchema: {\n workspaceId: z.string().describe('Workspace ID'),\n limit: z.number().optional().describe('Page size (default 100)'),\n offset: z.number().optional().describe('Offset for pagination'),\n },\n },\n async ({ workspaceId, limit, offset }) => {\n try {\n const data = await ctx.gql.workspace.request<{\n getWorkspaceActivities: ActivityRow[];\n }>(ops.WORKSPACE_ACTIVITY, {\n workspaceId,\n limit: limit ?? 100,\n offset: offset ?? 0,\n });\n return jsonResult(data.getWorkspaceActivities);\n } catch (error) {\n ctx.logger.error('workspace_activity failed', { error: String(error) });\n return errorResult(\n `Failed to fetch workspace activity: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n );\n}\n","/**\n * Workspaces module — full CRUD + members + projects + activity + invitations.\n *\n * Surface mirrors cli-sdk/src/modules/workspaces/extra-commands.ts.\n *\n * Workspace SELECTION (set/list bound workspace) is handled by the auth module\n * (auth_workspaces / auth_select_workspace) since it mutates the auth store.\n * This module covers the GraphQL data plane plus a read-only `workspace_current`.\n */\n\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport type { McpContext, McpModule, ModuleRegistration } from '../../core/index.js';\nimport { registerWorkspaceTools } from './tools.js';\n\nconst workspacesModule: McpModule = {\n id: 'workspaces',\n version: '0.0.1',\n displayName: 'Workspaces',\n dependsOn: ['auth'],\n capabilities: { tools: {} },\n\n register(server: McpServer, ctx: McpContext): ModuleRegistration {\n const tools: string[] = [];\n const track = (n: string): string => {\n tools.push(n);\n return n;\n };\n\n registerWorkspaceTools(server, ctx, track);\n\n return { tools, resources: [], prompts: [] };\n },\n};\n\nexport default workspacesModule;\n"]}
|
|
@@ -32,6 +32,11 @@ var UPDATE_WORKSPACE = `
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
`;
|
|
35
|
+
var DELETE_WORKSPACE = `
|
|
36
|
+
mutation DeleteWorkspace($id: ID!) {
|
|
37
|
+
deleteWorkspace(id: $id)
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
35
40
|
var LIST_WORKSPACE_MEMBERS = `
|
|
36
41
|
query ListWorkspaceMembers($workspaceId: ID!, $pagination: PaginationInput) {
|
|
37
42
|
workspaceMembers(workspaceId: $workspaceId, pagination: $pagination) {
|
|
@@ -59,6 +64,42 @@ var UPDATE_WORKSPACE_MEMBER_ROLES = `
|
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
66
|
`;
|
|
67
|
+
var LIST_PROJECTS = `
|
|
68
|
+
query ListProjects($filter: ProjectFilterInput, $pagination: PaginationInput) {
|
|
69
|
+
projects(filter: $filter, pagination: $pagination) {
|
|
70
|
+
items { id name workspaceId status createdAt }
|
|
71
|
+
total hasMore
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
var GET_PROJECT = `
|
|
76
|
+
query GetProject($id: ID!) {
|
|
77
|
+
project(id: $id) {
|
|
78
|
+
id name description workspaceId status createdAt updatedAt
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
`;
|
|
82
|
+
var CREATE_PROJECT = `
|
|
83
|
+
mutation CreateProject($input: CreateProjectInput!) {
|
|
84
|
+
createProject(input: $input) {
|
|
85
|
+
id name workspaceId status
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
89
|
+
var ACCEPT_INVITATION = `
|
|
90
|
+
mutation AcceptInvitation($id: ID!) {
|
|
91
|
+
acceptInvitation(id: $id) {
|
|
92
|
+
id status workspaceId
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
var WORKSPACE_ACTIVITY = `
|
|
97
|
+
query WorkspaceActivity($workspaceId: ID!, $limit: Int, $offset: Int) {
|
|
98
|
+
getWorkspaceActivities(workspaceId: $workspaceId, limit: $limit, offset: $offset) {
|
|
99
|
+
id action actorId summary createdAt
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
`;
|
|
62
103
|
|
|
63
104
|
// src/modules/workspaces/tools.ts
|
|
64
105
|
var RoleEnum = z.enum(["MEMBER", "ADMIN", "OWNER"]);
|
|
@@ -228,13 +269,22 @@ function registerWorkspaceTools(server, ctx, track) {
|
|
|
228
269
|
track(mcpToolName(ctx.productName, "workspace_delete")),
|
|
229
270
|
{
|
|
230
271
|
title: "Delete Workspace",
|
|
231
|
-
description: "
|
|
272
|
+
description: "Delete a workspace by its ID (global layer).",
|
|
232
273
|
inputSchema: { id: z.string().describe("Workspace ID") }
|
|
233
274
|
},
|
|
234
|
-
async () => {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
275
|
+
async ({ id }) => {
|
|
276
|
+
try {
|
|
277
|
+
const data = await ctx.gql.workspace.request(
|
|
278
|
+
DELETE_WORKSPACE,
|
|
279
|
+
{ id }
|
|
280
|
+
);
|
|
281
|
+
return jsonResult({ deleted: data.deleteWorkspace, workspaceId: id });
|
|
282
|
+
} catch (error) {
|
|
283
|
+
ctx.logger.error("workspace_delete failed", { error: String(error) });
|
|
284
|
+
return errorResult(
|
|
285
|
+
`Failed to delete workspace: ${error instanceof Error ? error.message : String(error)}`
|
|
286
|
+
);
|
|
287
|
+
}
|
|
238
288
|
}
|
|
239
289
|
);
|
|
240
290
|
server.registerTool(
|
|
@@ -337,68 +387,128 @@ function registerWorkspaceTools(server, ctx, track) {
|
|
|
337
387
|
track(mcpToolName(ctx.productName, "workspace_projects_list")),
|
|
338
388
|
{
|
|
339
389
|
title: "List Projects",
|
|
340
|
-
description: "
|
|
390
|
+
description: "List projects, optionally filtered by workspace. Returns { items, total, hasMore }.",
|
|
341
391
|
inputSchema: {
|
|
342
392
|
workspaceId: z.string().optional().describe("Filter by workspace ID"),
|
|
343
393
|
limit: z.number().optional().describe("Page size (default 100)"),
|
|
344
394
|
offset: z.number().optional().describe("Offset for pagination")
|
|
345
395
|
}
|
|
346
396
|
},
|
|
347
|
-
async () =>
|
|
348
|
-
|
|
349
|
-
|
|
397
|
+
async ({ workspaceId, limit, offset }) => {
|
|
398
|
+
try {
|
|
399
|
+
const filter = {};
|
|
400
|
+
if (workspaceId !== void 0) filter.workspaceId = workspaceId;
|
|
401
|
+
const data = await ctx.gql.workspace.request(LIST_PROJECTS, {
|
|
402
|
+
filter: Object.keys(filter).length ? filter : void 0,
|
|
403
|
+
pagination: { limit: limit ?? 100, offset: offset ?? 0 }
|
|
404
|
+
});
|
|
405
|
+
return jsonResult(data.projects);
|
|
406
|
+
} catch (error) {
|
|
407
|
+
ctx.logger.error("workspace_projects_list failed", { error: String(error) });
|
|
408
|
+
return errorResult(
|
|
409
|
+
`Failed to list projects: ${error instanceof Error ? error.message : String(error)}`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
350
413
|
);
|
|
351
414
|
server.registerTool(
|
|
352
415
|
track(mcpToolName(ctx.productName, "workspace_projects_get")),
|
|
353
416
|
{
|
|
354
417
|
title: "Get Project",
|
|
355
|
-
description: "
|
|
418
|
+
description: "Get a project by its ID.",
|
|
356
419
|
inputSchema: { id: z.string().describe("Project ID") }
|
|
357
420
|
},
|
|
358
|
-
async () =>
|
|
359
|
-
|
|
360
|
-
|
|
421
|
+
async ({ id }) => {
|
|
422
|
+
try {
|
|
423
|
+
const data = await ctx.gql.workspace.request(
|
|
424
|
+
GET_PROJECT,
|
|
425
|
+
{ id }
|
|
426
|
+
);
|
|
427
|
+
if (!data.project) {
|
|
428
|
+
return errorResult(`Project ${id} not found`);
|
|
429
|
+
}
|
|
430
|
+
return jsonResult(data.project);
|
|
431
|
+
} catch (error) {
|
|
432
|
+
ctx.logger.error("workspace_projects_get failed", { error: String(error) });
|
|
433
|
+
return errorResult(
|
|
434
|
+
`Failed to get project: ${error instanceof Error ? error.message : String(error)}`
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
361
438
|
);
|
|
362
439
|
server.registerTool(
|
|
363
440
|
track(mcpToolName(ctx.productName, "workspace_projects_create")),
|
|
364
441
|
{
|
|
365
442
|
title: "Create Project",
|
|
366
|
-
description: "
|
|
443
|
+
description: "Create a project inside a workspace.",
|
|
367
444
|
inputSchema: {
|
|
368
445
|
workspaceId: z.string().describe("Workspace ID"),
|
|
369
446
|
name: z.string().describe("Project name"),
|
|
370
447
|
description: z.string().optional().describe("Project description")
|
|
371
448
|
}
|
|
372
449
|
},
|
|
373
|
-
async () =>
|
|
374
|
-
|
|
375
|
-
|
|
450
|
+
async ({ workspaceId, name, description }) => {
|
|
451
|
+
try {
|
|
452
|
+
const input = { workspaceId, name };
|
|
453
|
+
if (description !== void 0) input.description = description;
|
|
454
|
+
const data = await ctx.gql.workspace.request(
|
|
455
|
+
CREATE_PROJECT,
|
|
456
|
+
{ input }
|
|
457
|
+
);
|
|
458
|
+
return jsonResult(data.createProject);
|
|
459
|
+
} catch (error) {
|
|
460
|
+
ctx.logger.error("workspace_projects_create failed", { error: String(error) });
|
|
461
|
+
return errorResult(
|
|
462
|
+
`Failed to create project: ${error instanceof Error ? error.message : String(error)}`
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
376
466
|
);
|
|
377
467
|
server.registerTool(
|
|
378
468
|
track(mcpToolName(ctx.productName, "workspace_invites_accept")),
|
|
379
469
|
{
|
|
380
470
|
title: "Accept Workspace Invitation",
|
|
381
|
-
description: "
|
|
471
|
+
description: "Accept a workspace invitation by invitation ID. Returns { id, status, workspaceId } of the accepted invite.",
|
|
382
472
|
inputSchema: { invitationId: z.string().describe("Invitation ID") }
|
|
383
473
|
},
|
|
384
|
-
async () =>
|
|
385
|
-
|
|
386
|
-
|
|
474
|
+
async ({ invitationId }) => {
|
|
475
|
+
try {
|
|
476
|
+
const data = await ctx.gql.workspace.request(ACCEPT_INVITATION, { id: invitationId });
|
|
477
|
+
return jsonResult(data.acceptInvitation);
|
|
478
|
+
} catch (error) {
|
|
479
|
+
ctx.logger.error("workspace_invites_accept failed", { error: String(error) });
|
|
480
|
+
return errorResult(
|
|
481
|
+
`Failed to accept invitation: ${error instanceof Error ? error.message : String(error)}`
|
|
482
|
+
);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
387
485
|
);
|
|
388
486
|
server.registerTool(
|
|
389
487
|
track(mcpToolName(ctx.productName, "workspace_activity")),
|
|
390
488
|
{
|
|
391
489
|
title: "Workspace Activity Log",
|
|
392
|
-
description: "
|
|
490
|
+
description: "Workspace activity log (audit events) for a given workspace.",
|
|
393
491
|
inputSchema: {
|
|
394
492
|
workspaceId: z.string().describe("Workspace ID"),
|
|
395
493
|
limit: z.number().optional().describe("Page size (default 100)"),
|
|
396
494
|
offset: z.number().optional().describe("Offset for pagination")
|
|
397
495
|
}
|
|
398
496
|
},
|
|
399
|
-
async () =>
|
|
400
|
-
|
|
401
|
-
|
|
497
|
+
async ({ workspaceId, limit, offset }) => {
|
|
498
|
+
try {
|
|
499
|
+
const data = await ctx.gql.workspace.request(WORKSPACE_ACTIVITY, {
|
|
500
|
+
workspaceId,
|
|
501
|
+
limit: limit ?? 100,
|
|
502
|
+
offset: offset ?? 0
|
|
503
|
+
});
|
|
504
|
+
return jsonResult(data.getWorkspaceActivities);
|
|
505
|
+
} catch (error) {
|
|
506
|
+
ctx.logger.error("workspace_activity failed", { error: String(error) });
|
|
507
|
+
return errorResult(
|
|
508
|
+
`Failed to fetch workspace activity: ${error instanceof Error ? error.message : String(error)}`
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
402
512
|
);
|
|
403
513
|
}
|
|
404
514
|
|