@testplanit/mcp-server 0.1.0
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/LICENSE.md +93 -0
- package/README.md +1346 -0
- package/dist/cli.js +5525 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.mts +490 -0
- package/dist/index.d.ts +490 -0
- package/dist/index.js +5543 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5501 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/env.ts","../src/http.ts","../src/errors.ts","../src/tools/whoami.ts","../src/api.ts","../src/tools/code-repositories/shared.ts","../src/tools/cases/shared.ts","../src/tools/cases/list.ts","../src/tools/cases/get.ts","../src/tools/cases/customFields.ts","../src/tools/cases/steps.ts","../src/tools/cases/fetchDetail.ts","../src/tools/cases/create.ts","../src/tools/cases/update.ts","../src/tools/cases/delete.ts","../src/tools/cases/index.ts","../src/tools/folders/shared.ts","../src/tools/folders/list.ts","../src/tools/folders/get.ts","../src/tools/folders/create.ts","../src/tools/folders/update.ts","../src/tools/folders/delete.ts","../src/tools/folders/index.ts","../src/tools/tags/list.ts","../src/tools/tags/index.ts","../src/tools/projects/list.ts","../src/tools/projects/index.ts","../src/tools/runs/shared.ts","../src/tools/runs/list.ts","../src/tools/runs/get.ts","../src/tools/runs/cases.ts","../src/tools/runs/results/list.ts","../src/tools/runs/results/get.ts","../src/tools/runs/results/create.ts","../src/tools/runs/results/index.ts","../src/tools/runs/create.ts","../src/tools/runs/update.ts","../src/tools/runs/cases-add.ts","../src/tools/runs/index.ts","../src/tools/sessions/shared.ts","../src/tools/sessions/list.ts","../src/tools/sessions/get.ts","../src/tools/sessions/results/list.ts","../src/tools/sessions/results/get.ts","../src/tools/sessions/results/index.ts","../src/tools/sessions/findings.ts","../src/tools/sessions/create.ts","../src/tools/sessions/update.ts","../src/tools/sessions/index.ts","../src/tools/code-repositories/list.ts","../src/tools/code-repositories/index.ts","../src/tools/issues/shared.ts","../src/tools/issues/find-by-key.ts","../src/tools/issues/list.ts","../src/tools/issues/get.ts","../src/tools/issues/links.ts","../src/tools/issues/link.ts","../src/tools/issues/index.ts","../src/tools/repository-case-links/shared.ts","../src/tools/repository-case-links/list.ts","../src/tools/repository-case-links/index.ts","../src/tools/milestones/shared.ts","../src/tools/milestones/list.ts","../src/tools/milestones/get.ts","../src/tools/milestones/types-list.ts","../src/tools/milestones/create.ts","../src/tools/milestones/update.ts","../src/tools/milestones/index.ts","../src/tools/index.ts","../src/server.ts","../src/cli.ts"],"names":["z","z2","TIMEOUT_MS","parsed","z4","coerceOptionId","z5","z6","z7","z8","z9","z10","z11","z12","z13","DEFAULT_LIMIT","MAX_LIMIT","z14","z15","z16","z17","z18","bearerHeaders","z19","TESTCASES_INLINE_LIMIT","MAX_CASE_IDS","z20","z21","z22","mapIssue","mapAttachment","z23","z24","z25","z26","z27","result","SESSION_RESULTS_INLINE_CAP","z28","z29","z30","ISSUE_DETAIL_INCLUDE","z31","z32","z33","z34","rows","hasNextPage","trimmed","items","nextCursor","z35","z36","FETCH_TIMEOUT_MS","z37","z38","z39","z40","z41"],"mappings":"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","file":"index.mjs","sourcesContent":["import * as z from \"zod/v4\";\n\nconst DEFAULT_API_URL = \"https://app.testplanit.com\";\n\nconst EnvSchema = z.object({\n TESTPLANIT_API_TOKEN: z\n .string()\n .regex(/^tpi_/, \"Token must start with tpi_\"),\n TESTPLANIT_API_URL: z.string().url().default(DEFAULT_API_URL),\n});\n\nexport interface EnvConfig {\n apiToken: string;\n apiUrl: string;\n}\n\n/**\n * Parse and validate the MCP server's environment.\n *\n * Throws a zod validation error when:\n * - `TESTPLANIT_API_TOKEN` is missing or does not start with `tpi_`\n * - `TESTPLANIT_API_URL` is set but is not a valid URL (omitting it uses the SaaS default)\n *\n * The returned `apiUrl` is normalized (trailing slash stripped).\n */\nexport function parseEnv(env: NodeJS.ProcessEnv): EnvConfig {\n const parsed = EnvSchema.parse(env);\n return {\n apiToken: parsed.TESTPLANIT_API_TOKEN,\n apiUrl: parsed.TESTPLANIT_API_URL.replace(/\\/$/, \"\"),\n };\n}\n","import type { EnvConfig } from \"./env.js\";\n\n/**\n * Response shape from `GET /api/auth/whoami` — locked in lockstep with\n * plan 05-02. Field semantics (frozen contract):\n * - `readOnly === scopes.includes(\"mode:read\")`\n * - `isAgent === scopes.includes(\"client:mcp\")`\n */\nexport interface WhoamiUser {\n id: string;\n name: string | null;\n email: string;\n scopes: string[];\n readOnly: boolean;\n isAgent: boolean;\n}\n\n/**\n * Result of `validateToken()`.\n *\n * The failure variant carries `code` (upstream errorCode such as\n * `READ_ONLY_TOKEN`, `EXPIRED_TOKEN`) and `statusCode` (HTTP status) so\n * downstream tools — plan 05-07's `whoami` and Phase 6+ write tools —\n * can construct `TestPlanItHttpError` without re-parsing the message\n * string. This shape is locked at plan 05-06 and consumed directly by\n * plan 05-07; do NOT widen retroactively.\n */\nexport type ValidateResult =\n | { ok: true; user: WhoamiUser }\n | { ok: false; message: string; code?: string; statusCode?: number };\n\n/**\n * Error class carrying upstream HTTP status + errorCode for tool handlers.\n * Plan 05-07 throws this from the `whoami` tool when validateToken returns\n * `ok: false` so the MCP error mapping retains the upstream codes.\n */\nexport class TestPlanItHttpError extends Error {\n public statusCode?: number;\n public code?: string;\n constructor(\n message: string,\n opts?: { statusCode?: number; code?: string },\n ) {\n super(message);\n this.name = \"TestPlanItHttpError\";\n this.statusCode = opts?.statusCode;\n this.code = opts?.code;\n }\n}\n\n/**\n * Returns at most the `tpi_xxxx`-style 8-character prefix of the token for\n * safe diagnostics. Never returns the full token. T-05-06 mitigation.\n */\nexport function redactToken(token: string): string {\n return token.slice(0, 8) + \"...\";\n}\n\nconst TIMEOUT_MS = 10000;\n\n/**\n * Probe `GET /api/auth/whoami` with the configured Bearer token.\n *\n * Returns `{ ok: true, user }` on a 200 response with a valid JSON body.\n * Returns `{ ok: false, message, code?, statusCode? }` on any non-2xx,\n * unparseable body, or transport failure. The error message NEVER contains\n * the raw token — only the redacted prefix appears (T-05-06).\n */\nexport async function validateToken(\n env: EnvConfig,\n): Promise<ValidateResult> {\n let response: Response;\n try {\n const url = new URL(\"/api/auth/whoami\", env.apiUrl);\n response = await fetch(url, {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${env.apiToken}`,\n \"Content-Type\": \"application/json\",\n },\n signal: AbortSignal.timeout(TIMEOUT_MS),\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n ok: false,\n message: `Network error contacting ${env.apiUrl}: ${message}`,\n // code + statusCode intentionally undefined — transport failure, not HTTP.\n };\n }\n\n const body = await response.text();\n\n if (!response.ok) {\n let code: string | undefined;\n try {\n const parsed = JSON.parse(body);\n if (parsed && typeof parsed.code === \"string\") {\n code = parsed.code;\n }\n } catch {\n // Body is not JSON — code stays undefined.\n }\n return {\n ok: false,\n message: `HTTP ${response.status}${code ? ` (${code})` : \"\"}: token ${redactToken(env.apiToken)} rejected`,\n code,\n statusCode: response.status,\n };\n }\n\n try {\n const user = JSON.parse(body) as WhoamiUser;\n return { ok: true, user };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n ok: false,\n message: `Failed to parse whoami response from ${env.apiUrl}: ${message}`,\n };\n }\n}\n","import { TestPlanItHttpError } from \"./http.js\";\n\n/**\n * MCP tool-result error envelope.\n *\n * The SDK accepts either a thrown exception (which it auto-converts) OR an\n * explicit return value with `isError: true`. We use the explicit form so\n * tool handlers control the agent-visible message verbatim — no SDK\n * stack-trace leakage and no opaque \"An error occurred\" wrappers.\n *\n * Reference: 05-RESEARCH.md § Don't Hand-Roll row \"Tool error formatting\".\n */\nexport interface ToolErrorResult {\n isError: true;\n content: Array<{ type: \"text\"; text: string }>;\n // Index signature satisfies the MCP SDK's CallToolResult contract, which\n // permits arbitrary string keys (e.g., `_meta`, future fields). Without\n // this, `registerTool`'s callback rejects our return type.\n [x: string]: unknown;\n}\n\n/**\n * Friendly translations for every known errorCode emitted by\n * `lib/api-token-auth.ts` (host side, post plan 05-01).\n *\n * The READ_ONLY_TOKEN message is the T-05-01 mitigation surface — it MUST\n * name both the scope (`mode:read`) and the human concept (`read-only`) so\n * agents can self-correct when a Phase 6+ write tool returns 403.\n */\nconst ERROR_CODE_MESSAGES: Record<string, string> = {\n NO_TOKEN:\n \"No API token provided. Set TESTPLANIT_API_TOKEN in the environment.\",\n INVALID_FORMAT:\n \"API token format is invalid. Tokens must start with 'tpi_'.\",\n INVALID_TOKEN:\n \"API token is not recognized. Verify the token in your TestPlanIt profile.\",\n EXPIRED_TOKEN:\n \"API token has expired. Mint a new token in your TestPlanIt profile.\",\n INACTIVE_TOKEN:\n \"API token is inactive. Re-enable or replace it in your TestPlanIt profile.\",\n INACTIVE_USER:\n \"The user associated with this token is inactive. Contact a TestPlanIt admin.\",\n API_ACCESS_DISABLED:\n \"API access is disabled for this user. Contact a TestPlanIt admin.\",\n READ_ONLY_TOKEN:\n \"This token is read-only (mode:read scope). Create a new token without the mode:read scope to perform write operations.\",\n};\n\n/**\n * Defense-in-depth scrub: redact any `tpi_<token>` substring that may have\n * leaked into an error message before we hand the text to the agent\n * (WR-03 / T-05-06b). The api.ts layer already avoids interpolating\n * env.apiToken into messages, but a future regression — or a host echoing\n * a header verbatim — would otherwise leak through `mapHttpErrorToToolResult`.\n *\n * Matches the `tpi_` prefix followed by URL-safe token characters; pasted\n * tokens, base64url-suffixed tokens, and shorter prefixes all collapse to\n * the literal string `tpi_***`.\n */\nconst TOKEN_PATTERN = /tpi_[A-Za-z0-9_-]+/g;\n\nfunction redactTokens(text: string): string {\n return text.replace(TOKEN_PATTERN, \"tpi_***\");\n}\n\n/**\n * Translate any thrown error from a tool handler into the MCP tool-result\n * error envelope. Three paths:\n *\n * 1. `TestPlanItHttpError` with a known `code`: friendly template, code\n * appended in parentheses for log-grep traceability.\n * 2. `TestPlanItHttpError` with an unknown / missing code: generic\n * \"Request failed: <message> (HTTP <status>)\" fallback.\n * 3. Any other `Error`: \"Network or runtime error: <message>\" fallback.\n * 4. Non-Error throwable: \"Unknown error\".\n *\n * The friendly templates are fixed strings, NOT echoes of `err.message`,\n * so a token-bearing message accidentally constructed upstream cannot leak\n * the raw token through this layer (T-05-06 defense in depth). The fallback\n * paths DO interpolate `err.message`, so the final text is run through\n * `redactTokens` as a belt-and-suspenders scrub (WR-03).\n */\nexport function mapHttpErrorToToolResult(err: unknown): ToolErrorResult {\n if (err instanceof TestPlanItHttpError) {\n const code = err.code;\n const friendly = code ? ERROR_CODE_MESSAGES[code] : undefined;\n const rawText = friendly\n ? `${friendly} (${code})`\n : `Request failed: ${err.message} (HTTP ${err.statusCode ?? \"unknown\"})`;\n return { isError: true, content: [{ type: \"text\", text: redactTokens(rawText) }] };\n }\n if (err instanceof Error) {\n return {\n isError: true,\n content: [\n { type: \"text\", text: redactTokens(`Network or runtime error: ${err.message}`) },\n ],\n };\n }\n return {\n isError: true,\n content: [{ type: \"text\", text: \"Unknown error\" }],\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { validateToken, TestPlanItHttpError } from \"../http.js\";\nimport type { EnvConfig } from \"../env.js\";\nimport { mapHttpErrorToToolResult } from \"../errors.js\";\n\nexport interface WhoamiDeps {\n env: EnvConfig;\n}\n\n/**\n * Register the `whoami` MCP tool — the production replacement for plan\n * 05-06's smoke tool.\n *\n * The tool re-fetches `GET /api/auth/whoami` on every invocation (NOT\n * cached from the bootstrap probe) so scope changes — particularly the\n * read-only flag — reflect immediately.\n *\n * On failure, the handler consumes the wider `ValidateResult` shape locked\n * in plan 05-06 by reading `probe.code` and `probe.statusCode` directly,\n * NOT by string-parsing `probe.message`. The constructed\n * `TestPlanItHttpError` is then translated by `mapHttpErrorToToolResult`\n * which knows how to format `READ_ONLY_TOKEN` (T-05-01 mitigation) and the\n * other 7 host errorCodes.\n *\n * The description starts with `\"Debug:\"` so well-behaved agents\n * deprioritize this tool versus the data tools shipping in Phase 6+.\n */\nexport function registerWhoami(server: McpServer, deps: WhoamiDeps): void {\n server.registerTool(\n \"whoami\",\n {\n description:\n \"Debug: returns the authenticated user (token owner) and scopes.\",\n // RAW zod shape per SDK Pitfall 4 — NOT z.object({}).\n inputSchema: {},\n outputSchema: {\n id: z.string(),\n name: z.string().nullable(),\n email: z.string().email(),\n scopes: z.array(z.string()),\n readOnly: z.boolean(),\n isAgent: z.boolean(),\n },\n },\n async () => {\n try {\n const probe = await validateToken(deps.env);\n if (!probe.ok) {\n // Consume the wider ValidateResult shape locked in plan 05-06.\n // probe.code and probe.statusCode flow through unchanged — no\n // string-includes parsing of probe.message.\n throw new TestPlanItHttpError(probe.message, {\n statusCode: probe.statusCode,\n code: probe.code,\n });\n }\n // The MCP SDK's tool-result `structuredContent` is typed as\n // `Record<string, unknown>`. WhoamiUser is locked at plan 05-06 and\n // does not carry an index signature, so we widen here at the\n // boundary — the runtime shape is unchanged, the cast only\n // satisfies TS's structural compatibility check against the SDK's\n // CallToolResult contract.\n return {\n content: [{ type: \"text\", text: JSON.stringify(probe.user) }],\n structuredContent: { ...probe.user } as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { TestPlanItHttpError } from \"./http.js\";\nimport type { EnvConfig } from \"./env.js\";\n\n/**\n * ZenStack RPC envelope returned by `/api/model/{model}/{operation}`.\n * On success: `{ data: T }`. On error: `{ error: { message, code? } }`.\n * Some failure modes return `error` as a string — handled explicitly below.\n */\ninterface ZenStackResponse<T> {\n data?: T;\n error?: { message: string; code?: string } | string;\n}\n\nconst READ_OPS = new Set([\n \"findMany\",\n \"findFirst\",\n \"findUnique\",\n \"count\",\n \"aggregate\",\n \"groupBy\",\n]);\nconst POST_OPS = new Set([\"create\", \"createMany\", \"upsert\"]);\nconst PATCH_OPS = new Set([\"update\", \"updateMany\"]);\nconst DELETE_OPS = new Set([\"delete\", \"deleteMany\"]);\n\nconst TIMEOUT_MS = 10000;\n\nfunction bearerHeaders(env: EnvConfig): Record<string, string> {\n return {\n Authorization: `Bearer ${env.apiToken}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\n/**\n * Internal ZenStack RPC client.\n *\n * Replicates the dispatch pattern from `packages/api/src/client.ts` so\n * `@testplanit/mcp-server` has NO dependency on `@testplanit/api` (D-01).\n *\n * Read operations use GET with `?q=encodeURIComponent(JSON.stringify(body))`.\n * Write operations use POST/PATCH/DELETE with the JSON body.\n *\n * Errors:\n * - Non-2xx → throws TestPlanItHttpError with statusCode + (when present) code\n * parsed from the response body. Critical: HTTP 422 may be a route.ts\n * remap of a ZenStack 403 (policy denial) or 404 (P2025 missing record).\n * The error mapper in errors.ts disambiguates by message content.\n * - 2xx with `error` envelope → throws TestPlanItHttpError with envelope code.\n * - 2xx with `data` → returns `data` unwrapped.\n *\n * Soft-delete invariant: callers MUST use `update` with `{ data: { isDeleted: true } }`\n * for soft-delete, NEVER the `delete` or `deleteMany` operations (T-06-06).\n */\nexport async function zenstack<T>(\n model: string,\n operation: string,\n body: unknown,\n env: EnvConfig,\n): Promise<T> {\n const baseUrl = env.apiUrl;\n let response: Response;\n\n if (READ_OPS.has(operation)) {\n const q = body !== undefined && body !== null\n ? `?q=${encodeURIComponent(JSON.stringify(body))}`\n : \"\";\n response = await fetch(`${baseUrl}/api/model/${model}/${operation}${q}`, {\n method: \"GET\",\n headers: bearerHeaders(env),\n signal: AbortSignal.timeout(TIMEOUT_MS),\n });\n } else {\n const method = POST_OPS.has(operation)\n ? \"POST\"\n : PATCH_OPS.has(operation)\n ? \"PATCH\"\n : DELETE_OPS.has(operation)\n ? \"DELETE\"\n : \"POST\"; // default for any unrecognized op\n response = await fetch(`${baseUrl}/api/model/${model}/${operation}`, {\n method,\n headers: bearerHeaders(env),\n body: JSON.stringify(body ?? {}),\n signal: AbortSignal.timeout(TIMEOUT_MS),\n });\n }\n\n const text = await response.text();\n\n if (!response.ok) {\n let code: string | undefined;\n let parsedMessage: string | undefined;\n try {\n const parsed = JSON.parse(text) as Record<string, unknown>;\n // Body shapes seen in the wild:\n // { error: \"msg\", code: \"X\" }\n // { error: { message: \"msg\", code: \"X\" } }\n if (parsed && typeof parsed[\"code\"] === \"string\") {\n code = parsed[\"code\"] as string;\n }\n const errField = parsed?.[\"error\"];\n if (errField && typeof errField === \"object\") {\n const errObj = errField as Record<string, unknown>;\n if (typeof errObj[\"code\"] === \"string\") code = errObj[\"code\"] as string;\n if (typeof errObj[\"message\"] === \"string\") parsedMessage = errObj[\"message\"] as string;\n }\n if (typeof errField === \"string\") {\n parsedMessage = errField;\n }\n } catch {\n // body is not JSON; code stays undefined\n }\n // NEVER include the bearer token in error messages (T-06-05 / T-05-06b).\n // We refer to the path + status only — no env.apiToken interpolation.\n throw new TestPlanItHttpError(\n `HTTP ${response.status} from /api/model/${model}/${operation}${parsedMessage ? `: ${parsedMessage}` : \"\"}`,\n { statusCode: response.status, code },\n );\n }\n\n let parsed: ZenStackResponse<T>;\n try {\n parsed = JSON.parse(text) as ZenStackResponse<T>;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new TestPlanItHttpError(\n `Failed to parse ZenStack response from /api/model/${model}/${operation}: ${msg}`,\n { statusCode: response.status },\n );\n }\n\n if (parsed?.error) {\n const errMessage =\n typeof parsed.error === \"string\"\n ? parsed.error\n : parsed.error.message;\n const errCode =\n typeof parsed.error === \"object\" && parsed.error !== null\n ? parsed.error.code\n : undefined;\n throw new TestPlanItHttpError(errMessage, { code: errCode });\n }\n return parsed.data as T;\n}\n\n/**\n * Name → ID lookup via `/api/cli/lookup` (D-02).\n *\n * NOT all entity types are supported — see VERIFIED type union below. Notably,\n * `CaseField` is NOT a lookup type; resolve custom fields via\n * `zenstack(\"caseFields\", \"findMany\", { where: { displayName: ..., isDeleted: false } })`.\n *\n * The `state` lookup type hardcodes `WorkflowScope.RUNS` on the host\n * (`/api/cli/lookup/route.ts` line 106). For case workflow state, use\n * `resolveCaseWorkflowState` instead.\n */\nexport type LookupType =\n | \"project\"\n | \"state\"\n | \"config\"\n | \"milestone\"\n | \"tag\"\n | \"folder\"\n | \"testRun\";\n\nexport interface LookupRequest {\n type: LookupType;\n name: string;\n projectId?: number;\n createIfMissing?: boolean;\n}\n\nexport interface LookupResponse {\n id: number;\n name: string;\n created?: boolean;\n}\n\nexport async function lookup(\n options: LookupRequest,\n env: EnvConfig,\n): Promise<LookupResponse> {\n const response = await fetch(`${env.apiUrl}/api/cli/lookup`, {\n method: \"POST\",\n headers: bearerHeaders(env),\n body: JSON.stringify(options),\n signal: AbortSignal.timeout(TIMEOUT_MS),\n });\n const text = await response.text();\n if (!response.ok) {\n // WR-08: mirror the zenstack() error parser so a host-side\n // validation message (\"tag name length exceeds limit\") reaches the\n // agent instead of a generic `HTTP 400 from /api/cli/lookup`.\n let code: string | undefined;\n let parsedMessage: string | undefined;\n try {\n const parsed = JSON.parse(text) as Record<string, unknown>;\n if (typeof parsed?.[\"code\"] === \"string\") code = parsed[\"code\"] as string;\n const errField = parsed?.[\"error\"];\n if (errField && typeof errField === \"object\") {\n const errObj = errField as Record<string, unknown>;\n if (typeof errObj[\"code\"] === \"string\") code = errObj[\"code\"] as string;\n if (typeof errObj[\"message\"] === \"string\") parsedMessage = errObj[\"message\"] as string;\n } else if (typeof errField === \"string\") {\n parsedMessage = errField;\n }\n } catch {\n // body is not JSON; leave parsedMessage / code undefined\n }\n // T-06-05 / T-05-06b: NEVER include the bearer token in error\n // messages — we only echo the parsed envelope `message`, never the\n // raw body or env.apiToken.\n throw new TestPlanItHttpError(\n `HTTP ${response.status} from /api/cli/lookup${parsedMessage ? `: ${parsedMessage}` : \"\"}`,\n { statusCode: response.status, code },\n );\n }\n return JSON.parse(text) as LookupResponse;\n}\n\n/**\n * Resolve the single active repository for a project. Cases and folders\n * require `repositoryId` on create; the active repository is selected by\n * the first row matching `isActive=true, isDeleted=false, isArchived=false`.\n *\n * Throws TestPlanItHttpError with statusCode 422 (host-class \"operation\n * refused / missing context\") when no active repository exists, with a\n * human-readable message instructing the user to initialize the repo via\n * the TestPlanIt UI. The 422 status routes the error through the same\n * `mapHttpErrorToToolResult` branch as host-side missing-record errors.\n */\nexport async function resolveActiveRepository(\n projectId: number,\n env: EnvConfig,\n): Promise<number> {\n const repos = await zenstack<{ id: number }[]>(\n \"repositories\",\n \"findMany\",\n {\n where: {\n projectId,\n isActive: true,\n isDeleted: false,\n isArchived: false,\n },\n select: { id: true },\n take: 1,\n },\n env,\n );\n if (!repos || repos.length === 0) {\n throw new TestPlanItHttpError(\n `No active repository found for project ${projectId}. Open TestPlanIt and add a test case to initialize the repository.`,\n { statusCode: 422 },\n );\n }\n return repos[0].id;\n}\n\n/**\n * Resolve a default template assigned to the project (cases require\n * `templateId` per RepositoryCases.templateId being non-nullable —\n * VERIFIED in schema.zmodel).\n */\nexport async function resolveDefaultTemplate(\n projectId: number,\n env: EnvConfig,\n): Promise<number> {\n const templates = await zenstack<{ id: number }[]>(\n \"templates\",\n \"findMany\",\n {\n where: {\n isDeleted: false,\n isEnabled: true,\n projects: { some: { projectId } },\n },\n select: { id: true },\n orderBy: { id: \"asc\" },\n take: 1,\n },\n env,\n );\n if (!templates || templates.length === 0) {\n throw new TestPlanItHttpError(\n `No enabled template assigned to project ${projectId}. Assign a template to the project from the TestPlanIt admin UI.`,\n { statusCode: 422 },\n );\n }\n return templates[0].id;\n}\n\n/**\n * Resolve a workflow state for the CASES scope (NOT runs). Pass `name` to\n * select by name; omit to take the first by `order asc`.\n *\n * Cannot use `/api/cli/lookup` — that endpoint hardcodes\n * `WorkflowScope.RUNS` (see /api/cli/lookup/route.ts line 106).\n */\nexport async function resolveCaseWorkflowState(\n projectId: number,\n env: EnvConfig,\n name?: string,\n): Promise<{ id: number; name: string }> {\n const workflows = await zenstack<{ id: number; name: string }[]>(\n \"workflows\",\n \"findMany\",\n {\n where: {\n isEnabled: true,\n isDeleted: false,\n scope: \"CASES\",\n projects: { some: { projectId } },\n ...(name ? { name } : {}),\n },\n orderBy: { order: \"asc\" },\n take: 1,\n },\n env,\n );\n if (!workflows || workflows.length === 0) {\n const suffix = name ? ` named \"${name}\"` : \"\";\n throw new TestPlanItHttpError(\n `No CASES-scope workflow state found for project ${projectId}${suffix}.`,\n { statusCode: 422 },\n );\n }\n return workflows[0];\n}\n","import type { Prisma } from \"@prisma/client\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Typed include — `as const satisfies Prisma.ProjectCodeRepositoryConfigInclude`\n// makes reintroduction of an unknown field a TS2353 at compile time. The\n// `repository` join is `select`-only; `credentials` is INTENTIONALLY ABSENT so\n// the secrets column never crosses the wire (defense-in-depth — REPO-01 /\n// T-08-CRED-LEAK).\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const PROJECT_REPO_CONFIG_INCLUDE = {\n repository: {\n select: {\n id: true,\n name: true,\n provider: true,\n status: true,\n lastTestedAt: true,\n settings: true,\n // credentials INTENTIONALLY ABSENT — defense in depth, never expose secrets in MCP responses\n },\n },\n} as const satisfies Prisma.ProjectCodeRepositoryConfigInclude;\n\n// Per-provider allow-list for the wholesale `settings` JSON. Keys outside this\n// list are stripped at the mapper boundary (T-08-CRED-LEAK mitigation #2).\n// Verified against testplanit/lib/integrations/adapters/*RepoAdapter.ts.\nexport const SETTINGS_ALLOW_LIST = {\n GITHUB: [\"owner\", \"repo\"],\n GITLAB: [\"baseUrl\", \"owner\", \"repo\"],\n BITBUCKET: [\"baseUrl\", \"owner\", \"repo\"],\n AZURE_DEVOPS: [\"organizationUrl\", \"project\", \"repositoryId\"],\n GITEA: [\"baseUrl\", \"owner\", \"repo\"],\n} as const;\n\ntype ProviderKey = keyof typeof SETTINGS_ALLOW_LIST;\n\nfunction isProviderKey(p: string): p is ProviderKey {\n return Object.prototype.hasOwnProperty.call(SETTINGS_ALLOW_LIST, p);\n}\n\nexport function stripSettings(\n provider: string,\n raw: unknown,\n): Record<string, string> {\n if (!raw || typeof raw !== \"object\" || !isProviderKey(provider)) return {};\n const allow = SETTINGS_ALLOW_LIST[provider];\n const out: Record<string, string> = {};\n for (const key of allow) {\n const v = (raw as Record<string, unknown>)[key];\n if (typeof v === \"string\") out[key] = v;\n }\n return out;\n}\n\nexport function deriveWebUrl(\n provider: string,\n settings: Record<string, string>,\n): string | null {\n switch (provider) {\n case \"GITHUB\":\n return settings.owner && settings.repo\n ? `https://github.com/${settings.owner}/${settings.repo}`\n : null;\n case \"GITLAB\":\n case \"BITBUCKET\":\n case \"GITEA\":\n return settings.baseUrl && settings.owner && settings.repo\n ? `${settings.baseUrl.replace(/\\/$/, \"\")}/${settings.owner}/${settings.repo}`\n : null;\n case \"AZURE_DEVOPS\":\n return settings.organizationUrl &&\n settings.project &&\n settings.repositoryId\n ? `${settings.organizationUrl.replace(/\\/$/, \"\")}/${settings.project}/_git/${settings.repositoryId}`\n : null;\n default:\n return null;\n }\n}\n\nexport interface RawCodeRepoConfigRow {\n id: number;\n projectId: number;\n branch: string | null;\n pathPatterns: unknown;\n cacheEnabled: boolean;\n cacheTtlDays: number;\n cacheStatus: string | null;\n cacheLastFetchedAt: Date | string | null;\n cacheFileCount: number | null;\n cacheTotalSize: bigint | number | null;\n cacheError: string | null;\n repository: {\n id: number;\n name: string;\n provider: string;\n status: string;\n lastTestedAt: Date | string | null;\n settings: unknown;\n };\n}\n\nexport function mapCodeRepoConfig(raw: RawCodeRepoConfigRow) {\n const settings = stripSettings(raw.repository.provider, raw.repository.settings);\n return {\n id: raw.id,\n projectId: raw.projectId,\n branch: raw.branch ?? null,\n pathPatterns: Array.isArray(raw.pathPatterns) ? raw.pathPatterns : [],\n cacheEnabled: raw.cacheEnabled,\n cacheTtlDays: raw.cacheTtlDays,\n cacheStatus: raw.cacheStatus ?? null,\n cacheLastFetchedAt: raw.cacheLastFetchedAt ?? null,\n cacheFileCount: raw.cacheFileCount ?? null,\n // BigInt → Number coercion (RESEARCH § Pitfall 6) — JSON.stringify rejects\n // BigInt, so the cache size column must be widened to a regular number at\n // the mapper boundary. PostgreSQL int8 fits in a JS number when the\n // logical value is bytes (Number.MAX_SAFE_INTEGER ≈ 9 PiB).\n cacheTotalSize:\n raw.cacheTotalSize != null ? Number(raw.cacheTotalSize) : null,\n cacheError: raw.cacheError ?? null,\n repository: {\n id: raw.repository.id,\n name: raw.repository.name,\n provider: raw.repository.provider,\n status: raw.repository.status,\n lastTestedAt: raw.repository.lastTestedAt ?? null,\n settings,\n url: deriveWebUrl(raw.repository.provider, settings),\n },\n };\n}\n","import type { Prisma } from \"@prisma/client\";\nimport { zenstack, lookup } from \"../../api.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { deriveWebUrl, stripSettings } from \"../code-repositories/shared.js\";\n\n/**\n * Resolve tag IDs from a mixed array of existing IDs (numbers) and tag\n * names (strings). Names are resolved via lookup with createIfMissing:true,\n * so the first reference to a new tag name lazily creates it. Empty string\n * tags are rejected (Pitfall 5). Shared between cases/create.ts and\n * cases/update.ts to avoid divergent copies (WR-07).\n */\nexport async function resolveTagIds(\n tags: Array<number | string> | undefined,\n env: EnvConfig,\n): Promise<number[]> {\n if (!tags || tags.length === 0) return [];\n const out: number[] = [];\n for (const t of tags) {\n if (typeof t === \"number\") {\n out.push(t);\n continue;\n }\n if (typeof t !== \"string\" || t.length === 0) {\n throw new TestPlanItHttpError(\"Empty tag name not allowed.\", { statusCode: 422 });\n }\n const result = await lookup({ type: \"tag\", name: t, createIfMissing: true }, env);\n out.push(result.id);\n }\n return out;\n}\n\n/**\n * Block-level node types per Tiptap / ProseMirror schema. Children of\n * these nodes are joined inline (no extra newlines between text runs);\n * the newline goes BETWEEN sibling block nodes only. Inline-content\n * containers (e.g., `text` itself) never appear here.\n *\n * (WR-05: previously the walker inserted \"\\n\" between every non-paragraph\n * child, corrupting code blocks and over-indenting nested lists.)\n */\nconst BLOCK_TYPES = new Set([\n \"paragraph\",\n \"code_block\",\n \"codeBlock\",\n \"heading\",\n \"list_item\",\n \"listItem\",\n \"blockquote\",\n]);\n\n/**\n * Walk a Tiptap ProseMirror document and extract concatenated plain text.\n * Marks (bold, italic, links) are ignored — only `text` nodes contribute.\n *\n * Newlines are inserted BETWEEN block-level nodes (paragraphs, headings,\n * code blocks, list items, blockquotes) — never within them. This matches\n * Tiptap `Node.textBetween` semantics and avoids the corruption mode\n * where a code block with two text runs gets a stray newline injected\n * between the runs (WR-05).\n *\n * Defensive: returns `\"\"` on null/undefined, or the string itself if\n * input is already a primitive string.\n */\nexport function extractProseMirrorText(doc: unknown): string {\n if (doc == null) return \"\";\n if (typeof doc === \"string\") return doc;\n\n const collectFromNode = (node: unknown): string => {\n if (!node || typeof node !== \"object\") return \"\";\n const n = node as { type?: string; text?: string; content?: unknown[] };\n if (n.type === \"text\" && typeof n.text === \"string\") return n.text;\n if (Array.isArray(n.content)) {\n // For block-level nodes, children are inline — concatenate without\n // separators. For container nodes (doc, bullet_list, ordered_list,\n // etc.), children are themselves blocks — join with \"\\n\".\n const isBlock = n.type ? BLOCK_TYPES.has(n.type) : false;\n const parts = n.content.map(collectFromNode);\n return isBlock ? parts.join(\"\") : parts.join(\"\\n\");\n }\n return \"\";\n };\n\n const root = doc as { type?: string; content?: unknown[] };\n if (Array.isArray(root)) {\n return (root as unknown[]).map(collectFromNode).join(\"\\n\");\n }\n if (root.type === \"doc\" && Array.isArray(root.content)) {\n return root.content.map(collectFromNode).join(\"\\n\");\n }\n return collectFromNode(doc);\n}\n\ninterface RawFieldOptionAssignment {\n fieldOption?: { id: number; name: string } | null;\n}\n\ninterface RawCaseFieldValueRow {\n value: unknown;\n field?: {\n displayName?: string | null;\n type?: { type?: string | null } | null;\n fieldOptions?: RawFieldOptionAssignment[] | null;\n } | null;\n}\n\n/**\n * Convert raw `caseFieldValues` rows into the flat `{ <displayName>: value }`\n * dict per D-08. For Dropdown / Multi-Select fields, resolve the stored\n * FieldOption IDs to the option's `name` so agents see the human label\n * instead of a raw FK. Other field types pass the raw value through.\n *\n * Rows with missing field metadata or unresolved option IDs fall back to\n * the raw value rather than dropping the entry.\n */\nexport function denormalizeCustomFields(\n rows: RawCaseFieldValueRow[] | null | undefined,\n): Record<string, unknown> {\n if (!rows || rows.length === 0) return {};\n const out: Record<string, unknown> = {};\n for (const row of rows) {\n const name = row.field?.displayName;\n if (typeof name !== \"string\" || name.length === 0) continue;\n out[name] = resolveCustomFieldValue(row.value, row.field);\n }\n return out;\n}\n\nfunction resolveCustomFieldValue(\n value: unknown,\n field: RawCaseFieldValueRow[\"field\"],\n): unknown {\n const type = field?.type?.type;\n const options = (field?.fieldOptions ?? [])\n .map((a) => a.fieldOption)\n .filter((o): o is { id: number; name: string } => o != null);\n if (options.length === 0) return value;\n\n const byId = new Map<number, string>();\n for (const o of options) byId.set(o.id, o.name);\n\n if (type === \"Dropdown\") {\n const id = coerceOptionId(value);\n if (id != null && byId.has(id)) return byId.get(id);\n return value;\n }\n if (type === \"Multi-Select\") {\n if (!Array.isArray(value)) return value;\n return value.map((v) => {\n const id = coerceOptionId(v);\n return id != null && byId.has(id) ? byId.get(id) : v;\n });\n }\n return value;\n}\n\nfunction coerceOptionId(v: unknown): number | null {\n // WR-06: option IDs are positive integers — reject non-integer numerics\n // (147.5 would have silently misrouted to FieldOption 147 via the\n // byId lookup) and reject 0 / negatives.\n if (typeof v === \"number\" && Number.isInteger(v) && v > 0) return v;\n if (typeof v === \"string\" && /^\\d+$/.test(v)) {\n const n = parseInt(v, 10);\n return Number.isInteger(n) && n > 0 ? n : null;\n }\n return null;\n}\n\n/**\n * Walk parent folders to build a breadcrumb from root to leaf. Bounded at\n * depth 10 to prevent pathological recursion. Each parent fetch goes through\n * `zenstack` so the host's access policies are enforced on every row.\n */\nconst MAX_BREADCRUMB_DEPTH = 10;\n\nexport interface FolderBreadcrumbInput {\n id: number;\n name: string;\n parentId: number | null;\n}\n\nexport async function buildFolderBreadcrumb(\n leaf: FolderBreadcrumbInput,\n env: EnvConfig,\n): Promise<Array<{ id: number; name: string }>> {\n const acc: Array<{ id: number; name: string }> = [{ id: leaf.id, name: leaf.name }];\n let parentId = leaf.parentId;\n let depth = 0;\n while (parentId != null) {\n if (depth >= MAX_BREADCRUMB_DEPTH) {\n throw new TestPlanItHttpError(\n `Folder breadcrumb exceeded max depth ${MAX_BREADCRUMB_DEPTH}; possible recursive parent chain.`,\n { statusCode: 422 },\n );\n }\n const parent = await zenstack<FolderBreadcrumbInput | null>(\n \"repositoryFolders\",\n \"findUnique\",\n {\n where: { id: parentId },\n select: { id: true, name: true, parentId: true } satisfies Prisma.RepositoryFoldersSelect,\n },\n env,\n );\n if (!parent) break;\n acc.unshift({ id: parent.id, name: parent.name });\n parentId = parent.parentId;\n depth += 1;\n }\n return acc;\n}\n\n/**\n * Compute the human-readable `fullPath` from a breadcrumb array.\n * Example: [{name:\"Regression\"},{name:\"Auth\"}] → \"Regression / Auth\".\n */\nexport function fullPathFromBreadcrumb(\n breadcrumb: Array<{ name: string }>,\n): string {\n return breadcrumb.map((b) => b.name).join(\" / \");\n}\n\n// ── Row & detail mappers ──────────────────────────────────────────────────\n\n// Phase-8 D8-02: latest junit + test-run result shapes used by\n// resolveLatestResult to surface a unified `latestResult` field on each\n// case row. Junit's status is nullable on the schema (statusId Int?);\n// TestRunResults.statusId is required, so its status is non-null.\nexport interface RawLatestJunit {\n id: number;\n executedAt: Date | string | null;\n status: { id: number; name: string } | null;\n}\n\nexport interface RawLatestRunResult {\n id: number;\n executedAt: Date | string | null;\n status: { id: number; name: string };\n}\n\n/**\n * Phase-8 D8-02 lastUpdatedAt source: walk the latest version row\n * (orderBy version desc, take:1) and read its createdAt. Returns null\n * when no version exists (defensive — should not happen for hydrated\n * cases, but the include shape uses `take: 1` which returns an empty\n * array gracefully). Tests in shared.test.ts cover the present /\n * empty-array / undefined cases.\n */\nexport function lastUpdatedAtFromRaw(raw: {\n repositoryCaseVersions?: Array<{ createdAt: Date | string }>;\n}): Date | string | null {\n return raw.repositoryCaseVersions?.[0]?.createdAt ?? null;\n}\n\n/**\n * Phase-8 D8-02 latestResult union: takes the latest junit result and\n * the latest test-run result (both `take:1` from the include shape) and\n * picks whichever has the greater executedAt. Source label distinguishes\n * the two (\"JUnit\" | \"TestRun\"). Returns null when neither has a usable\n * executedAt + status. Verbatim from RESEARCH § Example 3.\n */\nexport function resolveLatestResult(\n junit: RawLatestJunit | undefined,\n runResult: RawLatestRunResult | undefined,\n):\n | {\n id: number;\n status: { id: number; name: string };\n executedAt: Date | string;\n source: \"JUnit\" | \"TestRun\";\n }\n | null {\n const j = junit?.executedAt && junit.status ? junit : null;\n const r = runResult?.executedAt && runResult.status ? runResult : null;\n if (!j && !r) return null;\n if (j && !r) {\n return {\n id: j.id,\n status: j.status!,\n executedAt: j.executedAt!,\n source: \"JUnit\",\n };\n }\n if (r && !j) {\n return {\n id: r.id,\n status: r.status,\n executedAt: r.executedAt!,\n source: \"TestRun\",\n };\n }\n const jt = new Date(j!.executedAt!).getTime();\n const rt = new Date(r!.executedAt!).getTime();\n return jt >= rt\n ? {\n id: j!.id,\n status: j!.status!,\n executedAt: j!.executedAt!,\n source: \"JUnit\",\n }\n : {\n id: r!.id,\n status: r!.status,\n executedAt: r!.executedAt!,\n source: \"TestRun\",\n };\n}\n\ninterface RawCaseRow {\n id: number;\n name: string;\n source: string;\n automated: boolean;\n createdAt: string | Date;\n // Phase-8 (D8-02) widens project to optionally carry the\n // codeRepositoryConfig chain. Phase-6 row callers don't include this\n // sub-select so the field is optional; Phase-8 cases_get adds it via\n // CASE_DETAIL_INCLUDE.\n project: {\n id: number;\n name: string;\n codeRepositoryConfig?: {\n repository: {\n id: number;\n name: string;\n provider: string;\n status: string;\n lastTestedAt: Date | string | null;\n settings: unknown;\n } | null;\n } | null;\n };\n // WR-04: folderId is non-nullable in schema.zmodel — folder is always\n // present on a hydrated row. Call sites in get.ts / fetchDetail.ts\n // dereference raw.folder.id without a null check, so widening the\n // type here would create a runtime / compile-time mismatch.\n folder: { id: number; name: string; parentId: number | null };\n state: { id: number; name: string };\n creator: { id: string; name: string | null; email: string };\n tags: Array<{ id: number; name: string }>;\n // Phase-8 D8-02 sub-includes for lastUpdatedAt + latestResult.\n // All three are optional; rows fetched without the new include shape\n // (e.g. existing call sites in fetchDetail.ts) read undefined and\n // get null mappings.\n repositoryCaseVersions?: Array<{ createdAt: Date | string; version: number }>;\n junitResults?: RawLatestJunit[];\n testRuns?: Array<{ results: RawLatestRunResult[] }>;\n}\n\nexport function mapCaseRow(raw: RawCaseRow) {\n return {\n id: raw.id,\n name: raw.name,\n source: raw.source,\n automated: raw.automated,\n createdAt: raw.createdAt,\n project: raw.project ? { id: raw.project.id, name: raw.project.name } : null,\n folder: { id: raw.folder.id, name: raw.folder.name },\n state: raw.state ? { id: raw.state.id, name: raw.state.name } : null,\n creator: raw.creator\n ? { id: raw.creator.id, name: raw.creator.name, email: raw.creator.email }\n : null,\n tags: (raw.tags ?? []).map((t) => ({ id: t.id, name: t.name })),\n lastUpdatedAt: lastUpdatedAtFromRaw(raw),\n latestResult: resolveLatestResult(\n raw.junitResults?.[0],\n raw.testRuns?.[0]?.results?.[0],\n ),\n };\n}\n\ninterface RawCaseDetail extends RawCaseRow {\n issues: Array<{\n id: number;\n externalKey: string | null;\n integration: { provider: string } | null;\n title: string | null;\n externalStatus: string | null;\n }>;\n steps: Array<{\n id: number;\n order: number;\n step: unknown;\n expectedResult: unknown;\n }>;\n caseFieldValues: RawCaseFieldValueRow[];\n linksFrom: Array<{ caseB: { id: number; name: string; source: string } }>;\n linksTo: Array<{ caseA: { id: number; name: string; source: string } }>;\n}\n\nexport function mapCaseDetail(\n raw: RawCaseDetail,\n breadcrumb: Array<{ id: number; name: string }>,\n) {\n const linkedAutomatedTests = [\n ...raw.linksFrom.map((l) => l.caseB),\n ...raw.linksTo.map((l) => l.caseA),\n ]\n .filter((c) => c && c.source !== \"MANUAL\")\n .map((c) => ({ id: c.id, name: c.name, source: c.source }));\n\n // Phase-8 D8-02: derive inline codeRepository from the chained\n // project.codeRepositoryConfig.repository select. Reuses the 08-01\n // helpers (SETTINGS_ALLOW_LIST + stripSettings + deriveWebUrl) — never\n // forks them — so the per-provider public-key allow-list and URL\n // derivation stay in one place.\n const repo = raw.project?.codeRepositoryConfig?.repository;\n const codeRepository = repo\n ? (() => {\n const settings = stripSettings(repo.provider, repo.settings);\n return {\n id: repo.id,\n name: repo.name,\n type: repo.provider,\n url: deriveWebUrl(repo.provider, settings),\n };\n })()\n : null;\n\n return {\n ...mapCaseRow(raw),\n folderBreadcrumb: breadcrumb,\n folderFullPath: fullPathFromBreadcrumb(breadcrumb),\n steps: (raw.steps ?? []).map((s) => ({\n id: s.id,\n order: s.order,\n step: extractProseMirrorText(s.step),\n expectedResult: extractProseMirrorText(s.expectedResult),\n })),\n customFields: denormalizeCustomFields(raw.caseFieldValues),\n issues: (raw.issues ?? []).map((i) => ({\n id: i.id,\n externalKey: i.externalKey,\n externalSystem: i.integration?.provider ?? null,\n title: i.title,\n externalStatus: i.externalStatus,\n })),\n linkedAutomatedTests,\n codeRepository,\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { mapCaseRow } from \"./shared.js\";\n\nexport interface CasesListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n// Phase 8 D8-02: handler-side post-filter for staleSinceUpdate cannot be\n// expressed as a `where` clause (per-row arithmetic across two relation\n// timestamps + the versioned lastUpdatedAt). Bound the scan at 400 rows\n// (4× MAX_LIMIT) and surface `truncated: true` on the result envelope when\n// the cap is hit, so agents know they may need to page (RESEARCH § Pitfall 8).\nconst POST_FILTER_SCAN_CAP = 400;\n\nconst CASE_ROW_INCLUDE = {\n project: { select: { id: true, name: true } },\n folder: { select: { id: true, name: true, parentId: true } },\n state: { select: { id: true, name: true } },\n creator: { select: { id: true, name: true, email: true } },\n tags: { select: { id: true, name: true } },\n // Phase 8 D8-02: latest version for lastUpdatedAt + sub-orderings for\n // latestResult union. Each take:1 sub-include carries deterministic\n // orderBy [{<field>:\"desc\"},{id:\"desc\"}] (Pitfall 5 / Phase 7 MED-02).\n repositoryCaseVersions: {\n orderBy: [{ version: \"desc\" }, { id: \"desc\" }],\n take: 1,\n select: { createdAt: true, version: true },\n },\n junitResults: {\n orderBy: [{ executedAt: \"desc\" }, { id: \"desc\" }],\n take: 1,\n select: {\n id: true,\n executedAt: true,\n status: { select: { id: true, name: true } },\n },\n },\n testRuns: {\n // testRuns is the TestRunCases[] junction (RepositoryCases.testRuns).\n // Order by id desc and grab the latest result per junction row;\n // resolveLatestResult collapses the union at the mapper boundary.\n orderBy: [{ id: \"desc\" }],\n take: 1,\n select: {\n results: {\n where: { isDeleted: false },\n orderBy: [{ executedAt: \"desc\" }, { id: \"desc\" }],\n take: 1,\n select: {\n id: true,\n executedAt: true,\n status: { select: { id: true, name: true } },\n },\n },\n },\n },\n} as const satisfies Prisma.RepositoryCasesInclude;\n\n// Phase 8 D8-02: enum literals for the source filter. Mirrors\n// RepositoryCaseSource on schema.zmodel:1470 — keep synchronized.\nconst SOURCE_VALUES = [\n \"MANUAL\",\n \"JUNIT\",\n \"TESTNG\",\n \"XUNIT\",\n \"NUNIT\",\n \"MSTEST\",\n \"MOCHA\",\n \"CUCUMBER\",\n \"API\",\n] as const;\n\nexport function registerCasesList(server: McpServer, deps: CasesListDeps): void {\n server.registerTool(\n \"testplanit_cases_list\",\n {\n description:\n \"List test cases scoped to a project. Filters: folderId, tagIds, name (case-insensitive substring), stateId, customField (by display name), issueId (linked Issue numeric id — see issues_list for resolution from external keys). Cursor pagination via the `cursor` returned in `nextCursor`. (per CASE-01 + EXEC-06 chain via D7-03) \" +\n \"Phase-8 maintenance filters: automated (user-controlled flag), source (single or array of RepositoryCaseSource), repositoryId, hasNeverExecuted (no junitResults AND no TestRunResults via TestRunCases), staleSinceUpdate (handler-side post-filter — bounded scan of POST_FILTER_SCAN_CAP=400; surfaces truncated:true when scan cap hit), updatedAfter/updatedBefore (filter via the repositoryCaseVersions relation since RepositoryCases has no updatedAt column). Each row carries lastUpdatedAt and latestResult (union of latest junitResults / TestRunResults). \" +\n \"Creator and date filters: creatorIds (array of user ids — matches any; deliberately array-shaped while runs_list/sessions_list use single-string createdById), from/to (ISO 8601 createdAt range).\",\n inputSchema: {\n projectId: z.number().int().positive(),\n folderId: z.number().int().positive().optional(),\n tagIds: z.array(z.number().int().positive()).optional(),\n name: z.string().min(1).optional(),\n stateId: z.number().int().positive().optional(),\n // BL-02: only `name` is supported. Value-equality on the Json?\n // `caseFieldValues.value` column is unreliable across field types\n // (Dropdown stores option IDs, Multi-Select stores arrays, Text\n // stores strings). Silently swallowing an agent-supplied `value`\n // (the prior behavior) would let the agent act on incorrect data.\n // Dropping it from the schema makes the unsupported dimension\n // explicit; agents that need value filtering should call\n // testplanit_cases_get on candidate IDs and filter locally.\n customField: z\n .object({\n name: z.string().min(1),\n })\n .optional(),\n // D7-03: filter cases linked to a specific issue. Pass the internal\n // numeric Issue.id (the Phase-8 `issues_list` / `issues_get` `id`\n // field), NOT the externalKey. `externalKey` (e.g. \"JIRA-123\") is\n // intentionally NOT a filter dimension here because it is not\n // globally unique on the schema (`@@unique([externalId,\n // integrationId])` is the only constraint — multiple integrations\n // can have the same external key). Phase 8 ships proper issueKey\n // resolution scoped by integration.\n issueId: z.number().int().positive().optional(),\n // Phase-8 D8-02 maintenance filters.\n automated: z.boolean().optional(),\n source: z\n .union([z.enum(SOURCE_VALUES), z.array(z.enum(SOURCE_VALUES))])\n .optional(),\n repositoryId: z.number().int().positive().optional(),\n hasNeverExecuted: z.boolean().optional(),\n staleSinceUpdate: z.boolean().optional(),\n updatedAfter: z.string().datetime({ offset: true }).optional(),\n updatedBefore: z.string().datetime({ offset: true }).optional(),\n creatorIds: z.array(z.string().trim().min(1)).optional(),\n from: z.string().datetime({ offset: true }).optional(),\n to: z.string().datetime({ offset: true }).optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n // REVIEW MED-03 fix: use Prisma's typed where so reintroducing an\n // unknown column or forgetting a relation accessor TS2353s at\n // compile time. The previous `Record<string, unknown>` annotation\n // accepted any shape including `updatedAt` (which doesn't exist on\n // RepositoryCases — Pitfall 1).\n const where: Prisma.RepositoryCasesWhereInput = {\n projectId: input.projectId,\n isDeleted: false,\n };\n if (input.folderId !== undefined) where.folderId = input.folderId;\n if (input.tagIds && input.tagIds.length > 0) {\n where.tags = { some: { id: { in: input.tagIds } } };\n }\n if (input.name) {\n where.name = { contains: input.name, mode: \"insensitive\" };\n }\n if (input.stateId !== undefined) where.stateId = input.stateId;\n if (input.customField) {\n where.caseFieldValues = {\n some: { field: { displayName: input.customField.name } },\n };\n }\n if (input.issueId !== undefined) {\n // D7-03: RepositoryCases.issues is many-to-many to Issue. Filtering\n // `some: { isDeleted: false }` excludes soft-deleted issue links\n // from matching, consistent with the soft-delete invariant.\n where.issues = { some: { id: input.issueId, isDeleted: false } };\n }\n // Phase-8 D8-02 filter appends.\n if (input.automated !== undefined) where.automated = input.automated;\n if (input.source !== undefined) {\n where.source = Array.isArray(input.source)\n ? { in: input.source }\n : input.source;\n }\n if (input.repositoryId !== undefined) {\n where.repositoryId = input.repositoryId;\n }\n if (input.hasNeverExecuted) {\n // Pure-where (RESEARCH § 3.1) — no execution exists when\n // junitResults has no rows AND no TestRunCases junction has any\n // associated results.\n where.junitResults = { none: {} };\n where.testRuns = { none: { results: { some: {} } } };\n }\n if (\n input.updatedAfter !== undefined ||\n input.updatedBefore !== undefined\n ) {\n // Pitfall 1: RepositoryCases has no updatedAt column — go through\n // the repositoryCaseVersions relation (the row matching\n // currentVersion carries the canonical lastUpdatedAt).\n const createdAt: { gte?: Date; lte?: Date } = {};\n if (input.updatedAfter !== undefined) {\n createdAt.gte = new Date(input.updatedAfter);\n }\n if (input.updatedBefore !== undefined) {\n createdAt.lte = new Date(input.updatedBefore);\n }\n where.repositoryCaseVersions = { some: { createdAt } };\n }\n if (input.creatorIds && input.creatorIds.length > 0) {\n where.creatorId = { in: input.creatorIds };\n }\n if (input.from || input.to) {\n where.createdAt = {\n ...(input.from ? { gte: new Date(input.from) } : {}),\n ...(input.to ? { lte: new Date(input.to) } : {}),\n };\n }\n\n // staleSinceUpdate over-fetches up to POST_FILTER_SCAN_CAP+1 rows so\n // the handler can detect when more rows existed than the post-filter\n // could consider (Pitfall 8). Otherwise default cursor pagination.\n const fetchTake = input.staleSinceUpdate\n ? Math.min(POST_FILTER_SCAN_CAP, limit * 4) + 1\n : limit + 1;\n const body: Record<string, unknown> = {\n where,\n include: CASE_ROW_INCLUDE,\n orderBy: { id: \"asc\" },\n take: fetchTake,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows = (await zenstack<unknown[]>(\n \"repositoryCases\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n\n let scanned: unknown[] = rows;\n let staleTruncated = false;\n if (input.staleSinceUpdate) {\n // The over-fetch grabs POST_FILTER_SCAN_CAP+1 rows so we can\n // surface truncated when the underlying scan exceeded the cap.\n staleTruncated = scanned.length > POST_FILTER_SCAN_CAP;\n scanned = scanned.filter((r) => {\n const row = r as {\n repositoryCaseVersions?: Array<{ createdAt: Date | string }>;\n junitResults?: Array<{ executedAt: Date | string | null }>;\n testRuns?: Array<{\n results: Array<{ executedAt: Date | string | null }>;\n }>;\n };\n const lastUpdated = row.repositoryCaseVersions?.[0]?.createdAt;\n if (!lastUpdated) {\n // No version row → cannot compute staleness. Treat as\n // never-executed/stale per RESEARCH § 3 (the safer default\n // for a maintenance dashboard).\n return true;\n }\n const lastUpdatedMs = new Date(lastUpdated).getTime();\n const j = row.junitResults?.[0]?.executedAt;\n const t = row.testRuns?.[0]?.results?.[0]?.executedAt;\n const latestExec =\n j && t\n ? Math.max(new Date(j).getTime(), new Date(t).getTime())\n : j\n ? new Date(j).getTime()\n : t\n ? new Date(t).getTime()\n : null;\n // Stale = never executed OR latest exec strictly older than\n // the last-update timestamp.\n return latestExec === null || latestExec < lastUpdatedMs;\n });\n }\n\n const hasNextPage = input.staleSinceUpdate\n ? scanned.length > limit || staleTruncated\n : rows.length > limit;\n const trimmed = scanned.slice(0, limit);\n const items = trimmed.map((r) => mapCaseRow(r as never));\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result: Record<string, unknown> = {\n items,\n hasNextPage,\n nextCursor,\n };\n if (staleTruncated) result.truncated = true;\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { buildFolderBreadcrumb, mapCaseDetail } from \"./shared.js\";\n\nexport const CASE_DETAIL_INCLUDE = {\n // Phase-8 D8-02: surface inline codeRepository on cases_get by chaining\n // through the project's optional ProjectCodeRepositoryConfig back-relation\n // (schema.zmodel:394). The `repository` join is select-only; the secrets\n // column (credentials) is INTENTIONALLY ABSENT so it never crosses the\n // wire (defense in depth — T-08-PITFALL-7 / T-08-CRED-LEAK).\n project: {\n select: {\n id: true,\n name: true,\n codeRepositoryConfig: {\n select: {\n repository: {\n select: {\n id: true,\n name: true,\n provider: true,\n status: true,\n lastTestedAt: true,\n settings: true,\n // credentials INTENTIONALLY ABSENT — defense in depth, never expose secrets in MCP responses\n },\n },\n },\n },\n },\n },\n folder: { select: { id: true, name: true, parentId: true } },\n state: { select: { id: true, name: true } },\n creator: { select: { id: true, name: true, email: true } },\n tags: { select: { id: true, name: true } },\n issues: {\n select: {\n id: true,\n externalKey: true,\n integration: { select: { provider: true } },\n title: true,\n externalStatus: true,\n },\n },\n steps: {\n where: { isDeleted: false },\n orderBy: { order: \"asc\" },\n select: {\n id: true,\n step: true,\n expectedResult: true,\n order: true,\n },\n },\n caseFieldValues: {\n include: {\n field: {\n select: {\n displayName: true,\n type: { select: { type: true } },\n fieldOptions: {\n select: {\n fieldOption: { select: { id: true, name: true } },\n },\n },\n },\n },\n },\n },\n linksFrom: {\n where: { isDeleted: false },\n include: {\n caseB: { select: { id: true, name: true, source: true } },\n },\n },\n linksTo: {\n where: { isDeleted: false },\n include: {\n caseA: { select: { id: true, name: true, source: true } },\n },\n },\n} as const satisfies Prisma.RepositoryCasesInclude;\n\nexport interface CasesGetDeps {\n env: EnvConfig;\n}\n\nexport function registerCasesGet(server: McpServer, deps: CasesGetDeps): void {\n server.registerTool(\n \"testplanit_cases_get\",\n {\n description:\n \"Fetch a single test case by id with full denormalized details — steps (plain text), custom fields (flat dict), folder breadcrumb, tags, linked issues, linked automated tests. (per D-05 / CASE-02)\",\n inputSchema: {\n caseId: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<{\n folder: { id: number; name: string; parentId: number | null };\n [k: string]: unknown;\n }>(\n \"repositoryCases\",\n \"findUnique\",\n {\n where: { id: input.caseId },\n include: CASE_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Test case ${input.caseId} not found.`,\n },\n ],\n };\n }\n\n const breadcrumb = await buildFolderBreadcrumb(\n {\n id: raw.folder.id,\n name: raw.folder.name,\n parentId: raw.folder.parentId,\n },\n deps.env,\n );\n\n const detail = mapCaseDetail(raw as never, breadcrumb);\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import type { Prisma } from \"@prisma/client\";\nimport { zenstack } from \"../../api.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport type { EnvConfig } from \"../../env.js\";\n\nexport interface ResolvedField {\n fieldId: number;\n value: unknown;\n name: string;\n}\n\ninterface RawCaseField {\n id: number;\n displayName: string;\n type: { type: string | null } | null;\n fieldOptions: Array<{\n fieldOption: { id: number; name: string } | null;\n }>;\n}\n\nconst CASE_FIELD_RESOLVE_SELECT = {\n id: true,\n displayName: true,\n type: { select: { type: true } },\n fieldOptions: {\n select: {\n fieldOption: { select: { id: true, name: true } },\n },\n },\n} as const satisfies Prisma.CaseFieldsSelect;\n\n/**\n * Coerce a value to an option ID. Mirrors the read-side coercion in\n * shared.ts: accepts a positive integer (number or numeric string).\n * Returns null for anything else (incl. 147.5, -3, \"0\", BigInt, ...).\n */\nfunction coerceOptionId(v: unknown): number | null {\n if (typeof v === \"number\" && Number.isInteger(v) && v > 0) return v;\n if (typeof v === \"string\" && /^\\d+$/.test(v)) {\n const n = parseInt(v, 10);\n return Number.isInteger(n) && n > 0 ? n : null;\n }\n return null;\n}\n\n/**\n * Resolve a single Dropdown/Multi-Select agent value into the canonical\n * option ID stored in caseFieldValues.value. Accepts either:\n * - a numeric option ID (already canonical), OR\n * - an option name string (the shape denormalizeCustomFields returns\n * on the read path — closes the WR-01/WR-02 round-trip gap).\n *\n * Returns null when the value cannot be resolved to a valid option ID;\n * caller throws a 422 with the field name (NEVER the value, T-06-05).\n */\nfunction resolveOptionValue(\n value: unknown,\n options: Array<{ id: number; name: string }>,\n): number | null {\n const byId = new Map<number, true>();\n const byName = new Map<string, number>();\n for (const o of options) {\n byId.set(o.id, true);\n byName.set(o.name, o.id);\n }\n const id = coerceOptionId(value);\n if (id != null && byId.has(id)) return id;\n if (typeof value === \"string\" && byName.has(value)) return byName.get(value)!;\n return null;\n}\n\n/**\n * Resolve a flat `{ <displayName>: <value> }` input into resolved\n * `{ fieldId, value, name }` triples. Unknown or ambiguous display names\n * throw TestPlanItHttpError 422 — the message names the offending field\n * but NEVER includes the input value (T-06-05).\n *\n * For Dropdown / Multi-Select fields, the agent may pass either the\n * option ID (canonical) OR the option name (the read-path shape). We\n * resolve to the canonical option ID so caseFieldValues.value matches\n * what the UI / other consumers expect (closes WR-01 / WR-02).\n *\n * Ambiguity note (T-06-02): CaseFields are globally scoped (not per-project).\n * If two enabled fields share the same displayName, we throw rather than\n * silently picking one — ambiguity is a deployment configuration issue.\n */\nexport async function resolveCustomFields(\n input: Record<string, unknown> | undefined,\n env: EnvConfig,\n): Promise<ResolvedField[]> {\n if (!input) return [];\n const names = Object.keys(input);\n if (names.length === 0) return [];\n\n const fields = await zenstack<RawCaseField[]>(\n \"caseFields\",\n \"findMany\",\n {\n where: {\n displayName: { in: names },\n isDeleted: false,\n isEnabled: true,\n } satisfies Prisma.CaseFieldsWhereInput,\n select: CASE_FIELD_RESOLVE_SELECT,\n },\n env,\n );\n\n // Group full field rows by displayName to detect ambiguity.\n const byName = new Map<string, RawCaseField[]>();\n for (const f of fields) {\n const arr = byName.get(f.displayName) ?? [];\n arr.push(f);\n byName.set(f.displayName, arr);\n }\n\n const resolved: ResolvedField[] = [];\n for (const name of names) {\n const matches = byName.get(name);\n if (!matches || matches.length === 0) {\n // T-06-05: message contains the FIELD NAME only, never the value.\n throw new TestPlanItHttpError(\n `Custom field '${name}' not found or not enabled in this deployment.`,\n { statusCode: 422 },\n );\n }\n if (matches.length > 1) {\n throw new TestPlanItHttpError(\n `Custom field '${name}' is ambiguous — multiple enabled fields share this display name.`,\n { statusCode: 422 },\n );\n }\n const field = matches[0]!;\n const rawValue = input[name];\n const fieldType = field.type?.type ?? null;\n const options = field.fieldOptions\n .map((a) => a.fieldOption)\n .filter((o): o is { id: number; name: string } => o != null);\n\n let resolvedValue: unknown = rawValue;\n if (fieldType === \"Dropdown\") {\n const id = resolveOptionValue(rawValue, options);\n if (id == null) {\n // T-06-05: message names the field, NEVER the value.\n throw new TestPlanItHttpError(\n `Custom field '${name}' expects a valid Dropdown option (by id or name).`,\n { statusCode: 422 },\n );\n }\n resolvedValue = id;\n } else if (fieldType === \"Multi-Select\") {\n if (!Array.isArray(rawValue)) {\n throw new TestPlanItHttpError(\n `Custom field '${name}' expects an array of Multi-Select options (by id or name).`,\n { statusCode: 422 },\n );\n }\n const ids: number[] = [];\n for (const v of rawValue) {\n const id = resolveOptionValue(v, options);\n if (id == null) {\n throw new TestPlanItHttpError(\n `Custom field '${name}' contains an invalid Multi-Select option (must be a known option id or name).`,\n { statusCode: 422 },\n );\n }\n ids.push(id);\n }\n resolvedValue = ids;\n }\n // Other types (Text, Number, Date, Boolean, ...) pass through; the\n // host's ZenStack policies validate the rest.\n\n resolved.push({ fieldId: field.id, value: resolvedValue, name });\n }\n return resolved;\n}\n\n/**\n * Upsert CaseFieldValues for a case. For each resolved field, look for an\n * existing row (findFirst by testCaseId + fieldId) and PATCH it; otherwise\n * create. This prevents duplicate rows per case+field.\n */\nexport async function writeCustomFieldValues(\n caseId: number,\n resolved: ResolvedField[],\n env: EnvConfig,\n): Promise<void> {\n for (const r of resolved) {\n const existing = await zenstack<{ id: number } | null>(\n \"caseFieldValues\",\n \"findFirst\",\n {\n where: { testCaseId: caseId, fieldId: r.fieldId } satisfies Prisma.CaseFieldValuesWhereInput,\n select: { id: true } satisfies Prisma.CaseFieldValuesSelect,\n },\n env,\n );\n if (existing) {\n await zenstack(\n \"caseFieldValues\",\n \"update\",\n {\n where: { id: existing.id },\n data: { value: r.value },\n },\n env,\n );\n } else {\n await zenstack(\n \"caseFieldValues\",\n \"create\",\n {\n data: {\n testCase: { connect: { id: caseId } },\n field: { connect: { id: r.fieldId } },\n value: r.value,\n },\n },\n env,\n );\n }\n }\n}\n","import { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\n\nexport interface StepInput {\n text?: string | null;\n expectedResult?: string | null;\n order?: number;\n}\n\n/**\n * Wrap plain text in the minimal valid Tiptap ProseMirror doc structure.\n *\n * The TestPlanIt UI renders `Steps.step` and `Steps.expectedResult` via\n * Tiptap; passing a raw string would render as garbage. Agent-supplied text\n * must be wrapped before writing. Empty/null/undefined input produces a\n * paragraph node with no children (valid empty ProseMirror doc).\n */\nexport function wrapPlainTextInProseMirror(\n text: string | null | undefined,\n): unknown {\n if (text == null || text === \"\") {\n return { type: \"doc\", content: [{ type: \"paragraph\", content: [] }] };\n }\n return {\n type: \"doc\",\n content: [\n {\n type: \"paragraph\",\n content: [{ type: \"text\", text }],\n },\n ],\n };\n}\n\n/**\n * Create steps for a case in order. Called by create.ts AFTER the case row\n * exists. Each step text is wrapped in ProseMirror format before writing.\n *\n * Sequential creates are used instead of createMany to ensure relation-connect\n * syntax (`testCase: { connect: { id } }`) works cleanly with ZenStack's RPC.\n */\nexport async function createStepsForCase(\n caseId: number,\n steps: StepInput[],\n env: EnvConfig,\n): Promise<void> {\n for (const [index, step] of steps.entries()) {\n await zenstack(\n \"steps\",\n \"create\",\n {\n data: {\n testCase: { connect: { id: caseId } },\n order: step.order ?? index,\n step: wrapPlainTextInProseMirror(step.text ?? \"\"),\n expectedResult:\n step.expectedResult != null\n ? wrapPlainTextInProseMirror(step.expectedResult)\n : null,\n },\n },\n env,\n );\n }\n}\n\n/**\n * Replace ALL non-deleted steps for a case. Soft-deletes existing steps via\n * `updateMany` (T-06-06: the `delete` and `deleteMany` operations are NEVER\n * used — soft-delete invariant), then creates the new ordered set.\n *\n * This is called by the update tool when `steps` is provided in the update\n * input — the full replacement strategy ensures ordering is always consistent.\n */\nexport async function replaceStepsForCase(\n caseId: number,\n steps: StepInput[],\n env: EnvConfig,\n): Promise<void> {\n // Soft-delete all non-deleted steps for this case.\n await zenstack(\n \"steps\",\n \"updateMany\",\n {\n where: { testCaseId: caseId, isDeleted: false },\n data: { isDeleted: true },\n },\n env,\n );\n // Create the new ordered step set.\n await createStepsForCase(caseId, steps, env);\n}\n","import { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport { CASE_DETAIL_INCLUDE } from \"./get.js\";\nimport { buildFolderBreadcrumb, mapCaseDetail } from \"./shared.js\";\n\n/**\n * Re-fetch a case by ID with full D-10 denormalized detail.\n * Used by create.ts and update.ts after a write to return the CASE-02 shape.\n *\n * Reuses CASE_DETAIL_INCLUDE from get.ts so create/update/get always return\n * the identical shape — and any drift gets caught by the satisfies clause there.\n */\nexport async function fetchCaseDetail(\n caseId: number,\n env: EnvConfig,\n): Promise<ReturnType<typeof mapCaseDetail>> {\n const raw = await zenstack<{\n folder: { id: number; name: string; parentId: number | null };\n [k: string]: unknown;\n }>(\n \"repositoryCases\",\n \"findUnique\",\n {\n where: { id: caseId },\n include: CASE_DETAIL_INCLUDE,\n },\n env,\n );\n\n if (!raw) {\n // BL-03: surface the orphan caseId via a TestPlanItHttpError so the\n // create/update outer catch can compensate (soft-delete the case)\n // and the error mapper passes the structured 404 through to the\n // agent rather than the generic \"Network or runtime error\" branch.\n throw new TestPlanItHttpError(\n `Case ${caseId} not found after write — this is unexpected.`,\n { statusCode: 404 },\n );\n }\n\n const breadcrumb = await buildFolderBreadcrumb(\n {\n id: raw.folder.id,\n name: raw.folder.name,\n parentId: raw.folder.parentId,\n },\n env,\n );\n\n return mapCaseDetail(raw as never, breadcrumb);\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport {\n zenstack,\n resolveActiveRepository,\n resolveDefaultTemplate,\n resolveCaseWorkflowState,\n} from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport { resolveCustomFields, writeCustomFieldValues } from \"./customFields.js\";\nimport { resolveTagIds } from \"./shared.js\";\nimport { createStepsForCase, type StepInput } from \"./steps.js\";\nimport { fetchCaseDetail } from \"./fetchDetail.js\";\n\nexport interface CasesCreateDeps {\n env: EnvConfig;\n}\n\nexport function registerCasesCreate(\n server: McpServer,\n deps: CasesCreateDeps,\n): void {\n server.registerTool(\n \"testplanit_cases_create\",\n {\n description:\n \"Create a new test case in a project + folder. Resolves the active repository, default template, and CASES workflow state automatically. Returns the full denormalized case detail (CASE-02 shape). (per D-05 / CASE-03)\",\n inputSchema: {\n projectId: z.number().int().positive().describe(\"Project to create the case in.\"),\n folderId: z.number().int().positive().describe(\"Folder to place the case in.\"),\n name: z.string().min(1).max(2000).describe(\"Test case name.\"),\n stateName: z\n .string()\n .min(1)\n .optional()\n .describe(\"CASES workflow state name. Defaults to the first state by order.\"),\n steps: z\n .array(\n z.object({\n text: z.string().optional().describe(\"Step description.\"),\n expectedResult: z.string().optional().describe(\"Expected result.\"),\n order: z.number().int().nonnegative().optional().describe(\"Step order (0-based). Inferred if omitted.\"),\n }),\n )\n .optional()\n .describe(\"Ordered test steps.\"),\n tags: z\n .array(z.union([z.number().int().positive(), z.string().min(1)]))\n .optional()\n .describe(\"Tag IDs (numbers) or tag names (strings, created if missing).\"),\n customFields: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Custom field values keyed by display name, e.g. { 'Priority': 'High' }.\"),\n },\n },\n async (input) => {\n try {\n // Pre-resolution: fail fast if project is misconfigured.\n const repositoryId = await resolveActiveRepository(input.projectId, deps.env);\n const templateId = await resolveDefaultTemplate(input.projectId, deps.env);\n const state = await resolveCaseWorkflowState(\n input.projectId,\n deps.env,\n input.stateName,\n );\n\n // Resolve tags and custom fields before the create write.\n const resolvedCustomFields = await resolveCustomFields(\n input.customFields,\n deps.env,\n );\n const tagIds = await resolveTagIds(input.tags, deps.env);\n\n // Case create body — relation-connect syntax throughout (D-02 anti-pattern check).\n // creatorId is NOT passed — auto-injected by /api/model/[...path]/route.ts.\n const data: Record<string, unknown> = {\n name: input.name,\n source: \"MANUAL\",\n automated: false,\n project: { connect: { id: input.projectId } },\n repository: { connect: { id: repositoryId } },\n folder: { connect: { id: input.folderId } },\n template: { connect: { id: templateId } },\n state: { connect: { id: state.id } },\n };\n\n const created = await zenstack<{ id: number }>(\n \"repositoryCases\",\n \"create\",\n { data },\n deps.env,\n );\n\n // BL-03: post-create wiring (steps / tags / custom fields /\n // re-fetch) runs in a try/catch so a mid-flight failure does\n // not leave a half-built case in the database. On any failure\n // we issue a best-effort soft-delete (T-06-06: NEVER `delete`)\n // and re-throw an error that names the orphan caseId so the\n // agent can recover deterministically.\n try {\n if (input.steps && input.steps.length > 0) {\n await createStepsForCase(\n created.id,\n input.steps as StepInput[],\n deps.env,\n );\n }\n if (tagIds.length > 0) {\n await zenstack(\n \"repositoryCases\",\n \"update\",\n {\n where: { id: created.id },\n data: { tags: { set: tagIds.map((id) => ({ id })) } },\n },\n deps.env,\n );\n }\n if (resolvedCustomFields.length > 0) {\n await writeCustomFieldValues(created.id, resolvedCustomFields, deps.env);\n }\n\n // Re-fetch with full D-10 denormalized shape.\n const detail = await fetchCaseDetail(created.id, deps.env);\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (postCreateErr) {\n // Best-effort compensating soft-delete. Swallow cleanup failures\n // (the agent already has the orphan caseId in the surfaced\n // error and can call testplanit_cases_delete to clean up).\n await zenstack(\n \"repositoryCases\",\n \"update\",\n {\n where: { id: created.id },\n data: { isDeleted: true },\n },\n deps.env,\n ).catch(() => {\n /* swallow — we surface the orphan id below */\n });\n const inner =\n postCreateErr instanceof Error\n ? postCreateErr.message\n : String(postCreateErr);\n const status =\n postCreateErr instanceof TestPlanItHttpError\n ? postCreateErr.statusCode\n : undefined;\n throw new TestPlanItHttpError(\n `Test case ${created.id} was created but post-create wiring failed (steps / tags / custom fields / re-fetch); the case was soft-deleted as a best-effort cleanup. Underlying error: ${inner}`,\n status !== undefined ? { statusCode: status } : {},\n );\n }\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack, resolveCaseWorkflowState } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { resolveCustomFields, writeCustomFieldValues } from \"./customFields.js\";\nimport { resolveTagIds } from \"./shared.js\";\nimport { replaceStepsForCase, type StepInput } from \"./steps.js\";\nimport { fetchCaseDetail } from \"./fetchDetail.js\";\n\nexport interface CasesUpdateDeps {\n env: EnvConfig;\n}\n\nexport function registerCasesUpdate(\n server: McpServer,\n deps: CasesUpdateDeps,\n): void {\n server.registerTool(\n \"testplanit_cases_update\",\n {\n description:\n \"Update a test case (partial). Provide only the fields to change: name, steps (replaces all current steps), tags (replaces the tag set), customFields (upserts each), stateName, folderId. Returns the full denormalized case detail (CASE-02 shape). (per D-05 / CASE-04)\",\n inputSchema: {\n caseId: z.number().int().positive().describe(\"ID of the test case to update.\"),\n name: z.string().min(1).max(2000).optional().describe(\"New test case name.\"),\n stateName: z\n .string()\n .min(1)\n .optional()\n .describe(\"CASES workflow state name to set.\"),\n folderId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Move case to this folder ID.\"),\n steps: z\n .array(\n z.object({\n text: z.string().optional().describe(\"Step description.\"),\n expectedResult: z.string().optional().describe(\"Expected result.\"),\n order: z.number().int().nonnegative().optional().describe(\"Step order.\"),\n }),\n )\n .optional()\n .describe(\"New step set. Replaces ALL existing steps (soft-deletes them first).\"),\n tags: z\n .array(z.union([z.number().int().positive(), z.string().min(1)]))\n .optional()\n .describe(\"New tag set (replaces all tags). Mix of IDs and names.\"),\n customFields: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Custom field values to upsert, keyed by display name.\"),\n },\n },\n async (input) => {\n try {\n // Fetch the case head first — needed to get projectId for state resolution\n // and to validate the case exists before any writes.\n const head = await zenstack<{ id: number; projectId: number } | null>(\n \"repositoryCases\",\n \"findUnique\",\n {\n where: { id: input.caseId },\n select: { id: true, projectId: true } satisfies Prisma.RepositoryCasesSelect,\n },\n deps.env,\n );\n if (!head) {\n return {\n isError: true as const,\n content: [\n { type: \"text\" as const, text: `Test case ${input.caseId} not found.` },\n ],\n };\n }\n\n // Build the partial update data object — only include provided fields.\n const data: Record<string, unknown> = {};\n\n if (input.name !== undefined) {\n data.name = input.name;\n }\n if (input.folderId !== undefined) {\n data.folder = { connect: { id: input.folderId } };\n }\n if (input.stateName !== undefined) {\n const state = await resolveCaseWorkflowState(\n head.projectId,\n deps.env,\n input.stateName,\n );\n data.state = { connect: { id: state.id } };\n }\n if (input.tags !== undefined) {\n const tagIds = await resolveTagIds(input.tags, deps.env);\n data.tags = { set: tagIds.map((id) => ({ id })) };\n }\n\n // Only write if there are scalar/relation fields to update.\n if (Object.keys(data).length > 0) {\n await zenstack(\n \"repositoryCases\",\n \"update\",\n { where: { id: input.caseId }, data },\n deps.env,\n );\n }\n\n // Steps replacement: soft-delete existing + create new (T-06-06).\n if (input.steps !== undefined) {\n await replaceStepsForCase(\n input.caseId,\n input.steps as StepInput[],\n deps.env,\n );\n }\n\n // Custom field upserts.\n if (input.customFields !== undefined) {\n const resolved = await resolveCustomFields(input.customFields, deps.env);\n await writeCustomFieldValues(input.caseId, resolved, deps.env);\n }\n\n // Re-fetch with full D-10 denormalized shape.\n const detail = await fetchCaseDetail(input.caseId, deps.env);\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\n\nexport interface CasesDeleteDeps {\n env: EnvConfig;\n}\n\nconst CASE_DELETE_SELECT = {\n id: true,\n isDeleted: true,\n} as const satisfies Prisma.RepositoryCasesSelect;\n\n/**\n * Soft-delete a test case.\n *\n * Implementation invariant (T-06-06): this handler ONLY uses\n * `zenstack(\"repositoryCases\", \"update\", { data: { isDeleted: true } })`.\n * The ZenStack `delete` and `deleteMany` operations are NEVER invoked — the\n * soft-delete invariant is enforced at the package layer as defense in depth\n * (the host's ZenStack access policies would also reject hard-delete for\n * non-admin roles, but we don't rely on that).\n */\nexport function registerCasesDelete(\n server: McpServer,\n deps: CasesDeleteDeps,\n): void {\n server.registerTool(\n \"testplanit_cases_delete\",\n {\n description:\n \"Soft-delete a test case by id. Sets isDeleted=true so the case is hidden from subsequent list/get queries. Returns { id, isDeleted: true }. (per D-05 / CASE-05)\",\n inputSchema: {\n caseId: z.number().int().positive().describe(\"ID of the test case to soft-delete.\"),\n },\n },\n async (input) => {\n try {\n const result = await zenstack<{ id: number; isDeleted: boolean }>(\n \"repositoryCases\",\n \"update\",\n {\n where: { id: input.caseId },\n data: { isDeleted: true },\n select: CASE_DELETE_SELECT,\n },\n deps.env,\n );\n const out = { id: result.id, isDeleted: result.isDeleted };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerCasesList, type CasesListDeps } from \"./list.js\";\nimport { registerCasesGet, type CasesGetDeps } from \"./get.js\";\nimport { registerCasesCreate, type CasesCreateDeps } from \"./create.js\";\nimport { registerCasesUpdate, type CasesUpdateDeps } from \"./update.js\";\nimport { registerCasesDelete, type CasesDeleteDeps } from \"./delete.js\";\n\nexport type CasesDeps =\n & CasesListDeps\n & CasesGetDeps\n & CasesCreateDeps\n & CasesUpdateDeps\n & CasesDeleteDeps;\n\nexport function registerCases(server: McpServer, deps: CasesDeps): void {\n registerCasesList(server, deps);\n registerCasesGet(server, deps);\n registerCasesCreate(server, deps);\n registerCasesUpdate(server, deps);\n registerCasesDelete(server, deps);\n}\n\nexport {\n registerCasesList,\n registerCasesGet,\n registerCasesCreate,\n registerCasesUpdate,\n registerCasesDelete,\n};\nexport type {\n CasesListDeps,\n CasesGetDeps,\n CasesCreateDeps,\n CasesUpdateDeps,\n CasesDeleteDeps,\n};\n","import type { Prisma } from \"@prisma/client\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { buildFolderBreadcrumb } from \"../cases/shared.js\";\n\nconst FOLDER_DETAIL_INCLUDE = {\n children: {\n where: { isDeleted: false },\n select: {\n id: true,\n name: true,\n _count: { select: { cases: { where: { isDeleted: false } } } },\n },\n orderBy: { order: \"asc\" },\n },\n cases: {\n where: { isDeleted: false },\n select: { id: true, name: true, source: true },\n orderBy: { order: \"asc\" },\n take: 100,\n },\n _count: { select: { cases: { where: { isDeleted: false } } } },\n} as const satisfies Prisma.RepositoryFoldersInclude;\n\ninterface RawFolderNode {\n id: number;\n name: string;\n parentId: number | null;\n _count?: { cases?: number };\n children?: RawFolderNode[];\n}\n\nexport interface FolderTreeNode {\n id: number;\n name: string;\n parentId: number | null;\n caseCount: number;\n children: FolderTreeNode[];\n}\n\nexport function mapFolderTreeNode(raw: RawFolderNode): FolderTreeNode {\n return {\n id: raw.id,\n name: raw.name,\n parentId: raw.parentId,\n caseCount: raw._count?.cases ?? 0,\n children: (raw.children ?? []).map(mapFolderTreeNode),\n };\n}\n\n/**\n * Fetch a single folder with breadcrumb + children + cases summary.\n * Reused by create.ts and update.ts to return CASE-07-shaped responses\n * after a write.\n */\nexport async function fetchFolderDetail(folderId: number, env: EnvConfig) {\n const raw = await zenstack<{\n id: number;\n name: string;\n parentId: number | null;\n children: Array<{ id: number; name: string; _count?: { cases?: number } }>;\n cases: Array<{ id: number; name: string; source: string }>;\n _count?: { cases?: number };\n } | null>(\n \"repositoryFolders\",\n \"findUnique\",\n {\n where: { id: folderId },\n include: FOLDER_DETAIL_INCLUDE,\n },\n env,\n );\n if (!raw) return null;\n\n const breadcrumb = await buildFolderBreadcrumb(\n { id: raw.id, name: raw.name, parentId: raw.parentId },\n env,\n );\n const fullPath = breadcrumb.map((b) => b.name).join(\" / \");\n\n return {\n id: raw.id,\n name: raw.name,\n parentId: raw.parentId,\n breadcrumb,\n fullPath,\n children: raw.children.map((c) => ({\n id: c.id,\n name: c.name,\n caseCount: c._count?.cases ?? 0,\n })),\n cases: raw.cases,\n caseCount: raw._count?.cases ?? 0,\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { mapFolderTreeNode } from \"./shared.js\";\n\nexport interface FoldersListDeps {\n env: EnvConfig;\n}\n\nconst FOLDER_TREE_INCLUDE = {\n _count: { select: { cases: { where: { isDeleted: false } } } },\n children: {\n where: { isDeleted: false },\n include: {\n _count: { select: { cases: { where: { isDeleted: false } } } },\n children: { where: { isDeleted: false } },\n },\n },\n} as const satisfies Prisma.RepositoryFoldersInclude;\n\nexport function registerFoldersList(server: McpServer, deps: FoldersListDeps): void {\n server.registerTool(\n \"testplanit_folders_list\",\n {\n description:\n \"List the folder tree for a project. Returns root folders with nested children and per-folder case counts (soft-deleted excluded). Two levels deep inline; deeper subtrees can be fetched via testplanit_folders_get.\",\n inputSchema: { projectId: z.number().int().positive() },\n },\n async (input) => {\n try {\n const rows = await zenstack<unknown[]>(\n \"repositoryFolders\",\n \"findMany\",\n {\n where: { projectId: input.projectId, isDeleted: false, parentId: null },\n include: FOLDER_TREE_INCLUDE,\n orderBy: { order: \"asc\" },\n },\n deps.env,\n );\n const tree = (rows ?? []).map((r) => mapFolderTreeNode(r as never));\n const out = { tree };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { fetchFolderDetail } from \"./shared.js\";\n\nexport interface FoldersGetDeps {\n env: EnvConfig;\n}\n\nexport function registerFoldersGet(server: McpServer, deps: FoldersGetDeps): void {\n server.registerTool(\n \"testplanit_folders_get\",\n {\n description:\n \"Fetch a single folder by id with parent breadcrumb, children, cases summary (capped at 100; use testplanit_cases_list for full pagination), and total case count.\",\n inputSchema: { folderId: z.number().int().positive() },\n },\n async (input) => {\n try {\n const detail = await fetchFolderDetail(input.folderId, deps.env);\n if (!detail) {\n return {\n isError: true as const,\n content: [{ type: \"text\" as const, text: `Folder ${input.folderId} not found.` }],\n };\n }\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack, resolveActiveRepository } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { fetchFolderDetail } from \"./shared.js\";\n\nexport interface FoldersCreateDeps {\n env: EnvConfig;\n}\n\nexport function registerFoldersCreate(server: McpServer, deps: FoldersCreateDeps): void {\n server.registerTool(\n \"testplanit_folders_create\",\n {\n description:\n \"Create a folder under a parent (omit parentId for root). Resolves the active repository automatically. Returns the created folder with breadcrumb + case count.\",\n inputSchema: {\n projectId: z.number().int().positive(),\n name: z.string().min(1).max(255),\n parentId: z.number().int().positive().optional(),\n },\n },\n async (input) => {\n try {\n const repositoryId = await resolveActiveRepository(input.projectId, deps.env);\n const data: Record<string, unknown> = {\n name: input.name,\n project: { connect: { id: input.projectId } },\n repository: { connect: { id: repositoryId } },\n };\n if (input.parentId !== undefined) {\n data[\"parent\"] = { connect: { id: input.parentId } };\n }\n const created = await zenstack<{ id: number }>(\n \"repositoryFolders\",\n \"create\",\n { data },\n deps.env,\n );\n const detail = await fetchFolderDetail(created.id, deps.env);\n const out = detail ?? { id: created.id };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { fetchFolderDetail } from \"./shared.js\";\n\nexport interface FoldersUpdateDeps {\n env: EnvConfig;\n}\n\nexport function registerFoldersUpdate(server: McpServer, deps: FoldersUpdateDeps): void {\n server.registerTool(\n \"testplanit_folders_update\",\n {\n description:\n \"Update a folder (partial). Provide name to rename; provide parentId to reparent (use null to move to root). Returns the updated folder with breadcrumb + case count.\",\n inputSchema: {\n folderId: z.number().int().positive(),\n name: z.string().min(1).max(255).optional(),\n parentId: z.number().int().positive().nullable().optional(),\n },\n },\n async (input) => {\n try {\n const data: Record<string, unknown> = {};\n if (input.name !== undefined) data[\"name\"] = input.name;\n if (input.parentId !== undefined) {\n data[\"parent\"] = input.parentId === null\n ? { disconnect: true }\n : { connect: { id: input.parentId } };\n }\n if (Object.keys(data).length > 0) {\n await zenstack(\n \"repositoryFolders\",\n \"update\",\n { where: { id: input.folderId }, data },\n deps.env,\n );\n }\n const detail = await fetchFolderDetail(input.folderId, deps.env);\n if (!detail) {\n return {\n isError: true as const,\n content: [{ type: \"text\" as const, text: `Folder ${input.folderId} not found.` }],\n };\n }\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\n\nexport interface FoldersDeleteDeps {\n env: EnvConfig;\n}\n\nconst FOLDER_DELETE_SELECT = {\n id: true,\n isDeleted: true,\n} as const satisfies Prisma.RepositoryFoldersSelect;\n\n/**\n * Soft-delete a folder. The MCP tool layer enforces the \"no cases,\n * no sub-folders\" rule (BL-01) before issuing the soft-delete PATCH —\n * the host REST API does NOT enforce this constraint at the ZenStack\n * layer (verified by validation-errors.spec.ts), so the pre-check has\n * to live here.\n *\n * Non-empty folders yield a structured TestPlanItHttpError with status\n * 422 which `mapHttpErrorToToolResult` surfaces as a CASE-12 error.\n *\n * T-06-06: ALWAYS uses `update` with `isDeleted: true`. NEVER calls\n * ZenStack `delete` or `deleteMany`.\n */\nexport function registerFoldersDelete(server: McpServer, deps: FoldersDeleteDeps): void {\n server.registerTool(\n \"testplanit_folders_delete\",\n {\n description:\n \"Soft-delete a folder by id. Folders with cases or sub-folders cannot be deleted; the tool returns a structured error in that case. Returns { id, isDeleted: true } on success.\",\n inputSchema: {\n folderId: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n // BL-01: pre-check that the folder is empty before issuing the\n // soft-delete PATCH. Two `findMany` reads with take:1 are cheap\n // and avoid double-counting on the host. Empty arrays mean clear.\n const [activeCases, activeChildren] = await Promise.all([\n zenstack<Array<{ id: number }>>(\n \"repositoryCases\",\n \"findMany\",\n {\n where: {\n folderId: input.folderId,\n isDeleted: false,\n } satisfies Prisma.RepositoryCasesWhereInput,\n select: { id: true } satisfies Prisma.RepositoryCasesSelect,\n take: 1,\n },\n deps.env,\n ),\n zenstack<Array<{ id: number }>>(\n \"repositoryFolders\",\n \"findMany\",\n {\n where: {\n parentId: input.folderId,\n isDeleted: false,\n } satisfies Prisma.RepositoryFoldersWhereInput,\n select: { id: true } satisfies Prisma.RepositoryFoldersSelect,\n take: 1,\n },\n deps.env,\n ),\n ]);\n if (activeCases.length > 0 || activeChildren.length > 0) {\n const reasons: string[] = [];\n if (activeCases.length > 0) reasons.push(\"active cases\");\n if (activeChildren.length > 0) reasons.push(\"active sub-folders\");\n throw new TestPlanItHttpError(\n `Folder ${input.folderId} is not empty (contains ${reasons.join(\" and \")}). Move or soft-delete contents first.`,\n { statusCode: 422 },\n );\n }\n\n const result = await zenstack<{ id: number; isDeleted: boolean }>(\n \"repositoryFolders\",\n \"update\",\n {\n where: { id: input.folderId },\n data: { isDeleted: true },\n select: FOLDER_DELETE_SELECT,\n },\n deps.env,\n );\n const out = { id: result.id, isDeleted: result.isDeleted };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerFoldersList, type FoldersListDeps } from \"./list.js\";\nimport { registerFoldersGet, type FoldersGetDeps } from \"./get.js\";\nimport { registerFoldersCreate, type FoldersCreateDeps } from \"./create.js\";\nimport { registerFoldersUpdate, type FoldersUpdateDeps } from \"./update.js\";\nimport { registerFoldersDelete, type FoldersDeleteDeps } from \"./delete.js\";\n\nexport type FoldersDeps =\n & FoldersListDeps\n & FoldersGetDeps\n & FoldersCreateDeps\n & FoldersUpdateDeps\n & FoldersDeleteDeps;\n\nexport function registerFolders(server: McpServer, deps: FoldersDeps): void {\n registerFoldersList(server, deps);\n registerFoldersGet(server, deps);\n registerFoldersCreate(server, deps);\n registerFoldersUpdate(server, deps);\n registerFoldersDelete(server, deps);\n}\n\nexport {\n registerFoldersList,\n registerFoldersGet,\n registerFoldersCreate,\n registerFoldersUpdate,\n registerFoldersDelete,\n};\nexport type {\n FoldersListDeps,\n FoldersGetDeps,\n FoldersCreateDeps,\n FoldersUpdateDeps,\n FoldersDeleteDeps,\n};\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\n\nexport interface TagsListDeps {\n env: EnvConfig;\n}\n\ninterface RawTagRow {\n id: number;\n name: string;\n _count?: {\n repositoryCases?: number;\n testRuns?: number;\n sessions?: number;\n };\n}\n\n/**\n * List tags with per-tag usage counts (CASE-11).\n *\n * Tags are GLOBAL in the TestPlanIt schema (not project-scoped). When the\n * agent supplies `projectId`, the per-tag counts are scoped to that\n * project's cases/runs/sessions; without projectId, counts are global.\n * Either way, the tag list itself is global.\n */\nexport function registerTagsList(server: McpServer, deps: TagsListDeps): void {\n server.registerTool(\n \"testplanit_tags_list\",\n {\n description:\n \"List tags with usage counts per repository case / test run / session. Optionally pass projectId to scope counts to that project; without it, counts are global. Tags are global; this tool is read-only.\",\n inputSchema: {\n projectId: z.number().int().positive().optional(),\n },\n },\n async (input) => {\n try {\n const countSelect: Prisma.TagsCountOutputTypeSelect = input.projectId\n ? {\n repositoryCases: {\n where: { isDeleted: false, projectId: input.projectId },\n },\n testRuns: {\n where: { isDeleted: false, projectId: input.projectId },\n },\n sessions: {\n where: { isDeleted: false, projectId: input.projectId },\n },\n }\n : {\n repositoryCases: true,\n testRuns: true,\n sessions: true,\n };\n\n const rows = await zenstack<RawTagRow[]>(\n \"tags\",\n \"findMany\",\n {\n where: { isDeleted: false },\n include: { _count: { select: countSelect } },\n orderBy: { name: \"asc\" },\n },\n deps.env,\n );\n\n const tags = (rows ?? []).map((r) => ({\n id: r.id,\n name: r.name,\n usageCounts: {\n repositoryCases: r._count?.repositoryCases ?? 0,\n testRuns: r._count?.testRuns ?? 0,\n sessions: r._count?.sessions ?? 0,\n },\n }));\n const out = { tags };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerTagsList, type TagsListDeps } from \"./list.js\";\n\nexport type TagsDeps = TagsListDeps;\n\nexport function registerTags(server: McpServer, deps: TagsDeps): void {\n registerTagsList(server, deps);\n}\n\nexport { registerTagsList };\nexport type { TagsListDeps };\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\n\nexport interface ProjectsListDeps {\n env: EnvConfig;\n}\n\nconst PROJECTS_LIST_SELECT = {\n id: true,\n name: true,\n} as const satisfies Prisma.ProjectsSelect;\n\n/**\n * List projects accessible to the authenticated token.\n *\n * Claude's Discretion include (CONTEXT.md): without this tool, agents must\n * know the projectId out-of-band. Adding a 1-zenstack-call read tool\n * removes that friction. The host's ZenStack `@@allow` policy filters\n * rows per token; cross-tenant projects are absent automatically.\n *\n * The `select: { id: true, name: true }` keeps the response minimal —\n * no description, isArchived, tenantId, or other admin-domain fields\n * are exposed even if a future schema change widens the policy.\n */\nexport function registerProjectsList(\n server: McpServer,\n deps: ProjectsListDeps,\n): void {\n server.registerTool(\n \"testplanit_projects_list\",\n {\n description:\n \"List projects accessible to the authenticated token. Returns { id, name } pairs only — minimal context-disambiguation surface for agents.\",\n inputSchema: {},\n },\n async () => {\n try {\n const rows = await zenstack<Array<{ id: number; name: string }>>(\n \"projects\",\n \"findMany\",\n {\n where: { isDeleted: false },\n select: PROJECTS_LIST_SELECT,\n orderBy: { name: \"asc\" },\n },\n deps.env,\n );\n const out = { projects: rows ?? [] };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerProjectsList, type ProjectsListDeps } from \"./list.js\";\n\nexport type ProjectsDeps = ProjectsListDeps;\n\nexport function registerProjects(server: McpServer, deps: ProjectsDeps): void {\n registerProjectsList(server, deps);\n}\n\nexport { registerProjectsList };\nexport type { ProjectsListDeps };\n","import type { Prisma } from \"@prisma/client\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport {\n extractProseMirrorText,\n denormalizeCustomFields,\n} from \"../cases/shared.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Typed includes — every literal carries `as const satisfies Prisma.<Model><Include|Select>`.\n// Reintroducing an unknown column produces TS2353 (Phase 6 WR-09 invariant).\n//\n// CRITICAL invariants:\n// R1 — TestRunCases has NO `isDeleted` column (Cascade deletes only); never\n// add `isDeleted: false` to a TestRunCases-shaped where clause.\n// R2 — TestRunStepResults relation to Status is named `stepStatus` (NOT `status`).\n// R3 — Status rollup total is summed FROM groupBy results, never from a\n// separate count call (counts must always sum to total).\n// D7-02 — \"latest result per case\" = `executedAt` desc, take 1.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const RUN_ROW_INCLUDE = {\n project: { select: { id: true, name: true } },\n state: { select: { id: true, name: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n configuration: { select: { id: true, name: true } },\n milestone: { select: { id: true, name: true } },\n tags: { select: { id: true, name: true } },\n issues: {\n where: { isDeleted: false },\n select: {\n id: true,\n externalKey: true,\n title: true,\n externalStatus: true,\n integration: { select: { provider: true } },\n },\n },\n} as const satisfies Prisma.TestRunsInclude;\n\n// EXEC-02 / EXEC-03 inline test-case shape (latest result via take:1 nested include)\nexport const RUN_DETAIL_TESTCASE_INCLUDE = {\n repositoryCase: { select: { id: true, name: true, source: true } },\n assignedTo: { select: { id: true, name: true, email: true } },\n // CRITICAL: TestRunCases relation IS named `status` (not stepStatus — that's\n // TestRunStepResults). Verified against Prisma TestRunCasesInclude.\n status: { select: { id: true, name: true } },\n results: {\n where: { isDeleted: false },\n orderBy: { executedAt: \"desc\" }, // D7-02 — matches @@index([testRunCaseId, executedAt(sort: Desc)])\n take: 1,\n select: {\n id: true,\n statusId: true,\n status: { select: { id: true, name: true } },\n executedBy: { select: { id: true, name: true, email: true } },\n executedAt: true,\n },\n },\n} as const satisfies Prisma.TestRunCasesInclude;\n\n// EXEC-04 list rows\nexport const RUN_RESULT_LIST_INCLUDE = {\n status: { select: { id: true, name: true } },\n executedBy: { select: { id: true, name: true, email: true } },\n testRunCase: {\n select: {\n id: true,\n repositoryCaseId: true,\n repositoryCase: { select: { id: true, name: true, source: true } },\n testRun: { select: { id: true, name: true } },\n },\n },\n} as const satisfies Prisma.TestRunResultsInclude;\n\n// EXEC-05 step-result shape — R2: relation field on TestRunStepResults is\n// `stepStatus` NOT `status` (schema.zmodel:2437). Reintroducing `status` here\n// produces TS2353 against Prisma.TestRunStepResultsSelect.\nexport const STEP_RESULT_SELECT = {\n id: true,\n statusId: true,\n stepStatus: { select: { id: true, name: true } },\n notes: true, // Json? -> extractProseMirrorText\n evidence: true, // Json? -> as-is per D7-08\n executedAt: true,\n elapsed: true,\n step: {\n select: {\n id: true,\n order: true,\n step: true, // Json? -> stepText\n expectedResult: true, // Json? -> expectedResultText\n },\n },\n attachments: {\n where: { isDeleted: false },\n select: { id: true, name: true, url: true },\n },\n issues: {\n where: { isDeleted: false },\n select: {\n id: true,\n externalKey: true,\n title: true,\n externalStatus: true,\n integration: { select: { provider: true } },\n },\n },\n} as const satisfies Prisma.TestRunStepResultsSelect;\n\nexport const RUN_RESULT_DETAIL_INCLUDE = {\n status: { select: { id: true, name: true } },\n executedBy: { select: { id: true, name: true, email: true } },\n editedBy: { select: { id: true, name: true, email: true } },\n testRunCase: {\n select: {\n id: true,\n repositoryCaseId: true,\n repositoryCase: { select: { id: true, name: true, source: true } },\n testRun: { select: { id: true, name: true } },\n },\n },\n attachments: {\n where: { isDeleted: false },\n select: { id: true, name: true, url: true },\n },\n issues: {\n where: { isDeleted: false },\n select: {\n id: true,\n externalKey: true,\n title: true,\n externalStatus: true,\n integration: { select: { provider: true } },\n },\n },\n resultFieldValues: {\n include: {\n field: {\n select: {\n displayName: true,\n type: { select: { type: true } },\n fieldOptions: {\n select: { fieldOption: { select: { id: true, name: true } } },\n },\n },\n },\n },\n },\n stepResults: {\n where: { isDeleted: false },\n // R5 fallback: nested-relation orderBy (`step: { order: 'asc' }`) generates\n // the broken `TestRunStepResults$orderBy$0` alias under ZenStack v3. `stepId`\n // ordering approximates step order (steps are created sequentially) and the\n // `id` tiebreaker keeps it deterministic (BL-04 invariant from Phase 6).\n orderBy: [{ stepId: \"asc\" }, { id: \"asc\" }],\n select: STEP_RESULT_SELECT,\n },\n} as const satisfies Prisma.TestRunResultsInclude;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Status rollup (D7-04 statusCounts shape; R3 — total computed FROM groups)\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface StatusGroup {\n statusId: number | null;\n _count: { id: number };\n}\n\nexport interface StatusRollup {\n statusCounts: Array<{ id: number; name: string; count: number }>;\n untested: number;\n total: number;\n}\n\nexport function computeStatusRollup(\n groups: StatusGroup[],\n nameById: Map<number, string>,\n): StatusRollup {\n const untested = groups.find((g) => g.statusId === null)?._count.id ?? 0;\n // R3: total summed from groups, NEVER a separate count call. Splitting these\n // two queries (rollup + count) lets them disagree on race; keep the source\n // of truth as the groupBy result.\n const total = groups.reduce((s, g) => s + g._count.id, 0);\n const statusCounts = groups\n .filter(\n (g): g is { statusId: number; _count: { id: number } } =>\n g.statusId !== null,\n )\n .map((g) => ({\n id: g.statusId,\n name: nameById.get(g.statusId) ?? \"Unknown\",\n count: g._count.id,\n }));\n return { statusCounts, untested, total };\n}\n\n/**\n * Two-call status-name resolution: groupBy on TestRunCases.statusId for the\n * run, then status.findMany for the non-null statusIds. Returns the raw groups\n * + a name-by-id Map so callers pass both into `computeStatusRollup`.\n *\n * R6 efficiency: when every grouped statusId is null (run with no executed\n * cases yet), skip the second call.\n */\nexport async function extractStatusNames(\n runId: number,\n env: EnvConfig,\n): Promise<{ groups: StatusGroup[]; nameById: Map<number, string> }> {\n const groups = await zenstack<StatusGroup[]>(\n \"testRunCases\",\n \"groupBy\",\n {\n by: [\"statusId\"],\n // R1: TestRunCases has NO isDeleted; do NOT add `isDeleted: false`.\n where: { testRunId: runId },\n _count: { id: true },\n } satisfies Prisma.TestRunCasesGroupByArgs,\n env,\n );\n const safeGroups = groups ?? [];\n const statusIds = safeGroups\n .map((g) => g.statusId)\n .filter((id): id is number => id !== null);\n if (statusIds.length === 0) {\n return { groups: safeGroups, nameById: new Map() };\n }\n const statuses = await zenstack<Array<{ id: number; name: string }>>(\n \"status\",\n \"findMany\",\n {\n where: { id: { in: statusIds } },\n select: { id: true, name: true },\n } satisfies Prisma.StatusFindManyArgs,\n env,\n );\n const nameById = new Map<number, string>(\n (statuses ?? []).map((s) => [s.id, s.name]),\n );\n return { groups: safeGroups, nameById };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Mappers — every output field enumerated explicitly (T-07-03 mitigation:\n// never `...spread` raw rows; the include shape and the mapper output must\n// stay in sync explicitly so a schema drift can't leak new columns).\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface RawIssue {\n id: number;\n externalKey: string | null;\n title: string | null;\n externalStatus: string | null;\n integration: { provider: string } | null;\n}\n\nfunction mapIssue(raw: RawIssue) {\n return {\n id: raw.id,\n externalKey: raw.externalKey,\n title: raw.title,\n externalStatus: raw.externalStatus,\n externalSystem: raw.integration?.provider ?? null,\n };\n}\n\ninterface RawAttachment {\n id: number;\n name: string;\n url: string;\n}\n\nfunction mapAttachment(raw: RawAttachment) {\n return { id: raw.id, fileName: raw.name, url: raw.url };\n}\n\nexport interface RawRunRow {\n id: number;\n name: string;\n isCompleted: boolean;\n completedAt: string | Date | null;\n createdAt: string | Date;\n testRunType: string;\n project: { id: number; name: string };\n state: { id: number; name: string };\n // NOTE: schema relation is `createdBy` (NOT `creator` — RepositoryCases uses\n // `creator`, but TestRuns / Sessions use `createdBy`).\n createdBy: { id: string; name: string | null; email: string };\n configuration: { id: number; name: string } | null;\n milestone: { id: number; name: string } | null;\n tags: Array<{ id: number; name: string }>;\n issues: RawIssue[];\n}\n\nexport function mapRunRow(raw: RawRunRow) {\n return {\n id: raw.id,\n name: raw.name,\n isCompleted: raw.isCompleted,\n completedAt: raw.completedAt ?? null,\n createdAt: raw.createdAt,\n testRunType: raw.testRunType, // surface enum verbatim (RESEARCH discretion 5)\n project: raw.project\n ? { id: raw.project.id, name: raw.project.name }\n : null,\n state: raw.state ? { id: raw.state.id, name: raw.state.name } : null,\n createdBy: raw.createdBy\n ? {\n id: raw.createdBy.id,\n name: raw.createdBy.name,\n email: raw.createdBy.email,\n }\n : null,\n configuration: raw.configuration\n ? { id: raw.configuration.id, name: raw.configuration.name }\n : null,\n milestone: raw.milestone\n ? { id: raw.milestone.id, name: raw.milestone.name }\n : null,\n tags: (raw.tags ?? []).map((t) => ({ id: t.id, name: t.name })),\n issues: (raw.issues ?? []).map(mapIssue),\n };\n}\n\nexport interface RawRunCaseLatestResult {\n id: number;\n statusId: number | null;\n status: { id: number; name: string } | null;\n executedBy: { id: string; name: string | null; email: string } | null;\n executedAt: string | Date;\n}\n\nexport interface RawRunDetailTestCase {\n id: number;\n order: number;\n isCompleted: boolean;\n repositoryCase: { id: number; name: string; source: string } | null;\n assignedTo: { id: string; name: string | null; email: string } | null;\n status: { id: number; name: string } | null;\n results: RawRunCaseLatestResult[];\n}\n\nexport function mapRunDetailTestCase(raw: RawRunDetailTestCase) {\n const latest = raw.results?.[0] ?? null;\n return {\n id: raw.id,\n order: raw.order,\n isCompleted: raw.isCompleted,\n repositoryCase: raw.repositoryCase\n ? {\n id: raw.repositoryCase.id,\n name: raw.repositoryCase.name,\n source: raw.repositoryCase.source,\n }\n : null,\n assignedTo: raw.assignedTo\n ? {\n id: raw.assignedTo.id,\n name: raw.assignedTo.name,\n email: raw.assignedTo.email,\n }\n : null,\n status: raw.status ? { id: raw.status.id, name: raw.status.name } : null,\n latestResult: latest\n ? {\n id: latest.id,\n status: latest.status\n ? { id: latest.status.id, name: latest.status.name }\n : null,\n executedBy: latest.executedBy\n ? {\n id: latest.executedBy.id,\n name: latest.executedBy.name,\n email: latest.executedBy.email,\n }\n : null,\n executedAt: latest.executedAt,\n }\n : null,\n };\n}\n\nexport interface RawRunResultRow {\n id: number;\n statusId: number;\n status: { id: number; name: string };\n executedBy: { id: string; name: string | null; email: string };\n executedAt: string | Date;\n attempt: number;\n testRunCase: {\n id: number;\n repositoryCaseId: number;\n repositoryCase: { id: number; name: string; source: string } | null;\n testRun: { id: number; name: string } | null;\n };\n}\n\nexport function mapRunResultRow(raw: RawRunResultRow) {\n return {\n id: raw.id,\n attempt: raw.attempt,\n executedAt: raw.executedAt,\n status: raw.status ? { id: raw.status.id, name: raw.status.name } : null,\n executedBy: raw.executedBy\n ? {\n id: raw.executedBy.id,\n name: raw.executedBy.name,\n email: raw.executedBy.email,\n }\n : null,\n testRunCase: raw.testRunCase\n ? {\n id: raw.testRunCase.id,\n repositoryCaseId: raw.testRunCase.repositoryCaseId,\n repositoryCase: raw.testRunCase.repositoryCase\n ? {\n id: raw.testRunCase.repositoryCase.id,\n name: raw.testRunCase.repositoryCase.name,\n source: raw.testRunCase.repositoryCase.source,\n }\n : null,\n testRun: raw.testRunCase.testRun\n ? {\n id: raw.testRunCase.testRun.id,\n name: raw.testRunCase.testRun.name,\n }\n : null,\n }\n : null,\n };\n}\n\nexport interface RawStepResult {\n id: number;\n statusId: number;\n // R2: relation name is `stepStatus` (NOT `status`). Output uses `status` for\n // agent friendliness, but input source is raw.stepStatus.\n stepStatus: { id: number; name: string } | null;\n notes: unknown;\n evidence: unknown;\n executedAt: string | Date;\n elapsed: number | null;\n step: {\n id: number;\n order: number;\n step: unknown;\n expectedResult: unknown;\n } | null;\n attachments: RawAttachment[];\n issues: RawIssue[];\n}\n\nexport function mapStepResult(raw: RawStepResult) {\n return {\n id: raw.id,\n status: raw.stepStatus\n ? { id: raw.stepStatus.id, name: raw.stepStatus.name }\n : null,\n stepId: raw.step?.id ?? null,\n stepOrder: raw.step?.order ?? null,\n stepText: extractProseMirrorText(raw.step?.step),\n expectedResultText: extractProseMirrorText(raw.step?.expectedResult),\n notes: extractProseMirrorText(raw.notes),\n evidence: raw.evidence, // D7-08 — surface as-is, no truncation\n executedAt: raw.executedAt,\n elapsed: raw.elapsed ?? null,\n attachments: (raw.attachments ?? []).map(mapAttachment),\n issues: (raw.issues ?? []).map(mapIssue),\n };\n}\n\nexport interface RawRunResultDetail extends Omit<RawRunResultRow, \"executedBy\"> {\n executedBy: { id: string; name: string | null; email: string } | null;\n editedBy: { id: string; name: string | null; email: string } | null;\n editedAt: string | Date | null;\n elapsed: number | null;\n notes: unknown;\n evidence: unknown;\n resultFieldValues: Array<{\n value: unknown;\n field: {\n displayName: string | null;\n type: { type: string | null } | null;\n fieldOptions: Array<{\n fieldOption: { id: number; name: string } | null;\n }>;\n } | null;\n }>;\n stepResults: RawStepResult[];\n attachments: RawAttachment[];\n issues: RawIssue[];\n}\n\nexport function mapRunResultDetail(raw: RawRunResultDetail) {\n return {\n id: raw.id,\n attempt: raw.attempt,\n executedAt: raw.executedAt,\n editedAt: raw.editedAt,\n elapsed: raw.elapsed ?? null,\n notes: extractProseMirrorText(raw.notes),\n evidence: raw.evidence, // D7-08\n status: raw.status ? { id: raw.status.id, name: raw.status.name } : null,\n executedBy: raw.executedBy\n ? {\n id: raw.executedBy.id,\n name: raw.executedBy.name,\n email: raw.executedBy.email,\n }\n : null,\n editedBy: raw.editedBy\n ? {\n id: raw.editedBy.id,\n name: raw.editedBy.name,\n email: raw.editedBy.email,\n }\n : null,\n testRunCase: raw.testRunCase\n ? {\n id: raw.testRunCase.id,\n repositoryCaseId: raw.testRunCase.repositoryCaseId,\n repositoryCase: raw.testRunCase.repositoryCase\n ? {\n id: raw.testRunCase.repositoryCase.id,\n name: raw.testRunCase.repositoryCase.name,\n source: raw.testRunCase.repositoryCase.source,\n }\n : null,\n testRun: raw.testRunCase.testRun\n ? {\n id: raw.testRunCase.testRun.id,\n name: raw.testRunCase.testRun.name,\n }\n : null,\n }\n : null,\n // ResultFieldValues input shape matches CaseFieldValues input shape — both\n // surface `field.displayName / field.type.type / field.fieldOptions[].fieldOption`\n // (A3 verified in Phase 7 RESEARCH). We delegate to the Phase 6 helper to\n // keep the option-id resolution path identical.\n customFields: denormalizeCustomFields(raw.resultFieldValues as never),\n stepResults: (raw.stepResults ?? []).map(mapStepResult),\n attachments: (raw.attachments ?? []).map(mapAttachment),\n issues: (raw.issues ?? []).map(mapIssue),\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n RUN_ROW_INCLUDE,\n computeStatusRollup,\n mapRunRow,\n type RawRunRow,\n type StatusGroup,\n} from \"./shared.js\";\n\nexport interface RunsListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\n/**\n * Per-page batched groupBy result row. The handler issues ONE groupBy across\n * the whole page (`testRunId.in: [...pageIds]`) and fans the rollup out per\n * row via `computeStatusRollup` — never N per-row groupBy calls (D7-06 +\n * RESEARCH Q1/Q2 RESOLVED).\n */\ninterface BatchedStatusGroup extends StatusGroup {\n testRunId: number;\n}\n\nexport function registerRunsList(\n server: McpServer,\n deps: RunsListDeps,\n): void {\n server.registerTool(\n \"testplanit_test_runs_list\",\n {\n description:\n \"List test runs scoped to a project, with statusCounts rollup inline on every row (per D7-06). Filters: stateId, isCompleted, createdById (user id, string), from/to (createdAt date range, ISO 8601). Cursor pagination via the `cursor` returned in `nextCursor`. Each row carries denormalized project/state/createdBy/configuration/milestone/tags/issues + testRunType + `statusCounts: [{id,name,count}]` + `untested` + `total` (counts SUM to total). The rollup is fetched via a SINGLE batched groupBy per page, NOT per-row — agents can list 100 runs in one tool call without N+1 cost. (per EXEC-01 / D7-06)\",\n inputSchema: {\n projectId: z.number().int().positive(),\n stateId: z.number().int().positive().optional(),\n isCompleted: z.boolean().optional(),\n createdById: z.string().min(1).optional(),\n from: z.string().datetime({ offset: true }).optional(),\n to: z.string().datetime({ offset: true }).optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n\n const where: Prisma.TestRunsWhereInput = {\n projectId: input.projectId,\n isDeleted: false,\n };\n if (input.stateId !== undefined) where.stateId = input.stateId;\n if (input.isCompleted !== undefined) where.isCompleted = input.isCompleted;\n if (input.createdById) where.createdById = input.createdById;\n if (input.from || input.to) {\n where.createdAt = {\n ...(input.from ? { gte: new Date(input.from) } : {}),\n ...(input.to ? { lte: new Date(input.to) } : {}),\n };\n }\n\n const body: Record<string, unknown> = {\n where,\n include: RUN_ROW_INCLUDE,\n // BL-04: deterministic page ordering. Newest run first; id breaks ties\n // for runs created in the same millisecond.\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n // Call 1 — page rows.\n const rows =\n (await zenstack<RawRunRow[]>(\n \"testRuns\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const pageIds = trimmed.map((r) => r.id);\n\n // Call 2 — single batched groupBy across the whole trimmed page (D7-06).\n // Skipped entirely when the page is empty — no wasted round trips.\n let groups: BatchedStatusGroup[] = [];\n if (pageIds.length > 0) {\n groups =\n (await zenstack<BatchedStatusGroup[]>(\n \"testRunCases\",\n \"groupBy\",\n {\n by: [\"testRunId\", \"statusId\"],\n // R1: TestRunCases has NO isDeleted; do NOT add `isDeleted: false`.\n where: { testRunId: { in: pageIds } },\n _count: { id: true },\n } satisfies Prisma.TestRunCasesGroupByArgs,\n deps.env,\n )) ?? [];\n }\n\n // Call 3 — resolve names for non-null statusIds only. Skipped when\n // every grouped status is null (e.g., a page of runs with no executed\n // cases yet — R6 efficiency).\n const nonNullStatusIds = Array.from(\n new Set(\n groups\n .map((g) => g.statusId)\n .filter((id): id is number => id !== null),\n ),\n );\n const statuses =\n nonNullStatusIds.length === 0\n ? []\n : ((await zenstack<Array<{ id: number; name: string }>>(\n \"status\",\n \"findMany\",\n {\n where: { id: { in: nonNullStatusIds } },\n select: { id: true, name: true },\n } satisfies Prisma.StatusFindManyArgs,\n deps.env,\n )) ?? []);\n const nameById = new Map<number, string>(\n statuses.map((s) => [s.id, s.name]),\n );\n\n // Fan rollup out per run via the shared helper (single source of\n // truth — no inlined sums or option-resolution arithmetic here).\n const groupsByRun = new Map<number, StatusGroup[]>();\n for (const g of groups) {\n const arr = groupsByRun.get(g.testRunId) ?? [];\n arr.push({ statusId: g.statusId, _count: g._count });\n groupsByRun.set(g.testRunId, arr);\n }\n\n const items = trimmed.map((r) => {\n const rollup = computeStatusRollup(\n groupsByRun.get(r.id) ?? [],\n nameById,\n );\n return {\n ...mapRunRow(r),\n statusCounts: rollup.statusCounts,\n untested: rollup.untested,\n total: rollup.total,\n };\n });\n\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n RUN_ROW_INCLUDE,\n RUN_DETAIL_TESTCASE_INCLUDE,\n computeStatusRollup,\n extractStatusNames,\n mapRunRow,\n mapRunDetailTestCase,\n type RawRunRow,\n type RawRunDetailTestCase,\n} from \"./shared.js\";\n\nexport interface RunsGetDeps {\n env: EnvConfig;\n}\n\nconst TESTCASES_INLINE_LIMIT = 50;\n\n/**\n * Combined include for `testRuns.findUnique` — the run header (RUN_ROW_INCLUDE\n * shape) plus the first 50 testCases inline (each carrying repositoryCase /\n * assignedTo / status / latest result via RUN_DETAIL_TESTCASE_INCLUDE).\n *\n * Cases beyond the 50-cap are paginated via `testplanit_test_runs_cases_list`.\n * The include shape is `as const satisfies Prisma.TestRunsInclude` — adding\n * an unknown column produces TS2353 at compile time (Phase 6 WR-09).\n */\nexport const RUN_DETAIL_INCLUDE = {\n ...RUN_ROW_INCLUDE,\n testCases: {\n // BL-04 deterministic ordering carried into the inline include.\n orderBy: [{ order: \"asc\" }, { id: \"asc\" }],\n take: TESTCASES_INLINE_LIMIT,\n include: RUN_DETAIL_TESTCASE_INCLUDE,\n },\n} as const satisfies Prisma.TestRunsInclude;\n\nexport function registerRunsGet(\n server: McpServer,\n deps: RunsGetDeps,\n): void {\n server.registerTool(\n \"testplanit_test_runs_get\",\n {\n description:\n \"Fetch a single test run with denormalized header (state/createdBy/configuration/milestone/tags/issues/testRunType), status-count rollup (groupBy on testRunCases.statusId — counts SUM to total per R3), and the first 50 test cases inline (each with latestResult). When the run has more than 50 cases, `testCasesNextCursor` is set; call testplanit_test_runs_cases_list with that cursor to fetch the rest. (per EXEC-02 / D7-04 / D7-05)\",\n inputSchema: {\n runId: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<\n | (RawRunRow & { testCases: RawRunDetailTestCase[] })\n | null\n >(\n \"testRuns\",\n \"findUnique\",\n {\n where: { id: input.runId },\n include: RUN_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Test run ${input.runId} not found.`,\n },\n ],\n };\n }\n\n // R3 — total summed from groupBy results in computeStatusRollup;\n // never derived from a separate count call. The two-call sequence\n // (groupBy + status findMany) is encapsulated in extractStatusNames.\n const { groups, nameById } = await extractStatusNames(\n input.runId,\n deps.env,\n );\n const rollup = computeStatusRollup(groups, nameById);\n\n const testCases = (raw.testCases ?? []).map(mapRunDetailTestCase);\n // D7-05: if the run has more cases than fit inline AND the inline\n // page hit its cap, surface the last inline id as the cursor for\n // testplanit_test_runs_cases_list.\n const testCasesNextCursor =\n rollup.total > TESTCASES_INLINE_LIMIT &&\n testCases.length === TESTCASES_INLINE_LIMIT\n ? testCases[testCases.length - 1].id\n : null;\n\n const detail = {\n ...mapRunRow(raw),\n statusCounts: rollup.statusCounts,\n untested: rollup.untested,\n total: rollup.total,\n testCases,\n testCasesNextCursor,\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n RUN_DETAIL_TESTCASE_INCLUDE,\n mapRunDetailTestCase,\n type RawRunDetailTestCase,\n} from \"./shared.js\";\n\nexport interface RunsCasesListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\nexport function registerRunsCasesList(\n server: McpServer,\n deps: RunsCasesListDeps,\n): void {\n server.registerTool(\n \"testplanit_test_runs_cases_list\",\n {\n description:\n \"List the test cases assigned to a specific run. Filters: isCompleted, statusId, assignedToId (user id, string). Cursor pagination ordered by `order` then `id`. NOTE: TestRunCases does not have a soft-delete field — case removal from a run is via direct deletion (cascading from the run), not isDeleted. Each row carries `latestResult` (most recent executedAt) inline. (per EXEC-03 / D7-05)\",\n inputSchema: {\n runId: z.number().int().positive(),\n isCompleted: z.boolean().optional(),\n statusId: z.number().int().positive().optional(),\n // assignedToId is a String FK on TestRunCases — User PKs are strings\n // throughout TestPlanIt (Postgres uuid generated by NextAuth).\n assignedToId: z.string().min(1).optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n // R1: TestRunCases has NO isDeleted column. The\n // `Prisma.TestRunCasesWhereInput` annotation makes adding one a TS2353.\n const where: Prisma.TestRunCasesWhereInput = {\n testRunId: input.runId,\n };\n if (input.isCompleted !== undefined) where.isCompleted = input.isCompleted;\n if (input.statusId !== undefined) where.statusId = input.statusId;\n if (input.assignedToId) where.assignedToId = input.assignedToId;\n\n const body: Record<string, unknown> = {\n where,\n include: RUN_DETAIL_TESTCASE_INCLUDE,\n // BL-04 deterministic ordering. `order` is the user-facing sort\n // index; `id` breaks ties for cases inserted with the same order.\n orderBy: [{ order: \"asc\" }, { id: \"asc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows =\n (await zenstack<RawRunDetailTestCase[]>(\n \"testRunCases\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapRunDetailTestCase);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../../api.js\";\nimport type { EnvConfig } from \"../../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../../errors.js\";\nimport {\n RUN_RESULT_LIST_INCLUDE,\n mapRunResultRow,\n type RawRunResultRow,\n} from \"../shared.js\";\n\nexport interface RunResultsListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\nconst MAX_CASE_IDS = 500;\n\nexport function registerRunResultsList(\n server: McpServer,\n deps: RunResultsListDeps,\n): void {\n server.registerTool(\n \"testplanit_test_run_results_list\",\n {\n description:\n \"List test run results across runs. Filters: runId, caseIds (RepositoryCases ids — back-half of EXEC-06 chain when paired with testplanit_cases_list({issueId})), executedById (user id, string), statusId, from/to (executedAt date range, ISO 8601). Cursor pagination ordered by executedAt DESC then id DESC (BL-04 deterministic + D7-02 latest-first). Each row carries denormalized status/executedBy/testRunCase (with repositoryCase + testRun summary). For step-level detail call testplanit_test_run_results_get with the row id. (per EXEC-04 / D7-01)\",\n inputSchema: {\n runId: z.number().int().positive().optional(),\n caseIds: z\n .array(z.number().int().positive())\n .min(1)\n .max(MAX_CASE_IDS)\n .optional(),\n executedById: z.string().min(1).optional(),\n statusId: z.number().int().positive().optional(),\n from: z.string().datetime({ offset: true }).optional(),\n to: z.string().datetime({ offset: true }).optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n // TestRunResults HAS isDeleted (schema.zmodel:2393 area). Defense-in-depth:\n // every code path that builds `where` starts from this base object so no\n // input branch can drop the soft-delete filter.\n const where: Prisma.TestRunResultsWhereInput = { isDeleted: false };\n if (input.runId !== undefined) where.testRunId = input.runId;\n if (input.caseIds && input.caseIds.length > 0) {\n // EXEC-06 back-half: nested relation filter via\n // `where.testRunCase.repositoryCaseId.in` — Prisma expands this to a\n // join + IN over RepositoryCases.id, scoped per-row by the host's\n // ZenStack @@allow policy. Cross-tenant rows can't leak through\n // this filter (T-07-02 / T-07-04).\n where.testRunCase = { repositoryCaseId: { in: input.caseIds } };\n }\n if (input.executedById) where.executedById = input.executedById;\n if (input.statusId !== undefined) where.statusId = input.statusId;\n if (input.from || input.to) {\n where.executedAt = {\n ...(input.from ? { gte: new Date(input.from) } : {}),\n ...(input.to ? { lte: new Date(input.to) } : {}),\n };\n }\n\n const body: Record<string, unknown> = {\n where,\n include: RUN_RESULT_LIST_INCLUDE,\n // BL-04 deterministic ordering — D7-02 latest-first (matches the\n // (testRunCaseId, executedAt(sort: Desc)) schema index); id breaks\n // ties for results recorded in the same millisecond.\n orderBy: [{ executedAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows =\n (await zenstack<RawRunResultRow[]>(\n \"testRunResults\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapRunResultRow);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../../api.js\";\nimport type { EnvConfig } from \"../../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../../errors.js\";\nimport {\n RUN_RESULT_DETAIL_INCLUDE,\n mapRunResultDetail,\n type RawRunResultDetail,\n} from \"../shared.js\";\n\nexport interface RunResultsGetDeps {\n env: EnvConfig;\n}\n\nexport function registerRunResultsGet(\n server: McpServer,\n deps: RunResultsGetDeps,\n): void {\n server.registerTool(\n \"testplanit_test_run_results_get\",\n {\n description:\n \"Fetch a single test run result with step-level results inlined (drill-down model — D7-09; no separate step-results-list tool). Each step result carries stepText / expectedResultText (ProseMirror plain-text), status (from the stepStatus relation per R2 / schema.zmodel:2437), notes (ProseMirror), evidence (Json surfaced as-is per D7-08), attachments, and linked issues. Top-level result includes customFields (resultFieldValues denormalized) and the parent testRunCase summary. (per EXEC-05 / D7-07)\",\n inputSchema: {\n // T-07-04 IDOR mitigation: positive integer only; non-int / non-positive\n // rejected at the zod boundary before zenstack is called. Host's\n // ZenStack @@allow policy is the row-level access boundary.\n resultId: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<RawRunResultDetail | null>(\n \"testRunResults\",\n \"findUnique\",\n {\n where: { id: input.resultId },\n // RUN_RESULT_DETAIL_INCLUDE (07-01) ships the full step-level\n // shape: stepResults with stepStatus (R2), step text, attachments,\n // issues, plus top-level resultFieldValues / attachments / issues.\n // The constant is `as const satisfies Prisma.TestRunResultsInclude`\n // so a schema drift fails at typecheck (Phase 6 WR-09 invariant).\n include: RUN_RESULT_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n // T-07-02 IDOR: when the host's ZenStack @@allow policy denies the\n // row, findUnique returns null. Surface as a not-found rather than\n // a 403 to avoid leaking row-existence to unauthorized callers.\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Test run result ${input.resultId} not found.`,\n },\n ],\n };\n }\n\n const detail = mapRunResultDetail(raw);\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../../api.js\";\nimport type { EnvConfig } from \"../../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../../errors.js\";\nimport { TestPlanItHttpError } from \"../../../http.js\";\nimport {\n RUN_RESULT_DETAIL_INCLUDE,\n mapRunResultDetail,\n type RawRunResultDetail,\n} from \"../shared.js\";\n\nexport interface RunResultsCreateDeps {\n env: EnvConfig;\n}\n\nconst FETCH_TIMEOUT_MS = 10000;\n\nfunction bearerHeaders(env: EnvConfig): Record<string, string> {\n return {\n Authorization: `Bearer ${env.apiToken}`,\n \"Content-Type\": \"application/json\",\n };\n}\n\nasync function submitResult(\n payload: {\n testRunId: number;\n testRunCaseId: number;\n statusId: number;\n notes: string | undefined;\n elapsed: number | null;\n attempt: number;\n testRunCaseVersion: number;\n },\n env: EnvConfig,\n): Promise<{ result: { id: number } }> {\n const response = await fetch(\n `${env.apiUrl}/api/test-runs/submit-result`,\n {\n method: \"POST\",\n headers: bearerHeaders(env),\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n },\n );\n const text = await response.text();\n if (!response.ok) {\n let parsedMessage: string | undefined;\n try {\n const parsed = JSON.parse(text) as Record<string, unknown>;\n const errField = parsed?.error;\n if (typeof errField === \"string\") {\n parsedMessage = errField;\n } else if (errField && typeof errField === \"object\") {\n const msg = (errField as Record<string, unknown>).message;\n if (typeof msg === \"string\") parsedMessage = msg;\n }\n } catch {\n // non-JSON body\n }\n throw new TestPlanItHttpError(\n `HTTP ${response.status} from /api/test-runs/submit-result${parsedMessage ? `: ${parsedMessage}` : \"\"}`,\n { statusCode: response.status },\n );\n }\n return JSON.parse(text) as { result: { id: number } };\n}\n\nexport function registerRunResultsCreate(\n server: McpServer,\n deps: RunResultsCreateDeps,\n): void {\n server.registerTool(\n \"testplanit_test_run_results_create\",\n {\n description:\n \"Submit a test result for a case in a run. Atomically creates the result record and updates the run case's current status. The attempt number is auto-incremented — no need to track it manually. Returns the full denormalized result (same shape as testplanit_test_run_results_get).\",\n inputSchema: {\n testRunCaseId: z\n .number()\n .int()\n .positive()\n .describe(\"ID of the TestRunCase to submit a result for.\"),\n statusName: z\n .string()\n .min(1)\n .describe(\n \"Status name (e.g. 'Passed', 'Failed', 'Blocked'). Must match a status enabled for the project.\",\n ),\n notes: z\n .string()\n .optional()\n .describe(\"Plain-text notes for the result.\"),\n elapsed: z\n .number()\n .int()\n .nonnegative()\n .nullable()\n .optional()\n .describe(\"Elapsed time in milliseconds, or null.\"),\n },\n },\n async (input) => {\n try {\n // Fetch the test run case to get testRunId and projectId.\n const runCase = await zenstack<{\n id: number;\n testRunId: number;\n testRun: { projectId: number };\n } | null>(\n \"testRunCases\",\n \"findUnique\",\n {\n where: { id: input.testRunCaseId },\n select: {\n id: true,\n testRunId: true,\n testRun: { select: { projectId: true } },\n } satisfies Prisma.TestRunCasesSelect,\n },\n deps.env,\n );\n\n if (!runCase) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `TestRunCase ${input.testRunCaseId} not found.`,\n },\n ],\n };\n }\n\n // Resolve status by name scoped to the project.\n const statuses = await zenstack<Array<{ id: number }>>(\n \"status\",\n \"findMany\",\n {\n where: {\n name: input.statusName,\n isDeleted: false,\n isEnabled: true,\n projects: { some: { projectId: runCase.testRun.projectId } },\n } satisfies Prisma.StatusWhereInput,\n select: { id: true } satisfies Prisma.StatusSelect,\n take: 1,\n },\n deps.env,\n );\n\n if (!statuses || statuses.length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Status \"${input.statusName}\" not found for project ${runCase.testRun.projectId}. Use testplanit_test_runs_get to see available status names.`,\n },\n ],\n };\n }\n\n // Auto-increment attempt: count existing non-deleted results.\n const existingCount = await zenstack<number>(\n \"testRunResults\",\n \"count\",\n {\n where: {\n testRunCaseId: input.testRunCaseId,\n isDeleted: false,\n } satisfies Prisma.TestRunResultsWhereInput,\n },\n deps.env,\n );\n const attempt = (existingCount ?? 0) + 1;\n\n const { result } = await submitResult(\n {\n testRunId: runCase.testRunId,\n testRunCaseId: input.testRunCaseId,\n statusId: statuses[0].id,\n notes: input.notes,\n elapsed: input.elapsed ?? null,\n attempt,\n testRunCaseVersion: 1,\n },\n deps.env,\n );\n\n // Re-fetch the created result with the full denormalized shape.\n const raw = await zenstack<RawRunResultDetail | null>(\n \"testRunResults\",\n \"findUnique\",\n {\n where: { id: result.id },\n include: RUN_RESULT_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Result ${result.id} was created but could not be re-fetched.`,\n },\n ],\n };\n }\n\n const detail = mapRunResultDetail(raw);\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerRunResultsList, type RunResultsListDeps } from \"./list.js\";\nimport { registerRunResultsGet, type RunResultsGetDeps } from \"./get.js\";\nimport {\n registerRunResultsCreate,\n type RunResultsCreateDeps,\n} from \"./create.js\";\n\nexport type RunResultsDeps = RunResultsListDeps &\n RunResultsGetDeps &\n RunResultsCreateDeps;\n\nexport function registerRunResults(\n server: McpServer,\n deps: RunResultsDeps,\n): void {\n registerRunResultsList(server, deps);\n registerRunResultsGet(server, deps);\n registerRunResultsCreate(server, deps);\n}\n\nexport { registerRunResultsList, registerRunResultsGet, registerRunResultsCreate };\nexport type { RunResultsListDeps, RunResultsGetDeps, RunResultsCreateDeps };\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport { resolveTagIds } from \"../cases/shared.js\";\nimport { RUN_DETAIL_INCLUDE } from \"./get.js\";\nimport {\n computeStatusRollup,\n extractStatusNames,\n mapRunRow,\n mapRunDetailTestCase,\n type RawRunRow,\n type RawRunDetailTestCase,\n} from \"./shared.js\";\n\nexport interface RunsCreateDeps {\n env: EnvConfig;\n}\n\nconst TESTCASES_INLINE_LIMIT = 50;\nconst MAX_CASE_IDS = 250;\n\nexport async function resolveRunState(\n projectId: number,\n env: EnvConfig,\n name?: string,\n): Promise<{ id: number; name: string }> {\n const workflows = await zenstack<{ id: number; name: string }[]>(\n \"workflows\",\n \"findMany\",\n {\n where: {\n isEnabled: true,\n isDeleted: false,\n scope: \"RUNS\",\n projects: { some: { projectId } },\n ...(name ? { name } : {}),\n } satisfies Prisma.WorkflowsWhereInput,\n orderBy: { order: \"asc\" } satisfies Prisma.WorkflowsOrderByWithRelationInput,\n take: 1,\n },\n env,\n );\n if (!workflows || workflows.length === 0) {\n const suffix = name ? ` named \"${name}\"` : \"\";\n throw new TestPlanItHttpError(\n `No RUNS-scope workflow state found for project ${projectId}${suffix}.`,\n { statusCode: 422 },\n );\n }\n return workflows[0];\n}\n\nexport function registerRunsCreate(\n server: McpServer,\n deps: RunsCreateDeps,\n): void {\n server.registerTool(\n \"testplanit_runs_create\",\n {\n description:\n \"Create a new test run in a project. Optionally add test cases, link to a milestone or configuration, set tags, and pick a workflow state by name. Returns the full denormalized run detail (same shape as testplanit_test_runs_get). State defaults to the first RUNS-scope state by order when omitted. testRunType is always REGULAR.\",\n inputSchema: {\n projectId: z\n .number()\n .int()\n .positive()\n .describe(\"Project to create the run in.\"),\n name: z.string().min(1).max(500).describe(\"Test run name.\"),\n caseIds: z\n .array(z.number().int().positive())\n .max(MAX_CASE_IDS)\n .optional()\n .describe(\n `Repository case IDs to add to the run (max ${MAX_CASE_IDS}). Order is preserved.`,\n ),\n milestoneId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Milestone to link the run to.\"),\n configId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Configuration ID to associate with the run.\"),\n stateName: z\n .string()\n .min(1)\n .optional()\n .describe(\n \"RUNS workflow state name. Defaults to the first state by order.\",\n ),\n tags: z\n .array(z.union([z.number().int().positive(), z.string().min(1)]))\n .optional()\n .describe(\n \"Tag IDs (numbers) or tag names (strings, created if missing).\",\n ),\n },\n },\n async (input) => {\n try {\n const state = await resolveRunState(\n input.projectId,\n deps.env,\n input.stateName,\n );\n const tagIds = await resolveTagIds(input.tags, deps.env);\n\n const created = await zenstack<{ id: number }>(\n \"testRuns\",\n \"create\",\n {\n data: {\n name: input.name,\n testRunType: \"REGULAR\",\n project: { connect: { id: input.projectId } },\n state: { connect: { id: state.id } },\n ...(input.milestoneId\n ? { milestone: { connect: { id: input.milestoneId } } }\n : {}),\n ...(input.configId\n ? { configuration: { connect: { id: input.configId } } }\n : {}),\n ...(tagIds.length > 0\n ? { tags: { connect: tagIds.map((id) => ({ id })) } }\n : {}),\n },\n select: { id: true },\n },\n deps.env,\n );\n\n if (input.caseIds && input.caseIds.length > 0) {\n await zenstack(\n \"testRunCases\",\n \"createMany\",\n {\n data: input.caseIds.map((caseId, i) => ({\n testRunId: created.id,\n repositoryCaseId: caseId,\n order: i + 1,\n })),\n },\n deps.env,\n );\n }\n\n const raw = await zenstack<\n (RawRunRow & { testCases: RawRunDetailTestCase[] }) | null\n >(\n \"testRuns\",\n \"findUnique\",\n {\n where: { id: created.id },\n include: RUN_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n throw new TestPlanItHttpError(\n `Test run ${created.id} was created but could not be re-fetched.`,\n { statusCode: 422 },\n );\n }\n\n const { groups, nameById } = await extractStatusNames(\n created.id,\n deps.env,\n );\n const rollup = computeStatusRollup(groups, nameById);\n\n const testCases = (raw.testCases ?? []).map(mapRunDetailTestCase);\n const testCasesNextCursor =\n rollup.total > TESTCASES_INLINE_LIMIT &&\n testCases.length === TESTCASES_INLINE_LIMIT\n ? testCases[testCases.length - 1].id\n : null;\n\n const detail = {\n ...mapRunRow(raw),\n statusCounts: rollup.statusCounts,\n untested: rollup.untested,\n total: rollup.total,\n testCases,\n testCasesNextCursor,\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { resolveTagIds } from \"../cases/shared.js\";\nimport { resolveRunState } from \"./create.js\";\nimport {\n RUN_DETAIL_INCLUDE,\n} from \"./get.js\";\nimport {\n computeStatusRollup,\n extractStatusNames,\n mapRunRow,\n mapRunDetailTestCase,\n type RawRunRow,\n type RawRunDetailTestCase,\n} from \"./shared.js\";\n\nexport interface RunsUpdateDeps {\n env: EnvConfig;\n}\n\nconst TESTCASES_INLINE_LIMIT = 50;\n\nexport function registerRunsUpdate(\n server: McpServer,\n deps: RunsUpdateDeps,\n): void {\n server.registerTool(\n \"testplanit_runs_update\",\n {\n description:\n \"Update an existing test run. Supports renaming, changing workflow state, swapping milestone or configuration, and replacing tags. All fields except runId are optional — only supplied fields are changed. Returns the full denormalized run detail (same shape as testplanit_test_runs_get).\",\n inputSchema: {\n runId: z.number().int().positive().describe(\"ID of the run to update.\"),\n name: z\n .string()\n .min(1)\n .max(500)\n .optional()\n .describe(\"New run name.\"),\n stateName: z\n .string()\n .min(1)\n .optional()\n .describe(\"RUNS workflow state name to transition to.\"),\n milestoneId: z\n .number()\n .int()\n .positive()\n .nullable()\n .optional()\n .describe(\"Milestone to link; pass null to remove the current link.\"),\n configId: z\n .number()\n .int()\n .positive()\n .nullable()\n .optional()\n .describe(\"Configuration ID; pass null to remove.\"),\n tags: z\n .array(z.union([z.number().int().positive(), z.string().min(1)]))\n .optional()\n .describe(\n \"Replacement tag list (full set). Tag IDs (numbers) or names (strings, created if missing). Replaces all current tags.\",\n ),\n isCompleted: z\n .boolean()\n .optional()\n .describe(\"Mark the run as completed (true) or reopen it (false).\"),\n },\n },\n async (input) => {\n try {\n const data: Record<string, unknown> = {};\n\n if (input.name !== undefined) data.name = input.name;\n\n if (input.stateName !== undefined) {\n // Fetch the run first to get projectId for state resolution.\n const run = await zenstack<{ projectId: number } | null>(\n \"testRuns\",\n \"findUnique\",\n {\n where: { id: input.runId },\n select: { projectId: true } satisfies Prisma.TestRunsSelect,\n },\n deps.env,\n );\n if (!run) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Test run ${input.runId} not found.`,\n },\n ],\n };\n }\n const state = await resolveRunState(\n run.projectId,\n deps.env,\n input.stateName,\n );\n data.state = { connect: { id: state.id } };\n }\n\n if (input.milestoneId !== undefined) {\n data.milestone =\n input.milestoneId === null\n ? { disconnect: true }\n : { connect: { id: input.milestoneId } };\n }\n\n if (input.configId !== undefined) {\n data.configuration =\n input.configId === null\n ? { disconnect: true }\n : { connect: { id: input.configId } };\n }\n\n if (input.isCompleted !== undefined) {\n data.isCompleted = input.isCompleted;\n if (input.isCompleted) {\n data.completedAt = new Date().toISOString();\n } else {\n data.completedAt = null;\n }\n }\n\n if (input.tags !== undefined) {\n const tagIds = await resolveTagIds(input.tags, deps.env);\n data.tags = { set: tagIds.map((id) => ({ id })) };\n }\n\n if (Object.keys(data).length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"No fields to update — provide at least one optional field.\",\n },\n ],\n };\n }\n\n await zenstack(\n \"testRuns\",\n \"update\",\n {\n where: { id: input.runId },\n data,\n select: { id: true },\n },\n deps.env,\n );\n\n const raw = await zenstack<\n (RawRunRow & { testCases: RawRunDetailTestCase[] }) | null\n >(\n \"testRuns\",\n \"findUnique\",\n {\n where: { id: input.runId },\n include: RUN_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Test run ${input.runId} not found after update.`,\n },\n ],\n };\n }\n\n const { groups, nameById } = await extractStatusNames(\n input.runId,\n deps.env,\n );\n const rollup = computeStatusRollup(groups, nameById);\n\n const testCases = (raw.testCases ?? []).map(mapRunDetailTestCase);\n const testCasesNextCursor =\n rollup.total > TESTCASES_INLINE_LIMIT &&\n testCases.length === TESTCASES_INLINE_LIMIT\n ? testCases[testCases.length - 1].id\n : null;\n\n const detail = {\n ...mapRunRow(raw),\n statusCounts: rollup.statusCounts,\n untested: rollup.untested,\n total: rollup.total,\n testCases,\n testCasesNextCursor,\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\n\nexport interface RunsCasesAddDeps {\n env: EnvConfig;\n}\n\nconst MAX_CASE_IDS = 250;\n\nexport function registerRunsCasesAdd(\n server: McpServer,\n deps: RunsCasesAddDeps,\n): void {\n server.registerTool(\n \"testplanit_runs_cases_add\",\n {\n description:\n \"Add repository test cases to an existing test run. Cases are appended after any existing run cases (order preserved). Duplicate case IDs are silently skipped by the database. Returns a confirmation with the number of cases added and the updated total.\",\n inputSchema: {\n runId: z\n .number()\n .int()\n .positive()\n .describe(\"ID of the run to add cases to.\"),\n caseIds: z\n .array(z.number().int().positive())\n .min(1)\n .max(MAX_CASE_IDS)\n .describe(\n `Repository case IDs to add (1–${MAX_CASE_IDS}). Order is preserved.`,\n ),\n },\n },\n async (input) => {\n try {\n // Get the current max order for this run so new cases are appended.\n const agg = await zenstack<{ _max: { order: number | null } }>(\n \"testRunCases\",\n \"aggregate\",\n {\n where: { testRunId: input.runId },\n _max: { order: true },\n } satisfies Prisma.TestRunCasesAggregateArgs,\n deps.env,\n );\n const baseOrder = (agg?._max?.order ?? 0) + 1;\n\n await zenstack(\n \"testRunCases\",\n \"createMany\",\n {\n data: input.caseIds.map((caseId, i) => ({\n testRunId: input.runId,\n repositoryCaseId: caseId,\n order: baseOrder + i,\n })),\n skipDuplicates: true,\n },\n deps.env,\n );\n\n // Return the updated total (R1: no isDeleted on TestRunCases).\n const total = await zenstack<number>(\n \"testRunCases\",\n \"count\",\n {\n where: { testRunId: input.runId },\n } satisfies Prisma.TestRunCasesCountArgs,\n deps.env,\n );\n\n const result = {\n runId: input.runId,\n requested: input.caseIds.length,\n total: total ?? 0,\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerRunsList, type RunsListDeps } from \"./list.js\";\nimport { registerRunsGet, type RunsGetDeps } from \"./get.js\";\nimport {\n registerRunsCasesList,\n type RunsCasesListDeps,\n} from \"./cases.js\";\nimport {\n registerRunResults,\n type RunResultsDeps,\n} from \"./results/index.js\";\nimport { registerRunsCreate, type RunsCreateDeps } from \"./create.js\";\nimport { registerRunsUpdate, type RunsUpdateDeps } from \"./update.js\";\nimport { registerRunsCasesAdd, type RunsCasesAddDeps } from \"./cases-add.js\";\n\nexport type RunsDeps =\n & RunsListDeps\n & RunsGetDeps\n & RunsCasesListDeps\n & RunResultsDeps\n & RunsCreateDeps\n & RunsUpdateDeps\n & RunsCasesAddDeps;\n\nexport function registerRuns(server: McpServer, deps: RunsDeps): void {\n registerRunsList(server, deps);\n registerRunsGet(server, deps);\n registerRunsCasesList(server, deps);\n registerRunResults(server, deps);\n registerRunsCreate(server, deps);\n registerRunsUpdate(server, deps);\n registerRunsCasesAdd(server, deps);\n}\n\nexport {\n registerRunsList,\n registerRunsGet,\n registerRunsCasesList,\n registerRunResults,\n registerRunsCreate,\n registerRunsUpdate,\n registerRunsCasesAdd,\n};\nexport type {\n RunsListDeps,\n RunsGetDeps,\n RunsCasesListDeps,\n RunResultsDeps,\n RunsCreateDeps,\n RunsUpdateDeps,\n RunsCasesAddDeps,\n};\n","import type { Prisma } from \"@prisma/client\";\nimport {\n extractProseMirrorText,\n denormalizeCustomFields,\n} from \"../cases/shared.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Typed includes — every literal carries `as const satisfies Prisma.<Model><Include|Select>`.\n// Reintroducing an unknown column produces TS2353 (Phase 6 WR-09 invariant).\n//\n// CRITICAL invariants:\n// R4 — SessionResults has NO `testCaseId` FK; sessions are exploratory and\n// not case-linked. Filtering by testCaseId is impossible and any\n// attempt to do so trips Prisma.SessionResultsWhereInput's TS2353.\n// D7-12 — sessions inline up to 100 sessionResults; cap take at 101 so the\n// tool layer can detect overflow and surface truncated:true.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const SESSION_ROW_INCLUDE = {\n project: { select: { id: true, name: true } },\n state: { select: { id: true, name: true } },\n // NOTE: schema relation is `createdBy` (Sessions.createdBy), NOT `creator`.\n createdBy: { select: { id: true, name: true, email: true } },\n assignedTo: { select: { id: true, name: true, email: true } },\n // Templates.templateName is the field name on the schema (not `name`).\n // Surfaced to agents as `template: {id, name}` via the mapper.\n template: { select: { id: true, templateName: true } },\n configuration: { select: { id: true, name: true } },\n milestone: { select: { id: true, name: true } },\n tags: { select: { id: true, name: true } },\n} as const satisfies Prisma.SessionsInclude;\n\n// SESS-02 full include — sessionFieldValues use `field.type.type` +\n// `field.fieldOptions[].fieldOption` shape identical to caseFieldValues\n// (SessionFieldValues.fieldId points to CaseFields per schema.zmodel:2132,\n// not a separate SessionFields model). sessionResults capped at take:101\n// so the tool can detect overflow per D7-12.\nexport const SESSION_DETAIL_INCLUDE = {\n project: { select: { id: true, name: true } },\n state: { select: { id: true, name: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n assignedTo: { select: { id: true, name: true, email: true } },\n // Templates.templateName is the field name on the schema (not `name`).\n // Surfaced to agents as `template: {id, name}` via the mapper.\n template: { select: { id: true, templateName: true } },\n configuration: { select: { id: true, name: true } },\n milestone: { select: { id: true, name: true } },\n tags: { select: { id: true, name: true } },\n issues: {\n where: { isDeleted: false },\n select: {\n id: true,\n externalKey: true,\n title: true,\n externalStatus: true,\n integration: { select: { provider: true } },\n },\n },\n sessionResults: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"asc\" }, { id: \"asc\" }],\n take: 101, // D7-12 cap — tool layer detects overflow when length > 100\n select: {\n id: true,\n createdAt: true,\n elapsed: true,\n resultData: true,\n status: { select: { id: true, name: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n session: { select: { id: true, name: true, projectId: true } },\n },\n },\n sessionFieldValues: {\n include: {\n field: {\n select: {\n displayName: true,\n type: { select: { type: true } },\n fieldOptions: {\n select: { fieldOption: { select: { id: true, name: true } } },\n },\n },\n },\n },\n },\n} as const satisfies Prisma.SessionsInclude;\n\nexport const SESSION_RESULT_LIST_INCLUDE = {\n status: { select: { id: true, name: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n session: { select: { id: true, name: true, projectId: true } },\n} as const satisfies Prisma.SessionResultsInclude;\n\nexport const SESSION_RESULT_DETAIL_INCLUDE = {\n status: { select: { id: true, name: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n session: { select: { id: true, name: true, projectId: true } },\n attachments: {\n where: { isDeleted: false },\n select: { id: true, name: true, url: true },\n },\n issues: {\n where: { isDeleted: false },\n select: {\n id: true,\n externalKey: true,\n title: true,\n externalStatus: true,\n integration: { select: { provider: true } },\n },\n },\n resultFieldValues: {\n include: {\n field: {\n select: {\n displayName: true,\n type: { select: { type: true } },\n fieldOptions: {\n select: { fieldOption: { select: { id: true, name: true } } },\n },\n },\n },\n },\n },\n} as const satisfies Prisma.SessionResultsInclude;\n\n// FINDING_INCLUDE — for SESS-05 sessionId mode; per-Issue row shape\nexport const FINDING_INCLUDE = {\n integration: { select: { provider: true } },\n} as const satisfies Prisma.IssueInclude;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// denormalizeResultFieldValues\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface RawResultFieldValueRow {\n value: unknown;\n field?: {\n displayName?: string | null;\n type?: { type?: string | null } | null;\n fieldOptions?: Array<{\n fieldOption?: { id: number; name: string } | null;\n }> | null;\n } | null;\n}\n\n/**\n * Convert raw `resultFieldValues` rows into the flat `{ <displayName>: value }`\n * dict per D-08. Delegates to the Phase 6 `denormalizeCustomFields` helper:\n * ResultFields and CaseFields surface the same nested option-resolution shape\n * on read (`field.displayName / field.type.type / field.fieldOptions[].fieldOption`),\n * even though the join tables differ (`ResultFieldAssignment` vs.\n * `CaseFieldAssignment`). Verified A3 — both shapes match exactly at the\n * include level used here.\n */\nexport function denormalizeResultFieldValues(\n rows: RawResultFieldValueRow[] | null | undefined,\n): Record<string, unknown> {\n return denormalizeCustomFields(rows as never);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Mappers — every output field enumerated explicitly (T-07-03 mitigation)\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface RawIssue {\n id: number;\n externalKey: string | null;\n title: string | null;\n externalStatus: string | null;\n integration: { provider: string } | null;\n}\n\nfunction mapIssue(raw: RawIssue) {\n return {\n id: raw.id,\n externalKey: raw.externalKey,\n title: raw.title,\n externalStatus: raw.externalStatus,\n externalSystem: raw.integration?.provider ?? null,\n };\n}\n\ninterface RawAttachment {\n id: number;\n name: string;\n url: string;\n}\n\nfunction mapAttachment(raw: RawAttachment) {\n return { id: raw.id, fileName: raw.name, url: raw.url };\n}\n\nexport interface RawSessionRow {\n id: number;\n name: string;\n isCompleted: boolean;\n completedAt: string | Date | null;\n createdAt: string | Date;\n mission: unknown;\n note: unknown;\n project: { id: number; name: string } | null;\n state: { id: number; name: string } | null;\n createdBy: { id: string; name: string | null; email: string } | null;\n assignedTo: { id: string; name: string | null; email: string } | null;\n template: { id: number; templateName: string } | null;\n configuration: { id: number; name: string } | null;\n milestone: { id: number; name: string } | null;\n tags: Array<{ id: number; name: string }>;\n}\n\nexport function mapSessionRow(raw: RawSessionRow) {\n return {\n id: raw.id,\n name: raw.name,\n isCompleted: raw.isCompleted,\n completedAt: raw.completedAt ?? null,\n createdAt: raw.createdAt,\n mission: extractProseMirrorText(raw.mission),\n note: extractProseMirrorText(raw.note),\n project: raw.project\n ? { id: raw.project.id, name: raw.project.name }\n : null,\n state: raw.state ? { id: raw.state.id, name: raw.state.name } : null,\n createdBy: raw.createdBy\n ? {\n id: raw.createdBy.id,\n name: raw.createdBy.name,\n email: raw.createdBy.email,\n }\n : null,\n assignedTo: raw.assignedTo\n ? {\n id: raw.assignedTo.id,\n name: raw.assignedTo.name,\n email: raw.assignedTo.email,\n }\n : null,\n template: raw.template\n ? { id: raw.template.id, name: raw.template.templateName }\n : null,\n configuration: raw.configuration\n ? { id: raw.configuration.id, name: raw.configuration.name }\n : null,\n milestone: raw.milestone\n ? { id: raw.milestone.id, name: raw.milestone.name }\n : null,\n tags: (raw.tags ?? []).map((t) => ({ id: t.id, name: t.name })),\n };\n}\n\ninterface RawSessionResultInline {\n id: number;\n createdAt: string | Date;\n elapsed: number | null;\n resultData: unknown;\n status: { id: number; name: string } | null;\n createdBy: { id: string; name: string | null; email: string } | null;\n session: { id: number; name: string; projectId: number } | null;\n}\n\nfunction mapSessionResultInline(raw: RawSessionResultInline) {\n return {\n id: raw.id,\n createdAt: raw.createdAt,\n elapsed: raw.elapsed ?? null,\n resultDataText: extractProseMirrorText(raw.resultData),\n status: raw.status ? { id: raw.status.id, name: raw.status.name } : null,\n createdBy: raw.createdBy\n ? {\n id: raw.createdBy.id,\n name: raw.createdBy.name,\n email: raw.createdBy.email,\n }\n : null,\n session: raw.session\n ? {\n id: raw.session.id,\n name: raw.session.name,\n projectId: raw.session.projectId,\n }\n : null,\n };\n}\n\nexport interface RawSessionDetail extends RawSessionRow {\n issues: RawIssue[];\n sessionResults: RawSessionResultInline[];\n sessionFieldValues: Array<{\n value: unknown;\n field: {\n displayName: string | null;\n type: { type: string | null } | null;\n fieldOptions: Array<{\n fieldOption: { id: number; name: string } | null;\n }>;\n } | null;\n }>;\n}\n\nexport interface SessionDetailFlags {\n truncated: boolean;\n}\n\nexport function mapSessionDetail(\n raw: RawSessionDetail,\n flags: SessionDetailFlags,\n) {\n return {\n ...mapSessionRow(raw),\n issues: (raw.issues ?? []).map(mapIssue),\n customFields: denormalizeCustomFields(raw.sessionFieldValues as never),\n sessionResults: (raw.sessionResults ?? []).map(mapSessionResultInline),\n truncated: flags.truncated,\n };\n}\n\nexport interface RawSessionResultRow extends RawSessionResultInline {}\n\nexport function mapSessionResultRow(raw: RawSessionResultRow) {\n return mapSessionResultInline(raw);\n}\n\nexport interface RawSessionResultDetail extends RawSessionResultRow {\n attachments: RawAttachment[];\n issues: RawIssue[];\n resultFieldValues: Array<{\n value: unknown;\n field: {\n displayName: string | null;\n type: { type: string | null } | null;\n fieldOptions: Array<{\n fieldOption: { id: number; name: string } | null;\n }>;\n } | null;\n }>;\n}\n\nexport function mapSessionResultDetail(raw: RawSessionResultDetail) {\n return {\n ...mapSessionResultInline(raw),\n customFields: denormalizeResultFieldValues(raw.resultFieldValues),\n attachments: (raw.attachments ?? []).map(mapAttachment),\n issues: (raw.issues ?? []).map(mapIssue),\n };\n}\n\nexport interface RawFinding {\n id: number;\n externalKey: string | null;\n title: string | null;\n status: string | null;\n externalStatus: string | null;\n priority: string | null;\n integration: { provider: string } | null;\n}\n\nexport function mapFinding(raw: RawFinding) {\n return {\n id: raw.id,\n externalKey: raw.externalKey,\n title: raw.title,\n status: raw.status,\n externalStatus: raw.externalStatus,\n priority: raw.priority,\n externalSystem: raw.integration?.provider ?? null,\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n SESSION_ROW_INCLUDE,\n mapSessionRow,\n type RawSessionRow,\n} from \"./shared.js\";\n\nexport interface SessionsListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\nexport function registerSessionsList(\n server: McpServer,\n deps: SessionsListDeps,\n): void {\n server.registerTool(\n \"testplanit_sessions_list\",\n {\n description:\n \"List sessions scoped to a project. Filters: stateId, isCompleted, createdById (user id, string), from/to (createdAt date range, ISO 8601). Cursor pagination ordered by createdAt DESC then id DESC (BL-04 deterministic). Each row carries denormalized state/createdBy/assignedTo/template/configuration/milestone/tags + mission and note extracted to plain text. (per SESS-01)\",\n inputSchema: {\n projectId: z.number().int().positive(),\n stateId: z.number().int().positive().optional(),\n isCompleted: z.boolean().optional(),\n createdById: z.string().min(1).optional(),\n from: z.string().datetime({ offset: true }).optional(),\n to: z.string().datetime({ offset: true }).optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n\n const where: Prisma.SessionsWhereInput = {\n projectId: input.projectId,\n isDeleted: false,\n };\n if (input.stateId !== undefined) where.stateId = input.stateId;\n if (input.isCompleted !== undefined)\n where.isCompleted = input.isCompleted;\n if (input.createdById) where.createdById = input.createdById;\n if (input.from || input.to) {\n where.createdAt = {\n ...(input.from ? { gte: new Date(input.from) } : {}),\n ...(input.to ? { lte: new Date(input.to) } : {}),\n };\n }\n\n const body: Record<string, unknown> = {\n where,\n include: SESSION_ROW_INCLUDE,\n // BL-04: deterministic page ordering. Newest session first; id breaks\n // ties for sessions created in the same millisecond.\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows =\n (await zenstack<RawSessionRow[]>(\n \"sessions\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapSessionRow);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n SESSION_DETAIL_INCLUDE,\n mapSessionDetail,\n type RawSessionDetail,\n} from \"./shared.js\";\n\nexport interface SessionsGetDeps {\n env: EnvConfig;\n}\n\nconst SESSION_RESULTS_INLINE_CAP = 100;\n\nexport function registerSessionsGet(\n server: McpServer,\n deps: SessionsGetDeps,\n): void {\n server.registerTool(\n \"testplanit_sessions_get\",\n {\n description:\n \"Fetch a single session by id with denormalized header (state/createdBy/assignedTo/template/configuration/milestone/tags), session-level linked issues, mission and note (ProseMirror -> plain text), customFields (flat name-keyed dict from sessionFieldValues), and sessionResults inline up to 100 (D7-12 — when more exist, `truncated: true` is set; call testplanit_session_results_list({sessionId}) with cursor pagination for the full set). (per SESS-02 / D7-12)\",\n inputSchema: {\n sessionId: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<RawSessionDetail | null>(\n \"sessions\",\n \"findUnique\",\n {\n where: { id: input.sessionId },\n include: SESSION_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Session ${input.sessionId} not found.`,\n },\n ],\n };\n }\n\n // D7-12: detect overflow via the take:101 cap on the include shape.\n // Trim the raw rows to the inline cap (100) BEFORE mapping so the\n // surfaced sessionResults array never exceeds the documented bound.\n const sessionResultsRaw = raw.sessionResults ?? [];\n const truncated = sessionResultsRaw.length > SESSION_RESULTS_INLINE_CAP;\n const trimmedRaw: RawSessionDetail = {\n ...raw,\n sessionResults: truncated\n ? sessionResultsRaw.slice(0, SESSION_RESULTS_INLINE_CAP)\n : sessionResultsRaw,\n };\n\n const detail = mapSessionDetail(trimmedRaw, { truncated });\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../../api.js\";\nimport type { EnvConfig } from \"../../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../../errors.js\";\nimport {\n SESSION_RESULT_LIST_INCLUDE,\n mapSessionResultRow,\n type RawSessionResultRow,\n} from \"../shared.js\";\n\nexport interface SessionResultsListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\nexport function registerSessionResultsList(\n server: McpServer,\n deps: SessionResultsListDeps,\n): void {\n server.registerTool(\n \"testplanit_session_results_list\",\n {\n description:\n \"List session results with cursor pagination. Filters: sessionId, createdById (executor user id, string), statusId. NOTE: there is NO testCase filter — `SessionResults` has no `testCaseId` column (sessions are exploratory and not case-linked; R4 / Pitfall 4 / SESS-03 schema gap). Each row carries denormalized status / createdBy (the executor) / session summary, plus resultData extracted to plain text via ProseMirror. Ordered by createdAt DESC then id DESC (BL-04 deterministic). isDeleted:false defense-in-depth. (per SESS-03)\",\n inputSchema: {\n sessionId: z.number().int().positive().optional(),\n createdById: z.string().min(1).optional(),\n statusId: z.number().int().positive().optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n\n // R4 / Pitfall 4 invariant: SessionResults has NO `testCaseId` column.\n // The annotation `Prisma.SessionResultsWhereInput` would TS2353 if any\n // `testCaseId` assignment were ever introduced. The input schema does\n // not declare `testCaseId` either; zod's raw-shape validator strips\n // unknown fields before this handler runs.\n const where: Prisma.SessionResultsWhereInput = { isDeleted: false };\n if (input.sessionId !== undefined) where.sessionId = input.sessionId;\n if (input.createdById) where.createdById = input.createdById;\n if (input.statusId !== undefined) where.statusId = input.statusId;\n\n const body: Record<string, unknown> = {\n where,\n include: SESSION_RESULT_LIST_INCLUDE,\n // BL-04: deterministic page ordering. Newest result first; id breaks\n // ties for results recorded in the same millisecond.\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows =\n (await zenstack<RawSessionResultRow[]>(\n \"sessionResults\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapSessionResultRow);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../../api.js\";\nimport type { EnvConfig } from \"../../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../../errors.js\";\nimport {\n SESSION_RESULT_DETAIL_INCLUDE,\n mapSessionResultDetail,\n type RawSessionResultDetail,\n} from \"../shared.js\";\n\nexport interface SessionResultsGetDeps {\n env: EnvConfig;\n}\n\nexport function registerSessionResultsGet(\n server: McpServer,\n deps: SessionResultsGetDeps,\n): void {\n server.registerTool(\n \"testplanit_session_results_get\",\n {\n description:\n \"Fetch a single session result by id. Returns the result with denormalized status, createdBy (the executor — sessions don't have a separate executor field; per D7-13), session summary, attachments, linked issues, and customFields (resultFieldValues denormalized to a flat name-keyed dict per A3 — same shape as caseFieldValues for read). NOTE: no step-level results — sessions are exploratory and don't have ordered steps (per D7-13). resultData is surfaced as plain text (resultDataText) via ProseMirror extraction. (per SESS-04 / D7-13)\",\n inputSchema: {\n // T-07-04 IDOR mitigation: positive integer only; non-int / non-positive\n // values rejected at the zod boundary before zenstack is called. Host's\n // ZenStack @@allow policy is the per-row access boundary.\n resultId: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<RawSessionResultDetail | null>(\n \"sessionResults\",\n \"findUnique\",\n {\n where: { id: input.resultId },\n // SESSION_RESULT_DETAIL_INCLUDE (07-01) ships:\n // - status / createdBy / session denormalized\n // - attachments (isDeleted:false), issues (isDeleted:false)\n // - resultFieldValues with field.type.type + field.fieldOptions[].fieldOption\n // The constant is `as const satisfies Prisma.SessionResultsInclude`\n // so a schema drift fails at typecheck (Phase 6 WR-09 invariant).\n include: SESSION_RESULT_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n // T-07-02 IDOR: when host @@allow denies the row, findUnique returns\n // null. Surface as not-found rather than 403 to avoid leaking row\n // existence to unauthorized callers.\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Session result ${input.resultId} not found.`,\n },\n ],\n };\n }\n\n const detail = mapSessionResultDetail(raw);\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n registerSessionResultsList,\n type SessionResultsListDeps,\n} from \"./list.js\";\nimport {\n registerSessionResultsGet,\n type SessionResultsGetDeps,\n} from \"./get.js\";\n\n/**\n * Aggregate dependencies for the SESS-03 / SESS-04 session-result read tools.\n * Both tools share the same EnvConfig; this intersection lets the parent\n * `registerSessions` pass a single deps object (mirrors the runs/results\n * pattern from plan 07-03).\n */\nexport type SessionResultsDeps = SessionResultsListDeps & SessionResultsGetDeps;\n\nexport function registerSessionResults(\n server: McpServer,\n deps: SessionResultsDeps,\n): void {\n registerSessionResultsList(server, deps);\n registerSessionResultsGet(server, deps);\n}\n\nexport { registerSessionResultsList, registerSessionResultsGet };\nexport type { SessionResultsListDeps, SessionResultsGetDeps };\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { mapFinding } from \"./shared.js\";\n\nexport interface SessionsFindingsDeps {\n env: EnvConfig;\n}\n\nconst FINDINGS_TAKE_CAP = 500;\n\n// Issue-detail include for issueId mode — surfaces linkedSessions and\n// linkedSessionResults inline (D7-11 issueId-mode response). Each include\n// carries `where: { isDeleted: false }` and a take cap so a single issue\n// surfacing in many sessions cannot fan out to an unbounded payload (T-07-06).\nconst ISSUE_DETAIL_INCLUDE = {\n sessions: {\n where: { isDeleted: false },\n take: FINDINGS_TAKE_CAP,\n select: {\n id: true,\n name: true,\n createdAt: true,\n isCompleted: true,\n createdBy: { select: { id: true, name: true, email: true } },\n },\n },\n sessionResults: {\n where: { isDeleted: false },\n take: FINDINGS_TAKE_CAP,\n select: {\n id: true,\n sessionId: true,\n createdAt: true,\n status: { select: { id: true, name: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n },\n },\n integration: { select: { provider: true } },\n} as const satisfies Prisma.IssueInclude;\n\ninterface RawIssueDetail {\n id: number;\n externalKey: string | null;\n title: string | null;\n status: string | null;\n externalStatus: string | null;\n priority: string | null;\n integration: { provider: string } | null;\n sessions: Array<{\n id: number;\n name: string;\n createdAt: string | Date;\n isCompleted: boolean;\n createdBy: { id: string; name: string | null; email: string } | null;\n }>;\n sessionResults: Array<{\n id: number;\n sessionId: number;\n createdAt: string | Date;\n status: { id: number; name: string } | null;\n createdBy: { id: string; name: string | null; email: string } | null;\n }>;\n}\n\nexport function registerSessionsFindings(\n server: McpServer,\n deps: SessionsFindingsDeps,\n): void {\n server.registerTool(\n \"testplanit_sessions_findings_list\",\n {\n description:\n \"List findings — Issue rows linked to a session OR retrieve the cross-cutting view of one issue across sessions/results. Provide EXACTLY ONE of `sessionId` or `issueId` (XOR; per D7-11). \" +\n \"sessionId mode returns { session: {id,name}, findings: Issue[], truncated }. Findings are issues linked to the session OR to any of the session's results (Issue.sessions OR Issue.sessionResults.session per D7-11). Capped at 500 rows; truncated:true indicates overflow. \" +\n \"issueId mode returns { issue: {...full Issue with externalSystem}, linkedSessions: [...], linkedSessionResults: [...] } — use this to ask 'where did this issue surface?'. \" +\n \"Note: issueKey (e.g. JIRA-123) is intentionally NOT supported in Phase 7 because Issue.externalKey is not globally unique; resolve external keys via the upcoming Phase-8 issue tools first. (per SESS-05 / D7-11)\",\n inputSchema: {\n sessionId: z.number().int().positive().optional(),\n issueId: z.number().int().positive().optional(),\n },\n },\n async (input) => {\n try {\n // XOR validation per D7-11 / RESEARCH discretion. We validate inside\n // the handler (not via zod refine on the raw shape) — same pattern\n // Phase 6 folder reparent disambiguation uses; raw-shape inputSchema\n // doesn't compose cleanly with refine.\n const hasSession = input.sessionId !== undefined;\n const hasIssue = input.issueId !== undefined;\n if (hasSession === hasIssue) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"Provide exactly one of sessionId or issueId.\",\n },\n ],\n };\n }\n\n if (hasSession) {\n // sessionId mode: Issue.findMany with OR over both link paths.\n const sessionId = input.sessionId!;\n const where = {\n isDeleted: false,\n OR: [\n { sessions: { some: { id: sessionId } } },\n { sessionResults: { some: { session: { id: sessionId } } } },\n ],\n } satisfies Prisma.IssueWhereInput;\n\n const issuesBody: Record<string, unknown> = {\n where,\n select: {\n id: true,\n externalKey: true,\n title: true,\n status: true,\n externalStatus: true,\n priority: true,\n integration: { select: { provider: true } },\n },\n // BL-04 deterministic ordering — newest first; id breaks ties.\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n // T-07-06 cap — take FINDINGS_TAKE_CAP+1 to detect overflow.\n take: FINDINGS_TAKE_CAP + 1,\n };\n\n const issues =\n (await zenstack<unknown[]>(\n \"issue\",\n \"findMany\",\n issuesBody,\n deps.env,\n )) ?? [];\n const truncated = issues.length > FINDINGS_TAKE_CAP;\n const trimmed = issues.slice(0, FINDINGS_TAKE_CAP);\n const findings = trimmed.map((i) => mapFinding(i as never));\n\n // Resolve session header for the response envelope. If the host's\n // ZenStack @@allow policy denies the row (or it truly doesn't exist),\n // findUnique returns null — surfaced as not-found per T-07-02.\n const session = await zenstack<{ id: number; name: string } | null>(\n \"sessions\",\n \"findUnique\",\n {\n where: { id: sessionId },\n select: { id: true, name: true },\n },\n deps.env,\n );\n if (!session) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Session ${sessionId} not found.`,\n },\n ],\n };\n }\n\n const result = { session, findings, truncated };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n }\n\n // issueId mode: single findUnique on Issue with linkedSessions /\n // linkedSessionResults inlined under the documented include.\n const issueId = input.issueId!;\n const raw = await zenstack<RawIssueDetail | null>(\n \"issue\",\n \"findUnique\",\n {\n where: { id: issueId },\n include: ISSUE_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Issue ${issueId} not found.`,\n },\n ],\n };\n }\n\n // Map the issue to the canonical finding shape — externalSystem from\n // integration.provider so issueId-mode and sessionId-mode return the\n // same per-issue shape.\n const issue = mapFinding(raw as never);\n\n const linkedSessions = (raw.sessions ?? []).map((s) => ({\n id: s.id,\n name: s.name,\n createdAt: s.createdAt,\n isCompleted: s.isCompleted,\n createdBy: s.createdBy\n ? {\n id: s.createdBy.id,\n name: s.createdBy.name,\n email: s.createdBy.email,\n }\n : null,\n }));\n const linkedSessionResults = (raw.sessionResults ?? []).map((r) => ({\n id: r.id,\n sessionId: r.sessionId,\n createdAt: r.createdAt,\n status: r.status ? { id: r.status.id, name: r.status.name } : null,\n createdBy: r.createdBy\n ? {\n id: r.createdBy.id,\n name: r.createdBy.name,\n email: r.createdBy.email,\n }\n : null,\n }));\n\n const result = {\n issue,\n linkedSessions,\n linkedSessionResults,\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack, resolveDefaultTemplate } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport { resolveTagIds } from \"../cases/shared.js\";\nimport {\n SESSION_DETAIL_INCLUDE,\n mapSessionDetail,\n type RawSessionDetail,\n} from \"./shared.js\";\n\nexport interface SessionsCreateDeps {\n env: EnvConfig;\n}\n\nconst SESSION_RESULTS_INLINE_CAP = 100;\n\nexport async function resolveSessionState(\n projectId: number,\n env: EnvConfig,\n name?: string,\n): Promise<{ id: number; name: string }> {\n const workflows = await zenstack<{ id: number; name: string }[]>(\n \"workflows\",\n \"findMany\",\n {\n where: {\n isEnabled: true,\n isDeleted: false,\n scope: \"SESSIONS\",\n projects: { some: { projectId } },\n ...(name ? { name } : {}),\n } satisfies Prisma.WorkflowsWhereInput,\n orderBy: { order: \"asc\" } satisfies Prisma.WorkflowsOrderByWithRelationInput,\n take: 1,\n },\n env,\n );\n if (!workflows || workflows.length === 0) {\n const suffix = name ? ` named \"${name}\"` : \"\";\n throw new TestPlanItHttpError(\n `No SESSIONS-scope workflow state found for project ${projectId}${suffix}.`,\n { statusCode: 422 },\n );\n }\n return workflows[0];\n}\n\nexport function registerSessionsCreate(\n server: McpServer,\n deps: SessionsCreateDeps,\n): void {\n server.registerTool(\n \"testplanit_sessions_create\",\n {\n description:\n \"Create a new exploratory test session in a project. Resolves the default template and SESSIONS workflow state automatically. Returns the full denormalized session detail (same shape as testplanit_sessions_get).\",\n inputSchema: {\n projectId: z\n .number()\n .int()\n .positive()\n .describe(\"Project to create the session in.\"),\n name: z.string().min(1).max(500).describe(\"Session name.\"),\n mission: z\n .string()\n .optional()\n .describe(\"Plain-text mission statement for the session.\"),\n milestoneId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Milestone to link the session to.\"),\n configId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Configuration ID to associate with the session.\"),\n stateName: z\n .string()\n .min(1)\n .optional()\n .describe(\n \"SESSIONS workflow state name. Defaults to the first state by order.\",\n ),\n tags: z\n .array(z.union([z.number().int().positive(), z.string().min(1)]))\n .optional()\n .describe(\"Tag IDs (numbers) or tag names (strings, created if missing).\"),\n },\n },\n async (input) => {\n try {\n const templateId = await resolveDefaultTemplate(\n input.projectId,\n deps.env,\n );\n const state = await resolveSessionState(\n input.projectId,\n deps.env,\n input.stateName,\n );\n const tagIds = await resolveTagIds(input.tags, deps.env);\n\n const created = await zenstack<{ id: number }>(\n \"sessions\",\n \"create\",\n {\n data: {\n name: input.name,\n project: { connect: { id: input.projectId } },\n template: { connect: { id: templateId } },\n state: { connect: { id: state.id } },\n ...(input.mission !== undefined\n ? { mission: input.mission }\n : {}),\n ...(input.milestoneId\n ? { milestone: { connect: { id: input.milestoneId } } }\n : {}),\n ...(input.configId\n ? { configuration: { connect: { id: input.configId } } }\n : {}),\n ...(tagIds.length > 0\n ? { tags: { connect: tagIds.map((id) => ({ id })) } }\n : {}),\n },\n select: { id: true },\n },\n deps.env,\n );\n\n const raw = await zenstack<RawSessionDetail | null>(\n \"sessions\",\n \"findUnique\",\n {\n where: { id: created.id },\n include: SESSION_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n throw new TestPlanItHttpError(\n `Session ${created.id} was created but could not be re-fetched.`,\n { statusCode: 422 },\n );\n }\n\n const sessionResultsRaw = raw.sessionResults ?? [];\n const truncated = sessionResultsRaw.length > SESSION_RESULTS_INLINE_CAP;\n const trimmedRaw: RawSessionDetail = {\n ...raw,\n sessionResults: sessionResultsRaw.slice(0, SESSION_RESULTS_INLINE_CAP),\n };\n\n const detail = mapSessionDetail(trimmedRaw, { truncated });\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { resolveTagIds } from \"../cases/shared.js\";\nimport { resolveSessionState } from \"./create.js\";\nimport {\n SESSION_DETAIL_INCLUDE,\n mapSessionDetail,\n type RawSessionDetail,\n} from \"./shared.js\";\n\nexport interface SessionsUpdateDeps {\n env: EnvConfig;\n}\n\nconst SESSION_RESULTS_INLINE_CAP = 100;\n\nexport function registerSessionsUpdate(\n server: McpServer,\n deps: SessionsUpdateDeps,\n): void {\n server.registerTool(\n \"testplanit_sessions_update\",\n {\n description:\n \"Update an existing exploratory test session. All fields except sessionId are optional — only supplied fields are changed. Tags use full-replacement semantics (the new list replaces all current tags). Returns the full denormalized session detail.\",\n inputSchema: {\n sessionId: z\n .number()\n .int()\n .positive()\n .describe(\"ID of the session to update.\"),\n name: z.string().min(1).max(500).optional().describe(\"New session name.\"),\n mission: z\n .string()\n .nullable()\n .optional()\n .describe(\"Updated mission statement. Pass null to clear.\"),\n stateName: z\n .string()\n .min(1)\n .optional()\n .describe(\"SESSIONS workflow state name to transition to.\"),\n milestoneId: z\n .number()\n .int()\n .positive()\n .nullable()\n .optional()\n .describe(\"Milestone to link; pass null to remove.\"),\n configId: z\n .number()\n .int()\n .positive()\n .nullable()\n .optional()\n .describe(\"Configuration ID; pass null to remove.\"),\n tags: z\n .array(z.union([z.number().int().positive(), z.string().min(1)]))\n .optional()\n .describe(\"Replacement tag list (full set). Replaces all current tags.\"),\n isCompleted: z\n .boolean()\n .optional()\n .describe(\"Mark the session completed (true) or reopen it (false).\"),\n },\n },\n async (input) => {\n try {\n const data: Record<string, unknown> = {};\n\n if (input.name !== undefined) data.name = input.name;\n if (input.mission !== undefined) {\n data.mission = input.mission;\n }\n\n if (input.stateName !== undefined) {\n const session = await zenstack<{ projectId: number } | null>(\n \"sessions\",\n \"findUnique\",\n {\n where: { id: input.sessionId },\n select: { projectId: true } satisfies Prisma.SessionsSelect,\n },\n deps.env,\n );\n if (!session) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Session ${input.sessionId} not found.`,\n },\n ],\n };\n }\n const state = await resolveSessionState(\n session.projectId,\n deps.env,\n input.stateName,\n );\n data.state = { connect: { id: state.id } };\n }\n\n if (input.milestoneId !== undefined) {\n data.milestone =\n input.milestoneId === null\n ? { disconnect: true }\n : { connect: { id: input.milestoneId } };\n }\n\n if (input.configId !== undefined) {\n data.configuration =\n input.configId === null\n ? { disconnect: true }\n : { connect: { id: input.configId } };\n }\n\n if (input.isCompleted !== undefined) {\n data.isCompleted = input.isCompleted;\n if (input.isCompleted) {\n data.completedAt = new Date().toISOString();\n } else {\n data.completedAt = null;\n }\n }\n\n if (input.tags !== undefined) {\n const tagIds = await resolveTagIds(input.tags, deps.env);\n data.tags = { set: tagIds.map((id) => ({ id })) };\n }\n\n if (Object.keys(data).length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"No fields to update — provide at least one optional field.\",\n },\n ],\n };\n }\n\n await zenstack(\n \"sessions\",\n \"update\",\n {\n where: { id: input.sessionId },\n data,\n select: { id: true },\n },\n deps.env,\n );\n\n const raw = await zenstack<RawSessionDetail | null>(\n \"sessions\",\n \"findUnique\",\n {\n where: { id: input.sessionId },\n include: SESSION_DETAIL_INCLUDE,\n },\n deps.env,\n );\n\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Session ${input.sessionId} not found after update.`,\n },\n ],\n };\n }\n\n const sessionResultsRaw = raw.sessionResults ?? [];\n const truncated = sessionResultsRaw.length > SESSION_RESULTS_INLINE_CAP;\n const trimmedRaw: RawSessionDetail = {\n ...raw,\n sessionResults: sessionResultsRaw.slice(0, SESSION_RESULTS_INLINE_CAP),\n };\n\n const detail = mapSessionDetail(trimmedRaw, { truncated });\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerSessionsList, type SessionsListDeps } from \"./list.js\";\nimport { registerSessionsGet, type SessionsGetDeps } from \"./get.js\";\nimport {\n registerSessionResults,\n type SessionResultsDeps,\n} from \"./results/index.js\";\nimport {\n registerSessionsFindings,\n type SessionsFindingsDeps,\n} from \"./findings.js\";\nimport {\n registerSessionsCreate,\n type SessionsCreateDeps,\n} from \"./create.js\";\nimport {\n registerSessionsUpdate,\n type SessionsUpdateDeps,\n} from \"./update.js\";\n\nexport type SessionsDeps = SessionsListDeps &\n SessionsGetDeps &\n SessionResultsDeps &\n SessionsFindingsDeps &\n SessionsCreateDeps &\n SessionsUpdateDeps;\n\nexport function registerSessions(\n server: McpServer,\n deps: SessionsDeps,\n): void {\n registerSessionsList(server, deps);\n registerSessionsGet(server, deps);\n registerSessionResults(server, deps);\n registerSessionsFindings(server, deps);\n registerSessionsCreate(server, deps);\n registerSessionsUpdate(server, deps);\n}\n\nexport {\n registerSessionsList,\n registerSessionsGet,\n registerSessionResults,\n registerSessionsFindings,\n registerSessionsCreate,\n registerSessionsUpdate,\n};\nexport type {\n SessionsListDeps,\n SessionsGetDeps,\n SessionResultsDeps,\n SessionsFindingsDeps,\n SessionsCreateDeps,\n SessionsUpdateDeps,\n};\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n PROJECT_REPO_CONFIG_INCLUDE,\n mapCodeRepoConfig,\n type RawCodeRepoConfigRow,\n} from \"./shared.js\";\n\nexport interface CodeRepositoriesListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\nexport function registerCodeRepositoriesList(\n server: McpServer,\n deps: CodeRepositoriesListDeps,\n): void {\n server.registerTool(\n \"testplanit_code_repositories_list\",\n {\n description:\n \"List the project's code-repository configuration. Returns ProjectCodeRepositoryConfig rows with the underlying CodeRepository denormalized inline (id, name, provider, status, lastTestedAt, settings stripped to a public-key allow-list, and a derived web url). The secrets column is never returned. One row per project today (schema enforces @@unique([projectId])).\",\n inputSchema: {\n projectId: z.number().int().positive(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n const where: Prisma.ProjectCodeRepositoryConfigWhereInput = {\n projectId: input.projectId,\n // CodeRepository carries `isDeleted`; the join table does not.\n repository: { isDeleted: false },\n };\n const body: Record<string, unknown> = {\n where,\n include: PROJECT_REPO_CONFIG_INCLUDE,\n // BL-04 deterministic ordering — newest first; id breaks ties for\n // rows created in the same millisecond.\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows =\n (await zenstack<RawCodeRepoConfigRow[]>(\n \"projectCodeRepositoryConfig\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapCodeRepoConfig);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n registerCodeRepositoriesList,\n type CodeRepositoriesListDeps,\n} from \"./list.js\";\n\n/**\n * Aggregate dependencies for the Phase 8 code-repositories read tools. Only\n * one tool today (`testplanit_code_repositories_list`); aliasing rather than\n * intersecting keeps room to add `_get` etc. via union extension when the\n * single-row-per-project invariant relaxes.\n *\n * Registry wiring into `tools/index.ts` is intentionally deferred to plan\n * 08-05 (wave 3) so plans 08-01..08-04 can run in parallel without touching\n * the same file.\n */\nexport type CodeRepositoriesDeps = CodeRepositoriesListDeps;\n\nexport function registerCodeRepositories(\n server: McpServer,\n deps: CodeRepositoriesDeps,\n): void {\n registerCodeRepositoriesList(server, deps);\n}\n\nexport { registerCodeRepositoriesList };\nexport type { CodeRepositoriesListDeps };\n","import type { Prisma } from \"@prisma/client\";\nimport { extractProseMirrorText } from \"../cases/shared.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Typed includes — every literal carries `as const satisfies Prisma.IssueInclude`.\n// Adding an unknown column produces TS2353 at compile time (Phase 6 WR-09).\n//\n// Pitfall 7 (Phase 6 retrofit): `externalSystem` is NOT a column on Issue —\n// it is derived from `integration.provider` at the mapper boundary. Reintroducing\n// the externalSystem column in the select trips Prisma.IssueSelect's TS2353 wall.\n//\n// D8-06 / D7-12: each linked-array include declares `take: 101` so the get\n// handler can detect overflow and stamp `truncated.<key>: true`. The cap is\n// expressed as `LINKED_ARRAYS_INLINE_CAP_PLUS_ONE` so the +1 is intentional,\n// not a magic number.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const ISSUE_ROW_INCLUDE = {\n integration: { select: { id: true, name: true, provider: true } },\n createdBy: { select: { id: true, name: true, email: true } },\n _count: { select: { repositoryCases: true } },\n} as const satisfies Prisma.IssueInclude;\n\nconst LINKED_ARRAYS_INLINE_CAP_PLUS_ONE = 101;\n\nexport const ISSUE_DETAIL_INCLUDE = {\n ...ISSUE_ROW_INCLUDE,\n repositoryCases: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: LINKED_ARRAYS_INLINE_CAP_PLUS_ONE,\n select: { id: true, name: true, source: true, automated: true },\n },\n sessions: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: LINKED_ARRAYS_INLINE_CAP_PLUS_ONE,\n select: {\n id: true,\n name: true,\n mission: true,\n isCompleted: true,\n state: { select: { id: true, name: true } },\n },\n },\n testRuns: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: LINKED_ARRAYS_INLINE_CAP_PLUS_ONE,\n select: {\n id: true,\n name: true,\n isCompleted: true,\n completedAt: true,\n },\n },\n} as const satisfies Prisma.IssueInclude;\n\nexport const ISSUE_LINKED_ARRAYS_INLINE_CAP = 100;\n\nexport interface RawIssueIntegration {\n id: number;\n name: string;\n provider: string;\n}\n\nexport interface RawIssueRow {\n id: number;\n projectId: number | null;\n externalKey: string | null;\n title: string | null;\n name: string | null;\n status: string | null;\n externalStatus: string | null;\n externalUrl: string | null;\n createdAt: Date | string;\n lastSyncedAt: Date | string | null;\n integration: RawIssueIntegration | null;\n createdBy: { id: string; name: string | null; email: string } | null;\n _count?: { repositoryCases: number };\n}\n\nexport interface RawIssueDetail extends RawIssueRow {\n description: string | null;\n priority: string | null;\n issueTypeName: string | null;\n issueTypeIconUrl: string | null;\n note: unknown;\n repositoryCases: Array<{\n id: number;\n name: string;\n source: string;\n automated: boolean;\n }>;\n sessions: Array<{\n id: number;\n name: string;\n mission: unknown;\n isCompleted: boolean;\n state: { id: number; name: string } | null;\n }>;\n testRuns: Array<{\n id: number;\n name: string;\n isCompleted: boolean;\n completedAt: Date | string | null;\n }>;\n}\n\nexport function mapIssueRow(raw: RawIssueRow) {\n return {\n id: raw.id,\n externalKey: raw.externalKey ?? null,\n externalSystem: raw.integration?.provider ?? null,\n externalUrl: raw.externalUrl ?? null,\n externalStatus: raw.externalStatus ?? null,\n summary: raw.title ?? raw.name ?? \"\",\n status: raw.status ?? null,\n projectId: raw.projectId ?? null,\n integration: raw.integration\n ? {\n id: raw.integration.id,\n name: raw.integration.name,\n provider: raw.integration.provider,\n }\n : null,\n createdBy: raw.createdBy\n ? {\n id: raw.createdBy.id,\n name: raw.createdBy.name,\n email: raw.createdBy.email,\n }\n : null,\n createdAt: raw.createdAt,\n lastSyncedAt: raw.lastSyncedAt ?? null,\n linkedCaseCount: raw._count?.repositoryCases ?? 0,\n };\n}\n\nexport interface IssueDetailFlags {\n truncated: {\n linkedCases?: true;\n linkedSessions?: true;\n linkedTestRuns?: true;\n };\n}\n\nexport function mapIssueDetail(raw: RawIssueDetail, flags: IssueDetailFlags) {\n const head = mapIssueRow(raw);\n return {\n ...head,\n description: raw.description ?? null,\n priority: raw.priority ?? null,\n issueTypeName: raw.issueTypeName ?? null,\n issueTypeIconUrl: raw.issueTypeIconUrl ?? null,\n note: extractProseMirrorText(raw.note),\n linkedCases: raw.repositoryCases.map((c) => ({\n id: c.id,\n name: c.name,\n source: c.source,\n automated: c.automated,\n })),\n linkedSessions: raw.sessions.map((s) => ({\n id: s.id,\n name: s.name,\n mission: extractProseMirrorText(s.mission),\n isCompleted: s.isCompleted,\n state: s.state ? { id: s.state.id, name: s.state.name } : null,\n })),\n linkedTestRuns: raw.testRuns.map((r) => ({\n id: r.id,\n name: r.name,\n isCompleted: r.isCompleted,\n completedAt: r.completedAt ?? null,\n })),\n truncated: flags.truncated,\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n ISSUE_ROW_INCLUDE,\n mapIssueRow,\n type RawIssueRow,\n} from \"./shared.js\";\n\nexport interface IssuesFindByKeyDeps {\n env: EnvConfig;\n}\n\n// D8-04: hard cap on the multi-match probe. The schema constraint is only\n// @@unique([externalId, integrationId]); externalKey is NOT globally unique.\n// In practice 0–2 rows match a `(externalKey, externalSystem, projectId)`\n// tuple. Cap at 5 so a corrupt or pathological dataset can't fan out an\n// unbounded probe (T-08-DoS).\nconst MULTI_MATCH_TAKE = 5;\n\nexport function registerIssuesFindByKey(\n server: McpServer,\n deps: IssuesFindByKeyDeps,\n): void {\n server.registerTool(\n \"testplanit_issues_find_by_key\",\n {\n description:\n \"Resolve an Issue by (externalKey, externalSystem, projectId). Schema enforces @@unique([externalId, integrationId]) — externalKey is NOT globally unique, so when two integrations of the same provider share a key in the same project, the response shape is { issues: [...], multipleMatches: true, hint: 'Pass integrationId to disambiguate.' } instead of { issue, multipleMatches: false }. Pass optional integrationId to skip the multi-match path. Internal-only issues (where Issue.integrationId IS NULL) are NOT addressable by this tool — agents reach those via testplanit_issues_list.\",\n inputSchema: {\n externalKey: z.string().min(1),\n externalSystem: z.enum([\n \"JIRA\",\n \"GITHUB\",\n \"AZURE_DEVOPS\",\n \"SIMPLE_URL\",\n ]),\n projectId: z.number().int().positive(),\n integrationId: z.number().int().positive().optional(),\n },\n },\n async (input) => {\n try {\n const where: Prisma.IssueWhereInput = {\n externalKey: input.externalKey,\n isDeleted: false,\n projectId: input.projectId,\n integration: { provider: input.externalSystem },\n };\n if (input.integrationId !== undefined) {\n where.integrationId = input.integrationId;\n }\n const rows =\n (await zenstack<RawIssueRow[]>(\n \"issue\",\n \"findMany\",\n {\n where,\n include: ISSUE_ROW_INCLUDE,\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: MULTI_MATCH_TAKE,\n },\n deps.env,\n )) ?? [];\n if (rows.length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Issue '${input.externalKey}' not found in project ${input.projectId}.`,\n },\n ],\n };\n }\n const result =\n rows.length === 1\n ? { issue: mapIssueRow(rows[0]), multipleMatches: false as const }\n : {\n issues: rows.map(mapIssueRow),\n multipleMatches: true as const,\n hint: \"Pass integrationId to disambiguate.\",\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n ISSUE_ROW_INCLUDE,\n mapIssueRow,\n type RawIssueRow,\n} from \"./shared.js\";\n\nexport interface IssuesListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\nexport function registerIssuesList(\n server: McpServer,\n deps: IssuesListDeps,\n): void {\n server.registerTool(\n \"testplanit_issues_list\",\n {\n description:\n \"List issues scoped to a project. Filters: externalSystem (IntegrationProvider enum), integrationId, status (TestPlanIt-side, exact match), externalStatus (externally-synced label, case-insensitive substring). Cursor pagination ordered by createdAt DESC then id DESC (deterministic). Each row carries linkedCaseCount via _count for the dominant fan-out signal. The assignee filter is intentionally omitted — Issue has no native assigneeId column; assignee data lives in Issue.data: Json (provider-shaped) and is not addressable here.\",\n inputSchema: {\n projectId: z.number().int().positive(),\n externalSystem: z\n .enum([\"JIRA\", \"GITHUB\", \"AZURE_DEVOPS\", \"SIMPLE_URL\"])\n .optional(),\n integrationId: z.number().int().positive().optional(),\n status: z.string().min(1).optional(),\n externalStatus: z.string().min(1).optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n const where: Prisma.IssueWhereInput = {\n projectId: input.projectId,\n isDeleted: false,\n };\n if (input.externalSystem !== undefined) {\n where.integration = { provider: input.externalSystem };\n }\n if (input.integrationId !== undefined) {\n where.integrationId = input.integrationId;\n }\n if (input.status !== undefined) {\n where.status = input.status;\n }\n if (input.externalStatus !== undefined) {\n where.externalStatus = {\n contains: input.externalStatus,\n mode: \"insensitive\",\n };\n }\n const body: Record<string, unknown> = {\n where,\n include: ISSUE_ROW_INCLUDE,\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n const rows =\n (await zenstack<RawIssueRow[]>(\"issue\", \"findMany\", body, deps.env)) ??\n [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapIssueRow);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n ISSUE_DETAIL_INCLUDE,\n ISSUE_LINKED_ARRAYS_INLINE_CAP,\n mapIssueDetail,\n type RawIssueDetail,\n} from \"./shared.js\";\n\nexport interface IssuesGetDeps {\n env: EnvConfig;\n}\n\nexport function registerIssuesGet(\n server: McpServer,\n deps: IssuesGetDeps,\n): void {\n server.registerTool(\n \"testplanit_issues_get\",\n {\n description:\n \"Fetch a single Issue by id with its full denormalized header (including ProseMirror note rendered to plain text, integration, createdBy) and three inlined linked arrays — linkedCases, linkedSessions, linkedTestRuns — each capped at 100. When an array is over-capacity the response carries truncated.<key>: true and the rest are reachable via testplanit_cases_list({ issueId }) or testplanit_issues_list_links with the appropriate target.\",\n inputSchema: {\n id: z.number().int().positive(),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<RawIssueDetail | null>(\n \"issue\",\n \"findUnique\",\n {\n where: { id: input.id, isDeleted: false },\n include: ISSUE_DETAIL_INCLUDE,\n },\n deps.env,\n );\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Issue ${input.id} not found.`,\n },\n ],\n };\n }\n // D8-06 / D7-12 widened: detect overflow per array via the take:101\n // cap on each sub-include. Trim each array to the inline cap (100)\n // BEFORE mapping so the surfaced arrays never exceed the documented\n // bound. Each array gets its own truncated.<key> flag.\n const linkedCasesRaw = raw.repositoryCases ?? [];\n const linkedSessionsRaw = raw.sessions ?? [];\n const linkedTestRunsRaw = raw.testRuns ?? [];\n const truncated: {\n linkedCases?: true;\n linkedSessions?: true;\n linkedTestRuns?: true;\n } = {};\n if (linkedCasesRaw.length > ISSUE_LINKED_ARRAYS_INLINE_CAP) {\n truncated.linkedCases = true;\n }\n if (linkedSessionsRaw.length > ISSUE_LINKED_ARRAYS_INLINE_CAP) {\n truncated.linkedSessions = true;\n }\n if (linkedTestRunsRaw.length > ISSUE_LINKED_ARRAYS_INLINE_CAP) {\n truncated.linkedTestRuns = true;\n }\n const trimmedRaw: RawIssueDetail = {\n ...raw,\n repositoryCases: linkedCasesRaw.slice(\n 0,\n ISSUE_LINKED_ARRAYS_INLINE_CAP,\n ),\n sessions: linkedSessionsRaw.slice(\n 0,\n ISSUE_LINKED_ARRAYS_INLINE_CAP,\n ),\n testRuns: linkedTestRunsRaw.slice(\n 0,\n ISSUE_LINKED_ARRAYS_INLINE_CAP,\n ),\n };\n const detail = mapIssueDetail(trimmedRaw, { truncated });\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n ISSUE_ROW_INCLUDE,\n mapIssueRow,\n type RawIssueRow,\n} from \"./shared.js\";\n\nexport interface IssuesListLinksDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\nconst TARGET_VALUES = [\n \"cases\",\n \"sessions\",\n \"sessionResults\",\n \"testRuns\",\n \"testRunResults\",\n \"testRunStepResults\",\n] as const;\ntype Target = (typeof TARGET_VALUES)[number];\n\ninterface OutboundDescriptor {\n model: string;\n hasIsDeleted: boolean;\n selectShape: Record<string, unknown>;\n mapItem: (raw: Record<string, unknown>) => Record<string, unknown>;\n}\n\n// All 6 outbound targets carry `isDeleted` in their schema (verified against\n// schema.zmodel: RepositoryCases, Sessions, SessionResults, TestRuns,\n// TestRunResults, TestRunStepResults all declare `isDeleted Boolean`). We\n// filter consistently. R2: TestRunStepResults uses the `stepStatus` relation\n// to Status (NOT `status`); reintroducing `status: true` would TS2353 against\n// Prisma.TestRunStepResultsSelect (Phase 7 invariant).\nconst OUTBOUND_MAP: Record<Target, OutboundDescriptor> = {\n cases: {\n model: \"repositoryCases\",\n hasIsDeleted: true,\n selectShape: {\n id: true,\n name: true,\n source: true,\n automated: true,\n },\n mapItem: (raw) => ({\n id: raw.id,\n name: raw.name,\n source: raw.source,\n automated: raw.automated,\n }),\n },\n sessions: {\n model: \"sessions\",\n hasIsDeleted: true,\n selectShape: {\n id: true,\n name: true,\n isCompleted: true,\n state: { select: { id: true, name: true } },\n },\n mapItem: (raw) => ({\n id: raw.id,\n name: raw.name,\n isCompleted: raw.isCompleted,\n state: raw.state ?? null,\n }),\n },\n sessionResults: {\n model: \"sessionResults\",\n hasIsDeleted: true,\n selectShape: {\n id: true,\n sessionId: true,\n executedAt: true,\n status: { select: { id: true, name: true } },\n },\n mapItem: (raw) => ({\n id: raw.id,\n sessionId: raw.sessionId,\n executedAt: raw.executedAt ?? null,\n status: raw.status ?? null,\n }),\n },\n testRuns: {\n model: \"testRuns\",\n hasIsDeleted: true,\n selectShape: {\n id: true,\n name: true,\n isCompleted: true,\n completedAt: true,\n },\n mapItem: (raw) => ({\n id: raw.id,\n name: raw.name,\n isCompleted: raw.isCompleted,\n completedAt: raw.completedAt ?? null,\n }),\n },\n testRunResults: {\n model: \"testRunResults\",\n hasIsDeleted: true,\n selectShape: {\n id: true,\n testRunId: true,\n executedAt: true,\n status: { select: { id: true, name: true } },\n },\n mapItem: (raw) => ({\n id: raw.id,\n testRunId: raw.testRunId,\n executedAt: raw.executedAt ?? null,\n status: raw.status ?? null,\n }),\n },\n testRunStepResults: {\n // R2: relation to Status is named `stepStatus` (NOT `status`) per\n // schema.zmodel:2437 — Phase 7 runs/shared.ts:79 already established\n // this. TestRunStepResults DOES carry isDeleted (schema.zmodel:2443),\n // so we filter consistently with the other 5 targets.\n model: \"testRunStepResults\",\n hasIsDeleted: true,\n selectShape: {\n id: true,\n testRunResultId: true,\n stepStatus: { select: { id: true, name: true } },\n },\n mapItem: (raw) => ({\n id: raw.id,\n testRunResultId: raw.testRunResultId,\n stepStatus: raw.stepStatus ?? null,\n }),\n },\n};\n\nconst INBOUND_KEY_TO_RELATION: Record<\n string,\n { relation: string; hasIsDeleted: boolean }\n> = {\n caseId: { relation: \"repositoryCases\", hasIsDeleted: true },\n sessionId: { relation: \"sessions\", hasIsDeleted: true },\n sessionResultId: { relation: \"sessionResults\", hasIsDeleted: true },\n runId: { relation: \"testRuns\", hasIsDeleted: true },\n runResultId: { relation: \"testRunResults\", hasIsDeleted: true },\n // TestRunStepResults DOES carry isDeleted (schema.zmodel:2443); filter\n // consistently with the other 5 inbound keys.\n runStepResultId: { relation: \"testRunStepResults\", hasIsDeleted: true },\n};\n\nexport function registerIssuesListLinks(\n server: McpServer,\n deps: IssuesListLinksDeps,\n): void {\n server.registerTool(\n \"testplanit_issues_list_links\",\n {\n description:\n \"Walk the issue ↔ X graph in either direction. Outbound mode: provide issueId + target (one of: cases, sessions, sessionResults, testRuns, testRunResults, testRunStepResults) to get the linked counterpart rows. Inbound mode: provide exactly one of caseId, sessionId, sessionResultId, runId, runResultId, runStepResultId to get the issues linked to that row. Cursor pagination, deterministic orderBy.\",\n inputSchema: {\n issueId: z.number().int().positive().optional(),\n target: z.enum(TARGET_VALUES).optional(),\n caseId: z.number().int().positive().optional(),\n sessionId: z.number().int().positive().optional(),\n sessionResultId: z.number().int().positive().optional(),\n runId: z.number().int().positive().optional(),\n runResultId: z.number().int().positive().optional(),\n runStepResultId: z.number().int().positive().optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n // Symmetric XOR validation per D7-11 — raw-shape inputSchema doesn't\n // compose with zod refine, so the gate lives in the handler.\n const inboundEntries: Array<[string, number]> = [];\n for (const key of Object.keys(INBOUND_KEY_TO_RELATION)) {\n const v = (input as Record<string, unknown>)[key];\n if (typeof v === \"number\") inboundEntries.push([key, v]);\n }\n const hasIssue = input.issueId !== undefined;\n const hasInbound = inboundEntries.length > 0;\n if (hasIssue === hasInbound) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"Provide exactly one of issueId (with target) OR exactly one of (caseId, sessionId, sessionResultId, runId, runResultId, runStepResultId).\",\n },\n ],\n };\n }\n if (hasInbound && inboundEntries.length !== 1) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"Provide exactly one inbound id.\",\n },\n ],\n };\n }\n if (hasIssue && input.target === undefined) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"target is required when issueId is provided.\",\n },\n ],\n };\n }\n if (hasInbound && input.target !== undefined) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"target is only valid in outbound (issueId) mode.\",\n },\n ],\n };\n }\n\n const limit = input.limit ?? DEFAULT_LIMIT;\n const body: Record<string, unknown> = {\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n if (hasIssue) {\n const target = input.target as Target;\n const desc = OUTBOUND_MAP[target];\n const issueClause = desc.hasIsDeleted\n ? {\n isDeleted: false,\n issues: { some: { id: input.issueId, isDeleted: false } },\n }\n : {\n issues: { some: { id: input.issueId, isDeleted: false } },\n };\n body.where = issueClause;\n body.select = desc.selectShape;\n const rows =\n (await zenstack<Array<Record<string, unknown>>>(\n desc.model,\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(desc.mapItem);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1].id as number)\n : null;\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n }\n\n // inbound mode\n const [inboundKey, inboundId] = inboundEntries[0];\n const rel = INBOUND_KEY_TO_RELATION[inboundKey];\n const someClause = rel.hasIsDeleted\n ? { id: inboundId, isDeleted: false }\n : { id: inboundId };\n body.where = {\n isDeleted: false,\n [rel.relation]: { some: someClause },\n };\n body.include = ISSUE_ROW_INCLUDE;\n const rows =\n (await zenstack<RawIssueRow[]>(\"issue\", \"findMany\", body, deps.env)) ??\n [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items = trimmed.map(mapIssueRow);\n const nextCursor =\n hasNextPage && items.length > 0\n ? items[items.length - 1].id\n : null;\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\n\nexport interface IssuesLinkDeps {\n env: EnvConfig;\n}\n\nconst ENTITY_TYPES = [\n \"testCase\",\n \"session\",\n \"testRun\",\n \"testRunResult\",\n \"testRunStepResult\",\n] as const;\ntype EntityType = (typeof ENTITY_TYPES)[number];\n\nconst ENTITY_RELATION: Record<EntityType, string> = {\n testCase: \"repositoryCases\",\n session: \"sessions\",\n testRun: \"testRuns\",\n testRunResult: \"testRunResults\",\n testRunStepResult: \"testRunStepResults\",\n};\n\nconst LINK_INPUT_SCHEMA = {\n issueId: z\n .number()\n .int()\n .positive()\n .describe(\"ID of the issue to link entities to.\"),\n entityType: z\n .enum(ENTITY_TYPES)\n .describe(\n \"Type of entity to link: testCase | session | testRun | testRunResult | testRunStepResult.\",\n ),\n entityIds: z\n .array(z.number().int().positive())\n .min(1)\n .max(100)\n .describe(\"One or more entity IDs to link to the issue.\"),\n};\n\nconst UNLINK_INPUT_SCHEMA = {\n issueId: z\n .number()\n .int()\n .positive()\n .describe(\"ID of the issue to unlink entities from.\"),\n entityType: z\n .enum(ENTITY_TYPES)\n .describe(\n \"Type of entity to unlink: testCase | session | testRun | testRunResult | testRunStepResult.\",\n ),\n entityIds: z\n .array(z.number().int().positive())\n .min(1)\n .max(100)\n .describe(\"One or more entity IDs to unlink from the issue.\"),\n};\n\nexport function registerIssuesLink(\n server: McpServer,\n deps: IssuesLinkDeps,\n): void {\n server.registerTool(\n \"testplanit_issues_link\",\n {\n description:\n \"Link one or more entities (test cases, sessions, test runs, etc.) to an issue. Supports batch linking: pass up to 100 entity IDs in a single call. Use entityType='testCase' to link test cases created with testplanit_cases_create. Returns a count of linked entities.\",\n inputSchema: LINK_INPUT_SCHEMA,\n },\n async (input) => {\n try {\n const relation = ENTITY_RELATION[input.entityType];\n await zenstack(\n \"issue\",\n \"update\",\n {\n where: { id: input.issueId },\n data: {\n [relation]: {\n connect: input.entityIds.map((id) => ({ id })),\n },\n },\n select: { id: true },\n },\n deps.env,\n );\n const result = {\n linked: input.entityIds.length,\n issueId: input.issueId,\n entityType: input.entityType,\n entityIds: input.entityIds,\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n\nexport function registerIssuesUnlink(\n server: McpServer,\n deps: IssuesLinkDeps,\n): void {\n server.registerTool(\n \"testplanit_issues_unlink\",\n {\n description:\n \"Remove links between one or more entities and an issue. Supports batch: pass up to 100 entity IDs in a single call. Returns a count of unlinked entities.\",\n inputSchema: UNLINK_INPUT_SCHEMA,\n },\n async (input) => {\n try {\n const relation = ENTITY_RELATION[input.entityType];\n await zenstack(\n \"issue\",\n \"update\",\n {\n where: { id: input.issueId },\n data: {\n [relation]: {\n disconnect: input.entityIds.map((id) => ({ id })),\n },\n },\n select: { id: true },\n },\n deps.env,\n );\n const result = {\n unlinked: input.entityIds.length,\n issueId: input.issueId,\n entityType: input.entityType,\n entityIds: input.entityIds,\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n registerIssuesFindByKey,\n type IssuesFindByKeyDeps,\n} from \"./find-by-key.js\";\nimport { registerIssuesList, type IssuesListDeps } from \"./list.js\";\nimport { registerIssuesGet, type IssuesGetDeps } from \"./get.js\";\nimport {\n registerIssuesListLinks,\n type IssuesListLinksDeps,\n} from \"./links.js\";\nimport {\n registerIssuesLink,\n registerIssuesUnlink,\n type IssuesLinkDeps,\n} from \"./link.js\";\n\nexport type IssuesDeps = IssuesFindByKeyDeps &\n IssuesListDeps &\n IssuesGetDeps &\n IssuesListLinksDeps &\n IssuesLinkDeps;\n\nexport function registerIssues(server: McpServer, deps: IssuesDeps): void {\n registerIssuesFindByKey(server, deps);\n registerIssuesList(server, deps);\n registerIssuesGet(server, deps);\n registerIssuesListLinks(server, deps);\n registerIssuesLink(server, deps);\n registerIssuesUnlink(server, deps);\n}\n\nexport {\n registerIssuesFindByKey,\n registerIssuesList,\n registerIssuesGet,\n registerIssuesListLinks,\n registerIssuesLink,\n registerIssuesUnlink,\n};\nexport type {\n IssuesFindByKeyDeps,\n IssuesListDeps,\n IssuesGetDeps,\n IssuesListLinksDeps,\n IssuesLinkDeps,\n};\n","import type { Prisma } from \"@prisma/client\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// LINK_INCLUDE — typed include literal for RepositoryCaseLink reads.\n//\n// Selects denormalized counterpart cases (caseA, caseB) and the actor who\n// created the link. The `as const satisfies Prisma.RepositoryCaseLinkInclude`\n// annotation pins the shape: any unknown column reintroduced here trips\n// TS2353 — the same compile-time invariant the rest of the read tools rely on.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const LINK_INCLUDE = {\n caseA: {\n select: {\n id: true,\n name: true,\n source: true,\n automated: true,\n },\n },\n caseB: {\n select: {\n id: true,\n name: true,\n source: true,\n automated: true,\n },\n },\n createdBy: {\n select: {\n id: true,\n name: true,\n email: true,\n },\n },\n} as const satisfies Prisma.RepositoryCaseLinkInclude;\n\nexport interface RawLinkCase {\n id: number;\n name: string;\n source: string;\n automated: boolean;\n}\n\nexport interface RawLinkRow {\n id: number;\n type: string;\n createdAt: Date | string;\n caseA: RawLinkCase | null;\n caseB: RawLinkCase | null;\n createdBy: { id: string; name: string | null; email: string } | null;\n}\n\nfunction caseShape(raw: RawLinkCase | null) {\n return raw\n ? {\n id: raw.id,\n name: raw.name,\n source: raw.source,\n automated: raw.automated,\n }\n : null;\n}\n\nfunction createdByShape(raw: RawLinkRow[\"createdBy\"]) {\n return raw\n ? { id: raw.id, name: raw.name, email: raw.email }\n : null;\n}\n\n/**\n * Directional mapper — returns both `caseA` and `caseB`. Used in caseAId /\n * caseBId modes where the agent supplied a one-way endpoint and wants both\n * sides of every matching edge.\n */\nexport function mapLinkRowDirectional(raw: RawLinkRow) {\n return {\n id: raw.id,\n type: raw.type,\n createdAt: raw.createdAt,\n createdBy: createdByShape(raw.createdBy),\n caseA: caseShape(raw.caseA),\n caseB: caseShape(raw.caseB),\n };\n}\n\n/**\n * Bidirectional \"other side\" mapper — returns whichever of caseA/caseB has\n * `id !== queriedCaseId`. Used in `caseId` mode where the agent supplied\n * a single case and wants its counterparts denormalized inline.\n *\n * Behavior:\n * - caseA.id === queriedCaseId → otherCase = caseB\n * - caseB.id === queriedCaseId → otherCase = caseA\n * - Either side null (defensive) → otherCase = whichever side is non-null,\n * or null if both are.\n */\nexport function mapLinkRowOtherCase(raw: RawLinkRow, queriedCaseId: number) {\n const otherCase =\n raw.caseA && raw.caseA.id === queriedCaseId\n ? caseShape(raw.caseB)\n : caseShape(raw.caseA);\n return {\n id: raw.id,\n type: raw.type,\n createdAt: raw.createdAt,\n createdBy: createdByShape(raw.createdBy),\n otherCase,\n };\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n LINK_INCLUDE,\n mapLinkRowDirectional,\n mapLinkRowOtherCase,\n type RawLinkRow,\n} from \"./shared.js\";\n\nexport interface RepositoryCaseLinksListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\n/**\n * Register `testplanit_repository_case_links_list` — read-only traversal\n * of the RepositoryCaseLink graph between manual and imported cases.\n *\n * Three input modes (3-way XOR; exactly one ID must be supplied):\n * - caseId — bidirectional, matches both caseA.id and caseB.id via OR\n * - caseAId — one-way, originating side\n * - caseBId — one-way, destination side\n *\n * Optional `linkType` narrows to a single LinkType variant.\n * Optional `cursor` + `limit` (≤ 100) drive deterministic pagination\n * ordered by [createdAt DESC, id DESC].\n *\n * Response shape varies by mode:\n * - caseId mode: each row carries `otherCase` (the side opposite the\n * queried id) instead of caseA/caseB.\n * - caseAId / caseBId mode: each row carries both caseA and caseB.\n *\n * Project scope is enforced transitively by the host's @@allow rules on\n * caseA.project — RepositoryCaseLink itself is not project-scoped, so the\n * tool deliberately exposes no project-id input.\n */\nexport function registerRepositoryCaseLinksList(\n server: McpServer,\n deps: RepositoryCaseLinksListDeps,\n): void {\n server.registerTool(\n \"testplanit_repository_case_links_list\",\n {\n description:\n \"List RepositoryCaseLink rows for traversing the manual-↔-imported case linkage graph. Provide exactly one of caseId (bidirectional — matches both caseA.id and caseB.id), caseAId (one-way originating side), or caseBId (one-way destination side). Optional linkType narrows to SAME_TEST_DIFFERENT_SOURCE or DEPENDS_ON. In caseId mode each row carries an inline `otherCase` (the side opposite the queried id); in caseAId/caseBId mode each row carries both caseA and caseB. Project scope is enforced via the underlying access policy on caseA.project — the link row itself is not project-scoped.\",\n inputSchema: {\n caseId: z.number().int().positive().optional(),\n caseAId: z.number().int().positive().optional(),\n caseBId: z.number().int().positive().optional(),\n linkType: z\n .enum([\"SAME_TEST_DIFFERENT_SOURCE\", \"DEPENDS_ON\"])\n .optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const provided = [input.caseId, input.caseAId, input.caseBId].filter(\n (v) => v !== undefined,\n );\n if (provided.length !== 1) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"Provide exactly one of caseId, caseAId, or caseBId.\",\n },\n ],\n };\n }\n\n const limit = input.limit ?? DEFAULT_LIMIT;\n const where: Prisma.RepositoryCaseLinkWhereInput = {\n isDeleted: false,\n };\n if (input.linkType !== undefined) where.type = input.linkType;\n if (input.caseId !== undefined) {\n where.OR = [\n { caseAId: input.caseId },\n { caseBId: input.caseId },\n ];\n } else if (input.caseAId !== undefined) {\n where.caseAId = input.caseAId;\n } else if (input.caseBId !== undefined) {\n where.caseBId = input.caseBId;\n }\n\n const body: Record<string, unknown> = {\n where,\n include: LINK_INCLUDE,\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n const rows =\n (await zenstack<RawLinkRow[]>(\n \"repositoryCaseLink\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const items =\n input.caseId !== undefined\n ? trimmed.map((row) => mapLinkRowOtherCase(row, input.caseId!))\n : trimmed.map(mapLinkRowDirectional);\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1].id as number)\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n registerRepositoryCaseLinksList,\n type RepositoryCaseLinksListDeps,\n} from \"./list.js\";\n\nexport type RepositoryCaseLinksDeps = RepositoryCaseLinksListDeps;\n\nexport function registerRepositoryCaseLinks(\n server: McpServer,\n deps: RepositoryCaseLinksDeps,\n): void {\n registerRepositoryCaseLinksList(server, deps);\n}\n\nexport { registerRepositoryCaseLinksList };\nexport type { RepositoryCaseLinksListDeps };\n","import type { Prisma } from \"@prisma/client\";\nimport { extractProseMirrorText } from \"../cases/shared.js\";\nimport {\n computeStatusRollup,\n type StatusGroup,\n type StatusRollup,\n} from \"../runs/shared.js\";\nimport { TestPlanItHttpError } from \"../../http.js\";\nimport type { EnvConfig } from \"../../env.js\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Inline caps for the milestones_get linked arrays. linkedTestRuns is\n// deliberately wider than the standard 100-row ceiling — milestones legitimately\n// carry hundreds of test runs (the dominant fan-out), so a narrower cap\n// would force agents into pagination round trips for the common case.\n// linkedSessions and children stay at the standard ceiling.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const MILESTONE_LINKED_TEST_RUNS_CAP = 250;\nexport const MILESTONE_LINKED_SESSIONS_CAP = 100;\nexport const MILESTONE_CHILDREN_CAP = 100;\n\nconst TEST_RUNS_CAP_PLUS_ONE = MILESTONE_LINKED_TEST_RUNS_CAP + 1;\nconst SESSIONS_CAP_PLUS_ONE = MILESTONE_LINKED_SESSIONS_CAP + 1;\nconst CHILDREN_CAP_PLUS_ONE = MILESTONE_CHILDREN_CAP + 1;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Typed includes — `as const satisfies Prisma.MilestonesInclude` so reintroducing\n// an unknown column produces TS2353 at compile time.\n//\n// No `icon` selection: the schema only carries a 1-character `FieldIcon.name`\n// identifier (not a URL); deliberately dropped for the read surface so agents\n// don't see an opaque glyph code.\n//\n// `testRuns` and `sessions` on the row include are INTERNAL scaffolding — the\n// list handler reads only `id` from these arrays to fan out the pooled-rollup\n// groupBy calls. They are not surfaced on the mapped output row.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const MILESTONE_ROW_INCLUDE = {\n milestoneType: { select: { id: true, name: true } },\n creator: { select: { id: true, name: true, email: true } },\n _count: { select: { children: true, comments: true } },\n testRuns: { where: { isDeleted: false }, select: { id: true } },\n sessions: { where: { isDeleted: false }, select: { id: true } },\n} as const satisfies Prisma.MilestonesInclude;\n\n// Detail include — extends the row include with the three capped linked arrays.\n// Each nested array uses `take: cap + 1` so the get handler can detect overflow\n// and stamp a `truncated.<key>: true` flag on the response.\nexport const MILESTONE_DETAIL_INCLUDE = {\n milestoneType: { select: { id: true, name: true } },\n creator: { select: { id: true, name: true, email: true } },\n _count: { select: { children: true, comments: true } },\n testRuns: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: TEST_RUNS_CAP_PLUS_ONE,\n select: {\n id: true,\n name: true,\n isCompleted: true,\n completedAt: true,\n },\n },\n sessions: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: SESSIONS_CAP_PLUS_ONE,\n select: {\n id: true,\n name: true,\n isCompleted: true,\n state: { select: { id: true, name: true } },\n },\n },\n children: {\n where: { isDeleted: false },\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: CHILDREN_CAP_PLUS_ONE,\n select: {\n id: true,\n name: true,\n isCompleted: true,\n _count: { select: { children: true } },\n },\n },\n} as const satisfies Prisma.MilestonesInclude;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Raw row types\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface RawMilestoneRow {\n id: number;\n name: string;\n isStarted: boolean;\n isCompleted: boolean;\n automaticCompletion: boolean;\n startedAt: Date | string | null;\n completedAt: Date | string | null;\n createdAt: Date | string;\n parentId: number | null;\n milestoneType: { id: number; name: string } | null;\n creator: { id: string; name: string | null; email: string } | null;\n _count?: { children: number; comments: number };\n // Internal scaffolding for rollup fan-out — NOT surfaced in mapped output.\n testRuns?: Array<{ id: number }>;\n sessions?: Array<{ id: number }>;\n}\n\nexport interface RawMilestoneDetail\n extends Omit<RawMilestoneRow, \"testRuns\" | \"sessions\"> {\n note: unknown;\n docs: unknown;\n testRuns: Array<{\n id: number;\n name: string;\n isCompleted: boolean;\n completedAt: Date | string | null;\n }>;\n sessions: Array<{\n id: number;\n name: string;\n isCompleted: boolean;\n state: { id: number; name: string } | null;\n }>;\n children: Array<{\n id: number;\n name: string;\n isCompleted: boolean;\n _count: { children: number };\n }>;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Mappers — every output field enumerated explicitly. We never `...spread` raw\n// rows: the include shape and the mapper output must stay in sync explicitly so\n// schema drift can't leak new columns.\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport function mapMilestoneRow(\n raw: RawMilestoneRow,\n extras: { totalDescendants: number; rollup: StatusRollup },\n) {\n return {\n id: raw.id,\n name: raw.name,\n milestoneType: raw.milestoneType\n ? { id: raw.milestoneType.id, name: raw.milestoneType.name }\n : null,\n isStarted: raw.isStarted,\n isCompleted: raw.isCompleted,\n automaticCompletion: raw.automaticCompletion,\n startedAt: raw.startedAt ?? null,\n completedAt: raw.completedAt ?? null,\n createdAt: raw.createdAt,\n creator: raw.creator\n ? {\n id: raw.creator.id,\n name: raw.creator.name,\n email: raw.creator.email,\n }\n : null,\n parentId: raw.parentId ?? null,\n directChildrenCount: raw._count?.children ?? 0,\n commentCount: raw._count?.comments ?? 0,\n totalDescendants: extras.totalDescendants,\n statusCounts: extras.rollup.statusCounts,\n untested: extras.rollup.untested,\n total: extras.rollup.total,\n };\n}\n\nexport interface MilestoneDetailFlags {\n truncated: {\n linkedTestRuns?: true;\n linkedSessions?: true;\n children?: true;\n };\n childTotalDescendants: Map<number, number>;\n}\n\nexport function mapMilestoneDetail(\n raw: RawMilestoneDetail,\n extras: { totalDescendants: number; rollup: StatusRollup },\n flags: MilestoneDetailFlags,\n) {\n // The row mapper expects optional `testRuns`/`sessions` scaffolding; the\n // detail shape replaces both with full select rows further down, so we hand\n // the mapper a stripped surrogate to avoid double-shaping the fan-out arrays.\n const head = mapMilestoneRow(\n { ...raw, testRuns: [], sessions: [] } as RawMilestoneRow,\n extras,\n );\n return {\n ...head,\n note: extractProseMirrorText(raw.note),\n docs: extractProseMirrorText(raw.docs),\n linkedTestRuns: raw.testRuns.map((r) => ({\n id: r.id,\n name: r.name,\n isCompleted: r.isCompleted,\n completedAt: r.completedAt ?? null,\n })),\n linkedSessions: raw.sessions.map((s) => ({\n id: s.id,\n name: s.name,\n isCompleted: s.isCompleted,\n state: s.state ? { id: s.state.id, name: s.state.name } : null,\n })),\n children: raw.children.map((c) => ({\n id: c.id,\n name: c.name,\n isCompleted: c.isCompleted,\n directChildrenCount: c._count?.children ?? 0,\n totalDescendants: flags.childTotalDescendants.get(c.id) ?? 0,\n })),\n truncated: flags.truncated,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pooled-rollup merge.\n//\n// `TestRunResults` and `SessionResults` do not have a direct `milestoneId`\n// column — they reach milestones via `testRun.milestoneId` and\n// `session.milestoneId`. ZenStack RPC's `groupBy` only supports direct scalar\n// columns in the `by` array, so the handler issues two batched groupBy calls\n// (one keyed by `testRunId`, one keyed by `sessionId`), then this helper merges\n// the results back to the milestone dimension.\n//\n// `TestRunCases.statusId` IS nullable (cases with no execution yet); we keep\n// the null bucket so it can flow into `untested` via `computeStatusRollup`.\n// `SessionResults.statusId` is non-nullable — we treat null appearances as\n// impossible at compile time, but the merge still tolerates them (no null-check\n// branches needed).\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport interface BatchedRunGroup {\n testRunId: number;\n statusId: number | null;\n _count: { id: number };\n}\n\nexport interface BatchedSessionGroup {\n sessionId: number;\n statusId: number;\n _count: { id: number };\n}\n\nexport function mergeMilestoneStatusGroups(args: {\n runGroups: BatchedRunGroup[];\n sessionGroups: BatchedSessionGroup[];\n runIdToMilestoneId: Map<number, number>;\n sessionIdToMilestoneId: Map<number, number>;\n}): Map<number, StatusGroup[]> {\n const innerMap = new Map<number, Map<number | null, number>>();\n\n for (const g of args.runGroups) {\n const mId = args.runIdToMilestoneId.get(g.testRunId);\n if (mId === undefined) continue;\n const inner = innerMap.get(mId) ?? new Map<number | null, number>();\n inner.set(g.statusId, (inner.get(g.statusId) ?? 0) + g._count.id);\n innerMap.set(mId, inner);\n }\n for (const g of args.sessionGroups) {\n const mId = args.sessionIdToMilestoneId.get(g.sessionId);\n if (mId === undefined) continue;\n const inner = innerMap.get(mId) ?? new Map<number | null, number>();\n inner.set(g.statusId, (inner.get(g.statusId) ?? 0) + g._count.id);\n innerMap.set(mId, inner);\n }\n\n const out = new Map<number, StatusGroup[]>();\n for (const [mId, inner] of innerMap) {\n const arr: StatusGroup[] = [];\n for (const [statusId, count] of inner) {\n arr.push({ statusId, _count: { id: count } });\n }\n out.set(mId, arr);\n }\n return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Recursive CTE host-endpoint client.\n//\n// `totalDescendants` requires a recursive CTE (`WITH RECURSIVE`); ZenStack RPC\n// has no `$queryRaw` passthrough, so a dedicated host endpoint runs the CTE\n// once per page (batched across all milestone IDs) and returns a\n// milestoneId → descendantCount map. Empty input short-circuits without a\n// network call.\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst FETCH_TIMEOUT_MS = 10000;\n\nexport async function fetchDescendantCounts(\n milestoneIds: number[],\n env: EnvConfig,\n): Promise<Map<number, number>> {\n if (milestoneIds.length === 0) return new Map();\n\n const q = encodeURIComponent(JSON.stringify({ milestoneIds }));\n const response = await fetch(\n `${env.apiUrl}/api/mcp/milestones-descendants?q=${q}`,\n {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${env.apiToken}`,\n \"Content-Type\": \"application/json\",\n },\n signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n },\n );\n const text = await response.text();\n\n if (!response.ok) {\n let parsedMessage: string | undefined;\n try {\n const parsed = JSON.parse(text) as Record<string, unknown>;\n const errField = parsed?.error;\n if (typeof errField === \"string\") {\n parsedMessage = errField;\n } else if (\n errField &&\n typeof errField === \"object\" &&\n (errField as Record<string, unknown>).message\n ) {\n parsedMessage = String(\n (errField as Record<string, unknown>).message,\n );\n }\n } catch {\n // Body is not JSON — leave parsedMessage undefined.\n }\n // Never include the bearer token in error messages.\n throw new TestPlanItHttpError(\n `HTTP ${response.status} from /api/mcp/milestones-descendants${parsedMessage ? `: ${parsedMessage}` : \"\"}`,\n { statusCode: response.status },\n );\n }\n\n const json = JSON.parse(text) as { data?: Record<string, number> };\n const map = new Map<number, number>();\n for (const [k, v] of Object.entries(json.data ?? {})) {\n map.set(parseInt(k, 10), v);\n }\n // Defensive: every input id is present in the output map (defaulting to 0)\n // so callers can use `map.get(id) ?? 0` without surprises.\n for (const id of milestoneIds) {\n if (!map.has(id)) map.set(id, 0);\n }\n return map;\n}\n\n// Re-export shared helpers consumed by list.ts / get.ts so the milestones\n// module is the single import surface for the domain.\nexport { computeStatusRollup };\nexport type { StatusGroup, StatusRollup };\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n MILESTONE_ROW_INCLUDE,\n computeStatusRollup,\n fetchDescendantCounts,\n mapMilestoneRow,\n mergeMilestoneStatusGroups,\n type BatchedRunGroup,\n type BatchedSessionGroup,\n type RawMilestoneRow,\n type StatusGroup,\n} from \"./shared.js\";\n\nexport interface MilestonesListDeps {\n env: EnvConfig;\n}\n\nconst DEFAULT_LIMIT = 25;\nconst MAX_LIMIT = 100;\n\n/**\n * `testplanit_milestones_list` — milestones for a project, with the pooled\n * `statusCounts` rollup inline on every row.\n *\n * Per-page call sequence (at most 5 round trips):\n * 1. milestones.findMany — page rows + internal testRun/session id arrays.\n * 2. testRunCases.groupBy by [testRunId, statusId] — skipped if no runs.\n * 3. sessionResults.groupBy by [sessionId, statusId] — skipped if no\n * sessions.\n * 4. status.findMany — skipped if every grouped statusId is null (no\n * executed work yet).\n * 5. GET /api/mcp/milestones-descendants — batched recursive CTE for\n * `totalDescendants` across the whole page.\n *\n * Never per-row: the rollup helpers fan a single page-wide groupBy result\n * back to each milestone via in-memory merge.\n */\nexport function registerMilestonesList(\n server: McpServer,\n deps: MilestonesListDeps,\n): void {\n server.registerTool(\n \"testplanit_milestones_list\",\n {\n description:\n \"List milestones scoped to a project, with POOLED statusCounts rollup inline on every row (merged across linked test runs AND linked sessions). Filters: isCompleted, isStarted, milestoneTypeId, createdById (single string), from/to (ISO 8601 createdAt range), parentId (null = root-only, number = direct children of, omitted = all). Cursor pagination via the `cursor` returned in `nextCursor`. Each row carries denormalized milestoneType {id,name}, creator, parentId, directChildrenCount, totalDescendants (recursive CTE), commentCount inline, plus statusCounts:[{id,name,count}] + untested + total (counts SUM to total). Two batched groupBy calls per page (testRunCases + sessionResults), never per-row. No icon field — schema only carries an icon class identifier, deliberately dropped for v1.\",\n inputSchema: {\n projectId: z.number().int().positive(),\n isCompleted: z.boolean().optional(),\n isStarted: z.boolean().optional(),\n milestoneTypeId: z.number().int().positive().optional(),\n createdById: z.string().trim().min(1).optional(),\n from: z.string().datetime({ offset: true }).optional(),\n to: z.string().datetime({ offset: true }).optional(),\n // Three states — null (root-only), number (children-of), undefined (all)\n parentId: z\n .union([z.number().int().positive(), z.null()])\n .optional(),\n cursor: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(MAX_LIMIT).optional(),\n },\n },\n async (input) => {\n try {\n const limit = input.limit ?? DEFAULT_LIMIT;\n\n const where: Prisma.MilestonesWhereInput = {\n projectId: input.projectId,\n isDeleted: false,\n };\n if (input.isCompleted !== undefined) {\n where.isCompleted = input.isCompleted;\n }\n if (input.isStarted !== undefined) {\n where.isStarted = input.isStarted;\n }\n // Schema FK column is plural: `milestoneTypesId`.\n if (input.milestoneTypeId !== undefined) {\n where.milestoneTypesId = input.milestoneTypeId;\n }\n // Schema scalar field is `createdBy` (String); `creator` is the relation.\n if (input.createdById) {\n where.createdBy = input.createdById;\n }\n if (input.from || input.to) {\n where.createdAt = {\n ...(input.from ? { gte: new Date(input.from) } : {}),\n ...(input.to ? { lte: new Date(input.to) } : {}),\n };\n }\n // Three-branch parentId — explicit null check distinguishes\n // \"root-only\" from \"all\" semantics.\n if (input.parentId === null) {\n where.parentId = null;\n } else if (input.parentId !== undefined) {\n where.parentId = input.parentId;\n }\n // omitted → no where.parentId key (all milestones)\n\n const body: Record<string, unknown> = {\n where,\n include: MILESTONE_ROW_INCLUDE,\n orderBy: [{ createdAt: \"desc\" }, { id: \"desc\" }],\n take: limit + 1,\n };\n if (input.cursor !== undefined) {\n body.cursor = { id: input.cursor };\n body.skip = 1;\n }\n\n // Call 1 — milestones.findMany.\n const rows =\n (await zenstack<RawMilestoneRow[]>(\n \"milestones\",\n \"findMany\",\n body,\n deps.env,\n )) ?? [];\n const hasNextPage = rows.length > limit;\n const trimmed = rows.slice(0, limit);\n const pageIds = trimmed.map((r) => r.id);\n\n // Lookup tables for the merge fan-out and the all-* id arrays for\n // the two batched groupBy calls.\n const runIdToMilestoneId = new Map<number, number>();\n const sessionIdToMilestoneId = new Map<number, number>();\n const allRunIds: number[] = [];\n const allSessionIds: number[] = [];\n for (const m of trimmed) {\n for (const r of m.testRuns ?? []) {\n runIdToMilestoneId.set(r.id, m.id);\n allRunIds.push(r.id);\n }\n for (const s of m.sessions ?? []) {\n sessionIdToMilestoneId.set(s.id, m.id);\n allSessionIds.push(s.id);\n }\n }\n\n // Call 2 — testRunCases.groupBy. TestRunCases has no `isDeleted`\n // column (cascade deletes only); never add it to the where.\n let runGroups: BatchedRunGroup[] = [];\n if (allRunIds.length > 0) {\n runGroups =\n (await zenstack<BatchedRunGroup[]>(\n \"testRunCases\",\n \"groupBy\",\n {\n by: [\"testRunId\", \"statusId\"],\n where: { testRunId: { in: allRunIds } },\n _count: { id: true },\n } satisfies Prisma.TestRunCasesGroupByArgs,\n deps.env,\n )) ?? [];\n }\n\n // Call 3 — sessionResults.groupBy. SessionResults DOES have\n // `isDeleted`; defense in depth applies.\n let sessionGroups: BatchedSessionGroup[] = [];\n if (allSessionIds.length > 0) {\n sessionGroups =\n (await zenstack<BatchedSessionGroup[]>(\n \"sessionResults\",\n \"groupBy\",\n {\n by: [\"sessionId\", \"statusId\"],\n where: { sessionId: { in: allSessionIds }, isDeleted: false },\n _count: { id: true },\n } satisfies Prisma.SessionResultsGroupByArgs,\n deps.env,\n )) ?? [];\n }\n\n // Call 4 — status.findMany for the union of non-null statusIds.\n // Skipped when every grouped status is null (no executed work yet).\n const nonNullStatusIds = Array.from(\n new Set([\n ...runGroups\n .map((g) => g.statusId)\n .filter((id): id is number => id !== null),\n ...sessionGroups.map((g) => g.statusId),\n ]),\n );\n const statuses =\n nonNullStatusIds.length === 0\n ? []\n : ((await zenstack<Array<{ id: number; name: string }>>(\n \"status\",\n \"findMany\",\n {\n where: { id: { in: nonNullStatusIds } },\n select: { id: true, name: true },\n } satisfies Prisma.StatusFindManyArgs,\n deps.env,\n )) ?? []);\n const nameById = new Map<number, string>(\n statuses.map((s) => [s.id, s.name]),\n );\n\n // Merge run + session groups back to milestoneId.\n const groupsByMilestone: Map<number, StatusGroup[]> =\n mergeMilestoneStatusGroups({\n runGroups,\n sessionGroups,\n runIdToMilestoneId,\n sessionIdToMilestoneId,\n });\n\n // Call 5 — host CTE for totalDescendants, batched per page.\n const descendantCounts = await fetchDescendantCounts(pageIds, deps.env);\n\n const items = trimmed.map((r) => {\n const rollup = computeStatusRollup(\n groupsByMilestone.get(r.id) ?? [],\n nameById,\n );\n return mapMilestoneRow(r, {\n totalDescendants: descendantCounts.get(r.id) ?? 0,\n rollup,\n });\n });\n\n const nextCursor =\n hasNextPage && items.length > 0\n ? (items[items.length - 1] as { id: number }).id\n : null;\n\n const result = { items, hasNextPage, nextCursor };\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n structuredContent: result as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport {\n MILESTONE_DETAIL_INCLUDE,\n MILESTONE_LINKED_TEST_RUNS_CAP,\n MILESTONE_LINKED_SESSIONS_CAP,\n MILESTONE_CHILDREN_CAP,\n computeStatusRollup,\n fetchDescendantCounts,\n mapMilestoneDetail,\n mergeMilestoneStatusGroups,\n type BatchedRunGroup,\n type BatchedSessionGroup,\n type RawMilestoneDetail,\n} from \"./shared.js\";\n\nexport interface MilestonesGetDeps {\n env: EnvConfig;\n}\n\n/**\n * `testplanit_milestones_get` — fetch a single milestone with the full\n * denormalized header, plain-text note + docs (ProseMirror), pooled\n * `statusCounts`, and three inlined linked arrays:\n * - linkedTestRuns (cap 250 — wider than the standard 100; milestones\n * legitimately carry hundreds of runs)\n * - linkedSessions (cap 100)\n * - children (cap 100, 1-level deep; each child carries totalDescendants)\n *\n * Per-array `truncated.<key>: true` overflow stamps so the agent can decide\n * to paginate via the dedicated list tools.\n *\n * Issues two recursive-CTE host calls per request:\n * 1. self → totalDescendants for the milestone itself.\n * 2. children → totalDescendants for each direct child.\n */\nexport function registerMilestonesGet(\n server: McpServer,\n deps: MilestonesGetDeps,\n): void {\n server.registerTool(\n \"testplanit_milestones_get\",\n {\n description:\n \"Fetch a single Milestone by id with denormalized header (milestoneType {id,name}, creator, parentId, directChildrenCount, commentCount, totalDescendants), note + docs (ProseMirror plain text), pooled statusCounts (testRuns + sessions merged) + untested + total, and three inlined linked arrays — linkedTestRuns (cap 250), linkedSessions (cap 100), children (cap 100, 1-level deep with totalDescendants). When an array overflows the cap the response carries truncated.<key>: true; the rest is reachable via testplanit_milestones_list with parentId, or testplanit_test_runs_list. No icon field — schema only carries an icon class identifier, deliberately dropped for v1.\",\n inputSchema: { milestoneId: z.number().int().positive() },\n },\n async (input) => {\n try {\n const raw = await zenstack<RawMilestoneDetail | null>(\n \"milestones\",\n \"findUnique\",\n {\n where: {\n id: input.milestoneId,\n isDeleted: false,\n } satisfies Prisma.MilestonesWhereUniqueInput,\n include: MILESTONE_DETAIL_INCLUDE,\n },\n deps.env,\n );\n if (!raw) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: `Milestone ${input.milestoneId} not found.`,\n },\n ],\n };\n }\n\n // Detect overflow per array via the take:cap+1 ceilings stamped\n // into MILESTONE_DETAIL_INCLUDE; trim each array to its inline cap\n // BEFORE mapping so the surfaced output never exceeds the bound.\n const truncated: {\n linkedTestRuns?: true;\n linkedSessions?: true;\n children?: true;\n } = {};\n if (raw.testRuns.length > MILESTONE_LINKED_TEST_RUNS_CAP) {\n truncated.linkedTestRuns = true;\n }\n if (raw.sessions.length > MILESTONE_LINKED_SESSIONS_CAP) {\n truncated.linkedSessions = true;\n }\n if (raw.children.length > MILESTONE_CHILDREN_CAP) {\n truncated.children = true;\n }\n\n const trimmed: RawMilestoneDetail = {\n ...raw,\n testRuns: raw.testRuns.slice(0, MILESTONE_LINKED_TEST_RUNS_CAP),\n sessions: raw.sessions.slice(0, MILESTONE_LINKED_SESSIONS_CAP),\n children: raw.children.slice(0, MILESTONE_CHILDREN_CAP),\n };\n\n // CR-02 fix: derive the rollup id sets from milestoneId-scoped\n // findMany queries rather than the trimmed inline arrays, so the\n // pooled statusCounts / untested / total stay correct even when\n // the inline display caps fire (e.g. milestones with >250 linked\n // runs). The cost is two short id-only findMany calls; the\n // resulting rollup matches what milestones_list reports for the\n // same milestone.\n const allRuns =\n (await zenstack<Array<{ id: number }>>(\n \"testRuns\",\n \"findMany\",\n {\n where: { milestoneId: raw.id, isDeleted: false },\n select: { id: true },\n } satisfies Prisma.TestRunsFindManyArgs,\n deps.env,\n )) ?? [];\n const runIds = allRuns.map((r) => r.id);\n const allSessions =\n (await zenstack<Array<{ id: number }>>(\n \"sessions\",\n \"findMany\",\n {\n where: { milestoneId: raw.id, isDeleted: false },\n select: { id: true },\n } satisfies Prisma.SessionsFindManyArgs,\n deps.env,\n )) ?? [];\n const sessionIds = allSessions.map((s) => s.id);\n\n // Pooled rollup for the milestone itself: same merge algorithm as\n // milestones_list, but bounded to a single milestone's runs +\n // sessions.\n let runGroups: BatchedRunGroup[] = [];\n if (runIds.length > 0) {\n runGroups =\n (await zenstack<BatchedRunGroup[]>(\n \"testRunCases\",\n \"groupBy\",\n {\n by: [\"testRunId\", \"statusId\"],\n where: { testRunId: { in: runIds } },\n _count: { id: true },\n } satisfies Prisma.TestRunCasesGroupByArgs,\n deps.env,\n )) ?? [];\n }\n let sessionGroups: BatchedSessionGroup[] = [];\n if (sessionIds.length > 0) {\n sessionGroups =\n (await zenstack<BatchedSessionGroup[]>(\n \"sessionResults\",\n \"groupBy\",\n {\n by: [\"sessionId\", \"statusId\"],\n where: { sessionId: { in: sessionIds }, isDeleted: false },\n _count: { id: true },\n } satisfies Prisma.SessionResultsGroupByArgs,\n deps.env,\n )) ?? [];\n }\n const nonNullStatusIds = Array.from(\n new Set([\n ...runGroups\n .map((g) => g.statusId)\n .filter((id): id is number => id !== null),\n ...sessionGroups.map((g) => g.statusId),\n ]),\n );\n const statuses =\n nonNullStatusIds.length === 0\n ? []\n : ((await zenstack<Array<{ id: number; name: string }>>(\n \"status\",\n \"findMany\",\n {\n where: { id: { in: nonNullStatusIds } },\n select: { id: true, name: true },\n } satisfies Prisma.StatusFindManyArgs,\n deps.env,\n )) ?? []);\n const nameById = new Map<number, string>(\n statuses.map((s) => [s.id, s.name]),\n );\n\n const runIdToMilestoneId = new Map<number, number>(\n runIds.map((id) => [id, raw.id]),\n );\n const sessionIdToMilestoneId = new Map<number, number>(\n sessionIds.map((id) => [id, raw.id]),\n );\n const groupsByMilestone = mergeMilestoneStatusGroups({\n runGroups,\n sessionGroups,\n runIdToMilestoneId,\n sessionIdToMilestoneId,\n });\n const rollup = computeStatusRollup(\n groupsByMilestone.get(raw.id) ?? [],\n nameById,\n );\n\n // Two CTE calls — one for the milestone itself, one batched across\n // the direct children. Children's totalDescendants surfaces inline\n // so agents can prioritize which subtree to walk first without a\n // round trip per child.\n const selfDescendants = await fetchDescendantCounts(\n [raw.id],\n deps.env,\n );\n const childIds = trimmed.children.map((c) => c.id);\n const childTotalDescendants = await fetchDescendantCounts(\n childIds,\n deps.env,\n );\n\n const detail = mapMilestoneDetail(\n trimmed,\n {\n totalDescendants: selfDescendants.get(raw.id) ?? 0,\n rollup,\n },\n { truncated, childTotalDescendants },\n );\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\n\nexport interface MilestoneTypesListDeps {\n env: EnvConfig;\n}\n\ninterface RawMilestoneTypeRow {\n id: number;\n name: string;\n isDefault: boolean;\n}\n\n/**\n * `testplanit_milestone_types_list` — milestone types assigned to a project\n * via the `MilestoneTypesAssignment` junction. Returns\n * `{items: [{id, name, isDefault}]}` ordered by name. No cursor pagination —\n * types-per-project is small (~10 typical). Every milestones_list row + get\n * response also denormalizes milestoneType:{id,name} inline; this tool\n * exists for full-catalog and filter-picker use cases.\n */\nexport function registerMilestoneTypesList(\n server: McpServer,\n deps: MilestoneTypesListDeps,\n): void {\n server.registerTool(\n \"testplanit_milestone_types_list\",\n {\n description:\n \"List all milestone types assigned to a project (via the MilestoneTypesAssignment junction). Returns {items:[{id, name, isDefault}]} sorted by name asc. No cursor pagination — types-per-project is small (~10 typical). Every milestones_list row + milestones_get response also denormalizes milestoneType:{id,name} inline; this tool exists for full-catalog or filter-picker use cases. No icon field — schema only carries an icon class identifier, deliberately dropped for v1.\",\n inputSchema: { projectId: z.number().int().positive() },\n },\n async (input) => {\n try {\n const rows = await zenstack<RawMilestoneTypeRow[]>(\n \"milestoneTypes\",\n \"findMany\",\n {\n where: {\n isDeleted: false,\n projects: { some: { projectId: input.projectId } },\n },\n select: { id: true, name: true, isDefault: true },\n orderBy: { name: \"asc\" },\n } satisfies Prisma.MilestoneTypesFindManyArgs,\n deps.env,\n );\n const items = (rows ?? []).map((r) => ({\n id: r.id,\n name: r.name,\n isDefault: r.isDefault,\n }));\n const out = { items };\n return {\n content: [{ type: \"text\", text: JSON.stringify(out) }],\n structuredContent: out as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { extractProseMirrorText } from \"../cases/shared.js\";\n\nexport interface MilestonesCreateDeps {\n env: EnvConfig;\n}\n\ninterface RawCreatedMilestone {\n id: number;\n name: string;\n isStarted: boolean;\n isCompleted: boolean;\n createdAt: string | Date;\n milestoneType: { id: number; name: string };\n creator: { id: string; name: string | null; email: string };\n parent: { id: number; name: string } | null;\n note: unknown;\n}\n\nconst CREATED_MILESTONE_INCLUDE = {\n milestoneType: { select: { id: true, name: true } },\n creator: { select: { id: true, name: true, email: true } },\n parent: { select: { id: true, name: true } },\n} as const satisfies Prisma.MilestonesInclude;\n\nexport function registerMilestonesCreate(\n server: McpServer,\n deps: MilestonesCreateDeps,\n): void {\n server.registerTool(\n \"testplanit_milestones_create\",\n {\n description:\n \"Create a new milestone in a project. Use testplanit_milestone_types_list to get available milestoneTypeId values. Optionally nest under a parent milestone. Returns the created milestone header.\",\n inputSchema: {\n projectId: z\n .number()\n .int()\n .positive()\n .describe(\"Project to create the milestone in.\"),\n name: z.string().min(1).max(500).describe(\"Milestone name.\"),\n milestoneTypeId: z\n .number()\n .int()\n .positive()\n .describe(\n \"Milestone type ID. Use testplanit_milestone_types_list to get the available types.\",\n ),\n parentId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Parent milestone ID for nesting.\"),\n note: z\n .string()\n .optional()\n .describe(\"Plain-text note for the milestone.\"),\n },\n },\n async (input) => {\n try {\n const raw = await zenstack<RawCreatedMilestone>(\n \"milestones\",\n \"create\",\n {\n data: {\n name: input.name,\n project: { connect: { id: input.projectId } },\n milestoneType: { connect: { id: input.milestoneTypeId } },\n ...(input.parentId\n ? { parent: { connect: { id: input.parentId } } }\n : {}),\n ...(input.note !== undefined ? { note: input.note } : {}),\n },\n include: CREATED_MILESTONE_INCLUDE,\n },\n deps.env,\n );\n\n const detail = {\n id: raw.id,\n name: raw.name,\n isStarted: raw.isStarted,\n isCompleted: raw.isCompleted,\n createdAt: raw.createdAt,\n milestoneType: raw.milestoneType\n ? { id: raw.milestoneType.id, name: raw.milestoneType.name }\n : null,\n creator: raw.creator\n ? {\n id: raw.creator.id,\n name: raw.creator.name,\n email: raw.creator.email,\n }\n : null,\n parent: raw.parent\n ? { id: raw.parent.id, name: raw.parent.name }\n : null,\n note: extractProseMirrorText(raw.note),\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Prisma } from \"@prisma/client\";\nimport * as z from \"zod/v4\";\nimport { zenstack } from \"../../api.js\";\nimport type { EnvConfig } from \"../../env.js\";\nimport { mapHttpErrorToToolResult } from \"../../errors.js\";\nimport { extractProseMirrorText } from \"../cases/shared.js\";\n\nexport interface MilestonesUpdateDeps {\n env: EnvConfig;\n}\n\ninterface RawUpdatedMilestone {\n id: number;\n name: string;\n isStarted: boolean;\n isCompleted: boolean;\n startedAt: string | Date | null;\n completedAt: string | Date | null;\n createdAt: string | Date;\n milestoneType: { id: number; name: string };\n creator: { id: string; name: string | null; email: string };\n parent: { id: number; name: string } | null;\n note: unknown;\n}\n\nconst UPDATED_MILESTONE_INCLUDE = {\n milestoneType: { select: { id: true, name: true } },\n creator: { select: { id: true, name: true, email: true } },\n parent: { select: { id: true, name: true } },\n} as const satisfies Prisma.MilestonesInclude;\n\nexport function registerMilestonesUpdate(\n server: McpServer,\n deps: MilestonesUpdateDeps,\n): void {\n server.registerTool(\n \"testplanit_milestones_update\",\n {\n description:\n \"Update an existing milestone. All fields except milestoneId are optional — only supplied fields are changed. Setting isCompleted: true also records completedAt; setting isStarted: true records startedAt. Returns the updated milestone header.\",\n inputSchema: {\n milestoneId: z\n .number()\n .int()\n .positive()\n .describe(\"ID of the milestone to update.\"),\n name: z.string().min(1).max(500).optional().describe(\"New name.\"),\n note: z\n .string()\n .nullable()\n .optional()\n .describe(\"Updated plain-text note. Pass null to clear.\"),\n milestoneTypeId: z\n .number()\n .int()\n .positive()\n .optional()\n .describe(\"Change the milestone type.\"),\n parentId: z\n .number()\n .int()\n .positive()\n .nullable()\n .optional()\n .describe(\"Move under a different parent; null to make top-level.\"),\n isStarted: z\n .boolean()\n .optional()\n .describe(\"Mark as started (true) or not started (false).\"),\n isCompleted: z\n .boolean()\n .optional()\n .describe(\"Mark as completed (true) or reopen (false).\"),\n },\n },\n async (input) => {\n try {\n const data: Record<string, unknown> = {};\n\n if (input.name !== undefined) data.name = input.name;\n if (input.note !== undefined) {\n data.note = input.note === null ? null : input.note;\n }\n if (input.milestoneTypeId !== undefined) {\n data.milestoneType = { connect: { id: input.milestoneTypeId } };\n }\n if (input.parentId !== undefined) {\n data.parent =\n input.parentId === null\n ? { disconnect: true }\n : { connect: { id: input.parentId } };\n }\n if (input.isStarted !== undefined) {\n data.isStarted = input.isStarted;\n data.startedAt = input.isStarted ? new Date().toISOString() : null;\n }\n if (input.isCompleted !== undefined) {\n data.isCompleted = input.isCompleted;\n data.completedAt = input.isCompleted\n ? new Date().toISOString()\n : null;\n }\n\n if (Object.keys(data).length === 0) {\n return {\n isError: true as const,\n content: [\n {\n type: \"text\" as const,\n text: \"No fields to update — provide at least one optional field.\",\n },\n ],\n };\n }\n\n const raw = await zenstack<RawUpdatedMilestone>(\n \"milestones\",\n \"update\",\n {\n where: { id: input.milestoneId },\n data,\n include: UPDATED_MILESTONE_INCLUDE,\n },\n deps.env,\n );\n\n const detail = {\n id: raw.id,\n name: raw.name,\n isStarted: raw.isStarted,\n isCompleted: raw.isCompleted,\n startedAt: raw.startedAt ?? null,\n completedAt: raw.completedAt ?? null,\n createdAt: raw.createdAt,\n milestoneType: raw.milestoneType\n ? { id: raw.milestoneType.id, name: raw.milestoneType.name }\n : null,\n creator: raw.creator\n ? {\n id: raw.creator.id,\n name: raw.creator.name,\n email: raw.creator.email,\n }\n : null,\n parent: raw.parent\n ? { id: raw.parent.id, name: raw.parent.name }\n : null,\n note: extractProseMirrorText(raw.note),\n };\n\n return {\n content: [{ type: \"text\", text: JSON.stringify(detail) }],\n structuredContent: detail as unknown as Record<string, unknown>,\n };\n } catch (err) {\n return mapHttpErrorToToolResult(err);\n }\n },\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport {\n registerMilestonesList,\n type MilestonesListDeps,\n} from \"./list.js\";\nimport {\n registerMilestonesGet,\n type MilestonesGetDeps,\n} from \"./get.js\";\nimport {\n registerMilestoneTypesList,\n type MilestoneTypesListDeps,\n} from \"./types-list.js\";\nimport {\n registerMilestonesCreate,\n type MilestonesCreateDeps,\n} from \"./create.js\";\nimport {\n registerMilestonesUpdate,\n type MilestonesUpdateDeps,\n} from \"./update.js\";\n\nexport type MilestonesDeps = MilestonesListDeps &\n MilestonesGetDeps &\n MilestoneTypesListDeps &\n MilestonesCreateDeps &\n MilestonesUpdateDeps;\n\nexport function registerMilestones(\n server: McpServer,\n deps: MilestonesDeps,\n): void {\n registerMilestonesList(server, deps);\n registerMilestonesGet(server, deps);\n registerMilestoneTypesList(server, deps);\n registerMilestonesCreate(server, deps);\n registerMilestonesUpdate(server, deps);\n}\n\nexport {\n registerMilestonesList,\n registerMilestonesGet,\n registerMilestoneTypesList,\n registerMilestonesCreate,\n registerMilestonesUpdate,\n};\nexport type {\n MilestonesListDeps,\n MilestonesGetDeps,\n MilestoneTypesListDeps,\n MilestonesCreateDeps,\n MilestonesUpdateDeps,\n};\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { registerWhoami, type WhoamiDeps } from \"./whoami.js\";\nimport { registerCases, type CasesDeps } from \"./cases/index.js\";\nimport { registerFolders, type FoldersDeps } from \"./folders/index.js\";\nimport { registerTags, type TagsDeps } from \"./tags/index.js\";\nimport { registerProjects, type ProjectsDeps } from \"./projects/index.js\";\nimport { registerRuns, type RunsDeps } from \"./runs/index.js\";\nimport { registerSessions, type SessionsDeps } from \"./sessions/index.js\";\nimport {\n registerCodeRepositories,\n type CodeRepositoriesDeps,\n} from \"./code-repositories/index.js\";\nimport { registerIssues, type IssuesDeps } from \"./issues/index.js\";\nimport {\n registerRepositoryCaseLinks,\n type RepositoryCaseLinksDeps,\n} from \"./repository-case-links/index.js\";\nimport {\n registerMilestones,\n type MilestonesDeps,\n} from \"./milestones/index.js\";\n\n/**\n * Aggregate dependencies for every tool registered by\n * `@testplanit/mcp-server`. The intersection widens with each new domain;\n * adding a new domain barrel means adding the matching `& <Domain>Deps`\n * here so all registered tools see the same single deps object at runtime.\n */\nexport type ToolRegistryDeps =\n & WhoamiDeps\n & CasesDeps\n & FoldersDeps\n & TagsDeps\n & ProjectsDeps\n & RunsDeps\n & SessionsDeps\n & CodeRepositoriesDeps\n & IssuesDeps\n & RepositoryCaseLinksDeps\n & MilestonesDeps;\n\n/**\n * Register every tool shipped by `@testplanit/mcp-server`.\n *\n * Tools are grouped by domain: whoami (debug/identity), cases, folders,\n * tags, projects (agent context disambiguation), runs, sessions,\n * code-repositories, issues, repository-case-links, and milestones\n * (milestones_list, milestones_get, milestone_types_list).\n */\nexport function registerAll(\n server: McpServer,\n deps: ToolRegistryDeps,\n): void {\n registerWhoami(server, deps);\n registerCases(server, deps);\n registerFolders(server, deps);\n registerTags(server, deps);\n registerProjects(server, deps);\n registerRuns(server, deps);\n registerSessions(server, deps);\n registerCodeRepositories(server, deps);\n registerIssues(server, deps);\n registerRepositoryCaseLinks(server, deps);\n registerMilestones(server, deps);\n}\n\nexport {\n registerWhoami,\n registerCases,\n registerFolders,\n registerTags,\n registerProjects,\n registerRuns,\n registerSessions,\n registerCodeRepositories,\n registerIssues,\n registerRepositoryCaseLinks,\n registerMilestones,\n};\nexport type { WhoamiDeps } from \"./whoami.js\";\nexport type { CasesDeps } from \"./cases/index.js\";\nexport type { FoldersDeps } from \"./folders/index.js\";\nexport type { TagsDeps } from \"./tags/index.js\";\nexport type { ProjectsDeps } from \"./projects/index.js\";\nexport type { RunsDeps } from \"./runs/index.js\";\nexport type { SessionsDeps } from \"./sessions/index.js\";\nexport type { CodeRepositoriesDeps } from \"./code-repositories/index.js\";\nexport type { IssuesDeps } from \"./issues/index.js\";\nexport type { RepositoryCaseLinksDeps } from \"./repository-case-links/index.js\";\nexport type { MilestonesDeps } from \"./milestones/index.js\";\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { EnvConfig } from \"./env.js\";\nimport type { WhoamiUser } from \"./http.js\";\nimport { registerAll } from \"./tools/index.js\";\n\n/**\n * Dependencies the CLI bootstrap (cli.ts `runServer`) injects into\n * `createServer`.\n *\n * `user` is the `WhoamiUser` resolved by the bootstrap probe; it is\n * intentionally retained on the deps contract even though Phase 5's\n * production tools (`whoami`) re-fetch live data on every call. Future\n * tools may use `user` for static-shape decisions (e.g., gating Phase 6+\n * write tools on `!user.readOnly` at registration time).\n */\nexport interface ServerDeps {\n env: EnvConfig;\n user: WhoamiUser;\n}\n\n/**\n * Create an MCP server instance for TestPlanIt.\n *\n * Plan 05-06 registered a placeholder smoke tool so the\n * `InMemoryTransport` handshake test had something to find. Plan 05-07\n * replaces that with the production `whoami` tool, registered through the\n * central `registerAll` registry — Phase 6+ tools plug into the registry\n * without further edits to this file.\n */\nexport function createServer(deps: ServerDeps): McpServer {\n const server = new McpServer({\n name: \"@testplanit/mcp-server\",\n version: \"0.0.0\",\n });\n registerAll(server, { env: deps.env });\n return server;\n}\n","import { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { parseEnv, type EnvConfig } from \"./env.js\";\nimport {\n validateToken,\n redactToken,\n type ValidateResult,\n type WhoamiUser,\n} from \"./http.js\";\nimport { createServer } from \"./server.js\";\n\nexport interface RunDeps {\n parseEnvImpl: (env: NodeJS.ProcessEnv) => EnvConfig;\n validateImpl: (env: EnvConfig) => Promise<ValidateResult>;\n createServerImpl: (deps: { env: EnvConfig; user: WhoamiUser }) => McpServer;\n connectImpl: (server: McpServer) => Promise<void>;\n errLog: (...args: unknown[]) => void;\n exitImpl: (code: number) => void;\n}\n\n/**\n * Default implementations wiring the real env, http, and stdio transport.\n * Overridden in tests to assert exit codes + serial order without spawning\n * a real subprocess.\n */\nexport const defaultRunDeps: RunDeps = {\n parseEnvImpl: parseEnv,\n validateImpl: validateToken,\n createServerImpl: createServer,\n connectImpl: async (server) => {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n },\n errLog: (...args) => console.error(...args),\n exitImpl: (code) => process.exit(code),\n};\n\n/**\n * Bootstrap the MCP server in strict serial order:\n * parseEnv → validateToken → createServer → connect (stdio)\n *\n * Bad env or bad token exits with code 1 BEFORE any transport connect.\n * All diagnostics go through `errLog` (defaults to `console.error`); raw\n * token values are NEVER logged — only the redacted `tpi_xxxx` prefix\n * appears in error messages (T-05-06).\n */\nexport async function runServer(deps: RunDeps = defaultRunDeps): Promise<void> {\n let env: EnvConfig;\n try {\n env = deps.parseEnvImpl(process.env);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n deps.errLog(`[testplanit-mcp] env error: ${message}`);\n deps.exitImpl(1);\n return;\n }\n\n const probe = await deps.validateImpl(env);\n if (!probe.ok) {\n deps.errLog(\n `[testplanit-mcp] token validation failed (${redactToken(env.apiToken)}): ${probe.message}`\n );\n deps.exitImpl(1);\n return;\n }\n\n const server = deps.createServerImpl({ env, user: probe.user });\n await deps.connectImpl(server);\n deps.errLog(`[testplanit-mcp] connected as ${probe.user.email}`);\n}\n\n// Top-level entry guard: only fires when this module is the npm bin entry.\n// We resolve `process.argv[1]` through realpathSync because npm/npx install\n// the bin as a symlink (e.g. `.bin/testplanit-mcp-server` → `dist/cli.js`),\n// and node's `process.argv[1]` reports the shim path, not the symlink target.\n// A naive `endsWith(\"cli.js\")` check would silently exit 0 on `npx` invocation.\n// Vitest imports `runServer` directly so its argv[1] is the vitest runner —\n// the realpath check returns false there, so unit tests don't fire the bin.\nfunction isInvokedAsBin(): boolean {\n const argv1 = process.argv[1];\n if (!argv1) return false;\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const fs = require(\"node:fs\") as typeof import(\"node:fs\");\n return fs.realpathSync(argv1).endsWith(\"cli.js\");\n } catch {\n return false;\n }\n}\nif (isInvokedAsBin()) {\n runServer().catch((err) => {\n console.error(\"[testplanit-mcp] fatal:\", err);\n process.exit(1);\n });\n}\n"]}
|