opencode-gitlab-dap 1.12.1 → 1.13.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/README.md +13 -8
- package/dist/index.cjs +332 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +332 -87
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphql.ts","../src/mcp-servers.ts","../src/index.ts","../src/flow-execution.ts","../src/generated/foundational-flows.ts","../src/catalog-items.ts","../src/catalog-crud.ts","../src/catalog.ts","../src/auth.ts","../src/agents.ts","../src/prompts.ts","../src/hooks.ts","../src/tools/flow-tools.ts","../src/tools/catalog-crud-tools.ts","../src/flow-validator.ts","../vendor/schemas/flow_v2.json","../src/tools/catalog-item-tools.ts","../src/tools/mcp-tools.ts","../src/tools/memory-tools.ts","../src/wiki.ts","../src/tools/skill-tools.ts"],"sourcesContent":["export async function gql(\n instanceUrl: string,\n token: string,\n query: string,\n variables: Record<string, unknown>\n): Promise<any> {\n const res = await fetch(`${instanceUrl.replace(/\\/$/, \"\")}/api/graphql`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify({ query, variables }),\n });\n const json = (await res.json()) as any;\n if (json.errors?.length) throw new Error(json.errors[0].message);\n return json.data;\n}\n","import { gql } from \"./graphql\";\nimport type { CatalogAgent, McpServerInfo } from \"./types\";\n\nconst MCP_SERVERS_QUERY = `\nquery AiCatalogMcpServers($projectId: ProjectID!, $after: String) {\n aiCatalogConfiguredItems(first: 50, projectId: $projectId, itemTypes: [AGENT], after: $after) {\n pageInfo { hasNextPage endCursor }\n nodes {\n item {\n id\n name\n latestVersion {\n ... on AiCatalogAgentVersion {\n mcpServers {\n nodes { id name description url transport authType currentUserConnected }\n }\n }\n }\n }\n }\n }\n}`;\n\nexport async function fetchMcpServers(\n instanceUrl: string,\n token: string,\n projectId: string,\n agents: CatalogAgent[]\n): Promise<void> {\n try {\n let after: string | null = null;\n const serversByAgent = new Map<string, McpServerInfo[]>();\n\n for (;;) {\n const data = await gql(instanceUrl, token, MCP_SERVERS_QUERY, {\n projectId,\n ...(after ? { after } : {}),\n });\n const page = data?.aiCatalogConfiguredItems;\n if (!page) break;\n\n for (const node of page.nodes ?? []) {\n const item = node.item;\n const version = item?.latestVersion;\n if (!version?.mcpServers?.nodes?.length) continue;\n const servers: McpServerInfo[] = version.mcpServers.nodes.map((s: any) => ({\n id: s.id,\n name: s.name,\n description: s.description ?? \"\",\n url: s.url,\n transport: s.transport,\n authType: s.authType,\n currentUserConnected: !!s.currentUserConnected,\n }));\n serversByAgent.set(item.id, servers);\n }\n\n if (!page.pageInfo?.hasNextPage) break;\n after = page.pageInfo.endCursor;\n }\n\n for (const agent of agents) {\n const servers = serversByAgent.get(agent.identifier);\n if (servers?.length) agent.mcpServers = servers;\n }\n } catch {\n // MCP servers query not available — silently skip\n }\n}\n\nexport async function listMcpServerTools(\n server: McpServerInfo\n): Promise<Array<{ name: string; description: string }>> {\n try {\n const res = await fetch(server.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json, text/event-stream\",\n },\n body: JSON.stringify({ jsonrpc: \"2.0\", id: 1, method: \"tools/list\", params: {} }),\n });\n if (!res.ok) return [];\n const data = await res.json();\n const tools = data?.result?.tools;\n if (!Array.isArray(tools)) return [];\n return tools.map((t: any) => ({ name: t.name, description: t.description ?? \"\" }));\n } catch {\n return [];\n }\n}\n\nexport async function discoverMcpToolNames(agents: CatalogAgent[]): Promise<Map<string, string[]>> {\n const result = new Map<string, string[]>();\n const seen = new Set<string>();\n\n for (const agent of agents) {\n if (!agent.mcpServers?.length) continue;\n const agentToolNames: string[] = [];\n for (const server of agent.mcpServers) {\n if (seen.has(server.id)) {\n const key = server.name.toLowerCase().replace(/[^a-z0-9]+/g, \"_\");\n const cached = result.get(server.id);\n if (cached) agentToolNames.push(...cached.map((t) => `${key}_${t}`));\n continue;\n }\n seen.add(server.id);\n const tools = await listMcpServerTools(server);\n const toolNames = tools.map((t) => t.name);\n result.set(server.id, toolNames);\n const key = server.name.toLowerCase().replace(/[^a-z0-9]+/g, \"_\");\n agentToolNames.push(...toolNames.map((t) => `${key}_${t}`));\n }\n result.set(agent.identifier, agentToolNames);\n }\n return result;\n}\n","import type { Plugin } from \"@opencode-ai/plugin\";\nimport { GitLabModelCache } from \"gitlab-ai-provider\";\nimport { fetchCatalogAgents } from \"./catalog\";\nimport type { CatalogAgent } from \"./types\";\nimport { readAuth, type AuthInfo } from \"./auth\";\nimport { resolveModelId } from \"./agents\";\nimport {\n buildFlowSubagentPrompt,\n makeChatMessageHook,\n makeChatParamsHook,\n makeSystemTransformHook,\n} from \"./hooks\";\nimport { makeFlowTools } from \"./tools/flow-tools\";\nimport { makeCatalogCrudTools } from \"./tools/catalog-crud-tools\";\nimport { makeCatalogItemTools } from \"./tools/catalog-item-tools\";\nimport { makeMcpTools } from \"./tools/mcp-tools\";\nimport { makeMemoryTools } from \"./tools/memory-tools\";\nimport { makeSkillTools } from \"./tools/skill-tools\";\n\nconst memo = new Map<string, Awaited<ReturnType<typeof fetchCatalogAgents>>>();\n\nconst plugin: Plugin = async (input) => {\n let authCache: AuthInfo | null = null;\n let projectPath: string | undefined;\n let namespaceId: number | undefined;\n const flowAgents = new Map<string, CatalogAgent>();\n const gitlabAgentNames = new Set<string>();\n let cachedAgents: CatalogAgent[] = [];\n let cfgRef: any = null;\n let baseModelIdRef: string | undefined;\n\n function ensureAuth(): AuthInfo | null {\n if (!authCache) {\n const auth = readAuth();\n if (auth) authCache = auth;\n }\n return authCache;\n }\n\n async function load() {\n const auth = readAuth();\n if (!auth) return null;\n authCache = auth;\n\n const { token, instanceUrl } = auth;\n\n const cache = new GitLabModelCache(input.directory, instanceUrl);\n const entry = cache.load() as any;\n if (!entry?.discovery) return null;\n\n const projectId = entry.project?.id;\n if (!projectId) return null;\n projectPath = entry.project?.pathWithNamespace;\n namespaceId = entry.project?.namespaceId;\n\n const key = `${input.directory}\\0${instanceUrl}`;\n const cached = memo.get(key);\n const agents =\n cached ?? (await fetchCatalogAgents(instanceUrl, token, `gid://gitlab/Project/${projectId}`));\n if (!cached) memo.set(key, agents);\n\n return { agents, entry };\n }\n\n async function refreshAgents() {\n if (!authCache || !cfgRef) return;\n const key = `${input.directory}\\0${authCache.instanceUrl}`;\n memo.delete(key);\n const result = await load();\n if (!result) return;\n\n const previousNames = new Set([\n ...flowAgents.keys(),\n ...Object.keys(cfgRef.agent ?? {}).filter((n) => {\n const desc = cfgRef.agent[n]?.description ?? \"\";\n return desc.startsWith(\"[GitLab\");\n }),\n ]);\n\n flowAgents.clear();\n gitlabAgentNames.clear();\n const currentNames = new Set<string>();\n for (const agent of result.agents) {\n const isFlow = agent.itemType === \"FLOW\";\n const ico = agent.foundational ? \" \\u{1F98A}\" : \"\";\n const dName = `${agent.name}${ico}`;\n currentNames.add(dName);\n if (isFlow && agent.consumerId && projectPath) {\n flowAgents.set(dName, agent);\n const rBaseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n const rProjectUrl = `${rBaseUrl}/${projectPath}`;\n cfgRef.agent[dName] = {\n name: dName,\n description: `[GitLab Flow] ${agent.description}`,\n mode: \"subagent\",\n prompt: buildFlowSubagentPrompt(agent, projectPath, rProjectUrl),\n permission: { \"*\": \"allow\" },\n };\n } else {\n gitlabAgentNames.add(dName);\n cfgRef.agent[dName] = {\n name: dName,\n description: agent.foundational ? \"[GitLab Foundational Agent]\" : \"[GitLab Custom Agent]\",\n mode: \"primary\",\n model: `gitlab/${baseModelIdRef}`,\n options: {\n workflowDefinition: agent.workflowDefinition,\n flowConfig: agent.flowConfig,\n flowConfigSchemaVersion: agent.flowConfigSchemaVersion,\n aiCatalogItemVersionId: agent.catalogItemVersionId,\n },\n permission: { \"*\": \"allow\" },\n };\n }\n }\n\n for (const name of previousNames) {\n if (!currentNames.has(name)) {\n delete cfgRef.agent[name];\n }\n }\n }\n\n const ctx = {\n getAuth: () => authCache,\n ensureAuth,\n getFlowAgents: () => flowAgents,\n getCachedAgents: () => cachedAgents,\n getNamespaceId: () => namespaceId,\n refreshAgents,\n };\n\n return {\n async config(cfg: any) {\n const result = await load();\n if (!result?.agents.length) return;\n\n cachedAgents = result.agents;\n const baseModelId = resolveModelId(result.entry);\n cfg.agent ??= {};\n cfgRef = cfg;\n baseModelIdRef = baseModelId;\n const cfgBaseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n\n for (const agent of result.agents) {\n const isFlow = agent.itemType === \"FLOW\";\n const icon = agent.foundational ? \" \\u{1F98A}\" : \"\";\n\n if (isFlow && agent.consumerId && projectPath) {\n const displayName = `${agent.name}${icon}`;\n flowAgents.set(displayName, agent);\n const pUrl = `${cfgBaseUrl}/${projectPath}`;\n cfg.agent[displayName] = {\n name: displayName,\n description: `[GitLab Flow] ${agent.description}`,\n mode: \"subagent\",\n prompt: buildFlowSubagentPrompt(agent, projectPath, pUrl),\n permission: { \"*\": \"allow\" },\n };\n } else {\n const displayName = `${agent.name}${icon}`;\n gitlabAgentNames.add(displayName);\n cfg.agent[displayName] = {\n name: displayName,\n description: agent.foundational\n ? \"[GitLab Foundational Agent]\"\n : \"[GitLab Custom Agent]\",\n mode: \"primary\",\n model: `gitlab/${baseModelId}`,\n options: {\n workflowDefinition: agent.workflowDefinition,\n flowConfig: agent.flowConfig,\n flowConfigSchemaVersion: agent.flowConfigSchemaVersion,\n aiCatalogItemVersionId: agent.catalogItemVersionId,\n },\n permission: { \"*\": \"allow\" },\n };\n }\n }\n },\n\n \"chat.message\": makeChatMessageHook(\n () => authCache,\n flowAgents,\n () => projectPath\n ),\n \"chat.params\": makeChatParamsHook(gitlabAgentNames),\n \"experimental.chat.system.transform\": makeSystemTransformHook(flowAgents, () => authCache),\n\n tool: {\n ...makeFlowTools(ctx),\n ...makeMcpTools(() => cachedAgents),\n ...makeCatalogCrudTools(ctx),\n ...makeCatalogItemTools(ctx),\n ...makeMemoryTools(ctx),\n ...makeSkillTools(ctx),\n },\n };\n};\n\nexport default plugin;\n","import { load as yamlLoad } from \"js-yaml\";\nimport { gql } from \"./graphql\";\nimport { FOUNDATIONAL_FLOWS } from \"./generated/foundational-flows\";\nimport type { CatalogAgent, FlowInputDef } from \"./types\";\n\nexport function extractFlowInputs(flowConfig: Record<string, unknown> | undefined): FlowInputDef[] {\n if (!flowConfig) return [];\n const flow = flowConfig.flow as Record<string, unknown> | undefined;\n if (!flow?.inputs) return [];\n const inputs = flow.inputs as Array<Record<string, unknown>>;\n return inputs.map((inp) => ({\n category: inp.category as string,\n fields: Object.fromEntries(\n Object.entries((inp.input_schema ?? {}) as Record<string, any>).map(([k, v]) => [\n k,\n { type: v.type, description: v.description, format: v.format },\n ])\n ),\n }));\n}\n\nconst FOUNDATIONAL_QUERY = `\nquery AiFoundationalChatAgents($projectId: ProjectID!, $after: String) {\n aiFoundationalChatAgents(projectId: $projectId, first: 50, after: $after) {\n pageInfo { hasNextPage endCursor }\n nodes { id name description reference referenceWithVersion }\n }\n}`;\n\nconst CUSTOM_AGENTS_QUERY = `\nquery AiCatalogCustomAgents($projectId: ProjectID!, $after: String) {\n aiCatalogConfiguredItems(first: 50, projectId: $projectId, after: $after) {\n pageInfo { hasNextPage endCursor }\n nodes {\n id\n enabled\n item {\n id\n name\n description\n foundational\n foundationalFlowReference\n itemType\n latestVersion { id }\n }\n }\n }\n}`;\n\nconst FLOW_CONFIG_QUERY = `\nquery AiCatalogAgentFlowConfig($versionId: AiCatalogItemVersionID!) {\n aiCatalogAgentFlowConfig(agentVersionId: $versionId, flowConfigType: CHAT)\n}`;\n\nconst FLOW_VERSION_DEFINITION_QUERY = `\nquery FlowVersionDefinition($itemId: AiCatalogItemID!) {\n aiCatalogItem(id: $itemId) {\n latestVersion {\n ... on AiCatalogFlowVersion {\n definition\n }\n }\n }\n}`;\n\nconst RESOLVE_ROOT_NAMESPACE_QUERY = `\nquery resolveRootNamespace($projectPath: ID!) {\n project(fullPath: $projectPath) {\n id\n group {\n id\n rootNamespace { id }\n }\n }\n}`;\n\nconst WORKFLOW_STATUS_QUERY = `\nquery getWorkflowStatus($workflowId: AiDuoWorkflowsWorkflowID!) {\n duoWorkflowWorkflows(workflowId: $workflowId) {\n nodes {\n id\n status\n humanStatus\n createdAt\n updatedAt\n workflowDefinition\n lastExecutorLogsUrl\n latestCheckpoint {\n duoMessages {\n content\n correlationId\n role\n messageType\n status\n timestamp\n toolInfo\n }\n }\n }\n }\n}`;\n\nasync function fetchFoundationalChatAgents(\n instanceUrl: string,\n token: string,\n projectId: string\n): Promise<CatalogAgent[]> {\n const agents: CatalogAgent[] = [];\n let after: string | null = null;\n for (;;) {\n const data = await gql(instanceUrl, token, FOUNDATIONAL_QUERY, {\n projectId,\n ...(after ? { after } : {}),\n });\n const page = data?.aiFoundationalChatAgents;\n if (!page) break;\n for (const node of page.nodes ?? []) {\n if (!node.reference) continue;\n agents.push({\n identifier: node.reference,\n name: node.name,\n description: node.description ?? \"\",\n workflowDefinition: node.referenceWithVersion || node.reference,\n foundational: true,\n });\n }\n if (!page.pageInfo?.hasNextPage) break;\n after = page.pageInfo.endCursor;\n }\n return agents;\n}\n\nasync function fetchCustomAgents(\n instanceUrl: string,\n token: string,\n projectId: string\n): Promise<CatalogAgent[]> {\n const agents: CatalogAgent[] = [];\n const seen = new Set<string>();\n let after: string | null = null;\n\n for (;;) {\n const data = await gql(instanceUrl, token, CUSTOM_AGENTS_QUERY, {\n projectId,\n ...(after ? { after } : {}),\n });\n const page = data?.aiCatalogConfiguredItems;\n if (!page) break;\n\n for (const node of page.nodes ?? []) {\n if (!node.enabled) continue;\n const item = node.item;\n if (!item) continue;\n if (!item.latestVersion?.id) continue;\n const validTypes = [\"AGENT\", \"FLOW\"];\n if (!validTypes.includes(item.itemType)) continue;\n if (item.foundational && item.itemType === \"AGENT\") continue;\n if (seen.has(item.id)) continue;\n seen.add(item.id);\n\n const consumerNumericId = node.id\n ? parseInt(String(node.id).split(\"/\").pop() ?? \"\", 10) || undefined\n : undefined;\n\n try {\n const cfgData = await gql(instanceUrl, token, FLOW_CONFIG_QUERY, {\n versionId: item.latestVersion.id,\n });\n const yamlStr = cfgData?.aiCatalogAgentFlowConfig as string | null;\n const parsed = yamlStr ? (yamlLoad(yamlStr) as Record<string, unknown>) : undefined;\n agents.push({\n identifier: item.id,\n name: item.name,\n description: item.description ?? \"\",\n itemType: item.itemType,\n workflowDefinition: item.foundationalFlowReference ?? undefined,\n flowConfig: parsed,\n flowConfigSchemaVersion: parsed ? ((parsed?.version as string) ?? \"v1\") : undefined,\n foundational: !!item.foundational,\n catalogItemVersionId:\n parseInt(item.latestVersion.id.split(\"/\").pop() ?? \"\", 10) || undefined,\n consumerId: consumerNumericId,\n flowInputs: extractFlowInputs(parsed),\n });\n } catch {\n agents.push({\n identifier: item.id,\n name: item.name,\n description: item.description ?? \"\",\n itemType: item.itemType,\n workflowDefinition: item.foundationalFlowReference ?? undefined,\n foundational: !!item.foundational,\n catalogItemVersionId:\n parseInt(item.latestVersion.id.split(\"/\").pop() ?? \"\", 10) || undefined,\n consumerId: consumerNumericId,\n });\n }\n }\n\n if (!page.pageInfo?.hasNextPage) break;\n after = page.pageInfo.endCursor;\n }\n return agents;\n}\n\nexport async function fetchCatalogAgents(\n instanceUrl: string,\n token: string,\n projectId: string\n): Promise<CatalogAgent[]> {\n const { fetchMcpServers } = await import(\"./mcp-servers\");\n try {\n const [foundational, custom] = await Promise.all([\n fetchFoundationalChatAgents(instanceUrl, token, projectId),\n fetchCustomAgents(instanceUrl, token, projectId),\n ]);\n const agents = [...foundational, ...custom];\n await fetchMcpServers(instanceUrl, token, projectId, agents);\n return agents;\n } catch {\n return [];\n }\n}\n\nexport async function getFlowDefinition(\n instanceUrl: string,\n token: string,\n opts: {\n consumerId: number;\n flowName?: string;\n foundational?: boolean;\n catalogItemVersionId?: number;\n itemIdentifier?: string;\n workflowDefinition?: string;\n }\n): Promise<{ config: string | null; name: string; error?: string }> {\n const name = opts.flowName ?? `consumer-${opts.consumerId}`;\n let config: string | null = null;\n let apiError: string | undefined;\n\n if (opts.foundational && opts.workflowDefinition) {\n const flowKey = opts.workflowDefinition.split(\"/\")[0];\n config = FOUNDATIONAL_FLOWS[flowKey] ?? null;\n }\n\n if (!config && !opts.foundational && opts.itemIdentifier) {\n try {\n const data = await gql(instanceUrl, token, FLOW_VERSION_DEFINITION_QUERY, {\n itemId: opts.itemIdentifier,\n });\n config = (data?.aiCatalogItem?.latestVersion?.definition as string) ?? null;\n } catch (err: any) {\n apiError = err?.message ?? \"Unknown error fetching flow definition\";\n }\n }\n\n if (!config && !opts.foundational && opts.catalogItemVersionId) {\n const versionGid = `gid://gitlab/Ai::Catalog::ItemVersion/${opts.catalogItemVersionId}`;\n try {\n const cfgData = await gql(instanceUrl, token, FLOW_CONFIG_QUERY, { versionId: versionGid });\n config = (cfgData?.aiCatalogAgentFlowConfig as string) ?? null;\n } catch (err: any) {\n if (!apiError) apiError = err?.message ?? \"Unknown error fetching flow config\";\n }\n }\n\n return { config, name, ...(apiError && !config ? { error: apiError } : {}) };\n}\n\nasync function resolveRootNamespaceId(\n instanceUrl: string,\n token: string,\n projectPath: string\n): Promise<number | undefined> {\n try {\n const data = await gql(instanceUrl, token, RESOLVE_ROOT_NAMESPACE_QUERY, {\n projectPath,\n });\n const rootGid = data?.project?.group?.rootNamespace?.id as string | undefined;\n if (rootGid) {\n return parseInt(rootGid.split(\"/\").pop() ?? \"\", 10) || undefined;\n }\n } catch {\n // fall through\n }\n return undefined;\n}\n\nexport async function executeFlow(\n instanceUrl: string,\n token: string,\n projectPath: string,\n consumerId: number,\n goal: string,\n options?: {\n issueId?: number;\n mergeRequestId?: number;\n namespaceId?: number;\n flowInputs?: Array<{ Category: string; Content: string; Metadata?: string }>;\n }\n): Promise<Record<string, unknown>> {\n const projectUrl = `${instanceUrl.replace(/\\/$/, \"\")}/${projectPath}`;\n const additionalContext: Array<{ Category: string; Content: string; Metadata: string }> = [\n {\n Category: \"agent_user_environment\",\n Content: JSON.stringify({ project_url: projectUrl }),\n Metadata: \"{}\",\n },\n ];\n if (options?.flowInputs) {\n for (const input of options.flowInputs) {\n additionalContext.push({\n Category: input.Category,\n Content: input.Content,\n Metadata: input.Metadata ?? \"{}\",\n });\n }\n }\n const body: Record<string, unknown> = {\n project_id: projectPath,\n ai_catalog_item_consumer_id: consumerId,\n goal,\n start_workflow: true,\n environment: \"ambient\",\n agent_privileges: [1, 2, 3, 4, 5, 6],\n additional_context: additionalContext,\n };\n if (options?.namespaceId) body.namespace_id = options.namespaceId;\n if (options?.issueId) body.issue_id = options.issueId;\n if (options?.mergeRequestId) body.merge_request_id = options.mergeRequestId;\n\n const rootNsId = await resolveRootNamespaceId(instanceUrl, token, projectPath);\n if (rootNsId) body.root_namespace_id = rootNsId;\n\n const res = await fetch(`${instanceUrl.replace(/\\/$/, \"\")}/api/v4/ai/duo_workflows/workflows`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to execute flow (${res.status}): ${text}`);\n }\n return res.json() as Promise<Record<string, unknown>>;\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport async function getWorkflowStatus(\n instanceUrl: string,\n token: string,\n workflowId: number\n): Promise<Record<string, unknown>> {\n const gid = `gid://gitlab/Ai::DuoWorkflows::Workflow/${workflowId}`;\n const maxWait = 120_000;\n const pollInterval = 5_000;\n const start = Date.now();\n\n while (Date.now() - start < maxWait) {\n const data = await gql(instanceUrl, token, WORKFLOW_STATUS_QUERY, { workflowId: gid });\n const nodes = data?.duoWorkflowWorkflows?.nodes;\n if (!nodes?.length) throw new Error(`Workflow ${workflowId} not found`);\n const workflow = nodes[0];\n if ((workflow as any).status !== \"CREATED\") return workflow;\n await sleep(pollInterval);\n }\n\n const data = await gql(instanceUrl, token, WORKFLOW_STATUS_QUERY, { workflowId: gid });\n const nodes = data?.duoWorkflowWorkflows?.nodes;\n if (!nodes?.length) throw new Error(`Workflow ${workflowId} not found`);\n return nodes[0];\n}\n","/* eslint-disable */\n// AUTO-GENERATED — do not edit manually.\n// Run: npm run vendor:generate\n// Source: vendor/foundational-flows/ (12 files)\n\nexport const FOUNDATIONAL_FLOWS: Record<string, string> = {\n \"analytics_agent\": \"version: \\\"v1\\\"\\nenvironment: chat-partial\\ncomponents:\\n - name: \\\"analytics_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"analytics_agent_prompt\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"goal\\\"\\n toolset:\\n - \\\"get_current_user\\\"\\n - \\\"run_glql_query\\\"\\n - \\\"create_work_item_note\\\"\\n - \\\"create_merge_request_note\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters: []\\nflow:\\n entry_point: \\\"analytics_agent\\\"\\nprompts:\\n - name: \\\"analytics_agent_prompt\\\"\\n prompt_id: \\\"analytics_agent_prompt\\\"\\n model:\\n params:\\n max_tokens: 8_192\\n unit_primitives:\\n - duo_agent_platform\\n prompt_template:\\n system: |\\n <core_function>\\n You are a GitLab Analytics Expert who helps users understand their development data and answer analytical questions about their projects and teams. You use GLQL (GitLab Query Language) as a tool to retrieve and analyze data, but your primary focus is providing clear, actionable insights.\\n\\n **Input**: Analytical questions like \\\"How is my team performing this month?\\\" OR requests for GLQL queries/visualizations like \\\"Show me all currently open issues\\\"\\n\\n **Output**:\\n\\n - For analytical questions: Clear answers with insights, supported by collapsible GLQL queries\\n - For query/visualization requests: GLQL embedded view query (frontend will auto-render if applicable)\\n\\n 1. **Identify intent** - Is this an analytical question or a query/visualization request?\\n 2. **Determine scope** - Project, group, or cross-project analysis\\n 3. **Check for ambiguous concepts** - Does the question contain terms like \\\"team\\\", \\\"quarter\\\", \\\"bugs\\\" that need clarification?\\n 4. **Identify filters** - Time ranges, states, types, assignees, etc.\\n 5. **Generate insights or queries** - Based on user intent\\n </core_function>\\n\\n <user_intent>\\n **Analytical Questions** (answer-first approach): User wants insights and analysis of the data\\n\\n - \\\"How many MRs were merged this month?\\\"\\n - \\\"What's my team working on?\\\"\\n - \\\"What is the bug creation trend for the past month\\\"\\n - \\\"How is performance this quarter?\\\"\\n\\n **Query/Visualization Requests** (query-first approach): User wants to see the query or have data displayed\\n\\n - \\\"Show me...\\\" / \\\"Show all...\\\"\\n - \\\"Visualize...\\\" / \\\"Display...\\\"\\n - \\\"Create a list/table of...\\\"\\n - \\\"I want to see...\\\"\\n - \\\"List all...\\\" / \\\"Give me...\\\"\\n - \\\"Write a GLQL query for...\\\"\\n - \\\"How do I query...\\\"\\n - \\\"What's the GLQL syntax for...\\\"\\n </user_intent>\\n\\n <scope_clarification>\\n **When to Ask First**\\n\\n Ask for clarification when the question involves:\\n\\n - **Organization-specific concepts** where different interpretations produce drastically different results:\\n - \\\"Team\\\" → label (`~team-backend`) vs assignees (`@alice, @bob`) vs milestone?\\n - \\\"Quarter\\\" → calendar (Jan-Mar) vs fiscal year?\\n - \\\"Bugs\\\" → label (`~bug`) vs issue type vs custom field?\\n - \\\"Workload\\\" → open issues? MRs? both? by count or by weight/priority?\\n - **Vague analytical terms**: \\\"velocity\\\", \\\"performance\\\", \\\"productivity\\\"\\n - **Vague time/scope terms**: \\\"recently\\\", \\\"soon\\\", \\\"items\\\", \\\"things\\\"\\n - **Multiple ambiguities**: When a question combines several ambiguous terms, always ask for clarification\\n\\n **Clarification Format**: Keep it brief and offer 2-3 specific options to choose from.\\n\\n **When to Assume and Answer**\\n\\n For all other questions:\\n\\n - **Default to project-level scope** (most common, faster queries)\\n - **Use group-level** when context suggests broader scope\\n - **When users say \\\"me\\\", \\\"my\\\", \\\"mine\\\", or \\\"assigned to me\\\"**, always use `currentUser()` in the query (e.g., `assignee = currentUser()`). Do NOT ask for their username.\\n\\n When making assumptions, add a brief scope note to the answer.\\n </scope_clarification>\\n\\n <response_format>\\n **For Analytical Questions (Answer-First Approach)**\\n\\n **ALWAYS provide the analytical answer first, then supporting details.** Users expect immediate insights, not queries.\\n\\n Structure your response as:\\n\\n 1. **Direct Answer** - What the data shows (2-3 sentences with key insights)\\n 2. **Interpretation** (optional) - What this means for their workflow\\n 3. **Recommendations** (optional) - Suggested actions or follow-up questions\\n 4. **Supporting Query** - GLQL query in a collapsible section (ALWAYS LAST - see syntax below)\\n\\n **IMPORTANT**: Always include the collapsible GLQL query section, even when the query returns no results. Users need to see the query to verify it's correct, reuse it, or modify it for their needs.\\n\\n **Collapsible Section Syntax for GLQL Queries:**\\n\\n ```\\n <details>\\n <summary>See the underlying data and GLQL query</summary>\\n\\n \\\\`\\\\`\\\\`glql\\n type = MergeRequest and state = merged and merged > -1m\\n \\\\`\\\\`\\\\`\\n\\n 💡 *Click on the ⋮ menu to see or copy GLQL query*\\n\\n **Key Components:** Brief explanation of critical parts (1-2 sentences)\\n **Scope Note:** (if assumed) Brief note about scope assumptions\\n </details>\\n ```\\n\\n **Example Analytical Response:**\\n\\n Question: How many MRs were merged in the last month?\\n\\n Answer:\\n\\n Based on the data, 23 merge requests were merged in the last month, with most activity concentrated in the last two weeks. The team shows strong momentum with an average of 5-6 MRs merged per week.\\n\\n **Would you like me to:**\\n\\n - Break this down by team member?\\n - Compare with previous months?\\n - Show only specific types of MRs?\\n\\n ---\\n\\n <details>\\n <summary>See the underlying data and GLQL query</summary>\\n ```glql\\n display: table\\n fields: title, author, merged, targetBranch\\n title: \\\"MRs Merged This Month\\\"\\n limit: 20\\n sort: merged desc\\n query: type = MergeRequest and state = merged and merged > -1m and project = \\\"your-org/your-project\\\"\\n ```\\n\\n **Key Components:** Filters for merged MRs in the last month, sorted by merge date.\\n **Scope Note:** I assumed project-level scope. For group-wide analysis, replace with `group = \\\"your-org/your-group\\\"`.\\n\\n </details>\\n\\n **For Query/Visualization Requests (Validate-Then-Output Approach)**\\n\\n When users request queries, visualizations, or dashboards:\\n\\n 1. **First**: Execute the query using \\\"run_glql_query\\\" to validate it works\\n 2. **Then**: Output the validated GLQL query as a ```glql code block\\n\\n The frontend will render the results as an interactive widget. **Never output a GLQL code block without validating it first.**\\n\\n **Default limit**: Always include `limit: 20` in GLQL embedded views shown to the user. This keeps the rendered widget manageable. If the user explicitly requests a different limit, respect it (up to the maximum of 100).\\n\\n **Display type selection**:\\n - Use `display: table` for data with multiple fields (default)\\n - Use `display: list` for simple title-only lists\\n - Use `display: orderedList` when user requests a numbered or ranked list\\n\\n **Note**: GLQL displays data as tables, lists, or ordered lists - not charts. If a user requests a chart or graph, ask if they'd like a Mermaid diagram instead, which can visualize trends, distributions, or flows.\\n\\n **DO NOT render data as a markdown table or list** unless the user explicitly asks for \\\"markdown format\\\". The GLQL block provides an interactive, live-updating view that users can customize.\\n\\n **Correct** (always output a GLQL code block with the appropriate `display` type):\\n ```glql\\n display: list\\n fields: title, author\\n limit: 20\\n query: type = Issue and state = opened\\n ```\\n\\n\\n **Wrong** (don't render data as markdown table):\\n ```\\n | Title | Author | State |\\n |-------|--------|-------|\\n | Fix bug | @user | open |\\n ```\\n\\n **Also wrong** (don't render as markdown list):\\n ```\\n 1. Fix bug - @user\\n 2. Add feature - @admin\\n 3. Update docs - @user\\n ```\\n\\n Provide:\\n\\n 1. **GLQL Embedded View Query** - The complete query with display, fields, title, sort, and query parameters (use embedded view format by default unless simple query is specifically requested)\\n 2. **Tip** - Add: \\\"💡 _Click on the ⋮ menu to see or copy GLQL query_\\\"\\n 3. **Key Components** - Brief explanation of critical parts (1-2 sentences)\\n 4. **Scope Note** (if assumed) - Brief note about scope assumptions and alternatives\\n\\n **Example Query/Visualization Response:**\\n\\n Question: Show me all MRs merged in the last month in the project \\\"your-org/your-project\\\"\\n\\n Answer:\\n\\n ```glql\\n display: table\\n fields: title, author, merged, targetBranch\\n title: \\\"MRs Merged This Month\\\"\\n limit: 20\\n sort: merged desc\\n query: type = MergeRequest and state = merged and merged > -1m and project = \\\"your-org/your-project\\\"\\n ```\\n\\n 💡 _Click on the ⋮ menu to see or copy GLQL query_\\n\\n **Key Components:** Filters for merged MRs in the last month, sorted by merge date.\\n\\n **Scope Note:** To query across a group instead, replace `project = ...` with `group = \\\"your-org/your-group\\\"`.\\n </response_format>\\n\\n <ide_rendering>\\n **IDE Environment Handling**\\n\\n If the user's additional context includes local environment details (operating system, shell, working directory), the user is in an IDE that uses standard Markdown rendering and **cannot render GLQL embedded views** (```glql code blocks).\\n\\n **In IDE environments, adjust your response format:**\\n\\n - **For query requests**: Validate queries with `run_glql_query` and present the GLQL query in a plain ```yaml code block so the user can copy it.\\n - **For visualization requests**: Still validate queries with `run_glql_query`, but present the retrieved data in **standard Markdown** (tables, lists, or other appropriate formats) instead of a ```glql code block. Choose the format that best fits the data — tables for multi-field structured data, lists for simpler enumerations. Include the collapsible section with raw GLQL query in a plain ```yaml code block so the user can copy it.\\n - **For analytical questions**: Present insights the same way (answer-first), but use **standard Markdown** for any data. Include the raw GLQL query in a plain ```yaml code block in the collapsible section instead of a ```glql code block.\\n - **Always suggest GitLab for interactive views**: Add a note like: \\\"For a live, interactive view, paste this GLQL query into a GitLab issue, epic, or wiki page.\\\"\\n - **Do NOT include the \\\"💡 Click on the ⋮ menu\\\" tip** — this refers to the interactive GLQL widget which is not available in IDEs.\\n\\n **Example IDE response for a query/visualization request:**\\n\\n Based on the query results, here are the open issues:\\n\\n | Title | Author | Created |\\n |-------|--------|---------|\\n | Fix login bug | @alice | 2025-01-15 |\\n | Update docs | @bob | 2025-01-14 |\\n\\n <details>\\n <summary>GLQL query (paste into GitLab for an interactive view)</summary>\\n\\n ```yaml\\n display: table\\n fields: title, author, created\\n title: \\\"Open Issues\\\"\\n limit: 20\\n query: type = Issue and state = opened\\n ```\\n\\n </details>\\n\\n **When the user is NOT in an IDE** (no local environment context is present), use the standard GLQL ```glql code blocks as described in the response format section above.\\n </ide_rendering>\\n\\n <glql_syntax>\\n ## GLQL Syntax Reference\\n\\n ### Basic Query Structure\\n\\n ```\\n field operator value [and field operator value ...]\\n ```\\n\\n ### Essential Fields & Operators\\n\\n - **type**: `=`, `in` (Issue, Epic, MergeRequest, Task, Incident, etc.)\\n - **state**: `=` (opened, closed, merged for MRs)\\n - **assignee**: `=`, `!=`, `in` (@username, currentUser())\\n - **author**: `=`, `!=`, `in` (@username, currentUser())\\n - **created/updated/merged/closed**: `=`, `>`, `<`, `>=`, `<=` (dates: today(), -1w, 2024-01-01)\\n - **project**: `=` (\\\"namespace/project\\\")\\n - **group**: `=` (\\\"namespace/group\\\")\\n - **label**: `=`, `!=`, `in` (~labelname, ~\\\"label with spaces\\\")\\n - **milestone**: `=`, `!=`, `in` (%milestone, %\\\"milestone with spaces\\\")\\n - **id**: `=`, `in` (global ID for filtering - NOT the same as iid/MR number)\\n\\n #### Available operators\\n\\n - **Equality**: `=`, `!=`\\n - **List membership**: `in` (OR logic - matches ANY value in the list)\\n - **Comparison**: `>`, `<`, `>=`, `<=` (for dates)\\n\\n **Important**:\\n\\n - The `in` operator uses OR logic. For AND logic, use multiple conditions: `label = ~bug and label = ~security`\\n - There are NO text search, `contains`, `like`, or similar operators\\n - `currentUser()` is a valid value for `assignee` and `author` fields (e.g., `assignee = currentUser()`)\\n\\n ### Time Expressions (ALWAYS PREFER RELATIVE)\\n\\n - **Relative** (PREFERRED): `-1d`, `-1w`, `-1m`, `-1y` (past), `1d`, `1w` (future)\\n - **Absolute**: `2024-01-01`, `2024-12-31` (use only when specific dates required)\\n - **Functions**: `today()`\\n\\n **IMPORTANT**: Always use relative time expressions (`-1w`, `-1m`, etc.) for queries involving \\\"this week\\\", \\\"last month\\\", \\\"this quarter\\\", etc. Only use absolute dates when users specify exact dates.\\n\\n ### Sorting Options (RESTRICTED LIST ONLY)\\n\\n #### VALID SORT FIELDS\\n\\n - **Issues/Epics/Merge Requests**: closed, closedAt, created, createdAt, popularity, title, updated, updatedAt\\n - **Issues/Epics**: due, dueDate, health, healthStatus\\n - **Issues/Merge Requests**: milestone\\n - **Epics**: start, startDate\\n - **Issues**: weight\\n - **Merge Requests**: merged, mergedAt\\n\\n #### INVALID SORT FIELDS (DO NOT USE):\\n\\n - assignee, author, state, labels, type, project, group\\n\\n **CRITICAL**: Only use the exact sorting options from the VALID list above. Fields like `assignee`, `author`, `state`,\\n or `labels` are NOT valid sorting options and will cause query errors. If none of the valid sorting options are\\n applicable, omit the sort parameter entirely.\\n\\n ### Embedded View Syntax (for dashboards/reports)\\n\\n ```yaml\\n display: table|list|orderedList\\n fields: comma,separated,field,list\\n title: \\\"Custom Title\\\"\\n limit: 20\\n sort: field asc|desc\\n query: your GLQL query here\\n ```\\n\\n **LIMIT RESTRICTION**: The maximum allowed value for `limit` is 100. NEVER set a limit higher than 100. If a user explicitly requests more than 100 results, cap the limit at 100 and inform them: \\\"Note: I've set the limit to 100, which is the maximum allowed by GLQL.\\\"\\n\\n ### Advanced Features\\n\\n ### Custom Field Queries\\n\\n ```glql\\n customField(\\\"Field Name\\\") = \\\"Value\\\"\\n ```\\n\\n ### Label Extraction for Views\\n\\n ```glql\\n fields: title, labels(\\\"priority::*\\\"), labels(\\\"workflow::*\\\")\\n ```\\n\\n ### Complex Time Ranges\\n\\n ```glql\\n created > 2024-01-01 and created < 2024-02-01\\n ```\\n </glql_syntax>\\n\\n <query_execution>\\n **CRITICAL**: After generating ANY GLQL query (whether for analytical questions or GLQL query requests), you MUST execute it using the \\\"run_glql_query\\\" tool to validate the syntax and retrieve data.\\n\\n - If the query executes successfully, present the results in a human-readable format\\n - If the query fails with a syntax error, fix the query and execute again\\n - Never provide a GLQL query to the user without first validating it executes correctly\\n\\n This ensures all queries provided to users have valid syntax and will work when they use them.\\n </query_execution>\\n\\n <pagination>\\n **How Pagination Works**\\n\\n Pagination is handled via the `run_glql_query` tool's `after` parameter. The query itself never changes between pages.\\n\\n **Pagination Steps:**\\n 1. Call `run_glql_query` with your GLQL query\\n 2. Check the response for `pageInfo.hasNextPage` and `pageInfo.endCursor`\\n 3. If `hasNextPage` is true AND you need more data, call `run_glql_query` again with the SAME query but add `after: <endCursor>`\\n 4. Repeat until `hasNextPage` is false or you've reached the limit\\n\\n **CRITICAL**: You MUST call the tool multiple times to paginate. Each call returns one page of results.\\n\\n **When to Paginate (MUST fetch all pages)**\\n\\n Paginate when the question requires **complete data for an accurate answer**.\\n\\n **Important**: When fetching data internally via `run_glql_query` for analysis (rankings, aggregations, distributions), use the maximum page size (100) to minimize the number of API calls. The `limit: 20` default applies only to GLQL code blocks rendered for the user.\\n\\n - **Rankings/maximums**: \\\"Who contributed the most?\\\", \\\"Which labels are most common?\\\"\\n - **Distribution analysis**: \\\"Break down by author\\\", \\\"What's the distribution over time?\\\"\\n - **Aggregations**: Percentages, averages, comparisons across all data\\n - **Export requests**: \\\"Format as markdown table\\\", \\\"Export to CSV\\\"\\n\\n For these questions, if `hasNextPage` is true, you MUST continue fetching pages.\\n\\n **When NOT to Paginate (single page is enough)**\\n\\n - **Count-only**: Use `count` from response (\\\"How many bugs?\\\" → use the count, don't paginate)\\n - **Rendering a view**: The GLQL widget handles its own pagination\\n - **User-specified limit**: \\\"Show me the last 20 MRs\\\" → use `limit: 20`, single call\\n - **Sampling/overview**: First page provides sufficient insight\\n\\n **Pagination Limits**\\n\\n - **Stop after 10 pages maximum** and inform user if more exist\\n - **Show progress**: \\\"Retrieved 200 of 500 items...\\\"\\n - **Handle errors gracefully**: Provide partial results with explanation if pagination fails mid-way\\n </pagination>\\n\\n <performance>\\n If the GLQL API call times out, inform the user and suggest optimizations:\\n - Add time filters: `created > -3m`\\n - Limit scope: use `project` instead of `group` when possible\\n - Add specific filters: `label = ~specific-label`\\n - Reduce result set with `limit` parameter\\n </performance>\\n\\n <error_prevention>\\n - Always specify `type =` when querying specific object types\\n - Use proper label syntax with `~` prefix\\n - Use proper milestone syntax with `%` prefix\\n - Include quotes around names with spaces\\n - For partial GLQL snippets, do not add the `glql` language indicator to the code block. Only add it for full embedded views.\\n - NEVER use `iid` as a filter - it's display-only. Use `id` for filtering or broader filters with `iid` displayed\\n </error_prevention>\\n\\n <work_items>\\n When users ask to add the data on an issue, epic, work items or merge request, use the appropriate tool to post a note.\\n\\n **Tool selection**:\\n\\n - Use 'create_merge_request_note' for merge requests\\n - Use 'create_work_item_note' for work items (issues, epics and any other work items)\\n\\n **When to post**:\\n When the user explicitly requests: \\\"Add this query to the issue #123\\\", \\\"Post a summary in the epic\\\", \\\"Add the query to the work item\\\", \\\"\\\"Add it as a comment to this merge request\\\", \\\"Post this to ...\\\", \\\"Add this to ...\\\", \\\"Share this in ...\\\"\\n\\n **What to post:**\\n\\n - Unless already specified by the user, ALWAYS ask the user what to post. The user might want to share either the full answer (analysis + query), just a summary or just the GLQL query.\\n - Keep the comment focused and minimal\\n - Important: When including the GLQL query in the comment, use the embedded view format with a brief title field describing the query and setting `limit: 20`.\\n\\n **Example workflow:**\\n\\n - User: \\\"How many open issues are there in the gitlab-org group?\\\"\\n - You: Provide analysis with validated query\\n - User: \\\"Add this to issue #42\\\"\\n - You: \\\"What would you like me to comment? The full analysis, a summary or just the GLQL query?\\\"\\n - User: \\\"The full analysis\\\"\\n - You: Use `create_work_item_note` with the analysis provided above.\\n - You: \\\"The analysis has been posted to [#42](link-to-item)\\\"\\n\\n **Example of comment content:**\\n\\n There are **171 open issues** across the entire gitlab-org group.\\n\\n The issues are distributed across two main projects:\\n\\n - **gitlab-org/gitlab-shell**: Majority of the open issues\\n - **gitlab-org/gitlab-test**: Remaining open issues\\n\\n The oldest open issues date back to May 2025, with the most recent one created in August 2025.\\n\\n <details>\\n <summary>See the underlying data and GLQL query</summary>\\n\\n ```glql\\n display: table\\n fields: title, project, state, created\\n title: \\\"Open Issues in gitlab-org Group\\\"\\n sort: created desc\\n limit: 20\\n query: type = Issue and state = opened and group = \\\"gitlab-org\\\"\\n ```\\n\\n 💡 _Click on the ⋮ menu to see or copy GLQL query_\\n\\n **Note:** The GLQL query produces a live view, so the data you see now might not reflect what's been posted in the issue.\\n\\n </details>\\n </work_items>\\n\\n <feedback>\\n Provide a feedback link to https://gitlab.com/gitlab-org/gitlab/-/issues/574028 when:\\n - A GLQL query fails or returns unexpected results\\n - GLQL limitations prevent fulfilling the request (no text search, can't filter by iid, etc.)\\n - Suggesting a suboptimal workaround due to tool constraints\\n - Users ask about unsupported features\\n\\n Example: \\\"This isn't currently supported in GLQL. [Share feedback](https://gitlab.com/gitlab-org/gitlab/-/issues/574028) or describe your use case.\\\"\\n\\n **Don't include feedback links** for normal successful queries or when the issue is user error, not a tool limitation.\\n </feedback>\\n user: |\\n {{goal}}\\n placeholder: history\\n\",\n \"code_review\": \"version: \\\"v1\\\"\\nenvironment: ambient\\ncomponents:\\n # Step 1: Fetch complete MR context with full file contents for final review\\n - name: \\\"build_review_context\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"build_review_merge_request_context\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 2: Fetch lightweight MR diffs for prescan analysis\\n - name: \\\"fetch_mr_diffs\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"build_review_merge_request_context\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n - from: \\\"true\\\"\\n as: \\\"only_diffs\\\"\\n literal: true\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 3: Generate targeted directory tree exploration calls based on changed files\\n - name: \\\"explore_relevant_directories\\\"\\n type: OneOffComponent\\n prompt_id: \\\"explore_directories_for_prescan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:fetch_mr_diffs.tool_responses\\\"\\n as: \\\"mr_diffs\\\"\\n toolset:\\n - \\\"list_repository_tree\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 4: Batch read additional context files (tests, dependencies, custom instructions)\\n - name: \\\"prescan_codebase\\\"\\n type: OneOffComponent\\n prompt_id: \\\"code_review_prescan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n - from: \\\"context:fetch_mr_diffs.tool_responses\\\"\\n as: \\\"mr_context\\\"\\n - from: \\\"context:explore_relevant_directories.tool_responses\\\"\\n as: \\\"directory_trees\\\"\\n optional: True\\n toolset:\\n - \\\"get_repository_file\\\"\\n - \\\"read_file\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 5: Fetch lightweight MR metadata (file paths + custom instructions)\\n - name: \\\"fetch_mr_metadata\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"build_review_merge_request_context\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n - from: \\\"true\\\"\\n as: \\\"lightweight\\\"\\n literal: true\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 6: Transform prescan results into structured JSON for review consumption\\n - name: \\\"analyze_prescan_results\\\"\\n type: AgentComponent\\n prompt_id: \\\"analyze_prescan_codebase_results\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fetch_mr_metadata.tool_responses\\\"\\n as: \\\"mr_context\\\"\\n - from: \\\"context:prescan_codebase.tool_responses\\\"\\n as: \\\"prescan_tool_responses\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n # Step 7: Execute code review with complete context and publish results\\n - name: \\\"perform_code_review_and_publish\\\"\\n type: OneOffComponent\\n prompt_id: \\\"review_merge_request\\\"\\n prompt_version: \\\"^2.0.0\\\"\\n inputs:\\n - from: \\\"context:build_review_context.tool_responses\\\"\\n as: \\\"mr_data\\\"\\n - from: \\\"context:analyze_prescan_results.final_answer\\\"\\n as: \\\"codebase_context\\\"\\n - from: \\\"context:current_date\\\"\\n as: \\\"current_date\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n toolset:\\n - \\\"post_duo_code_review\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"build_review_context\\\"\\n to: \\\"fetch_mr_diffs\\\"\\n - from: \\\"fetch_mr_diffs\\\"\\n to: \\\"explore_relevant_directories\\\"\\n - from: \\\"explore_relevant_directories\\\"\\n to: \\\"prescan_codebase\\\"\\n - from: \\\"prescan_codebase\\\"\\n to: \\\"fetch_mr_metadata\\\"\\n - from: \\\"fetch_mr_metadata\\\"\\n to: \\\"analyze_prescan_results\\\"\\n - from: \\\"analyze_prescan_results\\\"\\n to: \\\"perform_code_review_and_publish\\\"\\n - from: \\\"perform_code_review_and_publish\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"build_review_context\\\"\\n\",\n \"convert_to_gl_ci\": \"name: \\\"Convert to GitLab CI\\\"\\ndescription: |\\n Converts Jenkins pipelines (Jenkinsfile) to GitLab CI/CD configuration files (.gitlab-ci.yml).\\n This flow reads a Jenkins configuration file, translates it to GitLab CI format with validation,\\n and creates a merge request with the converted configuration.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"load_jenkins_file\\\"\\n type: DeterministicStepComponent\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"file_path\\\"\\n tool_name: \\\"read_file\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"convert_to_gitlab_ci\\\"\\n type: AgentComponent\\n prompt_id: \\\"convert_to_gl_ci\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:load_jenkins_file.tool_responses\\\"\\n as: \\\"jenkins_file_content\\\"\\n toolset:\\n - \\\"create_file_with_contents\\\"\\n - \\\"read_file\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"Duo Agent: Convert to GitLab CI\\\"\\n as: \\\"naming_context\\\"\\n literal: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"git_commit\\\"\\n type: AgentComponent\\n prompt_id: \\\"commit_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"git_push\\\"\\n type: AgentComponent\\n prompt_id: \\\"convert_ci_push_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"target_branch_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"create_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"load_jenkins_file\\\"\\n to: \\\"convert_to_gitlab_ci\\\"\\n - from: \\\"convert_to_gitlab_ci\\\"\\n to: \\\"create_repository_branch\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"git_commit\\\"\\n - from: \\\"git_commit\\\"\\n to: \\\"git_push\\\"\\n - from: \\\"git_push\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"load_jenkins_file\\\"\\n inputs:\\n - category: agent_user_environment\\n input_schema:\\n source_branch:\\n type: string\\n description: Source branch of the Jenkins file\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"developer\": \"version: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"issue_parser\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"get_issue\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"url\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:issue_parser.tool_responses\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"draft_merge_request_creator\\\"\\n type: OneOffComponent\\n prompt_id: \\\"create_merge_request\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n tool_name: \\\"create_merge_request\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"issue_url\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:issue_parser.tool_responses\\\"\\n as: \\\"issue_details\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"source_branch_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"target_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"tool_listing_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"list_available_tools\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"large\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n - \\\"get_job_logs\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_pipeline_failing_jobs\\\"\\n - \\\"get_project\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"read_file\\\"\\n - \\\"create_file_with_contents\\\"\\n - \\\"edit_file\\\"\\n - \\\"find_files\\\"\\n - \\\"grep\\\"\\n - \\\"mkdir\\\"\\n - \\\"get_epic\\\"\\n - \\\"list_epics\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_dir\\\"\\n - \\\"list_epic_notes\\\"\\n - \\\"get_epic_note\\\"\\n - \\\"get_commit\\\"\\n - \\\"run_command\\\"\\n - name: \\\"planning_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"developer_planner\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:issue_parser.tool_responses\\\"\\n as: \\\"issue_details\\\"\\n - from: \\\"context:tool_listing_agent.final_answer\\\"\\n as: \\\"coding_agent_tools\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n - \\\"get_job_logs\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_project\\\"\\n - \\\"get_pipeline_failing_jobs\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"read_file\\\"\\n - \\\"find_files\\\"\\n - \\\"list_dir\\\"\\n - \\\"grep\\\"\\n - \\\"get_epic\\\"\\n - \\\"list_epics\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_epic_notes\\\"\\n - \\\"get_epic_note\\\"\\n - \\\"get_commit\\\"\\n - \\\"list_commits\\\"\\n - \\\"get_commit_comments\\\"\\n - \\\"get_commit_diff\\\"\\n - \\\"get_work_item\\\"\\n - \\\"list_work_items\\\"\\n - \\\"get_work_item_notes\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"add_plan_comment\\\"\\n type: OneOffComponent\\n prompt_id: \\\"developer_add_plan_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:planning_agent.final_answer\\\"\\n as: \\\"plan_text\\\"\\n - from: \\\"context:draft_merge_request_creator.tool_responses\\\"\\n as: \\\"merge_request_details\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"create_merge_request_note\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"programming_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"programming_agent\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:planning_agent.final_answer\\\"\\n as: \\\"planner_handover\\\"\\n - from: \\\"context:inputs.os_information\\\"\\n as: \\\"os_information\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n - \\\"get_job_logs\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_pipeline_failing_jobs\\\"\\n - \\\"get_project\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"read_file\\\"\\n - \\\"create_file_with_contents\\\"\\n - \\\"edit_file\\\"\\n - \\\"find_files\\\"\\n - \\\"grep\\\"\\n - \\\"mkdir\\\"\\n - \\\"get_epic\\\"\\n - \\\"list_epics\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_dir\\\"\\n - \\\"list_epic_notes\\\"\\n - \\\"get_epic_note\\\"\\n - \\\"get_commit\\\"\\n - \\\"run_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"git_actions\\\"\\n type: OneOffComponent\\n prompt_id: \\\"push_to_remote\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:programming_agent.final_answer\\\"\\n as: \\\"programming_agent_handover\\\"\\n - from: \\\"context:draft_merge_request_creator.tool_responses\\\"\\n as: \\\"merge_request_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.session_owner_id\\\"\\n as: \\\"assignee_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"issue_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"update_merge_request\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"issue_parser\\\"\\n to: \\\"create_repository_branch\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"draft_merge_request_creator\\\"\\n - from: \\\"draft_merge_request_creator\\\"\\n to: \\\"tool_listing_agent\\\"\\n - from: \\\"tool_listing_agent\\\"\\n to: \\\"planning_agent\\\"\\n - from: \\\"planning_agent\\\"\\n to: \\\"add_plan_comment\\\"\\n - from: \\\"add_plan_comment\\\"\\n to: \\\"programming_agent\\\"\\n - from: \\\"programming_agent\\\"\\n to: \\\"git_actions\\\"\\n - from: \\\"git_actions\\\"\\n condition:\\n input: \\\"context:git_actions.execution_result\\\"\\n routes:\\n \\\"success\\\": \\\"end\\\"\\n \\\"failed\\\": \\\"abort\\\"\\n\\nflow:\\n entry_point: \\\"issue_parser\\\"\\n inputs:\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"duo_permissions_assistant\": \"version: \\\"v1\\\"\\nenvironment: chat-partial\\ncomponents:\\n - name: \\\"duo_permissions_assistant\\\"\\n type: AgentComponent\\n prompt_id: \\\"duo_permissions_assistant_prompt\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"goal\\\"\\n toolset:\\n - \\\"gitlab_graphql\\\"\\n - \\\"update_form_permissions\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\nrouters: []\\nflow:\\n entry_point: \\\"duo_permissions_assistant\\\"\\nprompts:\\n - name: \\\"duo_permissions_assistant_prompt\\\"\\n prompt_id: \\\"duo_permissions_assistant_prompt\\\"\\n model:\\n params:\\n max_tokens: 8192\\n unit_primitives:\\n - duo_agent_platform\\n prompt_template:\\n system: |\\n You are a GitLab fine-grained access token permissions assistant.\\n You help users pick the right permissions for their access tokens.\\n\\n STEP 1 — FETCH PERMISSIONS:\\n On the first message, call the gitlab_graphql tool with this query to get all available permissions:\\n query GetAccessTokenPermissions { accessTokenPermissions { name description } }\\n\\n STEP 2 — SUGGEST PERMISSIONS:\\n Using ONLY permission names returned by the tool:\\n - Always suggest specific permissions immediately based on what the user describes. Do not ask clarifying questions about scope, projects, groups, or access level — you cannot act on that information.\\n - Apply the principle of least privilege.\\n - Do not suggest legacy scopes (api, read_api, write_repository, etc.) or anything not in the tool results.\\n - If nothing matches, say: \\\"No matching permissions are available.\\\"\\n - IMPORTANT: Each user message is a standalone request. Do NOT use prior conversation turns to infer what is currently selected — the user may have changed the form manually between messages. Only act on what the user explicitly asks for right now.\\n - If the user's request is vague, make your best guess and explain your reasoning. The user can refine afterward.\\n\\n STEP 3 — APPLY CHANGES:\\n After explaining your reasoning, call the update_form_permissions tool to apply the changes.\\n Only include \\\"select\\\" and/or \\\"clear\\\" as needed.\\n user: |\\n {{goal}}\\n placeholder: history\\n\",\n \"fix_pipeline\": \"name: \\\"Fix pipeline\\\"\\ndescription: |\\n Fix pipeline flow can be run for a failed CI jobs.\\n It opens a new MR with changes that address root cause of CI job failures.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"fix_pipeline_context\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_context\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - get_downstream_pipelines\\n - get_pipeline_failing_jobs\\n - get_job_logs\\n - list_merge_request_diffs\\n - read_file\\n - find_files\\n - list_dir\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_decide_approach\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_decide_approach\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n response_schema_id: \\\"fix_pipeline_decide_approach\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n response_schema_tracking: true\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_add_comment\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_add_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: [\\\"create_merge_request_note\\\"]\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_create_plan\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_create_plan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_execution\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_execution\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:fix_pipeline_create_plan.final_answer\\\"\\n as: \\\"fix_pipeline_plan\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.os_information\\\"\\n as: \\\"os_information\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - create_file_with_contents\\n - edit_file\\n - find_files\\n - mkdir\\n - read_file\\n - run_command\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_commit\\\"\\n type: AgentComponent\\n prompt_id: \\\"commit_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_push\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_push_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"target_branch_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"default_branch\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"create_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_summarize\\\"\\n type: OneOffComponent\\n prompt_id: \\\"fix_pipeline_summarize_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:fix_pipeline_execution.final_answer\\\"\\n as: \\\"execution_results\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.session_owner_id\\\"\\n as: \\\"assignee_id\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"update_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_decide_comment\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_decide_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n response_schema_id: \\\"fix_pipeline_decide_comment\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_comment_link\\\"\\n type: OneOffComponent\\n prompt_id: \\\"fix_pipeline_comment_link\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n max_correction_attempts: 3\\n inputs:\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: [\\\"create_merge_request_note\\\"]\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"fix_pipeline_context\\\"\\n to: \\\"fix_pipeline_decide_approach\\\"\\n - from: \\\"fix_pipeline_decide_approach\\\"\\n condition:\\n input: \\\"context:fix_pipeline_decide_approach.final_answer.decision\\\"\\n routes:\\n \\\"add_comment\\\": \\\"fix_pipeline_add_comment\\\"\\n \\\"create_fix\\\": \\\"create_repository_branch\\\"\\n \\\"default_route\\\": \\\"fix_pipeline_add_comment\\\"\\n - from: \\\"fix_pipeline_add_comment\\\"\\n to: \\\"end\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"fix_pipeline_create_plan\\\"\\n - from: \\\"fix_pipeline_create_plan\\\"\\n to: \\\"fix_pipeline_execution\\\"\\n - from: \\\"fix_pipeline_execution\\\"\\n to: \\\"fix_pipeline_git_commit\\\"\\n - from: \\\"fix_pipeline_git_commit\\\"\\n to: \\\"fix_pipeline_git_push\\\"\\n - from: \\\"fix_pipeline_git_push\\\"\\n to: \\\"fix_pipeline_summarize\\\"\\n - from: \\\"fix_pipeline_summarize\\\"\\n to: \\\"fix_pipeline_decide_comment\\\"\\n - from: \\\"fix_pipeline_decide_comment\\\"\\n condition:\\n input: \\\"context:fix_pipeline_decide_comment.final_answer.decision\\\"\\n routes:\\n \\\"comment_link\\\": \\\"fix_pipeline_comment_link\\\"\\n \\\"end\\\": \\\"end\\\"\\n \\\"default_route\\\": \\\"end\\\"\\n - from: \\\"fix_pipeline_comment_link\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"fix_pipeline_context\\\"\\n inputs:\\n - category: merge_request\\n input_schema:\\n url:\\n type: string\\n format: uri\\n description: The URL for the GitLab Merge Request\\n - category: pipeline\\n input_schema:\\n source_branch:\\n type: string\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"fix_pipeline_next\": \"name: \\\"Fix pipeline (next)\\\"\\ndescription: |\\n Fix pipeline flow can be run for a failed CI jobs.\\n When a merge request URL is provided, it pushes the fix directly to that MR's branch.\\n Otherwise it opens a new MR with changes that address root cause of CI job failures.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"fix_pipeline_context\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_context\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - get_downstream_pipelines\\n - get_pipeline_failing_jobs\\n - get_job_logs\\n - list_merge_request_diffs\\n - read_file\\n - find_files\\n - list_dir\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_decide_approach\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_decide_approach\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n response_schema_id: \\\"fix_pipeline_next_decide_approach\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n response_schema_tracking: true\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n optional: True\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_add_comment\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_add_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: [\\\"create_merge_request_note\\\"]\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_create_plan\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_create_plan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_execution\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_execution\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:fix_pipeline_create_plan.final_answer\\\"\\n as: \\\"fix_pipeline_plan\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.os_information\\\"\\n as: \\\"os_information\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - create_file_with_contents\\n - edit_file\\n - find_files\\n - mkdir\\n - read_file\\n - run_command\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_commit\\\"\\n type: AgentComponent\\n prompt_id: \\\"commit_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_push\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_push_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_create_new_mr\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_create_new_mr\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"default_branch\\\"\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:fix_pipeline_execution.final_answer\\\"\\n as: \\\"execution_results\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.session_owner_id\\\"\\n as: \\\"assignee_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"create_merge_request\\\"\\n - \\\"update_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_comment_existing_mr\\\"\\n type: OneOffComponent\\n prompt_id: \\\"fix_pipeline_next_comment_existing_mr\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:fix_pipeline_execution.final_answer\\\"\\n as: \\\"execution_results\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"create_merge_request_note\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"fix_pipeline_context\\\"\\n to: \\\"fix_pipeline_next_decide_approach\\\"\\n - from: \\\"fix_pipeline_next_decide_approach\\\"\\n condition:\\n input: \\\"context:fix_pipeline_next_decide_approach.final_answer.decision\\\"\\n routes:\\n \\\"add_comment\\\": \\\"fix_pipeline_add_comment\\\"\\n \\\"create_fix_on_new_mr\\\": \\\"create_repository_branch\\\"\\n \\\"create_fix_on_existing_mr\\\": \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n \\\"default_route\\\": \\\"fix_pipeline_add_comment\\\"\\n - from: \\\"fix_pipeline_add_comment\\\"\\n to: \\\"end\\\"\\n - from: \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n to: \\\"fix_pipeline_create_plan\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"fix_pipeline_create_plan\\\"\\n - from: \\\"fix_pipeline_create_plan\\\"\\n to: \\\"fix_pipeline_execution\\\"\\n - from: \\\"fix_pipeline_execution\\\"\\n to: \\\"fix_pipeline_git_commit\\\"\\n - from: \\\"fix_pipeline_git_commit\\\"\\n to: \\\"fix_pipeline_git_push\\\"\\n - from: \\\"fix_pipeline_git_push\\\"\\n condition:\\n input: \\\"context:fix_pipeline_next_decide_approach.final_answer.decision\\\"\\n routes:\\n \\\"create_fix_on_existing_mr\\\": \\\"fix_pipeline_next_comment_existing_mr\\\"\\n \\\"create_fix_on_new_mr\\\": \\\"fix_pipeline_next_create_new_mr\\\"\\n \\\"default_route\\\": \\\"fix_pipeline_next_create_new_mr\\\"\\n - from: \\\"fix_pipeline_next_comment_existing_mr\\\"\\n to: \\\"end\\\"\\n - from: \\\"fix_pipeline_next_create_new_mr\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"fix_pipeline_context\\\"\\n inputs:\\n - category: merge_request\\n input_schema:\\n url:\\n type: string\\n format: uri\\n description: The URL for the GitLab Merge Request\\n - category: pipeline\\n input_schema:\\n source_branch:\\n type: string\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"project_activity\": \"name: \\\"Project Activity\\\"\\ndescription: |\\n Summarize the issue and MR activity in a project for a given timeframe.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"fetch_new_issues\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_issues_new\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_closed_issues\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_issues_closed\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_updated_issues\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_issues_updated\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_new_merge_requests\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_merge_requests_new\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_closed_merge_requests\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_merge_requests_closed\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_updated_merge_requests\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_merge_requests_updated\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"summarize_activity\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_summarize_project_activity\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset: []\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n - from: \\\"context:fetch_new_issues.final_answer\\\"\\n as: \\\"new_issues_data\\\"\\n - from: \\\"context:fetch_closed_issues.final_answer\\\"\\n as: \\\"closed_issues_data\\\"\\n - from: \\\"context:fetch_updated_issues.final_answer\\\"\\n as: \\\"updated_issues_data\\\"\\n - from: \\\"context:fetch_new_merge_requests.final_answer\\\"\\n as: \\\"new_merge_requests_data\\\"\\n - from: \\\"context:fetch_closed_merge_requests.final_answer\\\"\\n as: \\\"closed_merge_requests_data\\\"\\n - from: \\\"context:fetch_updated_merge_requests.final_answer\\\"\\n as: \\\"updated_merge_requests_data\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"create_summary_issue\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_create_summary_issue\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"create_issue\\\"\\n - \\\"gitlab_api_post\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n - from: \\\"context:summarize_activity.final_answer\\\"\\n as: \\\"summary\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n\\nrouters:\\n - from: \\\"fetch_new_issues\\\"\\n to: \\\"fetch_closed_issues\\\"\\n - from: \\\"fetch_closed_issues\\\"\\n to: \\\"fetch_updated_issues\\\"\\n - from: \\\"fetch_updated_issues\\\"\\n to: \\\"fetch_new_merge_requests\\\"\\n - from: \\\"fetch_new_merge_requests\\\"\\n to: \\\"fetch_closed_merge_requests\\\"\\n - from: \\\"fetch_closed_merge_requests\\\"\\n to: \\\"fetch_updated_merge_requests\\\"\\n - from: \\\"fetch_updated_merge_requests\\\"\\n to: \\\"summarize_activity\\\"\\n - from: \\\"summarize_activity\\\"\\n to: \\\"create_summary_issue\\\"\\n - from: \\\"create_summary_issue\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"fetch_new_issues\\\"\\n inputs: []\\n\",\n \"resolve_sast_vulnerability\": \"version: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"gather_context\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"get_vulnerability_details\\\"\\n inputs:\\n - { from: \\\"context:goal\\\", as: \\\"vulnerability_id\\\" }\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"evaluate_vuln_fp_status\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"evaluate_vuln_fp_status\\\"\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_json\\\"\\n toolset:\\n - \\\"evaluate_vuln_fp_status\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"ensure_clean_git_state\\\"\\n type: AgentComponent\\n prompt_id: \\\"ensure_clean_git_state\\\"\\n prompt_version: \\\"1.0.0\\\"\\n response_schema_id: \\\"ensure_clean_git_state\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:project_default_branch\\\"\\n as: \\\"default_branch\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_default_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"execute_fix\\\"\\n type: AgentComponent\\n prompt_id: \\\"resolve_sast_vulnerability_execution\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_context\\\"\\n toolset:\\n - \\\"edit_file\\\"\\n - \\\"create_file_with_contents\\\"\\n - \\\"read_file\\\"\\n - \\\"read_files\\\"\\n - \\\"grep\\\"\\n - \\\"find_files\\\"\\n - \\\"list_dir\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"validate_fix_has_changes\\\"\\n type: AgentComponent\\n prompt_id: \\\"validate_sast_fix_has_changes\\\"\\n prompt_version: \\\"1.0.0\\\"\\n response_schema_id: \\\"validate_sast_fix_has_changes\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:execute_fix.final_answer\\\"\\n as: \\\"fix_execution_result\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"commit_changes\\\"\\n type: OneOffComponent\\n prompt_id: \\\"resolve_sast_vulnerability_commit\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n max_correction_attempts: 3\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_context\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"push_and_create_mr\\\"\\n type: OneOffComponent\\n prompt_id: \\\"resolve_sast_vulnerability_push_and_create_mr\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n max_correction_attempts: 3\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_details\\\"\\n - from: \\\"context:execute_fix.final_answer\\\"\\n as: \\\"fix_summary\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_default_branch\\\"\\n as: \\\"default_branch\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"source_branch_name\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"create_merge_request\\\"\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"link_vulnerability\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"link_vulnerability_to_merge_request\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"vulnerability_id\\\"\\n - from: \\\"context:push_and_create_mr.parsed_responses.created_merge_request.id\\\"\\n as: \\\"merge_request_id\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"evaluate_merge_request\\\"\\n type: AgentComponent\\n prompt_id: \\\"resolve_sast_evaluate_mr_readiness\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_context\\\"\\n - from: \\\"context:execute_fix.final_answer\\\"\\n as: \\\"fix_execution_result\\\"\\n - from: \\\"context:push_and_create_mr.tool_responses\\\"\\n as: \\\"git_operations_result\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n toolset:\\n - \\\"get_merge_request\\\"\\n - \\\"list_merge_request_diffs\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n\\nrouters:\\n - from: \\\"gather_context\\\"\\n to: \\\"evaluate_vuln_fp_status\\\"\\n - from: \\\"evaluate_vuln_fp_status\\\"\\n condition:\\n input: \\\"context:evaluate_vuln_fp_status.tool_responses\\\"\\n routes:\\n \\\"skip_false_positive\\\": \\\"end\\\"\\n \\\"proceed_with_fix\\\": \\\"ensure_clean_git_state\\\"\\n default_route: \\\"ensure_clean_git_state\\\"\\n - from: \\\"ensure_clean_git_state\\\"\\n to: \\\"create_repository_branch\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"execute_fix\\\"\\n - from: \\\"execute_fix\\\"\\n to: \\\"validate_fix_has_changes\\\"\\n - from: \\\"validate_fix_has_changes\\\"\\n condition:\\n input: \\\"context:validate_fix_has_changes.final_answer.decision\\\"\\n routes:\\n \\\"proceed\\\": \\\"commit_changes\\\"\\n \\\"no_changes\\\": \\\"end\\\"\\n default_route: \\\"end\\\"\\n - from: \\\"commit_changes\\\"\\n to: \\\"push_and_create_mr\\\"\\n - from: \\\"push_and_create_mr\\\"\\n to: \\\"evaluate_merge_request\\\"\\n - from: \\\"evaluate_merge_request\\\"\\n to: \\\"link_vulnerability\\\"\\n - from: \\\"link_vulnerability\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"gather_context\\\"\\n\",\n \"sast_fp_detection\": \"version: v1\\nenvironment: ambient\\ncomponents:\\n - name: \\\"sast_vulnerability_details_component\\\"\\n type: DeterministicStepComponent\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: vulnerability_id\\n tool_name: \\\"get_vulnerability_details\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"validate_sast_vulnerability_component\\\"\\n type: AgentComponent\\n prompt_id: \\\"validate_sast_vulnerability_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n response_schema_id: \\\"validate_sast_vulnerability\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n toolset: []\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"sast_vulnerability_source_file_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"sast_vulnerability_source_file_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n toolset:\\n - \\\"get_repository_file\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_vulnerability_lines_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"sast_vulnerability_lines_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:sast_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset:\\n - \\\"extract_lines_from_text\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_vulnerability_report_component\\\"\\n type: AgentComponent\\n prompt_id: \\\"sast_vulnerability_report_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:sast_vulnerability_lines_component.tool_responses\\\"\\n as: vulnerable_lines\\n - from: \\\"context:sast_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset: []\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_fp_detection_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"sast_fp_detection_agent_prompt\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_report_component.final_answer\\\"\\n as: vulnerability_details\\n toolset:\\n - \\\"read_file\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_repository_tree\\\"\\n - \\\"find_files\\\"\\n - \\\"gitlab_blob_search\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_post_results_to_gitlab_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"sast_post_results_to_gitlab_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:sast_fp_detection_agent.final_answer\\\"\\n as: sast_fp_detection_analysis\\n toolset:\\n - \\\"post_sast_fp_analysis_to_gitlab\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters:\\n - from: \\\"sast_vulnerability_details_component\\\"\\n to: \\\"validate_sast_vulnerability_component\\\"\\n - from: \\\"validate_sast_vulnerability_component\\\"\\n condition:\\n input: \\\"context:validate_sast_vulnerability_component.final_answer.decision\\\"\\n routes:\\n \\\"valid\\\": \\\"sast_vulnerability_source_file_component\\\"\\n \\\"invalid\\\": \\\"end\\\"\\n - from: \\\"sast_vulnerability_source_file_component\\\"\\n to: \\\"sast_vulnerability_lines_component\\\"\\n - from: \\\"sast_vulnerability_lines_component\\\"\\n to: \\\"sast_vulnerability_report_component\\\"\\n - from: \\\"sast_vulnerability_report_component\\\"\\n to: \\\"sast_fp_detection_agent\\\"\\n - from: \\\"sast_fp_detection_agent\\\"\\n to: \\\"sast_post_results_to_gitlab_component\\\"\\n - from: \\\"sast_post_results_to_gitlab_component\\\"\\n to: \\\"end\\\"\\nflow:\\n entry_point: \\\"sast_vulnerability_details_component\\\"\\n\",\n \"secrets_fp_detection\": \"version: \\\"v1\\\"\\nenvironment: ambient\\ncomponents:\\n - name: \\\"secret_vulnerability_details_component\\\"\\n type: DeterministicStepComponent\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: vulnerability_id\\n tool_name: \\\"get_vulnerability_details\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_vulnerability_source_file_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"secret_vulnerability_source_file_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n toolset:\\n - \\\"get_repository_file\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_vulnerability_lines_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"secret_vulnerability_lines_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:secret_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset:\\n - \\\"extract_lines_from_text\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_vulnerability_report_component\\\"\\n type: AgentComponent\\n prompt_id: \\\"secret_vulnerability_report_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:secret_vulnerability_lines_component.tool_responses\\\"\\n as: vulnerable_lines\\n - from: \\\"context:secret_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset: []\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_fp_detection_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"secret_fp_detection_agent_prompt\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_report_component.final_answer\\\"\\n as: vulnerability_details\\n toolset:\\n - \\\"read_file\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_repository_tree\\\"\\n - \\\"find_files\\\"\\n - \\\"gitlab_blob_search\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_post_results_to_gitlab_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"secret_post_results_to_gitlab_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:secret_fp_detection_agent.final_answer\\\"\\n as: secret_fp_detection_analysis\\n toolset:\\n - \\\"post_secret_fp_analysis_to_gitlab\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters:\\n - from: \\\"secret_vulnerability_details_component\\\"\\n to: \\\"secret_vulnerability_source_file_component\\\"\\n - from: \\\"secret_vulnerability_source_file_component\\\"\\n to: \\\"secret_vulnerability_lines_component\\\"\\n - from: \\\"secret_vulnerability_lines_component\\\"\\n to: \\\"secret_vulnerability_report_component\\\"\\n - from: \\\"secret_vulnerability_report_component\\\"\\n to: \\\"secret_fp_detection_agent\\\"\\n - from: \\\"secret_fp_detection_agent\\\"\\n to: \\\"secret_post_results_to_gitlab_component\\\"\\n - from: \\\"secret_post_results_to_gitlab_component\\\"\\n to: \\\"end\\\"\\nflow:\\n entry_point: \\\"secret_vulnerability_details_component\\\"\\n\",\n \"slack_assistant\": \"version: \\\"v1\\\"\\nenvironment: chat\\ncomponents:\\n - name: \\\"slack_assistant\\\"\\n type: AgentComponent\\n prompt_id: \\\"slack_assistant_prompt\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"goal\\\"\\n toolset:\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_graphql\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_wiki_page\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"gitlab_documentation_search\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters:\\n - from: \\\"slack_assistant\\\"\\n to: \\\"end\\\"\\nflow:\\n entry_point: \\\"slack_assistant\\\"\\nprompts:\\n - name: \\\"slack_assistant_prompt\\\"\\n prompt_id: \\\"slack_assistant_prompt\\\"\\n unit_primitives:\\n - duo_agent_platform\\n prompt_template:\\n system: |\\n You are a helpful GitLab assistant that people talk to in Slack.\\n\\n You receive the Slack thread as context (in <slack-thread-context> tags) and a user_context with the invoking user's identity and their group memberships. Use the groups to broaden your searches — search across multiple groups, not just the default namespace. When scoped searches return no results, always fall back to instance-wide search using `GET /api/v4/search?scope=issues&search=...` or `GET /api/v4/projects?search=...&search_namespaces=true`.\\n\\n Keep Slack responses short. Use bullet points and link to GitLab so people can click through. Format your responses using Slack mrkdwn syntax:\\n - *bold* for emphasis\\n - _italic_ for secondary emphasis\\n - `code` for inline code or commands\\n - ```multi-line code``` for code blocks\\n - <url|link text> for URLs (e.g., <https://gitlab.com/my-issue|View issue>)\\n - <#channel_id> to link channels\\n - <@user_id> to mention users\\n - <!subteam^group_id> to mention groups\\n - @here, @channel, @everyone for special mentions\\n - ~strikethrough~ to strikethrough text\\n - > quote for block quotes\\n - - item for bullet points\\n - \\\\n for line breaks\\n\\n You are currently *read-only* and act on behalf of the person who mentioned you. You can search and retrieve GitLab data (issues, projects, merge requests, users, etc.) but you cannot create, update, or delete anything. If someone asks you to create an issue or make changes, let them know this capability is not available yet and suggest they do it in GitLab directly.\\n\\n When a specific tool exists for the task (e.g. `get_issue`, `get_merge_request`, `get_wiki_page`, `get_repository_file`), prefer it over `gitlab_api_get` — it handles URL parsing and compound operations automatically. Use `gitlab_api_get` and `gitlab_graphql` as fallbacks for resources not covered by a specific tool.\\n\\n The GitLab API accepts URL-encoded project paths (like `gitlab-org%2Fgitlab`) wherever it accepts numeric project IDs. Use this when people reference projects by path.\\n user: |\\n {{goal}}\\n placeholder: history\\n\",\n};\n","import { gql } from \"./graphql\";\n\nconst LIST_AI_CATALOG_ITEMS_QUERY = `\nquery listAiCatalogItems(\n $itemTypes: [AiCatalogItemType!]\n $search: String\n $first: Int\n $after: String\n) {\n aiCatalogItems(\n itemTypes: $itemTypes\n search: $search\n first: $first\n after: $after\n ) {\n nodes {\n id\n name\n description\n itemType\n foundational\n public\n createdAt\n updatedAt\n softDeleted\n project { id, nameWithNamespace }\n latestVersion {\n id\n createdAt\n updatedAt\n createdBy { id, name, username }\n }\n }\n pageInfo { hasNextPage, hasPreviousPage, startCursor, endCursor }\n }\n}`;\n\nconst GET_AI_CATALOG_ITEM_QUERY = `\nquery getAiCatalogItem($id: AiCatalogItemID!) {\n aiCatalogItem(id: $id) {\n id\n name\n description\n itemType\n foundational\n public\n createdAt\n updatedAt\n softDeleted\n project { id, nameWithNamespace }\n latestVersion {\n id\n createdAt\n updatedAt\n createdBy { id, name, username, webUrl }\n }\n userPermissions { adminAiCatalogItem, reportAiCatalogItem }\n }\n}`;\n\nconst LIST_PROJECT_CONFIGURED_ITEMS_QUERY = `\nquery listProjectConfiguredItems(\n $projectId: ProjectID!\n $itemTypes: [AiCatalogItemType!]\n $includeFoundationalConsumers: Boolean\n $first: Int\n $after: String\n) {\n aiCatalogConfiguredItems(\n projectId: $projectId\n itemTypes: $itemTypes\n includeFoundationalConsumers: $includeFoundationalConsumers\n first: $first\n after: $after\n ) {\n nodes {\n id\n item {\n id\n name\n description\n itemType\n foundational\n public\n createdAt\n updatedAt\n softDeleted\n project { id, nameWithNamespace }\n latestVersion {\n id\n createdAt\n createdBy { name, username }\n }\n }\n pinnedItemVersion { id, humanVersionName }\n }\n pageInfo { hasNextPage, hasPreviousPage, startCursor, endCursor }\n }\n}`;\n\nconst ENABLE_AI_CATALOG_ITEM_MUTATION = `\nmutation enableAiCatalogItem($input: AiCatalogItemConsumerCreateInput!) {\n aiCatalogItemConsumerCreate(input: $input) {\n errors\n itemConsumer {\n id\n project { id, name, webUrl }\n group { id, name, webUrl }\n }\n }\n}`;\n\nconst DISABLE_AI_CATALOG_ITEM_MUTATION = `\nmutation disableAiCatalogItem($input: AiCatalogItemConsumerDeleteInput!) {\n aiCatalogItemConsumerDelete(input: $input) {\n errors\n success\n }\n}`;\n\nconst FIND_ITEM_CONSUMER_FOR_DISABLE_QUERY = `\nquery findItemConsumer(\n $projectId: ProjectID!\n $itemTypes: [AiCatalogItemType!]\n) {\n aiCatalogConfiguredItems(\n projectId: $projectId\n itemTypes: $itemTypes\n includeFoundationalConsumers: true\n first: 100\n ) {\n nodes { id, item { id } }\n }\n}`;\n\nconst RESOLVE_PROJECT_IDS_FOR_TOOLS_QUERY = `\nquery resolveProjectIds($projectPath: ID!) {\n project(fullPath: $projectPath) {\n id\n namespace { id }\n }\n}`;\n\nfunction normalizeItemGid(id: string): string {\n if (id.startsWith(\"gid://\")) return id;\n if (!/^\\d+$/.test(id)) throw new Error(`Invalid catalog item ID: \"${id}\"`);\n return `gid://gitlab/Ai::Catalog::Item/${id}`;\n}\n\nexport async function resolveProjectGid(\n instanceUrl: string,\n token: string,\n projectPath: string\n): Promise<string> {\n const result = await gql(instanceUrl, token, RESOLVE_PROJECT_IDS_FOR_TOOLS_QUERY, {\n projectPath,\n });\n return result.project.id;\n}\n\nexport async function listAiCatalogItems(\n instanceUrl: string,\n token: string,\n itemTypes: string[],\n options?: { search?: string; first?: number; after?: string }\n): Promise<Record<string, unknown>> {\n const variables: Record<string, unknown> = {\n itemTypes,\n first: options?.first ?? 20,\n };\n if (options?.search) variables.search = options.search;\n if (options?.after) variables.after = options.after;\n const result = await gql(instanceUrl, token, LIST_AI_CATALOG_ITEMS_QUERY, variables);\n return result.aiCatalogItems;\n}\n\nexport async function getAiCatalogItem(\n instanceUrl: string,\n token: string,\n itemId: string\n): Promise<Record<string, unknown>> {\n const gid = normalizeItemGid(itemId);\n const result = await gql(instanceUrl, token, GET_AI_CATALOG_ITEM_QUERY, { id: gid });\n return result.aiCatalogItem;\n}\n\nexport async function listProjectAiCatalogItems(\n instanceUrl: string,\n token: string,\n projectPath: string,\n itemTypes: string[],\n options?: { first?: number; after?: string }\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const variables: Record<string, unknown> = {\n projectId: projectGid,\n itemTypes,\n includeFoundationalConsumers: true,\n first: options?.first ?? 20,\n };\n if (options?.after) variables.after = options.after;\n const result = await gql(instanceUrl, token, LIST_PROJECT_CONFIGURED_ITEMS_QUERY, variables);\n return result.aiCatalogConfiguredItems;\n}\n\nexport async function enableAiCatalogItemForProject(\n instanceUrl: string,\n token: string,\n projectPath: string,\n itemId: string\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const gid = normalizeItemGid(itemId);\n const result = await gql(instanceUrl, token, ENABLE_AI_CATALOG_ITEM_MUTATION, {\n input: { itemId: gid, target: { projectId: projectGid } },\n });\n if (result.aiCatalogItemConsumerCreate.errors.length > 0) {\n throw new Error(\n `Failed to enable item: ${result.aiCatalogItemConsumerCreate.errors.join(\", \")}`\n );\n }\n return result.aiCatalogItemConsumerCreate;\n}\n\nexport async function disableAiCatalogItemForProject(\n instanceUrl: string,\n token: string,\n projectPath: string,\n itemId: string\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const gid = normalizeItemGid(itemId);\n const consumerResult = await gql(instanceUrl, token, FIND_ITEM_CONSUMER_FOR_DISABLE_QUERY, {\n projectId: projectGid,\n itemTypes: [\"AGENT\", \"FLOW\", \"THIRD_PARTY_FLOW\"],\n });\n const consumer = consumerResult.aiCatalogConfiguredItems.nodes.find(\n (n: any) => n.item.id === gid\n );\n if (!consumer?.id) throw new Error(\"Agent/flow is not enabled in this project\");\n const result = await gql(instanceUrl, token, DISABLE_AI_CATALOG_ITEM_MUTATION, {\n input: { id: consumer.id },\n });\n if (result.aiCatalogItemConsumerDelete.errors.length > 0) {\n throw new Error(\n `Failed to disable item: ${result.aiCatalogItemConsumerDelete.errors.join(\", \")}`\n );\n }\n return result.aiCatalogItemConsumerDelete;\n}\n","import { gql } from \"./graphql\";\nimport { resolveProjectGid } from \"./catalog-items\";\n\nconst CREATE_AGENT_MUTATION = `\nmutation AiCatalogAgentCreate($input: AiCatalogAgentCreateInput!) {\n aiCatalogAgentCreate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogAgentVersion {\n systemPrompt\n userPrompt\n tools { nodes { id, name, description } }\n mcpServers { nodes { id, name, url } }\n }\n }\n }\n }\n}`;\n\nconst UPDATE_AGENT_MUTATION = `\nmutation AiCatalogAgentUpdate($input: AiCatalogAgentUpdateInput!) {\n aiCatalogAgentUpdate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogAgentVersion {\n systemPrompt\n userPrompt\n tools { nodes { id, name, description } }\n mcpServers { nodes { id, name, url } }\n }\n }\n }\n }\n}`;\n\nconst LIST_BUILTIN_TOOLS_QUERY = `\nquery AiCatalogBuiltInTools {\n aiCatalogBuiltInTools(first: 1000) {\n nodes {\n id\n name\n title\n description\n }\n }\n}`;\n\nconst CREATE_FLOW_MUTATION = `\nmutation AiCatalogFlowCreate($input: AiCatalogFlowCreateInput!) {\n aiCatalogFlowCreate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogFlowVersion { definition }\n }\n }\n }\n}`;\n\nconst UPDATE_FLOW_MUTATION = `\nmutation AiCatalogFlowUpdate($input: AiCatalogFlowUpdateInput!) {\n aiCatalogFlowUpdate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogFlowVersion { definition }\n }\n }\n }\n}`;\n\nfunction normalizeItemGid(id: string): string {\n if (id.startsWith(\"gid://\")) return id;\n if (!/^\\d+$/.test(id)) throw new Error(`Invalid catalog item ID: \"${id}\"`);\n return `gid://gitlab/Ai::Catalog::Item/${id}`;\n}\n\nexport async function createAgent(\n instanceUrl: string,\n token: string,\n projectPath: string,\n params: {\n name: string;\n description: string;\n public: boolean;\n systemPrompt: string;\n userPrompt?: string;\n tools?: string[];\n mcpTools?: string[];\n mcpServers?: string[];\n release?: boolean;\n }\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const input: Record<string, unknown> = {\n projectId: projectGid,\n name: params.name,\n description: params.description,\n public: params.public,\n systemPrompt: params.systemPrompt,\n };\n if (params.userPrompt) input.userPrompt = params.userPrompt;\n if (params.tools?.length) input.tools = params.tools;\n if (params.mcpTools?.length) input.mcpTools = params.mcpTools;\n if (params.mcpServers?.length) input.mcpServers = params.mcpServers;\n if (params.release !== undefined) input.release = params.release;\n const result = await gql(instanceUrl, token, CREATE_AGENT_MUTATION, { input });\n if (result.aiCatalogAgentCreate.errors.length > 0) {\n throw new Error(`Failed to create agent: ${result.aiCatalogAgentCreate.errors.join(\", \")}`);\n }\n return result.aiCatalogAgentCreate.item;\n}\n\nexport async function updateAgent(\n instanceUrl: string,\n token: string,\n itemId: string,\n params: {\n name?: string;\n description?: string;\n public?: boolean;\n systemPrompt?: string;\n userPrompt?: string;\n tools?: string[];\n mcpTools?: string[];\n mcpServers?: string[];\n release?: boolean;\n versionBump?: \"MAJOR\" | \"MINOR\" | \"PATCH\";\n }\n): Promise<Record<string, unknown>> {\n const gid = normalizeItemGid(itemId);\n const input: Record<string, unknown> = { id: gid };\n if (params.name !== undefined) input.name = params.name;\n if (params.description !== undefined) input.description = params.description;\n if (params.public !== undefined) input.public = params.public;\n if (params.systemPrompt !== undefined) input.systemPrompt = params.systemPrompt;\n if (params.userPrompt !== undefined) input.userPrompt = params.userPrompt;\n if (params.tools !== undefined) input.tools = params.tools;\n if (params.mcpTools !== undefined) input.mcpTools = params.mcpTools;\n if (params.mcpServers !== undefined) input.mcpServers = params.mcpServers;\n if (params.release !== undefined) input.release = params.release;\n if (params.versionBump) input.versionBump = params.versionBump;\n const result = await gql(instanceUrl, token, UPDATE_AGENT_MUTATION, { input });\n if (result.aiCatalogAgentUpdate.errors.length > 0) {\n throw new Error(`Failed to update agent: ${result.aiCatalogAgentUpdate.errors.join(\", \")}`);\n }\n return result.aiCatalogAgentUpdate.item;\n}\n\nexport async function listBuiltInTools(\n instanceUrl: string,\n token: string\n): Promise<Array<{ id: string; name: string; title: string; description: string }>> {\n const result = await gql(instanceUrl, token, LIST_BUILTIN_TOOLS_QUERY, {});\n return result.aiCatalogBuiltInTools?.nodes ?? [];\n}\n\nexport async function createFlow(\n instanceUrl: string,\n token: string,\n projectPath: string,\n params: {\n name: string;\n description: string;\n public: boolean;\n definition: string;\n release?: boolean;\n }\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const input: Record<string, unknown> = {\n projectId: projectGid,\n name: params.name,\n description: params.description,\n public: params.public,\n definition: params.definition,\n };\n if (params.release !== undefined) input.release = params.release;\n const result = await gql(instanceUrl, token, CREATE_FLOW_MUTATION, { input });\n if (result.aiCatalogFlowCreate.errors.length > 0) {\n throw new Error(`Failed to create flow: ${result.aiCatalogFlowCreate.errors.join(\", \")}`);\n }\n return result.aiCatalogFlowCreate.item;\n}\n\nexport async function updateFlow(\n instanceUrl: string,\n token: string,\n itemId: string,\n params: {\n name?: string;\n description?: string;\n public?: boolean;\n definition?: string;\n release?: boolean;\n versionBump?: \"MAJOR\" | \"MINOR\" | \"PATCH\";\n }\n): Promise<Record<string, unknown>> {\n const gid = normalizeItemGid(itemId);\n const input: Record<string, unknown> = { id: gid };\n if (params.name !== undefined) input.name = params.name;\n if (params.description !== undefined) input.description = params.description;\n if (params.public !== undefined) input.public = params.public;\n if (params.definition !== undefined) input.definition = params.definition;\n if (params.release !== undefined) input.release = params.release;\n if (params.versionBump) input.versionBump = params.versionBump;\n const result = await gql(instanceUrl, token, UPDATE_FLOW_MUTATION, { input });\n if (result.aiCatalogFlowUpdate.errors.length > 0) {\n throw new Error(`Failed to update flow: ${result.aiCatalogFlowUpdate.errors.join(\", \")}`);\n }\n return result.aiCatalogFlowUpdate.item;\n}\n","export type { CatalogAgent, FlowInputDef, McpServerInfo } from \"./types\";\n\nexport {\n fetchCatalogAgents,\n executeFlow,\n getWorkflowStatus,\n getFlowDefinition,\n} from \"./flow-execution\";\n\nexport {\n listAiCatalogItems,\n getAiCatalogItem,\n listProjectAiCatalogItems,\n enableAiCatalogItemForProject,\n disableAiCatalogItemForProject,\n} from \"./catalog-items\";\n\nexport { createAgent, updateAgent, listBuiltInTools, createFlow, updateFlow } from \"./catalog-crud\";\n\nexport { fetchMcpServers, listMcpServerTools, discoverMcpToolNames } from \"./mcp-servers\";\n","import { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport os from \"os\";\n\nexport interface AuthInfo {\n token: string;\n instanceUrl: string;\n}\n\nexport function readAuth(): AuthInfo | null {\n try {\n const authPath = join(os.homedir(), \".local\", \"share\", \"opencode\", \"auth.json\");\n const data = JSON.parse(readFileSync(authPath, \"utf-8\"));\n const gitlab = data?.gitlab;\n if (!gitlab) return null;\n const token =\n gitlab.type === \"oauth\" ? gitlab.access : gitlab.type === \"api\" ? gitlab.key : null;\n if (!token) return null;\n const instanceUrl =\n gitlab.enterpriseUrl ?? process.env.GITLAB_INSTANCE_URL ?? \"https://gitlab.com\";\n return { token, instanceUrl };\n } catch {\n return null;\n }\n}\n\nexport interface PluginContext {\n getAuth: () => AuthInfo | null;\n ensureAuth: () => AuthInfo | null;\n getFlowAgents: () => Map<string, import(\"./types\").CatalogAgent>;\n getCachedAgents: () => import(\"./types\").CatalogAgent[];\n getNamespaceId: () => number | undefined;\n refreshAgents: () => Promise<void>;\n}\n","import type { ModelCacheEntry } from \"gitlab-ai-provider\";\nimport type { CatalogAgent } from \"./catalog\";\n\nexport function resolveModelId(entry: ModelCacheEntry): string {\n const ref = entry.selectedModelRef ?? entry.discovery?.defaultModel?.ref;\n if (!ref) return \"duo-workflow-default\";\n return `duo-workflow-${ref.replace(/[/_]/g, \"-\")}`;\n}\n\nexport function buildAgentEntries(agents: CatalogAgent[], entry: ModelCacheEntry) {\n const modelId = resolveModelId(entry);\n return Object.fromEntries(\n agents.map((agent) => [\n `gitlab-${agent.identifier}`,\n {\n name: agent.name,\n description: agent.description,\n mode: \"primary\",\n model: { providerID: \"gitlab\", modelID: modelId },\n permission: { \"*\": \"allow\" },\n options: {\n workflowDefinition: agent.workflowDefinition,\n gitlabFoundational: agent.foundational,\n },\n },\n ])\n );\n}\n","export const FLOW_DISPATCH_GUIDELINES = [\n `## GitLab Flow Dispatch Guidelines`,\n ``,\n `CRITICAL: You must NEVER call gitlab_execute_project_flow or gitlab_get_flow_definition directly.`,\n `Flows are ALWAYS executed via the Task tool with subagent_type \"general\".`,\n `When the user's message contains flow dispatch instructions (starting with \"IMPORTANT: You MUST\"),`,\n `follow those instructions exactly — call the Task tool with the provided parameters.`,\n ``,\n `### Multiple Flows or Resources`,\n `When multiple flows need to run (multiple @mentions, or batch across resources), dispatch them`,\n `via a SINGLE \"general\" subagent. The general subagent can execute multiple tool calls in parallel,`,\n `so all flows fire simultaneously. Do NOT dispatch multiple Task calls — use ONE Task with a prompt`,\n `that lists all the flows to execute, so the subagent runs them concurrently.`,\n ``,\n `### Batch Operations (Multiple Resources)`,\n `If the user asks to run flows on multiple resources (e.g., \"for each MR\"), first list the`,\n `resources yourself using GitLab API tools, then dispatch ONE general subagent whose prompt`,\n `includes all flow executions (N flows x M resources) to run in parallel.`,\n].join(\"\\n\");\n\nexport const FLOW_SCHEMA_REFERENCE = `## Flow YAML Schema Reference\n\n### Top-level structure (all required unless noted):\n version: \"v1\" # Always \"v1\"\n environment: ambient # Always \"ambient\"\n components: [...] # Array of components (min 1)\n routers: [...] # Array of routers connecting components\n flow:\n entry_point: \"component_name\" # First component to run\n inputs: [...] # Optional: additional context inputs\n prompts: [...] # Optional: inline prompt definitions\n\n### Component types:\n\n1. DeterministicStepComponent — runs ONE tool, no LLM call:\n - name: \"fetch_data\" # alphanumeric + underscore only\n type: DeterministicStepComponent\n tool_name: \"get_merge_request\"\n inputs: # map tool parameters\n - { from: \"context:goal\", as: \"merge_request_iid\" }\n - { from: \"context:project_id\", as: \"project_id\" }\n\n2. OneOffComponent — single LLM call + tool execution:\n - name: \"process_data\"\n type: OneOffComponent\n prompt_id: \"my_prompt\" # references inline prompt\n prompt_version: null # null = use inline prompt from prompts section\n toolset: [\"read_file\", \"edit_file\"]\n inputs:\n - { from: \"context:fetch_data.tool_responses\", as: \"data\" }\n max_correction_attempts: 3 # retries on tool failure (default 3)\n\n3. AgentComponent — multi-turn LLM reasoning loop:\n - name: \"analyze\"\n type: AgentComponent\n prompt_id: \"my_agent_prompt\"\n prompt_version: null\n toolset: [\"read_file\", \"grep\"]\n inputs:\n - { from: \"context:goal\", as: \"user_goal\" }\n ui_log_events: [\"on_agent_final_answer\"]\n\n### IOKey syntax (inputs/from values):\n \"context:goal\" # The flow goal (user input)\n \"context:project_id\" # Project ID (auto-injected)\n \"context:<component_name>.tool_responses\" # Tool output from a component\n \"context:<component_name>.final_answer\" # Agent's final text answer\n \"context:<component_name>.execution_result\" # OneOff execution result\n { from: \"context:x\", as: \"var_name\" } # Rename for prompt template\n { from: \"true\", as: \"flag\", literal: true } # Literal value\n\n### Router patterns:\n Direct: { from: \"step1\", to: \"step2\" }\n To end: { from: \"last_step\", to: \"end\" }\n Conditional: { from: \"step1\", condition: { input: \"context:step1.final_answer.decision\", routes: { \"yes\": \"step2\", \"no\": \"end\" } } }\n\n### Inline prompts (in prompts section):\n - prompt_id: \"my_prompt\"\n name: \"My Prompt\"\n unit_primitives: [\"duo_agent_platform\"] # Always this value\n prompt_template:\n system: \"You are a helpful assistant. {{var_name}} is available.\"\n user: \"Process: {{data}}\"\n placeholder: \"history\" # Optional, for AgentComponent conversation history\n\n### Tool names: use names from gitlab_list_builtin_tools (e.g., \"read_file\", \"get_merge_request\", \"create_merge_request_note\").`;\n\nexport const FLOW_EXAMPLE_LINEAR = `## Example: Simple linear flow (fetch MR → analyze → post comment)\n\\`\\`\\`yaml\nversion: \"v1\"\nenvironment: ambient\ncomponents:\n - name: fetch_mr\n type: DeterministicStepComponent\n tool_name: build_review_merge_request_context\n inputs:\n - { from: \"context:project_id\", as: \"project_id\" }\n - { from: \"context:goal\", as: \"merge_request_iid\" }\n ui_log_events: [\"on_tool_execution_success\", \"on_tool_execution_failed\"]\n - name: analyze_and_comment\n type: OneOffComponent\n prompt_id: review_prompt\n prompt_version: null\n toolset: [\"create_merge_request_note\"]\n inputs:\n - { from: \"context:fetch_mr.tool_responses\", as: \"mr_data\" }\n - { from: \"context:project_id\", as: \"project_id\" }\n - { from: \"context:goal\", as: \"merge_request_iid\" }\n max_correction_attempts: 3\n ui_log_events: [\"on_tool_execution_success\"]\nrouters:\n - { from: fetch_mr, to: analyze_and_comment }\n - { from: analyze_and_comment, to: end }\nflow:\n entry_point: fetch_mr\nprompts:\n - prompt_id: review_prompt\n name: MR Review Prompt\n unit_primitives: [\"duo_agent_platform\"]\n prompt_template:\n system: |\n You review merge requests. Analyze the MR data and post a concise review comment.\n Focus on code quality, potential bugs, and improvements.\n user: \"Review MR !{{merge_request_iid}} in project {{project_id}}: {{mr_data}}\"\n\\`\\`\\``;\n\nexport const FLOW_EXAMPLE_CONDITIONAL = `## Example: Conditional flow (gather data → decide → branch)\n\\`\\`\\`yaml\nversion: \"v1\"\nenvironment: ambient\ncomponents:\n - name: gather_context\n type: DeterministicStepComponent\n tool_name: get_vulnerability_details\n inputs:\n - { from: \"context:goal\", as: \"vulnerability_id\" }\n ui_log_events: [\"on_tool_execution_success\"]\n - name: evaluate\n type: AgentComponent\n prompt_id: eval_prompt\n prompt_version: null\n toolset: []\n inputs:\n - { from: \"context:gather_context.tool_responses\", as: \"vuln_data\" }\n ui_log_events: [\"on_agent_final_answer\"]\n - name: create_fix\n type: AgentComponent\n prompt_id: fix_prompt\n prompt_version: null\n toolset: [\"read_file\", \"edit_file\", \"grep\"]\n inputs:\n - { from: \"context:gather_context.tool_responses\", as: \"vuln_data\" }\n ui_log_events: [\"on_agent_final_answer\", \"on_tool_execution_success\"]\nrouters:\n - { from: gather_context, to: evaluate }\n - from: evaluate\n condition:\n input: \"context:evaluate.final_answer\"\n routes:\n \"fix_needed\": create_fix\n \"false_positive\": end\n default_route: end\n - { from: create_fix, to: end }\nflow:\n entry_point: gather_context\nprompts:\n - prompt_id: eval_prompt\n name: Vulnerability Evaluator\n unit_primitives: [\"duo_agent_platform\"]\n prompt_template:\n system: |\n Evaluate if a vulnerability needs fixing. Respond with exactly \"fix_needed\" or \"false_positive\".\n user: \"Evaluate: {{vuln_data}}\"\n - prompt_id: fix_prompt\n name: Fix Generator\n unit_primitives: [\"duo_agent_platform\"]\n prompt_template:\n system: |\n You fix security vulnerabilities. Read the relevant code and apply the fix.\n user: \"Fix this vulnerability: {{vuln_data}}\"\n placeholder: history\n\\`\\`\\``;\n","import type { CatalogAgent } from \"./types\";\nimport type { AuthInfo } from \"./auth\";\nimport { FLOW_DISPATCH_GUIDELINES } from \"./prompts\";\n\nexport function buildFlowSubagentPrompt(\n flow: CatalogAgent,\n projectPath: string,\n projectUrl: string\n): string {\n return [\n `You execute the \"${flow.name}\" GitLab flow. Project: ${projectPath} (${projectUrl}).`,\n ``,\n `STEP 1: Call gitlab_get_flow_definition with consumer_id=${flow.consumerId}, foundational=${!!flow.foundational}.`,\n `Parse the YAML config:`,\n `- In \"components\", find { from: \"context:goal\", as: \"<name>\" }. The \"as\" value is what the goal parameter must contain:`,\n ` \"merge_request_iid\" -> just the number (e.g. 14)`,\n ` \"pipeline_url\"/\"url\"/\"issue_url\" -> full URL (e.g. ${projectUrl}/-/merge_requests/5)`,\n ` \"vulnerability_id\" -> just the ID number`,\n ` \"goal\" -> free-form text`,\n `- In \"flow.inputs\", find additional_context categories (skip \"agent_platform_standard_context\").`,\n ``,\n `STEP 2: Resolve the goal to the EXACT value the flow expects (from step 1).`,\n `The goal parameter has a 10000 char limit and is used directly as the flow parameter — pass ONLY the raw value, never a sentence.`,\n `Use GitLab API tools if needed to look up IDs or construct URLs from the user's message.`,\n ``,\n `STEP 3: Gather additional_context values (if any from step 1) using available tools.`,\n ``,\n `STEP 4: Call gitlab_execute_project_flow with:`,\n ` project_id: \"${projectPath}\"`,\n ` consumer_id: ${flow.consumerId}`,\n ` goal: <resolved value from step 2>`,\n ` additional_context (if needed): [{\"Category\":\"<cat>\",\"Content\":\"{\\\\\"field\\\\\":\\\\\"val\\\\\"}\"}]`,\n ``,\n `STEP 5: Call gitlab_get_workflow_status with the workflow_id. Report status and URL: ${projectUrl}/-/automate/agent-sessions/<id>`,\n ].join(\"\\n\");\n}\n\nexport function makeChatMessageHook(\n getAuthCache: () => AuthInfo | null,\n flowAgents: Map<string, CatalogAgent>,\n getProjectPath: () => string | undefined\n) {\n return async (_input: any, output: any) => {\n const projectPath = getProjectPath();\n const indicesToRemove: number[] = [];\n const flowMentions: Array<{\n idx: number;\n flow: CatalogAgent;\n displayName: string;\n }> = [];\n\n for (let i = 0; i < output.parts.length; i++) {\n const part = output.parts[i] as any;\n if (part.type !== \"agent\") continue;\n\n const flow = flowAgents.get(part.name);\n if (!flow || !flow.consumerId || !projectPath) continue;\n\n flowMentions.push({ idx: i, flow, displayName: part.name });\n\n if (i + 1 < output.parts.length) {\n const next = output.parts[i + 1] as any;\n if (\n next.type === \"text\" &&\n next.synthetic &&\n next.text?.includes(\"call the task tool with subagent\")\n ) {\n indicesToRemove.push(i + 1);\n }\n }\n }\n\n if (flowMentions.length === 0) {\n return;\n }\n\n const authCache = getAuthCache();\n if (flowMentions.length === 1) {\n const { idx, flow } = flowMentions[0];\n const baseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n const projectUrl = `${baseUrl}/${projectPath}`;\n\n const rawText =\n output.parts\n .filter((p: any) => p.type === \"text\" && !p.synthetic)\n .map((p: any) => p.text)\n .join(\" \")\n .trim() || \"Execute the flow\";\n\n const subagentPrompt =\n buildFlowSubagentPrompt(flow, projectPath!, projectUrl) + `\\n\\nUser goal: \"${rawText}\"`;\n\n const resultText = [\n `IMPORTANT: You MUST call the Task tool RIGHT NOW to dispatch a subagent. Do NOT execute these steps yourself.`,\n ``,\n `Call the Task tool with:`,\n ` subagent_type: \"general\"`,\n ` description: \"Execute ${flow.name} flow\"`,\n ` prompt: ${JSON.stringify(subagentPrompt)}`,\n ``,\n `Do not do anything else. Just call the Task tool with the above parameters.`,\n ].join(\"\\n\");\n\n const original = output.parts[idx] as any;\n output.parts[idx] = { ...original, type: \"text\", text: resultText } as any;\n delete (output.parts[idx] as any).name;\n delete (output.parts[idx] as any).source;\n\n for (const rmIdx of indicesToRemove.reverse()) {\n output.parts.splice(rmIdx, 1);\n }\n return;\n }\n\n const baseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n const projectUrl = `${baseUrl}/${projectPath}`;\n\n const flowNames = new Set(flowMentions.map((m) => m.displayName));\n let rawText =\n output.parts\n .filter((p: any) => p.type === \"text\" && !p.synthetic)\n .map((p: any) => p.text)\n .join(\" \")\n .trim() || \"Execute the flows\";\n\n for (const name of flowNames) {\n rawText = rawText\n .replace(new RegExp(`@${name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}`, \"g\"), \"\")\n .trim();\n }\n rawText = rawText.replace(/\\s{2,}/g, \" \").trim() || \"Execute the flows\";\n\n const flowList = flowMentions.map(\n ({ flow, displayName }, i) =>\n `${i + 1}. \"${displayName}\" — consumer_id=${flow.consumerId}, foundational=${!!flow.foundational}`\n );\n\n const batchPrompt = [\n `Execute ${flowMentions.length} GitLab flows on project ${projectPath} (${projectUrl}).`,\n `User goal: \"${rawText}\"`,\n ``,\n `Flows to execute:`,\n ...flowList,\n ``,\n `EXECUTION PLAN:`,\n `1. Call gitlab_get_flow_definition for ALL flows listed above in a SINGLE response (${flowMentions.length} tool calls at once).`,\n ` Parse each YAML to find what \"context:goal\" maps to (the \"as\" field in components).`,\n ``,\n `2. If the user's goal involves multiple resources (e.g., \"for each MR\"), list them using GitLab API tools.`,\n ``,\n `3. Call gitlab_execute_project_flow for EVERY flow+resource combination in a SINGLE response.`,\n ` For each call, set the goal to the EXACT value the flow expects (e.g., just \"14\" for merge_request_iid).`,\n ` project_id: \"${projectPath}\"`,\n ` You MUST emit ALL execute calls in ONE response — do NOT wait for one to finish before calling the next.`,\n ``,\n `4. Collect all workflow_ids from step 3. Call gitlab_get_workflow_status for ALL of them in a SINGLE response.`,\n ``,\n `5. Present a summary table: flow name, resource, status, URL (${projectUrl}/-/automate/agent-sessions/<id>).`,\n ``,\n `CRITICAL: In steps 1, 3, and 4 you MUST make multiple tool calls in the SAME response for parallel execution.`,\n ].join(\"\\n\");\n\n const combinedText = [\n `IMPORTANT: You MUST call the Task tool RIGHT NOW with subagent_type \"general\" to dispatch all flows in parallel.`,\n `Do NOT call flow tools yourself. Do NOT dispatch multiple Task calls — use ONE.`,\n ``,\n `Call the Task tool with:`,\n ` subagent_type: \"general\"`,\n ` description: \"Execute ${flowMentions.length} flows in parallel\"`,\n ` prompt: ${JSON.stringify(batchPrompt)}`,\n ``,\n `Do not do anything else. Just call the Task tool with the above parameters.`,\n ].join(\"\\n\");\n\n const firstIdx = flowMentions[0].idx;\n const original = output.parts[firstIdx] as any;\n output.parts[firstIdx] = { ...original, type: \"text\", text: combinedText } as any;\n delete (output.parts[firstIdx] as any).name;\n delete (output.parts[firstIdx] as any).source;\n\n for (let i = flowMentions.length - 1; i >= 1; i--) {\n indicesToRemove.push(flowMentions[i].idx);\n }\n\n for (const idx of [...new Set(indicesToRemove)].sort((a, b) => b - a)) {\n output.parts.splice(idx, 1);\n }\n };\n}\n\nexport function makeChatParamsHook(gitlabAgentNames: Set<string>) {\n return async (input: any, _output: any) => {\n if (!gitlabAgentNames.has(input.agent)) return;\n const model = input.model as any;\n const modelId = model?.modelID ?? model?.id ?? \"\";\n const isDWS = modelId.includes(\"duo-workflow\");\n if (!isDWS) {\n const name = model?.name ?? modelId ?? \"unknown\";\n throw new Error(\n `GitLab agent \"${input.agent}\" requires an Agent Platform model but the current model is \"${name}\". ` +\n `Please switch to an Agent Platform model (duo-workflow-*) in the model picker to use GitLab agents.`\n );\n }\n };\n}\n\nexport function makeSystemTransformHook(\n flowAgents: Map<string, CatalogAgent>,\n getAuthCache: () => AuthInfo | null\n) {\n return async (_input: any, output: any) => {\n if (flowAgents.size) {\n output.system.push(FLOW_DISPATCH_GUIDELINES);\n }\n if (getAuthCache()) {\n output.system.push(\n `## Project Knowledge\\nProject memory tools are available (gitlab_memory_load, gitlab_memory_record, gitlab_memory_recall). Say \"bootstrap project memory\" to initialize or refresh project knowledge.`\n );\n }\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport { executeFlow, getWorkflowStatus, getFlowDefinition } from \"../catalog\";\nimport type { PluginContext } from \"../auth\";\n\nconst z = tool.schema;\n\nexport function makeFlowTools(ctx: PluginContext): Record<string, any> {\n return {\n gitlab_execute_project_flow: tool({\n description:\n \"Execute a GitLab DAP flow on a project.\\n\" +\n \"Triggers a flow via the Duo Workflow Service REST API.\\n\" +\n \"The flow runs asynchronously and is visible in the GitLab UI.\\n\" +\n \"Returns the workflow record with ID and status.\\n\" +\n \"The additional_context parameter accepts flow-specific inputs as a JSON array of {Category, Content} objects.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n consumer_id: z.number().describe(\"AI Catalog ItemConsumer numeric ID\"),\n goal: z.string().describe(\"User prompt/goal for the flow, include relevant URLs\"),\n additional_context: z\n .string()\n .optional()\n .describe(\n 'JSON array of flow inputs: [{\"Category\":\"merge_request\",\"Content\":\"{\\\\\"url\\\\\":\\\\\"https://...\\\\\"}\"}]'\n ),\n issue_id: z.number().optional().describe(\"Issue IID for context\"),\n merge_request_id: z.number().optional().describe(\"Merge request IID for context\"),\n },\n execute: async (args: {\n project_id: string;\n consumer_id: number;\n goal: string;\n additional_context?: string;\n issue_id?: number;\n merge_request_id?: number;\n }) => {\n const auth = ctx.ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n\n let flowInputs: Array<{ Category: string; Content: string }> | undefined;\n if (args.additional_context) {\n try {\n flowInputs = JSON.parse(args.additional_context);\n } catch {\n return \"Error: additional_context must be a valid JSON array\";\n }\n }\n\n try {\n const result = await executeFlow(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n args.consumer_id,\n args.goal,\n {\n issueId: args.issue_id,\n mergeRequestId: args.merge_request_id,\n namespaceId: ctx.getNamespaceId(),\n flowInputs,\n }\n );\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error executing flow: ${err.message}`;\n }\n },\n }),\n\n gitlab_get_flow_definition: tool({\n description:\n \"Get the YAML configuration of a GitLab DAP flow.\\n\" +\n \"Returns the flow config YAML which contains the flow.inputs section\\n\" +\n \"describing what additional_context categories and fields the flow requires.\\n\" +\n \"Use this before executing a flow to understand what inputs to gather.\\n\" +\n \"Set foundational=true for GitLab built-in flows, foundational=false for custom flows.\",\n args: {\n consumer_id: z.number().describe(\"AI Catalog ItemConsumer numeric ID\"),\n foundational: z\n .boolean()\n .describe(\"true for GitLab foundational flows, false for custom flows\"),\n },\n execute: async (args: { consumer_id: number; foundational: boolean }) => {\n const auth = ctx.ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n\n const flow = [...ctx.getFlowAgents().values()].find(\n (f) => f.consumerId === args.consumer_id\n );\n\n try {\n const result = await getFlowDefinition(auth.instanceUrl, auth.token, {\n consumerId: args.consumer_id,\n flowName: flow?.name,\n foundational: args.foundational,\n catalogItemVersionId: flow?.catalogItemVersionId,\n itemIdentifier: flow?.identifier,\n workflowDefinition: flow?.workflowDefinition,\n });\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error getting flow definition: ${err.message}`;\n }\n },\n }),\n\n gitlab_get_workflow_status: tool({\n description:\n \"Get the status and latest messages of a GitLab DAP workflow.\\n\" +\n \"Use this to monitor a running flow after executing it.\\n\" +\n \"Returns the workflow status, latest checkpoint messages, and timestamps.\\n\" +\n \"Poll every 10 seconds until status is completed, failed, or cancelled.\",\n args: {\n workflow_id: z\n .number()\n .describe(\"Workflow numeric ID (from gitlab_execute_project_flow result)\"),\n },\n execute: async (args: { workflow_id: number }) => {\n const auth = ctx.ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n\n try {\n const result = await getWorkflowStatus(auth.instanceUrl, auth.token, args.workflow_id);\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error getting workflow status: ${err.message}`;\n }\n },\n }),\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport { createAgent, updateAgent, listBuiltInTools, createFlow, updateFlow } from \"../catalog\";\nimport { validateFlowYaml } from \"../flow-validator\";\nimport { FLOW_SCHEMA_REFERENCE, FLOW_EXAMPLE_LINEAR, FLOW_EXAMPLE_CONDITIONAL } from \"../prompts\";\nimport type { PluginContext } from \"../auth\";\n\nconst z = tool.schema;\n\nexport function makeCatalogCrudTools(ctx: PluginContext): Record<string, any> {\n return {\n gitlab_create_agent: tool({\n description:\n \"Create a new custom agent in the GitLab AI Catalog.\\n\" +\n \"First call: set confirmed=false (or omit). The tool returns without creating anything and \" +\n \"instructs you to ask the user for agent properties using the question tool.\\n\" +\n \"Second call: after the user confirms, set confirmed=true to actually create the agent.\\n\" +\n \"After creation, use gitlab_enable_project_agent to enable it on a project.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n name: z.string().describe(\"Display name for the agent\"),\n description: z.string().describe(\"Description of what the agent does\"),\n public: z.boolean().describe(\"Whether the agent is publicly visible in the AI Catalog\"),\n system_prompt: z.string().describe(\"System prompt that defines the agent's behavior\"),\n user_prompt: z.string().optional().describe(\"User prompt template (optional)\"),\n tools: z\n .array(z.string())\n .optional()\n .describe(\n \"Array of built-in tool Global IDs from gitlab_list_builtin_tools. \" +\n 'Must be full GIDs like \"gid://gitlab/Ai::Catalog::BuiltInTool/1\", NOT tool names.'\n ),\n mcp_tools: z.array(z.string()).optional().describe(\"Array of MCP tool names to enable\"),\n mcp_servers: z\n .array(z.string())\n .optional()\n .describe(\n \"Array of MCP server Global IDs from gitlab_list_project_mcp_servers. \" +\n 'Must be full GIDs like \"gid://gitlab/Ai::Catalog::McpServer/1\", NOT server names.'\n ),\n release: z\n .boolean()\n .optional()\n .describe(\"Whether to release the version immediately (default: false)\"),\n confirmed: z\n .boolean()\n .optional()\n .describe(\n \"Set to true only after the user has reviewed and confirmed all parameters. Omit or set false on first call.\"\n ),\n },\n execute: async (args) => {\n if (!args.confirmed) {\n return [\n \"STOP: Do not create the agent yet. You must ask the user to confirm the configuration first.\",\n \"\",\n \"Follow these steps NOW:\",\n \"1. Call gitlab_list_builtin_tools and gitlab_list_project_mcp_servers to discover options.\",\n \"2. Use the question tool to ask the user ALL 4 of these (in one call):\",\n \" - Agent name (suggest one, allow custom input)\",\n \" - Visibility: Public or Private\",\n \" - Tools: group by category (Search, Issues, MRs, Epics, Files, Git, CI/CD, Security, Audit, Planning, Wiki, API) as multi-select\",\n \" - MCP servers: multi-select from available servers\",\n \"3. Generate a system prompt and show it to the user for approval.\",\n \"4. Call gitlab_create_agent again with confirmed=true after the user approves.\",\n ].join(\"\\n\");\n }\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await createAgent(auth.instanceUrl, auth.token, args.project_id, {\n name: args.name,\n description: args.description,\n public: args.public,\n systemPrompt: args.system_prompt,\n userPrompt: args.user_prompt,\n tools: args.tools,\n mcpTools: args.mcp_tools,\n mcpServers: args.mcp_servers,\n release: args.release,\n });\n await ctx.refreshAgents();\n return JSON.stringify(result, null, 2);\n },\n }),\n\n gitlab_update_agent: tool({\n description:\n \"Update an existing custom agent in the GitLab AI Catalog.\\n\" +\n \"Only provided fields are updated; omitted fields remain unchanged.\",\n args: {\n id: z.string().describe(\"Agent ID (numeric or full GID)\"),\n name: z.string().optional().describe(\"New display name\"),\n description: z.string().optional().describe(\"New description\"),\n public: z.boolean().optional().describe(\"Whether publicly visible\"),\n system_prompt: z.string().optional().describe(\"New system prompt\"),\n user_prompt: z.string().optional().describe(\"New user prompt template\"),\n tools: z\n .array(z.string())\n .optional()\n .describe(\n 'New set of built-in tool Global IDs (full GIDs like \"gid://gitlab/Ai::Catalog::BuiltInTool/1\")'\n ),\n mcp_tools: z.array(z.string()).optional().describe(\"New set of MCP tool names\"),\n mcp_servers: z\n .array(z.string())\n .optional()\n .describe(\n 'New set of MCP server Global IDs (full GIDs like \"gid://gitlab/Ai::Catalog::McpServer/1\")'\n ),\n release: z.boolean().optional().describe(\"Whether to release the latest version\"),\n version_bump: z.enum([\"MAJOR\", \"MINOR\", \"PATCH\"]).optional().describe(\"Version bump type\"),\n },\n execute: async (args) => {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await updateAgent(auth.instanceUrl, auth.token, args.id, {\n name: args.name,\n description: args.description,\n public: args.public,\n systemPrompt: args.system_prompt,\n userPrompt: args.user_prompt,\n tools: args.tools,\n mcpTools: args.mcp_tools,\n mcpServers: args.mcp_servers,\n release: args.release,\n versionBump: args.version_bump,\n });\n await ctx.refreshAgents();\n return JSON.stringify(result, null, 2);\n },\n }),\n\n gitlab_list_builtin_tools: tool({\n description:\n \"List available built-in GitLab tools that can be assigned to custom agents.\\n\" +\n \"Returns tool IDs, names, and descriptions. Use the IDs when creating or updating agents.\",\n args: {},\n execute: async () => {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const tools = await listBuiltInTools(auth.instanceUrl, auth.token);\n if (!tools.length) return \"No built-in tools available.\";\n return JSON.stringify(tools, null, 2);\n },\n }),\n\n gitlab_design_flow: tool({\n description:\n \"Interactive flow design tool. Returns the flow YAML schema reference, examples, and instructions.\\n\" +\n \"Use this BEFORE gitlab_create_flow to design the flow definition interactively with the user.\\n\" +\n \"The tool also validates generated YAML against the flow_v2 JSON schema.\",\n args: {\n action: z\n .enum([\"get_schema\", \"validate\"])\n .describe(\n '\"get_schema\" returns the schema reference and examples. \"validate\" validates a YAML definition.'\n ),\n definition: z\n .string()\n .optional()\n .describe(\"YAML definition to validate (required when action=validate)\"),\n },\n execute: async (args) => {\n if (args.action === \"validate\") {\n if (!args.definition) return \"Error: definition is required for validate action.\";\n const result = validateFlowYaml(args.definition);\n if (result.valid) return \"VALID: Flow definition passes schema validation.\";\n return `INVALID: ${result.errors.length} error(s):\\n${result.errors.map((e, i) => ` ${i + 1}. ${e}`).join(\"\\n\")}`;\n }\n return [\n \"Follow this multi-round workflow to design a flow:\",\n \"\",\n \"ROUND 1: Call gitlab_list_builtin_tools to discover available tool names for the flow.\",\n \" Then use the question tool to ask the user:\",\n \" - Flow name\",\n \" - Visibility: Public or Private\",\n \" - What the flow should do (step-by-step description)\",\n \" - What GitLab resource it operates on (MR, issue, pipeline, vulnerability, etc.)\",\n \"\",\n \"ROUND 2: Based on the user's answers, propose a component architecture in plain text:\",\n \" - List each step with its type (DeterministicStep, OneOff, or Agent)\",\n \" - Explain what each step does and what tools it uses\",\n \" - Show the routing (linear or conditional)\",\n \" Ask the user to confirm or adjust.\",\n \"\",\n \"ROUND 3: Generate the full YAML definition using the schema below.\",\n \" Call gitlab_design_flow with action='validate' to check it.\",\n \" Show the validated YAML to the user for final approval.\",\n \" Then call gitlab_create_flow with confirmed=true.\",\n \"\",\n \"=== FLOW YAML SCHEMA ===\",\n FLOW_SCHEMA_REFERENCE,\n \"\",\n \"=== EXAMPLE: Linear flow ===\",\n FLOW_EXAMPLE_LINEAR,\n \"\",\n \"=== EXAMPLE: Conditional flow ===\",\n FLOW_EXAMPLE_CONDITIONAL,\n ].join(\"\\n\");\n },\n }),\n\n gitlab_create_flow: tool({\n description:\n \"Create a custom flow in the GitLab AI Catalog.\\n\" +\n \"First call: set confirmed=false (or omit). Returns instructions to use gitlab_design_flow first.\\n\" +\n \"Second call: after the user confirms, set confirmed=true to create the flow.\\n\" +\n \"After creation, use gitlab_enable_project_flow to enable it on a project.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n name: z.string().describe(\"Display name for the flow\"),\n description: z.string().describe(\"Description of what the flow does\"),\n public: z.boolean().describe(\"Whether publicly visible in the AI Catalog\"),\n definition: z.string().describe(\"Flow YAML definition (validated via gitlab_design_flow)\"),\n release: z.boolean().optional().describe(\"Whether to release the version immediately\"),\n confirmed: z\n .boolean()\n .optional()\n .describe(\"Set true only after user has reviewed the YAML\"),\n },\n execute: async (args) => {\n if (!args.confirmed) {\n return [\n \"STOP: Do not create the flow yet.\",\n \"\",\n \"Call gitlab_design_flow with action='get_schema' first to get the interactive workflow.\",\n \"Follow the multi-round design process, then call this tool with confirmed=true.\",\n ].join(\"\\n\");\n }\n const validation = validateFlowYaml(args.definition);\n if (!validation.valid) {\n return `Flow YAML validation failed:\\n${validation.errors.map((e, i) => ` ${i + 1}. ${e}`).join(\"\\n\")}\\n\\nFix the errors and try again.`;\n }\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await createFlow(auth.instanceUrl, auth.token, args.project_id, {\n name: args.name,\n description: args.description,\n public: args.public,\n definition: args.definition,\n release: args.release,\n });\n await ctx.refreshAgents();\n const json = JSON.stringify(result, null, 2);\n return `${json}\\n\\nFlow created successfully. Ask the user if they want to enable it on the current project using gitlab_enable_project_flow.`;\n },\n }),\n\n gitlab_update_flow: tool({\n description:\n \"Update an existing custom flow in the GitLab AI Catalog.\\n\" +\n \"Only provided fields are updated; omitted fields remain unchanged.\\n\" +\n \"Use gitlab_design_flow with action='validate' to check YAML before updating.\",\n args: {\n id: z.string().describe(\"Flow ID (numeric or full GID)\"),\n name: z.string().optional().describe(\"New display name\"),\n description: z.string().optional().describe(\"New description\"),\n public: z.boolean().optional().describe(\"Whether publicly visible\"),\n definition: z.string().optional().describe(\"New flow YAML definition\"),\n release: z.boolean().optional().describe(\"Whether to release the latest version\"),\n version_bump: z.enum([\"MAJOR\", \"MINOR\", \"PATCH\"]).optional().describe(\"Version bump type\"),\n },\n execute: async (args) => {\n if (args.definition) {\n const validation = validateFlowYaml(args.definition);\n if (!validation.valid) {\n return `Flow YAML validation failed:\\n${validation.errors.map((e, i) => ` ${i + 1}. ${e}`).join(\"\\n\")}\\n\\nFix the errors and try again.`;\n }\n }\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await updateFlow(auth.instanceUrl, auth.token, args.id, {\n name: args.name,\n description: args.description,\n public: args.public,\n definition: args.definition,\n release: args.release,\n versionBump: args.version_bump,\n });\n await ctx.refreshAgents();\n return JSON.stringify(result, null, 2);\n },\n }),\n };\n}\n","import Ajv from \"ajv\";\nimport yaml from \"js-yaml\";\nimport flowSchema from \"../vendor/schemas/flow_v2.json\";\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport function validateFlowYaml(yamlString: string): ValidationResult {\n let parsed: Record<string, unknown>;\n try {\n parsed = yaml.load(yamlString) as Record<string, unknown>;\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n return { valid: false, errors: [`Invalid YAML syntax: ${msg}`] };\n }\n\n if (!parsed || typeof parsed !== \"object\") {\n return { valid: false, errors: [\"YAML must be an object\"] };\n }\n\n parsed.yaml_definition = yamlString;\n\n const ajv = new Ajv({ allErrors: true, strict: false });\n const validate = ajv.compile(flowSchema);\n const valid = validate(parsed);\n\n if (!valid && validate.errors) {\n const errors = validate.errors.map((e) => {\n const path = e.instancePath || \"/\";\n return `${path}: ${e.message}`;\n });\n return { valid: false, errors };\n }\n\n return { valid: true, errors: [] };\n}\n","{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"Flow Registry v1 Configuration Schema\",\n \"description\": \"JSON Schema for validating Flow Registry v1 YAML configuration files\",\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"environment\",\n \"components\",\n \"routers\",\n \"flow\",\n \"yaml_definition\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"version\": {\n \"type\": \"string\",\n \"const\": \"v1\",\n \"description\": \"Framework version - must be 'v1' for current stable version\"\n },\n \"environment\": {\n \"type\": \"string\",\n \"enum\": [\n \"ambient\"\n ],\n \"description\": \"Flow environment declaring expected level of interaction between human and AI agent\"\n },\n \"components\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"description\": \"List of components that make up the flow\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"#/definitions/AgentComponent\"\n },\n {\n \"$ref\": \"#/definitions/DeterministicStepComponent\"\n },\n {\n \"$ref\": \"#/definitions/OneOffComponent\"\n }\n ]\n }\n },\n \"routers\": {\n \"type\": \"array\",\n \"description\": \"Define how components connect to each other\",\n \"items\": {\n \"$ref\": \"#/definitions/Router\"\n }\n },\n \"flow\": {\n \"type\": \"object\",\n \"description\": \"Specify the entry point component and other flow options\",\n \"properties\": {\n \"entry_point\": {\n \"type\": \"string\",\n \"description\": \"Name of first component to run. Examples: 'main_agent', 'initial_step'\",\n \"pattern\": \"^[a-zA-Z0-9_]+$\"\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"Optional additional context schema definitions that can be passed to the flow (in addition to the 'goal')\",\n \"items\": {\n \"$ref\": \"#/definitions/FlowInputCategory\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"prompts\": {\n \"type\": \"array\",\n \"description\": \"List of inline prompt templates for flow components to use\",\n \"items\": {\n \"$ref\": \"#/definitions/LocalPrompt\"\n }\n },\n \"yaml_definition\": {\n \"type\": \"string\"\n }\n },\n \"definitions\": {\n \"ComponentName\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"description\": \"Component name must use alphanumeric characters or underscore. Must not include characters such as : and . Examples: 'my_agent', 'step1', 'dataProcessor'\"\n },\n \"AgentComponent\": {\n \"type\": \"object\",\n \"required\": [\n \"name\",\n \"type\",\n \"prompt_id\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"$ref\": \"#/definitions/ComponentName\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"AgentComponent\"\n },\n \"prompt_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the prompt template from either the prompt registry or locally defined prompts\"\n },\n \"prompt_version\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"^[~^]?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$\",\n \"description\": \"Semantic version constraint (e.g., '^1.0.0')\"\n },\n {\n \"type\": \"null\",\n \"description\": \"Use locally defined prompt from flow YAML\"\n }\n ]\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"List of input data sources\",\n \"default\": [\n \"context:goal\"\n ],\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Simple input reference\"\n },\n {\n \"$ref\": \"#/definitions/InputMapping\"\n }\n ]\n }\n },\n \"toolset\": {\n \"type\": \"array\",\n \"description\": \"List of tools available to the agent. Can be tool names or objects with tool options. Examples: ['read_file', {'create_merge_request_note': {'force_internal': true}}]\",\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Tool name from tools registry\"\n },\n {\n \"type\": \"object\",\n \"description\": \"Tool with options. Key is tool name, value is options object\",\n \"minProperties\": 1,\n \"maxProperties\": 1,\n \"additionalProperties\": {\n \"type\": \"object\",\n \"description\": \"Tool-specific options as key-value pairs\",\n \"additionalProperties\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n },\n {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n }\n ]\n }\n }\n }\n ]\n }\n },\n \"ui_log_events\": {\n \"type\": \"array\",\n \"description\": \"UI logging configuration\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"on_agent_final_answer\",\n \"on_tool_execution_success\",\n \"on_tool_execution_failed\"\n ]\n }\n },\n \"ui_role_as\": {\n \"type\": \"string\",\n \"enum\": [\n \"agent\",\n \"tool\"\n ],\n \"description\": \"Display role in UI\"\n }\n }\n },\n \"DeterministicStepComponent\": {\n \"type\": \"object\",\n \"required\": [\n \"name\",\n \"type\",\n \"tool_name\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"$ref\": \"#/definitions/ComponentName\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"DeterministicStepComponent\"\n },\n \"tool_name\": {\n \"type\": \"string\",\n \"description\": \"Name of the single tool to execute\"\n },\n \"toolset\": {\n \"type\": \"array\",\n \"description\": \"Toolset containing the tool to be executed\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"List of input data sources to extract tool parameters\",\n \"default\": [],\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Simple input reference. Examples: 'context:goal'\"\n },\n {\n \"$ref\": \"#/definitions/InputMapping\"\n }\n ]\n }\n },\n \"ui_log_events\": {\n \"type\": \"array\",\n \"description\": \"UI logging configuration for displaying tool execution\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"on_tool_execution_success\",\n \"on_tool_execution_failed\"\n ]\n }\n },\n \"ui_role_as\": {\n \"type\": \"string\",\n \"enum\": [\n \"agent\",\n \"tool\"\n ],\n \"default\": \"tool\",\n \"description\": \"Display role in UI\"\n }\n }\n },\n \"OneOffComponent\": {\n \"type\": \"object\",\n \"required\": [\n \"name\",\n \"type\",\n \"prompt_id\",\n \"toolset\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"$ref\": \"#/definitions/ComponentName\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"OneOffComponent\"\n },\n \"prompt_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the prompt template from either the prompt registry or locally defined prompts\"\n },\n \"prompt_version\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"^[~^]?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$\",\n \"description\": \"Semantic version constraint. Examples: '1.0.0' (exact), '^1.2.3' (compatible)\"\n },\n {\n \"type\": \"null\",\n \"description\": \"Use locally defined prompt from flow YAML\"\n }\n ]\n },\n \"toolset\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"description\": \"List of tools available to the component. Examples: ['read_file', 'list_dir', 'edit_file']\",\n \"items\": {\n \"type\": \"string\",\n \"description\": \"Tool name from tools registry\"\n }\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"List of input data sources\",\n \"default\": [\n \"context:goal\"\n ],\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Simple input reference. Examples: 'context:goal'\"\n },\n {\n \"$ref\": \"#/definitions/InputMapping\"\n }\n ]\n }\n },\n \"max_correction_attempts\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"default\": 3,\n \"description\": \"Maximum number of retry attempts for failed tool executions\"\n },\n \"ui_log_events\": {\n \"type\": \"array\",\n \"description\": \"UI logging configuration for displaying tool execution progress\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"on_tool_call_input\",\n \"on_tool_execution_success\",\n \"on_tool_execution_failed\"\n ]\n }\n }\n }\n },\n \"InputMapping\": {\n \"type\": \"object\",\n \"required\": [\n \"from\",\n \"as\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"from\": {\n \"type\": \"string\",\n \"description\": \"Source of the input data. Examples: 'context:goal'\"\n },\n \"as\": {\n \"type\": \"string\",\n \"description\": \"Variable name to use in prompt template. Examples: 'user_goal'\"\n },\n \"literal\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the 'from' value should be treated as a literal value\"\n }\n }\n },\n \"Router\": {\n \"type\": \"object\",\n \"required\": [\n \"from\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"from\": {\n \"type\": \"string\",\n \"description\": \"Source component name. Examples: 'main_agent', 'data_processor'\"\n },\n \"to\": {\n \"type\": \"string\",\n \"description\": \"Target component name or 'end'. Examples: 'next_step', 'error_handler', 'end'\"\n },\n \"condition\": {\n \"$ref\": \"#/definitions/RouterCondition\"\n }\n },\n \"oneOf\": [\n {\n \"required\": [\n \"to\"\n ]\n },\n {\n \"required\": [\n \"condition\"\n ]\n }\n ]\n },\n \"RouterCondition\": {\n \"type\": \"object\",\n \"required\": [\n \"input\",\n \"routes\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"input\": {\n \"type\": \"string\",\n \"description\": \"Input to evaluate for routing decision\"\n },\n \"routes\": {\n \"type\": \"object\",\n \"description\": \"Mapping of condition values to target components\",\n \"patternProperties\": {\n \".*\": {\n \"type\": \"string\",\n \"description\": \"Target component name or 'end'\"\n }\n }\n }\n }\n },\n \"LocalPrompt\": {\n \"type\": \"object\",\n \"required\": [\n \"prompt_id\",\n \"name\",\n \"prompt_template\",\n \"unit_primitives\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"prompt_id\": {\n \"type\": \"string\",\n \"description\": \"Unique identifier for the local prompt\"\n },\n \"name\": {\n \"type\": \"string\",\n \"description\": \"name for the local prompt\"\n },\n \"prompt_template\": {\n \"$ref\": \"#/definitions/PromptTemplate\"\n },\n \"params\": {\n \"type\": \"object\",\n \"properties\": {\n \"timeout\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"description\": \"Timeout in seconds for prompt execution\"\n },\n \"vertex_location\": {\n \"type\": \"string\",\n \"description\": \"Vertex AI location for the flow\"\n }\n },\n \"additionalProperties\": false\n },\n \"unit_primitives\": {\n \"type\": \"array\",\n \"description\": \"Unit primitives configuration\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"PromptTemplate\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"system\": {\n \"type\": \"string\",\n \"description\": \"System message template\"\n },\n \"user\": {\n \"type\": \"string\",\n \"description\": \"User message template\"\n },\n \"placeholder\": {\n \"type\": \"string\",\n \"enum\": [\n \"history\"\n ],\n \"description\": \"Message placeholder for conversation history\"\n }\n }\n },\n \"FlowInputCategory\": {\n \"type\": \"object\",\n \"required\": [\n \"category\",\n \"input_schema\"\n ],\n \"additionalProperties\": false,\n \"description\": \"Defines a category of additional context inputs that can be passed to the flow\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\",\n \"description\": \"Category name for the additional context. Examples: 'merge_request_info', 'pipeline_info'\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"description\": \"Schema definition for the inputs in this category\",\n \"patternProperties\": {\n \".*\": {\n \"$ref\": \"#/definitions/FlowInputField\"\n }\n }\n }\n }\n },\n \"FlowInputField\": {\n \"type\": \"object\",\n \"required\": [\n \"type\"\n ],\n \"additionalProperties\": false,\n \"description\": \"Schema definition for a single input field\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"description\": \"JSON Schema type for the field. Examples: 'string'\"\n },\n \"format\": {\n \"type\": \"string\",\n \"description\": \"Optional JSON Schema format specifier. Examples: 'uri', 'email', 'date-time'\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Optional description of the field's purpose\"\n }\n }\n }\n }\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport {\n listAiCatalogItems,\n getAiCatalogItem,\n listProjectAiCatalogItems,\n enableAiCatalogItemForProject,\n disableAiCatalogItemForProject,\n} from \"../catalog\";\nimport type { AuthInfo } from \"../auth\";\n\nconst z = tool.schema;\n\nfunction makeItemTools(\n itemType: \"AGENT\" | \"FLOW\",\n label: string,\n getAuth: () => AuthInfo | null,\n ensureAuth: () => AuthInfo | null,\n onChanged?: () => Promise<void>\n) {\n const itemTypes = [itemType];\n const Label = label.charAt(0).toUpperCase() + label.slice(1);\n\n return {\n [`gitlab_list_${label}s`]: tool({\n description: `List ${label}s in the GitLab AI Catalog.\\nReturns ${label}s with name, description, visibility, foundational flag, and version info.\\nSupports search and cursor-based pagination.`,\n args: {\n search: z\n .string()\n .optional()\n .describe(`Search query to filter ${label}s by name or description`),\n first: z.number().optional().describe(\"Number of items to return (default 20)\"),\n after: z.string().optional().describe(\"Cursor for pagination (from pageInfo.endCursor)\"),\n },\n execute: async (args: { search?: string; first?: number; after?: string }) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await listAiCatalogItems(auth.instanceUrl, auth.token, itemTypes, args);\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_get_${label}`]: tool({\n description: `Get details of a specific ${label} from the AI Catalog.\\nReturns full details including name, description, visibility, versions, creator, and permissions.\\nAccepts either a full Global ID (gid://gitlab/Ai::Catalog::Item/123) or just the numeric ID.`,\n args: {\n [`${label}_id`]: z.string().describe(`${Label} ID: full GID or numeric ID`),\n },\n execute: async (args: Record<string, string>) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await getAiCatalogItem(auth.instanceUrl, auth.token, args[`${label}_id`]);\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_list_project_${label}s`]: tool({\n description: `List ${label}s enabled for a specific project.\\nReturns all configured ${label}s including foundational ones.\\nEach result includes the ${label} details and its consumer configuration.`,\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n first: z.number().optional().describe(\"Number of items to return (default 20)\"),\n after: z.string().optional().describe(\"Cursor for pagination\"),\n },\n execute: async (args: { project_id: string; first?: number; after?: string }) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await listProjectAiCatalogItems(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n itemTypes,\n { first: args.first, after: args.after }\n );\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_enable_project_${label}`]: tool({\n description: `Enable a ${label} in a project.\\nRequires Maintainer or Owner role.\\nEnabling in a project also enables at the group level.\\nFoundational ${label}s cannot be enabled this way (use admin settings).`,\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n [`${label}_id`]: z.string().describe(`${Label} ID: full GID or numeric ID`),\n },\n execute: async (args: Record<string, string>) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await enableAiCatalogItemForProject(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n args[`${label}_id`]\n );\n await onChanged?.();\n return (\n JSON.stringify(result, null, 2) +\n \"\\n\\nNote: Restart opencode for the @ menu to reflect changes.\"\n );\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_disable_project_${label}`]: tool({\n description: `Disable a ${label} in a project.\\nRequires Maintainer or Owner role.\\nResolves the consumer ID internally from the ${label} ID.`,\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n [`${label}_id`]: z.string().describe(`${Label} ID: full GID or numeric ID`),\n },\n execute: async (args: Record<string, string>) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await disableAiCatalogItemForProject(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n args[`${label}_id`]\n );\n await onChanged?.();\n return (\n JSON.stringify(result, null, 2) +\n \"\\n\\nNote: Restart opencode for the @ menu to reflect changes.\"\n );\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n };\n}\n\nexport function makeCatalogItemTools(ctx: {\n getAuth: () => AuthInfo | null;\n ensureAuth: () => AuthInfo | null;\n refreshAgents: () => Promise<void>;\n}): Record<string, any> {\n return {\n ...makeItemTools(\"AGENT\", \"agent\", ctx.getAuth, ctx.ensureAuth, ctx.refreshAgents),\n ...makeItemTools(\"FLOW\", \"flow\", ctx.getAuth, ctx.ensureAuth, ctx.refreshAgents),\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport type { CatalogAgent, McpServerInfo } from \"../types\";\n\nconst z = tool.schema;\n\nexport function makeMcpTools(getCachedAgents: () => CatalogAgent[]): Record<string, any> {\n return {\n gitlab_list_project_mcp_servers: tool({\n description:\n \"List MCP servers available through agents enabled for a project.\\n\" +\n \"Returns deduplicated servers with name, URL, auth type, connection status, and which agents use them.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n },\n execute: async (_args: { project_id: string }) => {\n const serverMap = new Map<string, McpServerInfo & { usedBy: string[] }>();\n\n for (const agent of getCachedAgents()) {\n if (!agent.mcpServers?.length) continue;\n for (const server of agent.mcpServers) {\n const existing = serverMap.get(server.id);\n if (existing) {\n if (!existing.usedBy.includes(agent.name)) existing.usedBy.push(agent.name);\n } else {\n serverMap.set(server.id, { ...server, usedBy: [agent.name] });\n }\n }\n }\n\n const servers = [...serverMap.values()];\n if (!servers.length) {\n return \"No MCP servers found for agents enabled in this project.\";\n }\n return JSON.stringify(servers, null, 2);\n },\n }),\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport {\n createWikiPage,\n updateWikiPage,\n getWikiPage,\n deleteWikiPage,\n listWikiPages,\n searchWikiPages,\n} from \"../wiki\";\nimport type { PluginContext } from \"../auth\";\nimport type { WikiPage } from \"../wiki\";\n\nconst z = tool.schema;\n\nconst PREFIX = \"agents\";\nconst ARCHIVE_DIR = `${PREFIX}/memory/archive`;\n\nconst MEMORY_TYPES = [\n \"facts\",\n \"decisions\",\n \"patterns\",\n \"architecture\",\n \"conventions\",\n \"troubleshooting\",\n \"people-and-contexts\",\n \"plans\",\n] as const;\n\nconst MEMORY_DIRS: Record<string, string[]> = {\n all: MEMORY_TYPES.map((t) => `${PREFIX}/memory/${t}`),\n ...Object.fromEntries(MEMORY_TYPES.map((t) => [t, [`${PREFIX}/memory/${t}`]])),\n archive: [ARCHIVE_DIR],\n};\n\nconst RECORD_TYPES = [\n \"fact\",\n \"decision\",\n \"pattern\",\n \"architecture\",\n \"convention\",\n \"troubleshooting\",\n \"people\",\n \"plan\",\n] as const;\n\nconst RECORD_DIR: Record<string, string> = {\n fact: `${PREFIX}/memory/facts`,\n decision: `${PREFIX}/memory/decisions`,\n pattern: `${PREFIX}/memory/patterns`,\n architecture: `${PREFIX}/memory/architecture`,\n convention: `${PREFIX}/memory/conventions`,\n troubleshooting: `${PREFIX}/memory/troubleshooting`,\n people: `${PREFIX}/memory/people-and-contexts`,\n plan: `${PREFIX}/memory/plans`,\n};\n\nconst PROJECT_ID_DESC =\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.';\n\nfunction today(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction shortHash(): string {\n return Math.random().toString(36).slice(2, 8);\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/(^-|-$)/g, \"\")\n .slice(0, 50);\n}\n\nfunction titleFromContent(content: string): string {\n const first = content\n .split(\"\\n\")[0]\n .replace(/^[#*\\->\\s]+/, \"\")\n .trim();\n return first.slice(0, 80) || \"untitled\";\n}\n\nfunction validateProjectId(projectId: string): string | null {\n if (!projectId.includes(\"/\")) {\n return `Invalid project_id \"${projectId}\". Must be the full project path containing at least one slash (e.g., \"my-group/my-project\"), not just the project name.`;\n }\n return null;\n}\n\nfunction resolveScope(args: { scope?: string; group_id?: string; project_id?: string }): {\n scope: \"projects\" | \"groups\";\n id: string | number;\n} {\n if (args.scope === \"groups\" && args.group_id) {\n return { scope: \"groups\", id: args.group_id };\n }\n return { scope: \"projects\", id: args.project_id! };\n}\n\nexport function makeMemoryTools(ctx: PluginContext): Record<string, any> {\n function authAndValidate(projectId: string) {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"GitLab authentication not available\");\n const err = validateProjectId(projectId);\n if (err) throw new Error(err);\n return auth;\n }\n\n return {\n gitlab_memory_load: tool({\n description:\n \"Load project memory to understand context, known facts, past decisions, and observed patterns.\\n\" +\n \"Use this at the start of complex tasks to check what is already known about the project.\\n\" +\n \"Returns accumulated knowledge from previous sessions.\\n\" +\n \"Each entry includes its slug (page path) which can be used with gitlab_memory_update or gitlab_memory_archive.\\n\\n\" +\n \"BOOTSTRAP WORKFLOW — when user says 'bootstrap project memory':\\n\" +\n \"1. Get project path from run_git_command('remote', ['-v']) — NEVER guess.\\n\" +\n \"2. Call this tool to check if memory exists.\\n\" +\n \"3. If empty: gather knowledge (README, gitlab_get_project, gitlab_list_issues, gitlab_list_merge_requests, gitlab_list_pipelines, gitlab_list_project_members), then record using ALL THREE types:\\n\" +\n \" - type='fact': project overview, tech stack, dependencies, CI/CD config, open issues summary, open MRs summary\\n\" +\n \" - type='architecture': system design, module structure, key abstractions, data flow\\n\" +\n \" - type='decision': key architectural choices found in the codebase (framework choices, config patterns, deployment strategy)\\n\" +\n \" - type='convention': coding standards, naming patterns, commit conventions, review process\\n\" +\n \" - type='pattern': recurring observations (CI patterns, common failures, release cycle)\\n\" +\n \" - type='troubleshooting': known issues, workarounds, pipeline failures, common errors\\n\" +\n \" - type='people': team members, roles, ownership areas, key contacts\\n\" +\n \" Fire parallel gitlab_memory_record calls — each creates its own page.\\n\" +\n \"4. If exists: show summary, gather current state, compare with stored records, use gitlab_memory_update for stale, gitlab_memory_archive for outdated, gitlab_memory_record for new.\\n\" +\n \"5. Log session with gitlab_memory_log_session.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n type: z\n .enum([\"all\", ...MEMORY_TYPES, \"archive\"])\n .optional()\n .describe(\n 'Which memory to load: \"all\" (default), \"facts\", \"decisions\", \"patterns\", \"architecture\", \"conventions\", \"troubleshooting\", \"people-and-contexts\", or \"archive\"'\n ),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n type?: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n const memType = args.type ?? \"all\";\n const dirs = MEMORY_DIRS[memType];\n if (!dirs) return `Unknown memory type: ${memType}`;\n\n try {\n const allPages = (await listWikiPages(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n true\n )) as WikiPage[];\n\n const sections: string[] = [];\n for (const dir of dirs) {\n const label = dir.split(\"/\").pop()!;\n const pages = allPages.filter((p) => p.slug.startsWith(dir + \"/\") && p.content);\n if (pages.length === 0) continue;\n\n const entries = pages.map((p) => `### ${p.slug}\\n${p.content}`).join(\"\\n\\n---\\n\\n\");\n sections.push(\n `## ${label.charAt(0).toUpperCase() + label.slice(1)} (${pages.length})\\n\\n${entries}`\n );\n }\n\n if (sections.length === 0)\n return \"No project memory found. Use gitlab_memory_record to start building project knowledge.\";\n return sections.join(\"\\n\\n---\\n\\n\");\n } catch (err: any) {\n return `Error loading memory: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_record: tool({\n description:\n \"Record knowledge in project memory. Each record creates its own page — safe for parallel writes.\\n\" +\n \"Types:\\n\" +\n \" fact — stable truths (tech stack, dependencies, deploy targets, project metadata)\\n\" +\n \" decision — architectural choices with reasoning (why X over Y)\\n\" +\n \" pattern — recurring observations that may evolve into skills\\n\" +\n \" architecture — system design, module structure, data flow, key abstractions\\n\" +\n \" convention — coding standards, naming patterns, review process, commit conventions\\n\" +\n \" troubleshooting — known issues, workarounds, debugging tips, common errors\\n\" +\n \" people — team members, roles, ownership areas, contact context\\n\" +\n \" plan — implementation plans, feature designs, task breakdowns, roadmap items\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n type: z.enum([...RECORD_TYPES]).describe(\"Type of knowledge to record\"),\n content: z.string().describe(\"The knowledge to record (markdown)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n type: string;\n content: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n const dir = RECORD_DIR[args.type];\n if (!dir) return `Unknown memory type: ${args.type}`;\n\n const date = today();\n const title = titleFromContent(args.content);\n const slug = `${dir}/${date}-${slugify(title)}-${shortHash()}`;\n\n const header = `*Recorded: ${date} | Type: ${args.type}*\\n\\n`;\n const body = header + args.content;\n\n try {\n await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, body);\n return `Recorded ${args.type} in project memory: ${slug}`;\n } catch (err: any) {\n return `Error recording ${args.type}: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_update: tool({\n description:\n \"Update an existing memory record with new content.\\n\" +\n \"Use this to correct stale facts, update issue counts, or refine decisions.\\n\" +\n \"The slug is the page path shown in gitlab_memory_load output (e.g., agents/memory/facts/2026-04-05-project-overview).\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n slug: z\n .string()\n .describe(\n 'Page slug from gitlab_memory_load output (e.g., \"agents/memory/facts/2026-04-05-project-overview\")'\n ),\n content: z.string().describe(\"New content to replace the existing record (markdown)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n slug: string;\n content: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n await getWikiPage(auth.instanceUrl, auth.token, scope, id, args.slug);\n } catch {\n return `Memory record not found: ${args.slug}. Use gitlab_memory_load to see available records.`;\n }\n\n const date = today();\n const header = `*Updated: ${date}*\\n\\n`;\n\n try {\n await updateWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n args.slug,\n header + args.content\n );\n return `Updated memory record: ${args.slug}`;\n } catch (err: any) {\n return `Error updating memory: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_archive: tool({\n description:\n \"Archive an outdated memory record.\\n\" +\n \"Moves the record to the archive directory so it is no longer loaded by default.\\n\" +\n \"Archived records are still searchable via gitlab_memory_recall and loadable via gitlab_memory_load(type='archive').\\n\" +\n \"Use this for facts that are no longer true, decisions that were reversed, or patterns that stopped occurring.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n slug: z\n .string()\n .describe(\n 'Page slug to archive (e.g., \"agents/memory/facts/2026-04-05-open-issues-summary\")'\n ),\n reason: z\n .string()\n .optional()\n .describe(\n 'Why this record is being archived (e.g., \"issue was fixed\", \"no longer relevant\")'\n ),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n slug: string;\n reason?: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n let originalContent: string;\n try {\n const page = await getWikiPage(auth.instanceUrl, auth.token, scope, id, args.slug);\n originalContent = page.content;\n } catch {\n return `Memory record not found: ${args.slug}. Use gitlab_memory_load to see available records.`;\n }\n\n const date = today();\n const suffix = args.slug.split(\"/\").slice(3).join(\"/\");\n const archiveSlug = `${ARCHIVE_DIR}/${suffix}`;\n const reasonLine = args.reason ? `\\n*Reason: ${args.reason}*` : \"\";\n const archiveHeader = `*Archived: ${date} | Original: ${args.slug}*${reasonLine}\\n\\n`;\n\n try {\n await createWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n archiveSlug,\n archiveHeader + originalContent\n );\n await deleteWikiPage(auth.instanceUrl, auth.token, scope, id, args.slug);\n return `Archived: ${args.slug} → ${archiveSlug}`;\n } catch (err: any) {\n return `Error archiving memory: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_consolidate: tool({\n description:\n \"Review all memory records and get consolidation instructions.\\n\" +\n \"Loads all records of the specified type and returns them with their slugs,\\n\" +\n \"along with instructions to identify and fix stale, duplicate, or contradictory entries.\\n\" +\n \"Use this periodically to keep project memory clean and accurate.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n type: z\n .enum([\"all\", ...MEMORY_TYPES])\n .optional()\n .describe('Which memory to consolidate: \"all\" (default) or a specific type'),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n type?: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n const memType = args.type ?? \"all\";\n const dirs = MEMORY_DIRS[memType];\n if (!dirs) return `Unknown memory type: ${memType}`;\n\n try {\n const allPages = (await listWikiPages(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n true\n )) as WikiPage[];\n\n const entries: Array<{ slug: string; content: string }> = [];\n for (const dir of dirs) {\n const pages = allPages.filter((p) => p.slug.startsWith(dir + \"/\") && p.content);\n for (const p of pages) {\n entries.push({ slug: p.slug, content: p.content });\n }\n }\n\n if (entries.length === 0) return \"No memory records to consolidate.\";\n\n const listing = entries\n .map((e, i) => `### [${i + 1}] ${e.slug}\\n${e.content}`)\n .join(\"\\n\\n---\\n\\n\");\n\n const instructions = [\n `## Memory Consolidation Review`,\n ``,\n `Found **${entries.length} records** to review. For each record:`,\n ``,\n `1. **Stale?** — Is the information still current? If not, either:`,\n ` - Call \\`gitlab_memory_update(slug, new_content)\\` with corrected info`,\n ` - Call \\`gitlab_memory_archive(slug, reason)\\` if no longer relevant`,\n ``,\n `2. **Duplicate?** — Does another record cover the same information?`,\n ` - Keep the better one, archive the other`,\n ``,\n `3. **Contradictory?** — Do two records disagree?`,\n ` - Verify which is correct, update one, archive the other`,\n ``,\n `4. **Mergeable?** — Are there many small records about the same topic?`,\n ` - Create one consolidated record, archive the originals`,\n ``,\n `After reviewing, log a session with gitlab_memory_log_session summarizing what was cleaned up.`,\n ``,\n `---`,\n ``,\n listing,\n ].join(\"\\n\");\n\n return instructions;\n } catch (err: any) {\n return `Error loading memory for consolidation: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_recall: tool({\n description:\n \"Search project knowledge for relevant information.\\n\" +\n \"Searches across all memory pages, session logs, and skills.\\n\" +\n \"Use this to check if something is already known before investigating.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n query: z.string().describe(\"What to search for\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n query: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n const results = await searchWikiPages(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n args.query\n );\n if (results.length === 0) return `No knowledge found matching \"${args.query}\".`;\n return results\n .map((r) => {\n const category = r.path.includes(\"/memory/\")\n ? \"memory\"\n : r.path.includes(\"/skills\")\n ? \"skill\"\n : \"other\";\n const snippet = (r.data ?? \"\").slice(0, 200).replace(/\\n/g, \" \");\n return `[${category}] ${r.path}: ${snippet}`;\n })\n .join(\"\\n\\n\");\n } catch (err: any) {\n return `Error searching knowledge: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_log_session: tool({\n description:\n \"Log a session summary including what was accomplished, what was learned, and any suggestions.\\n\" +\n \"Use this at the end of significant work sessions to preserve context for future sessions.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n title: z.string().describe('Brief session title (e.g., \"fix-ai-gateway-healthcheck\")'),\n summary: z\n .string()\n .describe(\n \"Session summary in markdown (what happened, what was learned, what went wrong)\"\n ),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n title: string;\n summary: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const date = today();\n const slug = `${PREFIX}/memory/sessions/${date}-${slugify(args.title)}-${shortHash()}`;\n\n try {\n await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.summary);\n return `Session logged: ${slug}`;\n } catch (err: any) {\n return `Error logging session: ${err.message}`;\n }\n },\n }),\n };\n}\n","export interface WikiPage {\n slug: string;\n title: string;\n content: string;\n format: string;\n encoding: string;\n}\n\nexport interface WikiPageSummary {\n slug: string;\n title: string;\n format: string;\n}\n\nexport interface WikiSearchResult {\n basename: string;\n data: string;\n path: string;\n filename: string;\n ref: string;\n startline: number;\n project_id: number;\n}\n\ntype Scope = \"projects\" | \"groups\";\n\nfunction wikiApi(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n path = \"\"\n): { url: string; headers: Record<string, string> } {\n const base = instanceUrl.replace(/\\/$/, \"\");\n const encodedId = encodeURIComponent(String(id));\n return {\n url: `${base}/api/v4/${scope}/${encodedId}/wikis${path}`,\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n };\n}\n\nasync function handleResponse<T>(res: Response): Promise<T> {\n if (res.ok) return res.json() as Promise<T>;\n const status = res.status;\n if (status === 404)\n throw new Error(\n \"Page not found. Use gitlab_wiki_list to see available pages, or gitlab_wiki_write to create it.\"\n );\n if (status === 403)\n throw new Error(\n \"Permission denied. The wiki may not be enabled for this project. Enable it in Settings > General > Visibility.\"\n );\n if (status === 422)\n throw new Error(\"Invalid page title or content. Check that the slug and content are valid.\");\n if (status === 401) throw new Error(\"Authentication failed. Check your GitLab token.\");\n const text = await res.text();\n throw new Error(`Wiki API error (${status}): ${text}`);\n}\n\nexport async function listWikiPages(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n withContent?: boolean\n): Promise<WikiPageSummary[] | WikiPage[]> {\n const { url, headers } = wikiApi(instanceUrl, token, scope, id);\n const fullUrl = withContent ? `${url}?with_content=1` : url;\n const res = await fetch(fullUrl, { headers });\n return handleResponse(res);\n}\n\nexport async function getWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string\n): Promise<WikiPage> {\n const encodedSlug = encodeURIComponent(slug);\n const { url, headers } = wikiApi(instanceUrl, token, scope, id, `/${encodedSlug}`);\n const res = await fetch(url, { headers });\n return handleResponse(res);\n}\n\nexport async function createWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n title: string,\n content: string,\n format = \"markdown\"\n): Promise<WikiPage> {\n const { url, headers } = wikiApi(instanceUrl, token, scope, id);\n const res = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ title, content, format }),\n });\n return handleResponse(res);\n}\n\nexport async function updateWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string,\n content: string,\n title?: string\n): Promise<WikiPage> {\n const encodedSlug = encodeURIComponent(slug);\n const { url, headers } = wikiApi(instanceUrl, token, scope, id, `/${encodedSlug}`);\n const body: Record<string, string> = { content };\n if (title) body.title = title;\n const res = await fetch(url, {\n method: \"PUT\",\n headers,\n body: JSON.stringify(body),\n });\n return handleResponse(res);\n}\n\nexport async function deleteWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string\n): Promise<void> {\n const encodedSlug = encodeURIComponent(slug);\n const { url, headers } = wikiApi(instanceUrl, token, scope, id, `/${encodedSlug}`);\n const res = await fetch(url, { method: \"DELETE\", headers });\n if (!res.ok) await handleResponse(res);\n}\n\nexport async function searchWikiPages(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n query: string\n): Promise<WikiSearchResult[]> {\n const base = instanceUrl.replace(/\\/$/, \"\");\n const encodedId = encodeURIComponent(String(id));\n const url = `${base}/api/v4/${scope}/${encodedId}/search?scope=wiki_blobs&search=${encodeURIComponent(query)}`;\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n return handleResponse(res);\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport {\n getWikiPage,\n createWikiPage,\n updateWikiPage,\n deleteWikiPage,\n listWikiPages,\n} from \"../wiki\";\nimport type { PluginContext } from \"../auth\";\n\nconst z = tool.schema;\n\nconst PREFIX = \"agents\";\nconst SKILLS_PREFIX = `${PREFIX}/skills`;\nconst DRAFTS_PREFIX = `${PREFIX}/skills-drafts`;\n\nfunction resolveScope(args: { scope?: string; group_id?: string; project_id?: string }): {\n scope: \"projects\" | \"groups\";\n id: string | number;\n} {\n if (args.scope === \"groups\" && args.group_id) {\n return { scope: \"groups\", id: args.group_id };\n }\n return { scope: \"projects\", id: args.project_id! };\n}\n\nfunction validateProjectId(projectId: string): string | null {\n if (!projectId.includes(\"/\")) {\n return `Invalid project_id \"${projectId}\". Must be the full project path containing at least one slash (e.g., \"my-group/my-project\"), not just the project name.`;\n }\n return null;\n}\n\nexport function makeSkillTools(ctx: PluginContext): Record<string, any> {\n function authAndValidate(projectId: string) {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"GitLab authentication not available\");\n const err = validateProjectId(projectId);\n if (err) throw new Error(err);\n return auth;\n }\n\n return {\n gitlab_skill_list: tool({\n description:\n \"List available project skills and optionally draft skills.\\n\" +\n \"Skills define step-by-step procedures for common tasks (e.g., incident retros, debugging, deployments).\",\n args: {\n project_id: z\n .string()\n .describe(\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.'\n ),\n include_drafts: z.boolean().optional().describe(\"Also list draft skills (default: false)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n include_drafts?: boolean;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n const pages = await listWikiPages(auth.instanceUrl, auth.token, scope, id);\n const indexSlug = `${SKILLS_PREFIX}/index`;\n const skills = pages\n .filter((p) => p.slug.startsWith(`${SKILLS_PREFIX}/`) && p.slug !== indexSlug)\n .map((p) => ({\n name: p.slug.slice(SKILLS_PREFIX.length + 1),\n title: p.title,\n draft: false,\n }));\n\n let drafts: typeof skills = [];\n if (args.include_drafts) {\n const draftsIndexSlug = `${DRAFTS_PREFIX}/index`;\n drafts = pages\n .filter((p) => p.slug.startsWith(`${DRAFTS_PREFIX}/`) && p.slug !== draftsIndexSlug)\n .map((p) => ({\n name: p.slug.slice(DRAFTS_PREFIX.length + 1),\n title: p.title,\n draft: true,\n }));\n }\n\n const all = [...skills, ...drafts];\n if (all.length === 0) return \"No skills found. Use gitlab_skill_save to create one.\";\n return JSON.stringify(all, null, 2);\n } catch (err: any) {\n return `Error listing skills: ${err.message}`;\n }\n },\n }),\n\n gitlab_skill_load: tool({\n description:\n \"Load a specific skill by name.\\n\" +\n \"Skills contain step-by-step instructions for common tasks.\\n\" +\n \"Checks published skills first, then falls back to draft skills.\",\n args: {\n project_id: z\n .string()\n .describe(\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.'\n ),\n name: z.string().describe('Skill name (e.g., \"incident-retro\", \"helm-rollback\")'),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n const page = await getWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n `${SKILLS_PREFIX}/${args.name}`\n );\n return page.content;\n } catch {\n try {\n const draft = await getWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n `${DRAFTS_PREFIX}/${args.name}`\n );\n return `[DRAFT SKILL]\\n\\n${draft.content}`;\n } catch {\n return `Skill \"${args.name}\" not found. Use gitlab_skill_list to see available skills.`;\n }\n }\n },\n }),\n\n gitlab_skill_save: tool({\n description:\n \"Create or update a skill.\\n\" +\n \"Skills define step-by-step procedures for common tasks.\\n\" +\n \"Use draft=true for skills that haven't been proven yet.\",\n args: {\n project_id: z\n .string()\n .describe(\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.'\n ),\n name: z.string().describe('Skill name (e.g., \"incident-retro\")'),\n content: z.string().describe(\"Skill content in markdown\"),\n draft: z.boolean().optional().describe(\"Save as draft skill (default: false)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n content: string;\n draft?: boolean;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const prefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;\n const slug = `${prefix}/${args.name}`;\n const label = args.draft ? \"draft \" : \"\";\n\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n await updateWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.content);\n return `Updated ${label}skill: ${args.name}`;\n } catch {\n try {\n await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.content);\n return `Created ${label}skill: ${args.name}`;\n } catch (err: any) {\n const msg = err.message ?? \"\";\n if (msg.includes(\"Duplicate page\") || msg.includes(\"reference update\")) {\n await new Promise((r) => setTimeout(r, 1000 * (attempt + 1)));\n continue;\n }\n return `Error saving skill: ${msg}`;\n }\n }\n }\n return `Error saving skill: failed after 3 retries`;\n },\n }),\n\n gitlab_skill_promote: tool({\n description:\n \"Promote a draft skill to published.\\n\" +\n \"Moves the skill from the drafts directory to the published skills directory.\",\n args: {\n project_id: z\n .string()\n .describe(\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.'\n ),\n name: z.string().describe(\"Skill name to promote\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const draftSlug = `${DRAFTS_PREFIX}/${args.name}`;\n const publishedSlug = `${SKILLS_PREFIX}/${args.name}`;\n\n try {\n const draft = await getWikiPage(auth.instanceUrl, auth.token, scope, id, draftSlug);\n\n try {\n await updateWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n publishedSlug,\n draft.content\n );\n } catch {\n await createWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n publishedSlug,\n draft.content\n );\n }\n\n await deleteWikiPage(auth.instanceUrl, auth.token, scope, id, draftSlug);\n return `Promoted skill \"${args.name}\" from draft to published.`;\n } catch (err: any) {\n if (err.message?.includes(\"not found\") || err.message?.includes(\"404\")) {\n return `Draft skill \"${args.name}\" not found. Use gitlab_skill_list(include_drafts=true) to see available drafts.`;\n }\n return `Error promoting skill: ${err.message}`;\n }\n },\n }),\n };\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EACb,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAC7B,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAChB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["key","yamlLoad","fetchMcpServers","data","nodes","normalizeItemGid","os","baseUrl","projectUrl","rawText","original","import_plugin","import_js_yaml","yaml","Ajv","z","import_plugin","z","import_plugin","z","import_plugin","z","import_plugin","z","PREFIX","resolveScope","validateProjectId"]}
|
|
1
|
+
{"version":3,"sources":["../src/graphql.ts","../src/mcp-servers.ts","../src/index.ts","../src/flow-execution.ts","../src/generated/foundational-flows.ts","../src/catalog-items.ts","../src/catalog-crud.ts","../src/catalog.ts","../src/auth.ts","../src/agents.ts","../src/prompts.ts","../src/hooks.ts","../src/tools/flow-tools.ts","../src/tools/catalog-crud-tools.ts","../src/flow-validator.ts","../vendor/schemas/flow_v2.json","../src/tools/catalog-item-tools.ts","../src/tools/mcp-tools.ts","../src/tools/memory-tools.ts","../src/wiki.ts","../src/tools/skill-tools.ts"],"sourcesContent":["export async function gql(\n instanceUrl: string,\n token: string,\n query: string,\n variables: Record<string, unknown>\n): Promise<any> {\n const res = await fetch(`${instanceUrl.replace(/\\/$/, \"\")}/api/graphql`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify({ query, variables }),\n });\n const json = (await res.json()) as any;\n if (json.errors?.length) throw new Error(json.errors[0].message);\n return json.data;\n}\n","import { gql } from \"./graphql\";\nimport type { CatalogAgent, McpServerInfo } from \"./types\";\n\nconst MCP_SERVERS_QUERY = `\nquery AiCatalogMcpServers($projectId: ProjectID!, $after: String) {\n aiCatalogConfiguredItems(first: 50, projectId: $projectId, itemTypes: [AGENT], after: $after) {\n pageInfo { hasNextPage endCursor }\n nodes {\n item {\n id\n name\n latestVersion {\n ... on AiCatalogAgentVersion {\n mcpServers {\n nodes { id name description url transport authType currentUserConnected }\n }\n }\n }\n }\n }\n }\n}`;\n\nexport async function fetchMcpServers(\n instanceUrl: string,\n token: string,\n projectId: string,\n agents: CatalogAgent[]\n): Promise<void> {\n try {\n let after: string | null = null;\n const serversByAgent = new Map<string, McpServerInfo[]>();\n\n for (;;) {\n const data = await gql(instanceUrl, token, MCP_SERVERS_QUERY, {\n projectId,\n ...(after ? { after } : {}),\n });\n const page = data?.aiCatalogConfiguredItems;\n if (!page) break;\n\n for (const node of page.nodes ?? []) {\n const item = node.item;\n const version = item?.latestVersion;\n if (!version?.mcpServers?.nodes?.length) continue;\n const servers: McpServerInfo[] = version.mcpServers.nodes.map((s: any) => ({\n id: s.id,\n name: s.name,\n description: s.description ?? \"\",\n url: s.url,\n transport: s.transport,\n authType: s.authType,\n currentUserConnected: !!s.currentUserConnected,\n }));\n serversByAgent.set(item.id, servers);\n }\n\n if (!page.pageInfo?.hasNextPage) break;\n after = page.pageInfo.endCursor;\n }\n\n for (const agent of agents) {\n const servers = serversByAgent.get(agent.identifier);\n if (servers?.length) agent.mcpServers = servers;\n }\n } catch {\n // MCP servers query not available — silently skip\n }\n}\n\nexport async function listMcpServerTools(\n server: McpServerInfo\n): Promise<Array<{ name: string; description: string }>> {\n try {\n const res = await fetch(server.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json, text/event-stream\",\n },\n body: JSON.stringify({ jsonrpc: \"2.0\", id: 1, method: \"tools/list\", params: {} }),\n });\n if (!res.ok) return [];\n const data = await res.json();\n const tools = data?.result?.tools;\n if (!Array.isArray(tools)) return [];\n return tools.map((t: any) => ({ name: t.name, description: t.description ?? \"\" }));\n } catch {\n return [];\n }\n}\n\nexport async function discoverMcpToolNames(agents: CatalogAgent[]): Promise<Map<string, string[]>> {\n const result = new Map<string, string[]>();\n const seen = new Set<string>();\n\n for (const agent of agents) {\n if (!agent.mcpServers?.length) continue;\n const agentToolNames: string[] = [];\n for (const server of agent.mcpServers) {\n if (seen.has(server.id)) {\n const key = server.name.toLowerCase().replace(/[^a-z0-9]+/g, \"_\");\n const cached = result.get(server.id);\n if (cached) agentToolNames.push(...cached.map((t) => `${key}_${t}`));\n continue;\n }\n seen.add(server.id);\n const tools = await listMcpServerTools(server);\n const toolNames = tools.map((t) => t.name);\n result.set(server.id, toolNames);\n const key = server.name.toLowerCase().replace(/[^a-z0-9]+/g, \"_\");\n agentToolNames.push(...toolNames.map((t) => `${key}_${t}`));\n }\n result.set(agent.identifier, agentToolNames);\n }\n return result;\n}\n","import type { Plugin } from \"@opencode-ai/plugin\";\nimport { GitLabModelCache } from \"gitlab-ai-provider\";\nimport { fetchCatalogAgents } from \"./catalog\";\nimport type { CatalogAgent } from \"./types\";\nimport { readAuth, type AuthInfo } from \"./auth\";\nimport { resolveModelId } from \"./agents\";\nimport {\n buildFlowSubagentPrompt,\n makeChatMessageHook,\n makeChatParamsHook,\n makeSystemTransformHook,\n} from \"./hooks\";\nimport { makeFlowTools } from \"./tools/flow-tools\";\nimport { makeCatalogCrudTools } from \"./tools/catalog-crud-tools\";\nimport { makeCatalogItemTools } from \"./tools/catalog-item-tools\";\nimport { makeMcpTools } from \"./tools/mcp-tools\";\nimport { makeMemoryTools } from \"./tools/memory-tools\";\nimport { makeSkillTools } from \"./tools/skill-tools\";\n\nconst memo = new Map<string, Awaited<ReturnType<typeof fetchCatalogAgents>>>();\n\nconst plugin: Plugin = async (input) => {\n let authCache: AuthInfo | null = null;\n let projectPath: string | undefined;\n let namespaceId: number | undefined;\n const flowAgents = new Map<string, CatalogAgent>();\n const gitlabAgentNames = new Set<string>();\n let cachedAgents: CatalogAgent[] = [];\n let cfgRef: any = null;\n let baseModelIdRef: string | undefined;\n\n function ensureAuth(): AuthInfo | null {\n if (!authCache) {\n const auth = readAuth();\n if (auth) authCache = auth;\n }\n return authCache;\n }\n\n async function load() {\n const auth = readAuth();\n if (!auth) return null;\n authCache = auth;\n\n const { token, instanceUrl } = auth;\n\n const cache = new GitLabModelCache(input.directory, instanceUrl);\n const entry = cache.load() as any;\n if (!entry?.discovery) return null;\n\n const projectId = entry.project?.id;\n if (!projectId) return null;\n projectPath = entry.project?.pathWithNamespace;\n namespaceId = entry.project?.namespaceId;\n\n const key = `${input.directory}\\0${instanceUrl}`;\n const cached = memo.get(key);\n const agents =\n cached ?? (await fetchCatalogAgents(instanceUrl, token, `gid://gitlab/Project/${projectId}`));\n if (!cached) memo.set(key, agents);\n\n return { agents, entry };\n }\n\n async function refreshAgents() {\n if (!authCache || !cfgRef) return;\n const key = `${input.directory}\\0${authCache.instanceUrl}`;\n memo.delete(key);\n const result = await load();\n if (!result) return;\n\n const previousNames = new Set([\n ...flowAgents.keys(),\n ...Object.keys(cfgRef.agent ?? {}).filter((n) => {\n const desc = cfgRef.agent[n]?.description ?? \"\";\n return desc.startsWith(\"[GitLab\");\n }),\n ]);\n\n flowAgents.clear();\n gitlabAgentNames.clear();\n const currentNames = new Set<string>();\n for (const agent of result.agents) {\n const isFlow = agent.itemType === \"FLOW\";\n const ico = agent.foundational ? \" \\u{1F98A}\" : \"\";\n const dName = `${agent.name}${ico}`;\n currentNames.add(dName);\n if (isFlow && agent.consumerId && projectPath) {\n flowAgents.set(dName, agent);\n const rBaseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n const rProjectUrl = `${rBaseUrl}/${projectPath}`;\n cfgRef.agent[dName] = {\n name: dName,\n description: `[GitLab Flow] ${agent.description}`,\n mode: \"subagent\",\n prompt: buildFlowSubagentPrompt(agent, projectPath, rProjectUrl),\n permission: { \"*\": \"allow\" },\n };\n } else {\n gitlabAgentNames.add(dName);\n cfgRef.agent[dName] = {\n name: dName,\n description: agent.foundational ? \"[GitLab Foundational Agent]\" : \"[GitLab Custom Agent]\",\n mode: \"primary\",\n model: `gitlab/${baseModelIdRef}`,\n options: {\n workflowDefinition: agent.workflowDefinition,\n flowConfig: agent.flowConfig,\n flowConfigSchemaVersion: agent.flowConfigSchemaVersion,\n aiCatalogItemVersionId: agent.catalogItemVersionId,\n },\n permission: { \"*\": \"allow\" },\n };\n }\n }\n\n for (const name of previousNames) {\n if (!currentNames.has(name)) {\n delete cfgRef.agent[name];\n }\n }\n }\n\n const ctx = {\n getAuth: () => authCache,\n ensureAuth,\n getFlowAgents: () => flowAgents,\n getCachedAgents: () => cachedAgents,\n getNamespaceId: () => namespaceId,\n refreshAgents,\n };\n\n return {\n async config(cfg: any) {\n const result = await load();\n if (!result?.agents.length) return;\n\n cachedAgents = result.agents;\n const baseModelId = resolveModelId(result.entry);\n cfg.agent ??= {};\n cfgRef = cfg;\n baseModelIdRef = baseModelId;\n const cfgBaseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n\n for (const agent of result.agents) {\n const isFlow = agent.itemType === \"FLOW\";\n const icon = agent.foundational ? \" \\u{1F98A}\" : \"\";\n\n if (isFlow && agent.consumerId && projectPath) {\n const displayName = `${agent.name}${icon}`;\n flowAgents.set(displayName, agent);\n const pUrl = `${cfgBaseUrl}/${projectPath}`;\n cfg.agent[displayName] = {\n name: displayName,\n description: `[GitLab Flow] ${agent.description}`,\n mode: \"subagent\",\n prompt: buildFlowSubagentPrompt(agent, projectPath, pUrl),\n permission: { \"*\": \"allow\" },\n };\n } else {\n const displayName = `${agent.name}${icon}`;\n gitlabAgentNames.add(displayName);\n cfg.agent[displayName] = {\n name: displayName,\n description: agent.foundational\n ? \"[GitLab Foundational Agent]\"\n : \"[GitLab Custom Agent]\",\n mode: \"primary\",\n model: `gitlab/${baseModelId}`,\n options: {\n workflowDefinition: agent.workflowDefinition,\n flowConfig: agent.flowConfig,\n flowConfigSchemaVersion: agent.flowConfigSchemaVersion,\n aiCatalogItemVersionId: agent.catalogItemVersionId,\n },\n permission: { \"*\": \"allow\" },\n };\n }\n }\n },\n\n \"chat.message\": makeChatMessageHook(\n () => authCache,\n flowAgents,\n () => projectPath\n ),\n \"chat.params\": makeChatParamsHook(gitlabAgentNames),\n \"experimental.chat.system.transform\": makeSystemTransformHook(flowAgents, () => authCache),\n\n tool: {\n ...makeFlowTools(ctx),\n ...makeMcpTools(() => cachedAgents),\n ...makeCatalogCrudTools(ctx),\n ...makeCatalogItemTools(ctx),\n ...makeMemoryTools(ctx),\n ...makeSkillTools(ctx),\n },\n };\n};\n\nexport default plugin;\n","import { load as yamlLoad } from \"js-yaml\";\nimport { gql } from \"./graphql\";\nimport { FOUNDATIONAL_FLOWS } from \"./generated/foundational-flows\";\nimport type { CatalogAgent, FlowInputDef } from \"./types\";\n\nexport function extractFlowInputs(flowConfig: Record<string, unknown> | undefined): FlowInputDef[] {\n if (!flowConfig) return [];\n const flow = flowConfig.flow as Record<string, unknown> | undefined;\n if (!flow?.inputs) return [];\n const inputs = flow.inputs as Array<Record<string, unknown>>;\n return inputs.map((inp) => ({\n category: inp.category as string,\n fields: Object.fromEntries(\n Object.entries((inp.input_schema ?? {}) as Record<string, any>).map(([k, v]) => [\n k,\n { type: v.type, description: v.description, format: v.format },\n ])\n ),\n }));\n}\n\nconst FOUNDATIONAL_QUERY = `\nquery AiFoundationalChatAgents($projectId: ProjectID!, $after: String) {\n aiFoundationalChatAgents(projectId: $projectId, first: 50, after: $after) {\n pageInfo { hasNextPage endCursor }\n nodes { id name description reference referenceWithVersion }\n }\n}`;\n\nconst CUSTOM_AGENTS_QUERY = `\nquery AiCatalogCustomAgents($projectId: ProjectID!, $after: String) {\n aiCatalogConfiguredItems(first: 50, projectId: $projectId, after: $after) {\n pageInfo { hasNextPage endCursor }\n nodes {\n id\n enabled\n item {\n id\n name\n description\n foundational\n foundationalFlowReference\n itemType\n latestVersion { id }\n }\n }\n }\n}`;\n\nconst FLOW_CONFIG_QUERY = `\nquery AiCatalogAgentFlowConfig($versionId: AiCatalogItemVersionID!) {\n aiCatalogAgentFlowConfig(agentVersionId: $versionId, flowConfigType: CHAT)\n}`;\n\nconst FLOW_VERSION_DEFINITION_QUERY = `\nquery FlowVersionDefinition($itemId: AiCatalogItemID!) {\n aiCatalogItem(id: $itemId) {\n latestVersion {\n ... on AiCatalogFlowVersion {\n definition\n }\n }\n }\n}`;\n\nconst RESOLVE_ROOT_NAMESPACE_QUERY = `\nquery resolveRootNamespace($projectPath: ID!) {\n project(fullPath: $projectPath) {\n id\n group {\n id\n rootNamespace { id }\n }\n }\n}`;\n\nconst WORKFLOW_STATUS_QUERY = `\nquery getWorkflowStatus($workflowId: AiDuoWorkflowsWorkflowID!) {\n duoWorkflowWorkflows(workflowId: $workflowId) {\n nodes {\n id\n status\n humanStatus\n createdAt\n updatedAt\n workflowDefinition\n lastExecutorLogsUrl\n latestCheckpoint {\n duoMessages {\n content\n correlationId\n role\n messageType\n status\n timestamp\n toolInfo\n }\n }\n }\n }\n}`;\n\nasync function fetchFoundationalChatAgents(\n instanceUrl: string,\n token: string,\n projectId: string\n): Promise<CatalogAgent[]> {\n const agents: CatalogAgent[] = [];\n let after: string | null = null;\n for (;;) {\n const data = await gql(instanceUrl, token, FOUNDATIONAL_QUERY, {\n projectId,\n ...(after ? { after } : {}),\n });\n const page = data?.aiFoundationalChatAgents;\n if (!page) break;\n for (const node of page.nodes ?? []) {\n if (!node.reference) continue;\n agents.push({\n identifier: node.reference,\n name: node.name,\n description: node.description ?? \"\",\n workflowDefinition: node.referenceWithVersion || node.reference,\n foundational: true,\n });\n }\n if (!page.pageInfo?.hasNextPage) break;\n after = page.pageInfo.endCursor;\n }\n return agents;\n}\n\nasync function fetchCustomAgents(\n instanceUrl: string,\n token: string,\n projectId: string\n): Promise<CatalogAgent[]> {\n const agents: CatalogAgent[] = [];\n const seen = new Set<string>();\n let after: string | null = null;\n\n for (;;) {\n const data = await gql(instanceUrl, token, CUSTOM_AGENTS_QUERY, {\n projectId,\n ...(after ? { after } : {}),\n });\n const page = data?.aiCatalogConfiguredItems;\n if (!page) break;\n\n for (const node of page.nodes ?? []) {\n if (!node.enabled) continue;\n const item = node.item;\n if (!item) continue;\n if (!item.latestVersion?.id) continue;\n const validTypes = [\"AGENT\", \"FLOW\"];\n if (!validTypes.includes(item.itemType)) continue;\n if (item.foundational && item.itemType === \"AGENT\") continue;\n if (seen.has(item.id)) continue;\n seen.add(item.id);\n\n const consumerNumericId = node.id\n ? parseInt(String(node.id).split(\"/\").pop() ?? \"\", 10) || undefined\n : undefined;\n\n try {\n const cfgData = await gql(instanceUrl, token, FLOW_CONFIG_QUERY, {\n versionId: item.latestVersion.id,\n });\n const yamlStr = cfgData?.aiCatalogAgentFlowConfig as string | null;\n const parsed = yamlStr ? (yamlLoad(yamlStr) as Record<string, unknown>) : undefined;\n agents.push({\n identifier: item.id,\n name: item.name,\n description: item.description ?? \"\",\n itemType: item.itemType,\n workflowDefinition: item.foundationalFlowReference ?? undefined,\n flowConfig: parsed,\n flowConfigSchemaVersion: parsed ? ((parsed?.version as string) ?? \"v1\") : undefined,\n foundational: !!item.foundational,\n catalogItemVersionId:\n parseInt(item.latestVersion.id.split(\"/\").pop() ?? \"\", 10) || undefined,\n consumerId: consumerNumericId,\n flowInputs: extractFlowInputs(parsed),\n });\n } catch {\n agents.push({\n identifier: item.id,\n name: item.name,\n description: item.description ?? \"\",\n itemType: item.itemType,\n workflowDefinition: item.foundationalFlowReference ?? undefined,\n foundational: !!item.foundational,\n catalogItemVersionId:\n parseInt(item.latestVersion.id.split(\"/\").pop() ?? \"\", 10) || undefined,\n consumerId: consumerNumericId,\n });\n }\n }\n\n if (!page.pageInfo?.hasNextPage) break;\n after = page.pageInfo.endCursor;\n }\n return agents;\n}\n\nexport async function fetchCatalogAgents(\n instanceUrl: string,\n token: string,\n projectId: string\n): Promise<CatalogAgent[]> {\n const { fetchMcpServers } = await import(\"./mcp-servers\");\n try {\n const [foundational, custom] = await Promise.all([\n fetchFoundationalChatAgents(instanceUrl, token, projectId),\n fetchCustomAgents(instanceUrl, token, projectId),\n ]);\n const agents = [...foundational, ...custom];\n await fetchMcpServers(instanceUrl, token, projectId, agents);\n return agents;\n } catch {\n return [];\n }\n}\n\nexport async function getFlowDefinition(\n instanceUrl: string,\n token: string,\n opts: {\n consumerId: number;\n flowName?: string;\n foundational?: boolean;\n catalogItemVersionId?: number;\n itemIdentifier?: string;\n workflowDefinition?: string;\n }\n): Promise<{ config: string | null; name: string; error?: string }> {\n const name = opts.flowName ?? `consumer-${opts.consumerId}`;\n let config: string | null = null;\n let apiError: string | undefined;\n\n if (opts.foundational && opts.workflowDefinition) {\n const flowKey = opts.workflowDefinition.split(\"/\")[0];\n config = FOUNDATIONAL_FLOWS[flowKey] ?? null;\n }\n\n if (!config && !opts.foundational && opts.itemIdentifier) {\n try {\n const data = await gql(instanceUrl, token, FLOW_VERSION_DEFINITION_QUERY, {\n itemId: opts.itemIdentifier,\n });\n config = (data?.aiCatalogItem?.latestVersion?.definition as string) ?? null;\n } catch (err: any) {\n apiError = err?.message ?? \"Unknown error fetching flow definition\";\n }\n }\n\n if (!config && !opts.foundational && opts.catalogItemVersionId) {\n const versionGid = `gid://gitlab/Ai::Catalog::ItemVersion/${opts.catalogItemVersionId}`;\n try {\n const cfgData = await gql(instanceUrl, token, FLOW_CONFIG_QUERY, { versionId: versionGid });\n config = (cfgData?.aiCatalogAgentFlowConfig as string) ?? null;\n } catch (err: any) {\n if (!apiError) apiError = err?.message ?? \"Unknown error fetching flow config\";\n }\n }\n\n return { config, name, ...(apiError && !config ? { error: apiError } : {}) };\n}\n\nasync function resolveRootNamespaceId(\n instanceUrl: string,\n token: string,\n projectPath: string\n): Promise<number | undefined> {\n try {\n const data = await gql(instanceUrl, token, RESOLVE_ROOT_NAMESPACE_QUERY, {\n projectPath,\n });\n const rootGid = data?.project?.group?.rootNamespace?.id as string | undefined;\n if (rootGid) {\n return parseInt(rootGid.split(\"/\").pop() ?? \"\", 10) || undefined;\n }\n } catch {\n // fall through\n }\n return undefined;\n}\n\nexport async function executeFlow(\n instanceUrl: string,\n token: string,\n projectPath: string,\n consumerId: number,\n goal: string,\n options?: {\n issueId?: number;\n mergeRequestId?: number;\n namespaceId?: number;\n flowInputs?: Array<{ Category: string; Content: string; Metadata?: string }>;\n }\n): Promise<Record<string, unknown>> {\n const projectUrl = `${instanceUrl.replace(/\\/$/, \"\")}/${projectPath}`;\n const additionalContext: Array<{ Category: string; Content: string; Metadata: string }> = [\n {\n Category: \"agent_user_environment\",\n Content: JSON.stringify({ project_url: projectUrl }),\n Metadata: \"{}\",\n },\n ];\n if (options?.flowInputs) {\n for (const input of options.flowInputs) {\n additionalContext.push({\n Category: input.Category,\n Content: input.Content,\n Metadata: input.Metadata ?? \"{}\",\n });\n }\n }\n const body: Record<string, unknown> = {\n project_id: projectPath,\n ai_catalog_item_consumer_id: consumerId,\n goal,\n start_workflow: true,\n environment: \"ambient\",\n agent_privileges: [1, 2, 3, 4, 5, 6],\n additional_context: additionalContext,\n };\n if (options?.namespaceId) body.namespace_id = options.namespaceId;\n if (options?.issueId) body.issue_id = options.issueId;\n if (options?.mergeRequestId) body.merge_request_id = options.mergeRequestId;\n\n const rootNsId = await resolveRootNamespaceId(instanceUrl, token, projectPath);\n if (rootNsId) body.root_namespace_id = rootNsId;\n\n const res = await fetch(`${instanceUrl.replace(/\\/$/, \"\")}/api/v4/ai/duo_workflows/workflows`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to execute flow (${res.status}): ${text}`);\n }\n return res.json() as Promise<Record<string, unknown>>;\n}\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport async function getWorkflowStatus(\n instanceUrl: string,\n token: string,\n workflowId: number\n): Promise<Record<string, unknown>> {\n const gid = `gid://gitlab/Ai::DuoWorkflows::Workflow/${workflowId}`;\n const maxWait = 120_000;\n const pollInterval = 5_000;\n const start = Date.now();\n\n while (Date.now() - start < maxWait) {\n const data = await gql(instanceUrl, token, WORKFLOW_STATUS_QUERY, { workflowId: gid });\n const nodes = data?.duoWorkflowWorkflows?.nodes;\n if (!nodes?.length) throw new Error(`Workflow ${workflowId} not found`);\n const workflow = nodes[0];\n if ((workflow as any).status !== \"CREATED\") return workflow;\n await sleep(pollInterval);\n }\n\n const data = await gql(instanceUrl, token, WORKFLOW_STATUS_QUERY, { workflowId: gid });\n const nodes = data?.duoWorkflowWorkflows?.nodes;\n if (!nodes?.length) throw new Error(`Workflow ${workflowId} not found`);\n return nodes[0];\n}\n","/* eslint-disable */\n// AUTO-GENERATED — do not edit manually.\n// Run: npm run vendor:generate\n// Source: vendor/foundational-flows/ (12 files)\n\nexport const FOUNDATIONAL_FLOWS: Record<string, string> = {\n \"analytics_agent\": \"version: \\\"v1\\\"\\nenvironment: chat-partial\\ncomponents:\\n - name: \\\"analytics_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"analytics_agent_prompt\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"goal\\\"\\n toolset:\\n - \\\"get_current_user\\\"\\n - \\\"run_glql_query\\\"\\n - \\\"create_work_item_note\\\"\\n - \\\"create_merge_request_note\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters: []\\nflow:\\n entry_point: \\\"analytics_agent\\\"\\nprompts:\\n - name: \\\"analytics_agent_prompt\\\"\\n prompt_id: \\\"analytics_agent_prompt\\\"\\n model:\\n params:\\n max_tokens: 8_192\\n unit_primitives:\\n - duo_agent_platform\\n prompt_template:\\n system: |\\n <core_function>\\n You are a GitLab Analytics Expert who helps users understand their development data and answer analytical questions about their projects and teams. You use GLQL (GitLab Query Language) as a tool to retrieve and analyze data, but your primary focus is providing clear, actionable insights.\\n\\n **Input**: Analytical questions like \\\"How is my team performing this month?\\\" OR requests for GLQL queries/visualizations like \\\"Show me all currently open issues\\\"\\n\\n **Output**:\\n\\n - For analytical questions: Clear answers with insights, supported by collapsible GLQL queries\\n - For query/visualization requests: GLQL embedded view query (frontend will auto-render if applicable)\\n\\n 1. **Identify intent** - Is this an analytical question or a query/visualization request?\\n 2. **Determine scope** - Project, group, or cross-project analysis\\n 3. **Check for ambiguous concepts** - Does the question contain terms like \\\"team\\\", \\\"quarter\\\", \\\"bugs\\\" that need clarification?\\n 4. **Identify filters** - Time ranges, states, types, assignees, etc.\\n 5. **Generate insights or queries** - Based on user intent\\n </core_function>\\n\\n <user_intent>\\n **Analytical Questions** (answer-first approach): User wants insights and analysis of the data\\n\\n - \\\"How many MRs were merged this month?\\\"\\n - \\\"What's my team working on?\\\"\\n - \\\"What is the bug creation trend for the past month\\\"\\n - \\\"How is performance this quarter?\\\"\\n\\n **Query/Visualization Requests** (query-first approach): User wants to see the query or have data displayed\\n\\n - \\\"Show me...\\\" / \\\"Show all...\\\"\\n - \\\"Visualize...\\\" / \\\"Display...\\\"\\n - \\\"Create a list/table of...\\\"\\n - \\\"I want to see...\\\"\\n - \\\"List all...\\\" / \\\"Give me...\\\"\\n - \\\"Write a GLQL query for...\\\"\\n - \\\"How do I query...\\\"\\n - \\\"What's the GLQL syntax for...\\\"\\n </user_intent>\\n\\n <scope_clarification>\\n **When to Ask First**\\n\\n Ask for clarification when the question involves:\\n\\n - **Organization-specific concepts** where different interpretations produce drastically different results:\\n - \\\"Team\\\" → label (`~team-backend`) vs assignees (`@alice, @bob`) vs milestone?\\n - \\\"Quarter\\\" → calendar (Jan-Mar) vs fiscal year?\\n - \\\"Bugs\\\" → label (`~bug`) vs issue type vs custom field?\\n - \\\"Workload\\\" → open issues? MRs? both? by count or by weight/priority?\\n - **Vague analytical terms**: \\\"velocity\\\", \\\"performance\\\", \\\"productivity\\\"\\n - **Vague time/scope terms**: \\\"recently\\\", \\\"soon\\\", \\\"items\\\", \\\"things\\\"\\n - **Multiple ambiguities**: When a question combines several ambiguous terms, always ask for clarification\\n\\n **Clarification Format**: Keep it brief and offer 2-3 specific options to choose from.\\n\\n **When to Assume and Answer**\\n\\n For all other questions:\\n\\n - **Default to project-level scope** (most common, faster queries)\\n - **Use group-level** when context suggests broader scope\\n - **When users say \\\"me\\\", \\\"my\\\", \\\"mine\\\", or \\\"assigned to me\\\"**, always use `currentUser()` in the query (e.g., `assignee = currentUser()`). Do NOT ask for their username.\\n\\n When making assumptions, add a brief scope note to the answer.\\n </scope_clarification>\\n\\n <response_format>\\n **For Analytical Questions (Answer-First Approach)**\\n\\n **ALWAYS provide the analytical answer first, then supporting details.** Users expect immediate insights, not queries.\\n\\n Structure your response as:\\n\\n 1. **Direct Answer** - What the data shows (2-3 sentences with key insights)\\n 2. **Interpretation** (optional) - What this means for their workflow\\n 3. **Recommendations** (optional) - Suggested actions or follow-up questions\\n 4. **Supporting Query** - GLQL query in a collapsible section (ALWAYS LAST - see syntax below)\\n\\n **IMPORTANT**: Always include the collapsible GLQL query section, even when the query returns no results. Users need to see the query to verify it's correct, reuse it, or modify it for their needs.\\n\\n **Collapsible Section Syntax for GLQL Queries:**\\n\\n ```\\n <details>\\n <summary>See the underlying data and GLQL query</summary>\\n\\n \\\\`\\\\`\\\\`glql\\n type = MergeRequest and state = merged and merged > -1m\\n \\\\`\\\\`\\\\`\\n\\n 💡 *Click on the ⋮ menu to see or copy GLQL query*\\n\\n **Key Components:** Brief explanation of critical parts (1-2 sentences)\\n **Scope Note:** (if assumed) Brief note about scope assumptions\\n </details>\\n ```\\n\\n **Example Analytical Response:**\\n\\n Question: How many MRs were merged in the last month?\\n\\n Answer:\\n\\n Based on the data, 23 merge requests were merged in the last month, with most activity concentrated in the last two weeks. The team shows strong momentum with an average of 5-6 MRs merged per week.\\n\\n **Would you like me to:**\\n\\n - Break this down by team member?\\n - Compare with previous months?\\n - Show only specific types of MRs?\\n\\n ---\\n\\n <details>\\n <summary>See the underlying data and GLQL query</summary>\\n ```glql\\n display: table\\n fields: title, author, merged, targetBranch\\n title: \\\"MRs Merged This Month\\\"\\n limit: 20\\n sort: merged desc\\n query: type = MergeRequest and state = merged and merged > -1m and project = \\\"your-org/your-project\\\"\\n ```\\n\\n **Key Components:** Filters for merged MRs in the last month, sorted by merge date.\\n **Scope Note:** I assumed project-level scope. For group-wide analysis, replace with `group = \\\"your-org/your-group\\\"`.\\n\\n </details>\\n\\n **For Query/Visualization Requests (Validate-Then-Output Approach)**\\n\\n When users request queries, visualizations, or dashboards:\\n\\n 1. **First**: Execute the query using \\\"run_glql_query\\\" to validate it works\\n 2. **Then**: Output the validated GLQL query as a ```glql code block\\n\\n The frontend will render the results as an interactive widget. **Never output a GLQL code block without validating it first.**\\n\\n **Default limit**: Always include `limit: 20` in GLQL embedded views shown to the user. This keeps the rendered widget manageable. If the user explicitly requests a different limit, respect it (up to the maximum of 100).\\n\\n **Display type selection**:\\n - Use `display: table` for data with multiple fields (default)\\n - Use `display: list` for simple title-only lists\\n - Use `display: orderedList` when user requests a numbered or ranked list\\n\\n **Note**: GLQL displays data as tables, lists, or ordered lists - not charts. If a user requests a chart or graph, ask if they'd like a Mermaid diagram instead, which can visualize trends, distributions, or flows.\\n\\n **DO NOT render data as a markdown table or list** unless the user explicitly asks for \\\"markdown format\\\". The GLQL block provides an interactive, live-updating view that users can customize.\\n\\n **Correct** (always output a GLQL code block with the appropriate `display` type):\\n ```glql\\n display: list\\n fields: title, author\\n limit: 20\\n query: type = Issue and state = opened\\n ```\\n\\n\\n **Wrong** (don't render data as markdown table):\\n ```\\n | Title | Author | State |\\n |-------|--------|-------|\\n | Fix bug | @user | open |\\n ```\\n\\n **Also wrong** (don't render as markdown list):\\n ```\\n 1. Fix bug - @user\\n 2. Add feature - @admin\\n 3. Update docs - @user\\n ```\\n\\n Provide:\\n\\n 1. **GLQL Embedded View Query** - The complete query with display, fields, title, sort, and query parameters (use embedded view format by default unless simple query is specifically requested)\\n 2. **Tip** - Add: \\\"💡 _Click on the ⋮ menu to see or copy GLQL query_\\\"\\n 3. **Key Components** - Brief explanation of critical parts (1-2 sentences)\\n 4. **Scope Note** (if assumed) - Brief note about scope assumptions and alternatives\\n\\n **Example Query/Visualization Response:**\\n\\n Question: Show me all MRs merged in the last month in the project \\\"your-org/your-project\\\"\\n\\n Answer:\\n\\n ```glql\\n display: table\\n fields: title, author, merged, targetBranch\\n title: \\\"MRs Merged This Month\\\"\\n limit: 20\\n sort: merged desc\\n query: type = MergeRequest and state = merged and merged > -1m and project = \\\"your-org/your-project\\\"\\n ```\\n\\n 💡 _Click on the ⋮ menu to see or copy GLQL query_\\n\\n **Key Components:** Filters for merged MRs in the last month, sorted by merge date.\\n\\n **Scope Note:** To query across a group instead, replace `project = ...` with `group = \\\"your-org/your-group\\\"`.\\n </response_format>\\n\\n <ide_rendering>\\n **IDE Environment Handling**\\n\\n If the user's additional context includes local environment details (operating system, shell, working directory), the user is in an IDE that uses standard Markdown rendering and **cannot render GLQL embedded views** (```glql code blocks).\\n\\n **In IDE environments, adjust your response format:**\\n\\n - **For query requests**: Validate queries with `run_glql_query` and present the GLQL query in a plain ```yaml code block so the user can copy it.\\n - **For visualization requests**: Still validate queries with `run_glql_query`, but present the retrieved data in **standard Markdown** (tables, lists, or other appropriate formats) instead of a ```glql code block. Choose the format that best fits the data — tables for multi-field structured data, lists for simpler enumerations. Include the collapsible section with raw GLQL query in a plain ```yaml code block so the user can copy it.\\n - **For analytical questions**: Present insights the same way (answer-first), but use **standard Markdown** for any data. Include the raw GLQL query in a plain ```yaml code block in the collapsible section instead of a ```glql code block.\\n - **Always suggest GitLab for interactive views**: Add a note like: \\\"For a live, interactive view, paste this GLQL query into a GitLab issue, epic, or wiki page.\\\"\\n - **Do NOT include the \\\"💡 Click on the ⋮ menu\\\" tip** — this refers to the interactive GLQL widget which is not available in IDEs.\\n\\n **Example IDE response for a query/visualization request:**\\n\\n Based on the query results, here are the open issues:\\n\\n | Title | Author | Created |\\n |-------|--------|---------|\\n | Fix login bug | @alice | 2025-01-15 |\\n | Update docs | @bob | 2025-01-14 |\\n\\n <details>\\n <summary>GLQL query (paste into GitLab for an interactive view)</summary>\\n\\n ```yaml\\n display: table\\n fields: title, author, created\\n title: \\\"Open Issues\\\"\\n limit: 20\\n query: type = Issue and state = opened\\n ```\\n\\n </details>\\n\\n **When the user is NOT in an IDE** (no local environment context is present), use the standard GLQL ```glql code blocks as described in the response format section above.\\n </ide_rendering>\\n\\n <glql_syntax>\\n ## GLQL Syntax Reference\\n\\n ### Basic Query Structure\\n\\n ```\\n field operator value [and field operator value ...]\\n ```\\n\\n ### Essential Fields & Operators\\n\\n - **type**: `=`, `in` (Issue, Epic, MergeRequest, Task, Incident, etc.)\\n - **state**: `=` (opened, closed, merged for MRs)\\n - **assignee**: `=`, `!=`, `in` (@username, currentUser())\\n - **author**: `=`, `!=`, `in` (@username, currentUser())\\n - **created/updated/merged/closed**: `=`, `>`, `<`, `>=`, `<=` (dates: today(), -1w, 2024-01-01)\\n - **project**: `=` (\\\"namespace/project\\\")\\n - **group**: `=` (\\\"namespace/group\\\")\\n - **label**: `=`, `!=`, `in` (~labelname, ~\\\"label with spaces\\\")\\n - **milestone**: `=`, `!=`, `in` (%milestone, %\\\"milestone with spaces\\\")\\n - **id**: `=`, `in` (global ID for filtering - NOT the same as iid/MR number)\\n\\n #### Available operators\\n\\n - **Equality**: `=`, `!=`\\n - **List membership**: `in` (OR logic - matches ANY value in the list)\\n - **Comparison**: `>`, `<`, `>=`, `<=` (for dates)\\n\\n **Important**:\\n\\n - The `in` operator uses OR logic. For AND logic, use multiple conditions: `label = ~bug and label = ~security`\\n - There are NO text search, `contains`, `like`, or similar operators\\n - `currentUser()` is a valid value for `assignee` and `author` fields (e.g., `assignee = currentUser()`)\\n\\n ### Time Expressions (ALWAYS PREFER RELATIVE)\\n\\n - **Relative** (PREFERRED): `-1d`, `-1w`, `-1m`, `-1y` (past), `1d`, `1w` (future)\\n - **Absolute**: `2024-01-01`, `2024-12-31` (use only when specific dates required)\\n - **Functions**: `today()`\\n\\n **IMPORTANT**: Always use relative time expressions (`-1w`, `-1m`, etc.) for queries involving \\\"this week\\\", \\\"last month\\\", \\\"this quarter\\\", etc. Only use absolute dates when users specify exact dates.\\n\\n ### Sorting Options (RESTRICTED LIST ONLY)\\n\\n #### VALID SORT FIELDS\\n\\n - **Issues/Epics/Merge Requests**: closed, closedAt, created, createdAt, popularity, title, updated, updatedAt\\n - **Issues/Epics**: due, dueDate, health, healthStatus\\n - **Issues/Merge Requests**: milestone\\n - **Epics**: start, startDate\\n - **Issues**: weight\\n - **Merge Requests**: merged, mergedAt\\n\\n #### INVALID SORT FIELDS (DO NOT USE):\\n\\n - assignee, author, state, labels, type, project, group\\n\\n **CRITICAL**: Only use the exact sorting options from the VALID list above. Fields like `assignee`, `author`, `state`,\\n or `labels` are NOT valid sorting options and will cause query errors. If none of the valid sorting options are\\n applicable, omit the sort parameter entirely.\\n\\n ### Embedded View Syntax (for dashboards/reports)\\n\\n ```yaml\\n display: table|list|orderedList\\n fields: comma,separated,field,list\\n title: \\\"Custom Title\\\"\\n limit: 20\\n sort: field asc|desc\\n query: your GLQL query here\\n ```\\n\\n **LIMIT RESTRICTION**: The maximum allowed value for `limit` is 100. NEVER set a limit higher than 100. If a user explicitly requests more than 100 results, cap the limit at 100 and inform them: \\\"Note: I've set the limit to 100, which is the maximum allowed by GLQL.\\\"\\n\\n ### Advanced Features\\n\\n ### Custom Field Queries\\n\\n ```glql\\n customField(\\\"Field Name\\\") = \\\"Value\\\"\\n ```\\n\\n ### Label Extraction for Views\\n\\n ```glql\\n fields: title, labels(\\\"priority::*\\\"), labels(\\\"workflow::*\\\")\\n ```\\n\\n ### Complex Time Ranges\\n\\n ```glql\\n created > 2024-01-01 and created < 2024-02-01\\n ```\\n </glql_syntax>\\n\\n <query_execution>\\n **CRITICAL**: After generating ANY GLQL query (whether for analytical questions or GLQL query requests), you MUST execute it using the \\\"run_glql_query\\\" tool to validate the syntax and retrieve data.\\n\\n - If the query executes successfully, present the results in a human-readable format\\n - If the query fails with a syntax error, fix the query and execute again\\n - Never provide a GLQL query to the user without first validating it executes correctly\\n\\n This ensures all queries provided to users have valid syntax and will work when they use them.\\n </query_execution>\\n\\n <pagination>\\n **How Pagination Works**\\n\\n Pagination is handled via the `run_glql_query` tool's `after` parameter. The query itself never changes between pages.\\n\\n **Pagination Steps:**\\n 1. Call `run_glql_query` with your GLQL query\\n 2. Check the response for `pageInfo.hasNextPage` and `pageInfo.endCursor`\\n 3. If `hasNextPage` is true AND you need more data, call `run_glql_query` again with the SAME query but add `after: <endCursor>`\\n 4. Repeat until `hasNextPage` is false or you've reached the limit\\n\\n **CRITICAL**: You MUST call the tool multiple times to paginate. Each call returns one page of results.\\n\\n **When to Paginate (MUST fetch all pages)**\\n\\n Paginate when the question requires **complete data for an accurate answer**.\\n\\n **Important**: When fetching data internally via `run_glql_query` for analysis (rankings, aggregations, distributions), use the maximum page size (100) to minimize the number of API calls. The `limit: 20` default applies only to GLQL code blocks rendered for the user.\\n\\n - **Rankings/maximums**: \\\"Who contributed the most?\\\", \\\"Which labels are most common?\\\"\\n - **Distribution analysis**: \\\"Break down by author\\\", \\\"What's the distribution over time?\\\"\\n - **Aggregations**: Percentages, averages, comparisons across all data\\n - **Export requests**: \\\"Format as markdown table\\\", \\\"Export to CSV\\\"\\n\\n For these questions, if `hasNextPage` is true, you MUST continue fetching pages.\\n\\n **When NOT to Paginate (single page is enough)**\\n\\n - **Count-only**: Use `count` from response (\\\"How many bugs?\\\" → use the count, don't paginate)\\n - **Rendering a view**: The GLQL widget handles its own pagination\\n - **User-specified limit**: \\\"Show me the last 20 MRs\\\" → use `limit: 20`, single call\\n - **Sampling/overview**: First page provides sufficient insight\\n\\n **Pagination Limits**\\n\\n - **Stop after 10 pages maximum** and inform user if more exist\\n - **Show progress**: \\\"Retrieved 200 of 500 items...\\\"\\n - **Handle errors gracefully**: Provide partial results with explanation if pagination fails mid-way\\n </pagination>\\n\\n <performance>\\n If the GLQL API call times out, inform the user and suggest optimizations:\\n - Add time filters: `created > -3m`\\n - Limit scope: use `project` instead of `group` when possible\\n - Add specific filters: `label = ~specific-label`\\n - Reduce result set with `limit` parameter\\n </performance>\\n\\n <error_prevention>\\n - Always specify `type =` when querying specific object types\\n - Use proper label syntax with `~` prefix\\n - Use proper milestone syntax with `%` prefix\\n - Include quotes around names with spaces\\n - For partial GLQL snippets, do not add the `glql` language indicator to the code block. Only add it for full embedded views.\\n - NEVER use `iid` as a filter - it's display-only. Use `id` for filtering or broader filters with `iid` displayed\\n </error_prevention>\\n\\n <work_items>\\n When users ask to add the data on an issue, epic, work items or merge request, use the appropriate tool to post a note.\\n\\n **Tool selection**:\\n\\n - Use 'create_merge_request_note' for merge requests\\n - Use 'create_work_item_note' for work items (issues, epics and any other work items)\\n\\n **When to post**:\\n When the user explicitly requests: \\\"Add this query to the issue #123\\\", \\\"Post a summary in the epic\\\", \\\"Add the query to the work item\\\", \\\"\\\"Add it as a comment to this merge request\\\", \\\"Post this to ...\\\", \\\"Add this to ...\\\", \\\"Share this in ...\\\"\\n\\n **What to post:**\\n\\n - Unless already specified by the user, ALWAYS ask the user what to post. The user might want to share either the full answer (analysis + query), just a summary or just the GLQL query.\\n - Keep the comment focused and minimal\\n - Important: When including the GLQL query in the comment, use the embedded view format with a brief title field describing the query and setting `limit: 20`.\\n\\n **Example workflow:**\\n\\n - User: \\\"How many open issues are there in the gitlab-org group?\\\"\\n - You: Provide analysis with validated query\\n - User: \\\"Add this to issue #42\\\"\\n - You: \\\"What would you like me to comment? The full analysis, a summary or just the GLQL query?\\\"\\n - User: \\\"The full analysis\\\"\\n - You: Use `create_work_item_note` with the analysis provided above.\\n - You: \\\"The analysis has been posted to [#42](link-to-item)\\\"\\n\\n **Example of comment content:**\\n\\n There are **171 open issues** across the entire gitlab-org group.\\n\\n The issues are distributed across two main projects:\\n\\n - **gitlab-org/gitlab-shell**: Majority of the open issues\\n - **gitlab-org/gitlab-test**: Remaining open issues\\n\\n The oldest open issues date back to May 2025, with the most recent one created in August 2025.\\n\\n <details>\\n <summary>See the underlying data and GLQL query</summary>\\n\\n ```glql\\n display: table\\n fields: title, project, state, created\\n title: \\\"Open Issues in gitlab-org Group\\\"\\n sort: created desc\\n limit: 20\\n query: type = Issue and state = opened and group = \\\"gitlab-org\\\"\\n ```\\n\\n 💡 _Click on the ⋮ menu to see or copy GLQL query_\\n\\n **Note:** The GLQL query produces a live view, so the data you see now might not reflect what's been posted in the issue.\\n\\n </details>\\n </work_items>\\n\\n <feedback>\\n Provide a feedback link to https://gitlab.com/gitlab-org/gitlab/-/issues/574028 when:\\n - A GLQL query fails or returns unexpected results\\n - GLQL limitations prevent fulfilling the request (no text search, can't filter by iid, etc.)\\n - Suggesting a suboptimal workaround due to tool constraints\\n - Users ask about unsupported features\\n\\n Example: \\\"This isn't currently supported in GLQL. [Share feedback](https://gitlab.com/gitlab-org/gitlab/-/issues/574028) or describe your use case.\\\"\\n\\n **Don't include feedback links** for normal successful queries or when the issue is user error, not a tool limitation.\\n </feedback>\\n user: |\\n {{goal}}\\n placeholder: history\\n\",\n \"code_review\": \"version: \\\"v1\\\"\\nenvironment: ambient\\ncomponents:\\n # Step 1: Fetch complete MR context with full file contents for final review\\n - name: \\\"build_review_context\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"build_review_merge_request_context\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 2: Fetch lightweight MR diffs for prescan analysis\\n - name: \\\"fetch_mr_diffs\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"build_review_merge_request_context\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n - from: \\\"true\\\"\\n as: \\\"only_diffs\\\"\\n literal: true\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 3: Generate targeted directory tree exploration calls based on changed files\\n - name: \\\"explore_relevant_directories\\\"\\n type: OneOffComponent\\n prompt_id: \\\"explore_directories_for_prescan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:fetch_mr_diffs.tool_responses\\\"\\n as: \\\"mr_diffs\\\"\\n toolset:\\n - \\\"list_repository_tree\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 4: Batch read additional context files (tests, dependencies, custom instructions)\\n - name: \\\"prescan_codebase\\\"\\n type: OneOffComponent\\n prompt_id: \\\"code_review_prescan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n - from: \\\"context:fetch_mr_diffs.tool_responses\\\"\\n as: \\\"mr_context\\\"\\n - from: \\\"context:explore_relevant_directories.tool_responses\\\"\\n as: \\\"directory_trees\\\"\\n optional: True\\n toolset:\\n - \\\"get_repository_file\\\"\\n - \\\"read_file\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 5: Fetch lightweight MR metadata (file paths + custom instructions)\\n - name: \\\"fetch_mr_metadata\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"build_review_merge_request_context\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n - from: \\\"true\\\"\\n as: \\\"lightweight\\\"\\n literal: true\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n # Step 6: Transform prescan results into structured JSON for review consumption\\n - name: \\\"analyze_prescan_results\\\"\\n type: AgentComponent\\n prompt_id: \\\"analyze_prescan_codebase_results\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fetch_mr_metadata.tool_responses\\\"\\n as: \\\"mr_context\\\"\\n - from: \\\"context:prescan_codebase.tool_responses\\\"\\n as: \\\"prescan_tool_responses\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n # Step 7: Execute code review with complete context and publish results\\n - name: \\\"perform_code_review_and_publish\\\"\\n type: OneOffComponent\\n prompt_id: \\\"review_merge_request\\\"\\n prompt_version: \\\"^2.0.0\\\"\\n inputs:\\n - from: \\\"context:build_review_context.tool_responses\\\"\\n as: \\\"mr_data\\\"\\n - from: \\\"context:analyze_prescan_results.final_answer\\\"\\n as: \\\"codebase_context\\\"\\n - from: \\\"context:current_date\\\"\\n as: \\\"current_date\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"merge_request_iid\\\"\\n toolset:\\n - \\\"post_duo_code_review\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"build_review_context\\\"\\n to: \\\"fetch_mr_diffs\\\"\\n - from: \\\"fetch_mr_diffs\\\"\\n to: \\\"explore_relevant_directories\\\"\\n - from: \\\"explore_relevant_directories\\\"\\n to: \\\"prescan_codebase\\\"\\n - from: \\\"prescan_codebase\\\"\\n to: \\\"fetch_mr_metadata\\\"\\n - from: \\\"fetch_mr_metadata\\\"\\n to: \\\"analyze_prescan_results\\\"\\n - from: \\\"analyze_prescan_results\\\"\\n to: \\\"perform_code_review_and_publish\\\"\\n - from: \\\"perform_code_review_and_publish\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"build_review_context\\\"\\n\",\n \"convert_to_gl_ci\": \"name: \\\"Convert to GitLab CI\\\"\\ndescription: |\\n Converts Jenkins pipelines (Jenkinsfile) to GitLab CI/CD configuration files (.gitlab-ci.yml).\\n This flow reads a Jenkins configuration file, translates it to GitLab CI format with validation,\\n and creates a merge request with the converted configuration.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"load_jenkins_file\\\"\\n type: DeterministicStepComponent\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"file_path\\\"\\n tool_name: \\\"read_file\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"convert_to_gitlab_ci\\\"\\n type: AgentComponent\\n prompt_id: \\\"convert_to_gl_ci\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:load_jenkins_file.tool_responses\\\"\\n as: \\\"jenkins_file_content\\\"\\n toolset:\\n - \\\"create_file_with_contents\\\"\\n - \\\"read_file\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"Duo Agent: Convert to GitLab CI\\\"\\n as: \\\"naming_context\\\"\\n literal: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"git_commit\\\"\\n type: AgentComponent\\n prompt_id: \\\"commit_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"git_push\\\"\\n type: AgentComponent\\n prompt_id: \\\"convert_ci_push_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"target_branch_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"create_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"load_jenkins_file\\\"\\n to: \\\"convert_to_gitlab_ci\\\"\\n - from: \\\"convert_to_gitlab_ci\\\"\\n to: \\\"create_repository_branch\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"git_commit\\\"\\n - from: \\\"git_commit\\\"\\n to: \\\"git_push\\\"\\n - from: \\\"git_push\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"load_jenkins_file\\\"\\n inputs:\\n - category: agent_user_environment\\n input_schema:\\n source_branch:\\n type: string\\n description: Source branch of the Jenkins file\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"developer\": \"version: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"issue_parser\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"get_issue\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"url\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:issue_parser.tool_responses\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"draft_merge_request_creator\\\"\\n type: OneOffComponent\\n prompt_id: \\\"create_merge_request\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n tool_name: \\\"create_merge_request\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"issue_url\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:issue_parser.tool_responses\\\"\\n as: \\\"issue_details\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"source_branch_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"target_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"tool_listing_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"list_available_tools\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"large\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n - \\\"get_job_logs\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_pipeline_failing_jobs\\\"\\n - \\\"get_project\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"read_file\\\"\\n - \\\"create_file_with_contents\\\"\\n - \\\"edit_file\\\"\\n - \\\"find_files\\\"\\n - \\\"grep\\\"\\n - \\\"mkdir\\\"\\n - \\\"get_epic\\\"\\n - \\\"list_epics\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_dir\\\"\\n - \\\"list_epic_notes\\\"\\n - \\\"get_epic_note\\\"\\n - \\\"get_commit\\\"\\n - \\\"run_command\\\"\\n - name: \\\"planning_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"developer_planner\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:issue_parser.tool_responses\\\"\\n as: \\\"issue_details\\\"\\n - from: \\\"context:tool_listing_agent.final_answer\\\"\\n as: \\\"coding_agent_tools\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n - \\\"get_job_logs\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_project\\\"\\n - \\\"get_pipeline_failing_jobs\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"read_file\\\"\\n - \\\"find_files\\\"\\n - \\\"list_dir\\\"\\n - \\\"grep\\\"\\n - \\\"get_epic\\\"\\n - \\\"list_epics\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_epic_notes\\\"\\n - \\\"get_epic_note\\\"\\n - \\\"get_commit\\\"\\n - \\\"list_commits\\\"\\n - \\\"get_commit_comments\\\"\\n - \\\"get_commit_diff\\\"\\n - \\\"get_work_item\\\"\\n - \\\"list_work_items\\\"\\n - \\\"get_work_item_notes\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"add_plan_comment\\\"\\n type: OneOffComponent\\n prompt_id: \\\"developer_add_plan_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:planning_agent.final_answer\\\"\\n as: \\\"plan_text\\\"\\n - from: \\\"context:draft_merge_request_creator.tool_responses\\\"\\n as: \\\"merge_request_details\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"create_merge_request_note\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"programming_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"programming_agent\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:planning_agent.final_answer\\\"\\n as: \\\"planner_handover\\\"\\n - from: \\\"context:inputs.os_information\\\"\\n as: \\\"os_information\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n - \\\"get_job_logs\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_pipeline_failing_jobs\\\"\\n - \\\"get_project\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"read_file\\\"\\n - \\\"create_file_with_contents\\\"\\n - \\\"edit_file\\\"\\n - \\\"find_files\\\"\\n - \\\"grep\\\"\\n - \\\"mkdir\\\"\\n - \\\"get_epic\\\"\\n - \\\"list_epics\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_dir\\\"\\n - \\\"list_epic_notes\\\"\\n - \\\"get_epic_note\\\"\\n - \\\"get_commit\\\"\\n - \\\"run_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"git_actions\\\"\\n type: OneOffComponent\\n prompt_id: \\\"push_to_remote\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n model_size_preference: \\\"small\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:programming_agent.final_answer\\\"\\n as: \\\"programming_agent_handover\\\"\\n - from: \\\"context:draft_merge_request_creator.tool_responses\\\"\\n as: \\\"merge_request_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.session_owner_id\\\"\\n as: \\\"assignee_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"issue_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"update_merge_request\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"issue_parser\\\"\\n to: \\\"create_repository_branch\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"draft_merge_request_creator\\\"\\n - from: \\\"draft_merge_request_creator\\\"\\n to: \\\"tool_listing_agent\\\"\\n - from: \\\"tool_listing_agent\\\"\\n to: \\\"planning_agent\\\"\\n - from: \\\"planning_agent\\\"\\n to: \\\"add_plan_comment\\\"\\n - from: \\\"add_plan_comment\\\"\\n to: \\\"programming_agent\\\"\\n - from: \\\"programming_agent\\\"\\n to: \\\"git_actions\\\"\\n - from: \\\"git_actions\\\"\\n condition:\\n input: \\\"context:git_actions.execution_result\\\"\\n routes:\\n \\\"success\\\": \\\"end\\\"\\n \\\"failed\\\": \\\"abort\\\"\\n\\nflow:\\n entry_point: \\\"issue_parser\\\"\\n inputs:\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"duo_permissions_assistant\": \"version: \\\"v1\\\"\\nenvironment: chat-partial\\ncomponents:\\n - name: \\\"duo_permissions_assistant\\\"\\n type: AgentComponent\\n prompt_id: \\\"duo_permissions_assistant_prompt\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"goal\\\"\\n toolset:\\n - \\\"gitlab_graphql\\\"\\n - \\\"update_form_permissions\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\nrouters: []\\nflow:\\n entry_point: \\\"duo_permissions_assistant\\\"\\nprompts:\\n - name: \\\"duo_permissions_assistant_prompt\\\"\\n prompt_id: \\\"duo_permissions_assistant_prompt\\\"\\n model:\\n params:\\n max_tokens: 8192\\n unit_primitives:\\n - duo_agent_platform\\n prompt_template:\\n system: |\\n You are a GitLab fine-grained access token permissions assistant.\\n You help users pick the right permissions for their access tokens.\\n\\n STEP 1 — FETCH PERMISSIONS:\\n On the first message, call the gitlab_graphql tool with this query to get all available permissions:\\n query GetAccessTokenPermissions { accessTokenPermissions { name description } }\\n\\n STEP 2 — SUGGEST PERMISSIONS:\\n Using ONLY permission names returned by the tool:\\n - Always suggest specific permissions immediately based on what the user describes. Do not ask clarifying questions about scope, projects, groups, or access level — you cannot act on that information.\\n - Apply the principle of least privilege.\\n - Do not suggest legacy scopes (api, read_api, write_repository, etc.) or anything not in the tool results.\\n - If nothing matches, say: \\\"No matching permissions are available.\\\"\\n - IMPORTANT: Each user message is a standalone request. Do NOT use prior conversation turns to infer what is currently selected — the user may have changed the form manually between messages. Only act on what the user explicitly asks for right now.\\n - If the user's request is vague, make your best guess and explain your reasoning. The user can refine afterward.\\n\\n STEP 3 — APPLY CHANGES:\\n After explaining your reasoning, call the update_form_permissions tool to apply the changes.\\n Only include \\\"select\\\" and/or \\\"clear\\\" as needed.\\n user: |\\n {{goal}}\\n placeholder: history\\n\",\n \"fix_pipeline\": \"name: \\\"Fix pipeline\\\"\\ndescription: |\\n Fix pipeline flow can be run for a failed CI jobs.\\n It opens a new MR with changes that address root cause of CI job failures.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"fix_pipeline_context\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_context\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - get_downstream_pipelines\\n - get_pipeline_failing_jobs\\n - get_job_logs\\n - list_merge_request_diffs\\n - read_file\\n - find_files\\n - list_dir\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_decide_approach\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_decide_approach\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n response_schema_id: \\\"fix_pipeline_decide_approach\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n response_schema_tracking: true\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_add_comment\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_add_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: [\\\"create_merge_request_note\\\"]\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_create_plan\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_create_plan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_execution\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_execution\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:fix_pipeline_create_plan.final_answer\\\"\\n as: \\\"fix_pipeline_plan\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.os_information\\\"\\n as: \\\"os_information\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - create_file_with_contents\\n - edit_file\\n - find_files\\n - mkdir\\n - read_file\\n - run_command\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_commit\\\"\\n type: AgentComponent\\n prompt_id: \\\"commit_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_push\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_push_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"target_branch_details\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"default_branch\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"create_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_summarize\\\"\\n type: OneOffComponent\\n prompt_id: \\\"fix_pipeline_summarize_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:fix_pipeline_execution.final_answer\\\"\\n as: \\\"execution_results\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.session_owner_id\\\"\\n as: \\\"assignee_id\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"update_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_decide_comment\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_decide_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n response_schema_id: \\\"fix_pipeline_decide_comment\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_comment_link\\\"\\n type: OneOffComponent\\n prompt_id: \\\"fix_pipeline_comment_link\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n max_correction_attempts: 3\\n inputs:\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: [\\\"create_merge_request_note\\\"]\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"fix_pipeline_context\\\"\\n to: \\\"fix_pipeline_decide_approach\\\"\\n - from: \\\"fix_pipeline_decide_approach\\\"\\n condition:\\n input: \\\"context:fix_pipeline_decide_approach.final_answer.decision\\\"\\n routes:\\n \\\"add_comment\\\": \\\"fix_pipeline_add_comment\\\"\\n \\\"create_fix\\\": \\\"create_repository_branch\\\"\\n \\\"default_route\\\": \\\"fix_pipeline_add_comment\\\"\\n - from: \\\"fix_pipeline_add_comment\\\"\\n to: \\\"end\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"fix_pipeline_create_plan\\\"\\n - from: \\\"fix_pipeline_create_plan\\\"\\n to: \\\"fix_pipeline_execution\\\"\\n - from: \\\"fix_pipeline_execution\\\"\\n to: \\\"fix_pipeline_git_commit\\\"\\n - from: \\\"fix_pipeline_git_commit\\\"\\n to: \\\"fix_pipeline_git_push\\\"\\n - from: \\\"fix_pipeline_git_push\\\"\\n to: \\\"fix_pipeline_summarize\\\"\\n - from: \\\"fix_pipeline_summarize\\\"\\n to: \\\"fix_pipeline_decide_comment\\\"\\n - from: \\\"fix_pipeline_decide_comment\\\"\\n condition:\\n input: \\\"context:fix_pipeline_decide_comment.final_answer.decision\\\"\\n routes:\\n \\\"comment_link\\\": \\\"fix_pipeline_comment_link\\\"\\n \\\"end\\\": \\\"end\\\"\\n \\\"default_route\\\": \\\"end\\\"\\n - from: \\\"fix_pipeline_comment_link\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"fix_pipeline_context\\\"\\n inputs:\\n - category: merge_request\\n input_schema:\\n url:\\n type: string\\n format: uri\\n description: The URL for the GitLab Merge Request\\n - category: pipeline\\n input_schema:\\n source_branch:\\n type: string\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"fix_pipeline_next\": \"name: \\\"Fix pipeline (next)\\\"\\ndescription: |\\n Fix pipeline flow can be run for a failed CI jobs.\\n When a merge request URL is provided, it pushes the fix directly to that MR's branch.\\n Otherwise it opens a new MR with changes that address root cause of CI job failures.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"fix_pipeline_context\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_context\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - get_downstream_pipelines\\n - get_pipeline_failing_jobs\\n - get_job_logs\\n - list_merge_request_diffs\\n - read_file\\n - find_files\\n - list_dir\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_decide_approach\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_decide_approach\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n response_schema_id: \\\"fix_pipeline_next_decide_approach\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n response_schema_tracking: true\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n optional: True\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_add_comment\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_add_comment\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: [\\\"create_merge_request_note\\\"]\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_create_plan\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_create_plan\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset: []\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"fix_pipeline_execution\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_execution\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:fix_pipeline_context.final_answer\\\"\\n as: \\\"fix_pipeline_context_results\\\"\\n - from: \\\"context:fix_pipeline_create_plan.final_answer\\\"\\n as: \\\"fix_pipeline_plan\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.os_information\\\"\\n as: \\\"os_information\\\"\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - create_file_with_contents\\n - edit_file\\n - find_files\\n - mkdir\\n - read_file\\n - run_command\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_commit\\\"\\n type: AgentComponent\\n prompt_id: \\\"commit_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_git_push\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_push_changes\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_create_new_mr\\\"\\n type: AgentComponent\\n prompt_id: \\\"fix_pipeline_next_create_new_mr\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"pipeline_url\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:inputs.pipeline.source_branch\\\"\\n as: \\\"source_branch\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.primary_branch\\\"\\n as: \\\"default_branch\\\"\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:fix_pipeline_execution.final_answer\\\"\\n as: \\\"execution_results\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.agent_platform_standard_context.session_owner_id\\\"\\n as: \\\"assignee_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"create_merge_request\\\"\\n - \\\"update_merge_request\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"fix_pipeline_next_comment_existing_mr\\\"\\n type: OneOffComponent\\n prompt_id: \\\"fix_pipeline_next_comment_existing_mr\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:inputs.merge_request.url\\\"\\n as: \\\"merge_request_url\\\"\\n - from: \\\"context:fix_pipeline_git_push.final_answer\\\"\\n as: \\\"git_push_response\\\"\\n - from: \\\"context:fix_pipeline_execution.final_answer\\\"\\n as: \\\"execution_results\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:session_url\\\"\\n as: \\\"session_url\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n toolset:\\n - \\\"create_merge_request_note\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\nrouters:\\n - from: \\\"fix_pipeline_context\\\"\\n to: \\\"fix_pipeline_next_decide_approach\\\"\\n - from: \\\"fix_pipeline_next_decide_approach\\\"\\n condition:\\n input: \\\"context:fix_pipeline_next_decide_approach.final_answer.decision\\\"\\n routes:\\n \\\"add_comment\\\": \\\"fix_pipeline_add_comment\\\"\\n \\\"create_fix_on_new_mr\\\": \\\"create_repository_branch\\\"\\n \\\"create_fix_on_existing_mr\\\": \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n \\\"default_route\\\": \\\"fix_pipeline_add_comment\\\"\\n - from: \\\"fix_pipeline_add_comment\\\"\\n to: \\\"end\\\"\\n - from: \\\"fix_pipeline_next_checkout_existing_branch\\\"\\n to: \\\"fix_pipeline_create_plan\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"fix_pipeline_create_plan\\\"\\n - from: \\\"fix_pipeline_create_plan\\\"\\n to: \\\"fix_pipeline_execution\\\"\\n - from: \\\"fix_pipeline_execution\\\"\\n to: \\\"fix_pipeline_git_commit\\\"\\n - from: \\\"fix_pipeline_git_commit\\\"\\n to: \\\"fix_pipeline_git_push\\\"\\n - from: \\\"fix_pipeline_git_push\\\"\\n condition:\\n input: \\\"context:fix_pipeline_next_decide_approach.final_answer.decision\\\"\\n routes:\\n \\\"create_fix_on_existing_mr\\\": \\\"fix_pipeline_next_comment_existing_mr\\\"\\n \\\"create_fix_on_new_mr\\\": \\\"fix_pipeline_next_create_new_mr\\\"\\n \\\"default_route\\\": \\\"fix_pipeline_next_create_new_mr\\\"\\n - from: \\\"fix_pipeline_next_comment_existing_mr\\\"\\n to: \\\"end\\\"\\n - from: \\\"fix_pipeline_next_create_new_mr\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"fix_pipeline_context\\\"\\n inputs:\\n - category: merge_request\\n input_schema:\\n url:\\n type: string\\n format: uri\\n description: The URL for the GitLab Merge Request\\n - category: pipeline\\n input_schema:\\n source_branch:\\n type: string\\n - category: agent_platform_standard_context\\n input_schema:\\n workload_branch:\\n type: string\\n description: The workload branch for the GitLab Merge Request\\n primary_branch:\\n type: string\\n description: Merge Request target branch\\n session_owner_id:\\n type: string\\n description: Human user's ID that initiated the flow\\n\",\n \"project_activity\": \"name: \\\"Project Activity\\\"\\ndescription: |\\n Summarize the issue and MR activity in a project for a given timeframe.\\nproduct_group: agent_foundations\\nversion: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"fetch_new_issues\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_issues_new\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_closed_issues\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_issues_closed\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_updated_issues\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_issues_updated\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"list_issues\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"list_issue_notes\\\"\\n - \\\"get_issue_note\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_new_merge_requests\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_merge_requests_new\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_closed_merge_requests\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_merge_requests_closed\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"fetch_updated_merge_requests\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_fetch_merge_requests_updated\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"gitlab_merge_request_search\\\"\\n - \\\"gitlab_api_get\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"list_all_merge_request_notes\\\"\\n - \\\"list_merge_request_diffs\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"summarize_activity\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_summarize_project_activity\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset: []\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n - from: \\\"context:fetch_new_issues.final_answer\\\"\\n as: \\\"new_issues_data\\\"\\n - from: \\\"context:fetch_closed_issues.final_answer\\\"\\n as: \\\"closed_issues_data\\\"\\n - from: \\\"context:fetch_updated_issues.final_answer\\\"\\n as: \\\"updated_issues_data\\\"\\n - from: \\\"context:fetch_new_merge_requests.final_answer\\\"\\n as: \\\"new_merge_requests_data\\\"\\n - from: \\\"context:fetch_closed_merge_requests.final_answer\\\"\\n as: \\\"closed_merge_requests_data\\\"\\n - from: \\\"context:fetch_updated_merge_requests.final_answer\\\"\\n as: \\\"updated_merge_requests_data\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"create_summary_issue\\\"\\n type: AgentComponent\\n prompt_id: \\\"project_activity_create_summary_issue\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"create_issue\\\"\\n - \\\"gitlab_api_post\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:goal\\\"\\n as: \\\"date_range\\\"\\n - from: \\\"context:summarize_activity.final_answer\\\"\\n as: \\\"summary\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n\\nrouters:\\n - from: \\\"fetch_new_issues\\\"\\n to: \\\"fetch_closed_issues\\\"\\n - from: \\\"fetch_closed_issues\\\"\\n to: \\\"fetch_updated_issues\\\"\\n - from: \\\"fetch_updated_issues\\\"\\n to: \\\"fetch_new_merge_requests\\\"\\n - from: \\\"fetch_new_merge_requests\\\"\\n to: \\\"fetch_closed_merge_requests\\\"\\n - from: \\\"fetch_closed_merge_requests\\\"\\n to: \\\"fetch_updated_merge_requests\\\"\\n - from: \\\"fetch_updated_merge_requests\\\"\\n to: \\\"summarize_activity\\\"\\n - from: \\\"summarize_activity\\\"\\n to: \\\"create_summary_issue\\\"\\n - from: \\\"create_summary_issue\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"fetch_new_issues\\\"\\n inputs: []\\n\",\n \"resolve_sast_vulnerability\": \"version: \\\"v1\\\"\\nenvironment: ambient\\n\\ncomponents:\\n - name: \\\"gather_context\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"get_vulnerability_details\\\"\\n inputs:\\n - { from: \\\"context:goal\\\", as: \\\"vulnerability_id\\\" }\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"evaluate_vuln_fp_status\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"evaluate_vuln_fp_status\\\"\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_json\\\"\\n toolset:\\n - \\\"evaluate_vuln_fp_status\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"ensure_clean_git_state\\\"\\n type: AgentComponent\\n prompt_id: \\\"ensure_clean_git_state\\\"\\n prompt_version: \\\"1.0.0\\\"\\n response_schema_id: \\\"ensure_clean_git_state\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:project_default_branch\\\"\\n as: \\\"default_branch\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"create_repository_branch\\\"\\n type: AgentComponent\\n prompt_id: \\\"create_repository_branch\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n inputs:\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_default_branch\\\"\\n as: \\\"ref\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"naming_context\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:inputs.user_rule\\\"\\n as: \\\"agents_dot_md\\\"\\n optional: True\\n - from: \\\"context:inputs.workspace_agent_skills\\\"\\n as: \\\"workspace_agent_skills\\\"\\n optional: True\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"execute_fix\\\"\\n type: AgentComponent\\n prompt_id: \\\"resolve_sast_vulnerability_execution\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_context\\\"\\n toolset:\\n - \\\"edit_file\\\"\\n - \\\"create_file_with_contents\\\"\\n - \\\"read_file\\\"\\n - \\\"read_files\\\"\\n - \\\"grep\\\"\\n - \\\"find_files\\\"\\n - \\\"list_dir\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"validate_fix_has_changes\\\"\\n type: AgentComponent\\n prompt_id: \\\"validate_sast_fix_has_changes\\\"\\n prompt_version: \\\"1.0.0\\\"\\n response_schema_id: \\\"validate_sast_fix_has_changes\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:execute_fix.final_answer\\\"\\n as: \\\"fix_execution_result\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n\\n - name: \\\"commit_changes\\\"\\n type: OneOffComponent\\n prompt_id: \\\"resolve_sast_vulnerability_commit\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n max_correction_attempts: 3\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_context\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"push_and_create_mr\\\"\\n type: OneOffComponent\\n prompt_id: \\\"resolve_sast_vulnerability_push_and_create_mr\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n max_correction_attempts: 3\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_details\\\"\\n - from: \\\"context:execute_fix.final_answer\\\"\\n as: \\\"fix_summary\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n - from: \\\"context:project_id\\\"\\n as: \\\"project_id\\\"\\n - from: \\\"context:project_default_branch\\\"\\n as: \\\"default_branch\\\"\\n - from: \\\"context:create_repository_branch.final_answer\\\"\\n as: \\\"source_branch_name\\\"\\n toolset:\\n - \\\"run_git_command\\\"\\n - \\\"create_merge_request\\\"\\n ui_log_events:\\n - \\\"on_tool_call_input\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"link_vulnerability\\\"\\n type: DeterministicStepComponent\\n tool_name: \\\"link_vulnerability_to_merge_request\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"vulnerability_id\\\"\\n - from: \\\"context:push_and_create_mr.parsed_responses.created_merge_request.id\\\"\\n as: \\\"merge_request_id\\\"\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n\\n - name: \\\"evaluate_merge_request\\\"\\n type: AgentComponent\\n prompt_id: \\\"resolve_sast_evaluate_mr_readiness\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:gather_context.tool_responses\\\"\\n as: \\\"vulnerability_context\\\"\\n - from: \\\"context:execute_fix.final_answer\\\"\\n as: \\\"fix_execution_result\\\"\\n - from: \\\"context:push_and_create_mr.tool_responses\\\"\\n as: \\\"git_operations_result\\\"\\n - from: \\\"context:project_http_url_to_repo\\\"\\n as: \\\"repository_url\\\"\\n - from: \\\"context:workflow_id\\\"\\n as: \\\"workflow_id\\\"\\n toolset:\\n - \\\"get_merge_request\\\"\\n - \\\"list_merge_request_diffs\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n\\nrouters:\\n - from: \\\"gather_context\\\"\\n to: \\\"evaluate_vuln_fp_status\\\"\\n - from: \\\"evaluate_vuln_fp_status\\\"\\n condition:\\n input: \\\"context:evaluate_vuln_fp_status.tool_responses\\\"\\n routes:\\n \\\"skip_false_positive\\\": \\\"end\\\"\\n \\\"proceed_with_fix\\\": \\\"ensure_clean_git_state\\\"\\n default_route: \\\"ensure_clean_git_state\\\"\\n - from: \\\"ensure_clean_git_state\\\"\\n to: \\\"create_repository_branch\\\"\\n - from: \\\"create_repository_branch\\\"\\n to: \\\"execute_fix\\\"\\n - from: \\\"execute_fix\\\"\\n to: \\\"validate_fix_has_changes\\\"\\n - from: \\\"validate_fix_has_changes\\\"\\n condition:\\n input: \\\"context:validate_fix_has_changes.final_answer.decision\\\"\\n routes:\\n \\\"proceed\\\": \\\"commit_changes\\\"\\n \\\"no_changes\\\": \\\"end\\\"\\n default_route: \\\"end\\\"\\n - from: \\\"commit_changes\\\"\\n to: \\\"push_and_create_mr\\\"\\n - from: \\\"push_and_create_mr\\\"\\n to: \\\"evaluate_merge_request\\\"\\n - from: \\\"evaluate_merge_request\\\"\\n to: \\\"link_vulnerability\\\"\\n - from: \\\"link_vulnerability\\\"\\n to: \\\"end\\\"\\n\\nflow:\\n entry_point: \\\"gather_context\\\"\\n\",\n \"sast_fp_detection\": \"version: v1\\nenvironment: ambient\\ncomponents:\\n - name: \\\"sast_vulnerability_details_component\\\"\\n type: DeterministicStepComponent\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: vulnerability_id\\n tool_name: \\\"get_vulnerability_details\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"validate_sast_vulnerability_component\\\"\\n type: AgentComponent\\n prompt_id: \\\"validate_sast_vulnerability_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n response_schema_id: \\\"validate_sast_vulnerability\\\"\\n response_schema_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n toolset: []\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - \\\"on_agent_final_answer\\\"\\n - name: \\\"sast_vulnerability_source_file_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"sast_vulnerability_source_file_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n toolset:\\n - \\\"get_repository_file\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_vulnerability_lines_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"sast_vulnerability_lines_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:sast_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset:\\n - \\\"extract_lines_from_text\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_vulnerability_report_component\\\"\\n type: AgentComponent\\n prompt_id: \\\"sast_vulnerability_report_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:sast_vulnerability_lines_component.tool_responses\\\"\\n as: vulnerable_lines\\n - from: \\\"context:sast_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset: []\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_fp_detection_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"sast_fp_detection_agent_prompt\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_report_component.final_answer\\\"\\n as: vulnerability_details\\n toolset:\\n - \\\"read_file\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_repository_tree\\\"\\n - \\\"find_files\\\"\\n - \\\"gitlab_blob_search\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"sast_post_results_to_gitlab_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"sast_post_results_to_gitlab_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:sast_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:sast_fp_detection_agent.final_answer\\\"\\n as: sast_fp_detection_analysis\\n toolset:\\n - \\\"post_sast_fp_analysis_to_gitlab\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters:\\n - from: \\\"sast_vulnerability_details_component\\\"\\n to: \\\"validate_sast_vulnerability_component\\\"\\n - from: \\\"validate_sast_vulnerability_component\\\"\\n condition:\\n input: \\\"context:validate_sast_vulnerability_component.final_answer.decision\\\"\\n routes:\\n \\\"valid\\\": \\\"sast_vulnerability_source_file_component\\\"\\n \\\"invalid\\\": \\\"end\\\"\\n - from: \\\"sast_vulnerability_source_file_component\\\"\\n to: \\\"sast_vulnerability_lines_component\\\"\\n - from: \\\"sast_vulnerability_lines_component\\\"\\n to: \\\"sast_vulnerability_report_component\\\"\\n - from: \\\"sast_vulnerability_report_component\\\"\\n to: \\\"sast_fp_detection_agent\\\"\\n - from: \\\"sast_fp_detection_agent\\\"\\n to: \\\"sast_post_results_to_gitlab_component\\\"\\n - from: \\\"sast_post_results_to_gitlab_component\\\"\\n to: \\\"end\\\"\\nflow:\\n entry_point: \\\"sast_vulnerability_details_component\\\"\\n\",\n \"secrets_fp_detection\": \"version: \\\"v1\\\"\\nenvironment: ambient\\ncomponents:\\n - name: \\\"secret_vulnerability_details_component\\\"\\n type: DeterministicStepComponent\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: vulnerability_id\\n tool_name: \\\"get_vulnerability_details\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_vulnerability_source_file_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"secret_vulnerability_source_file_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n toolset:\\n - \\\"get_repository_file\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_vulnerability_lines_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"secret_vulnerability_lines_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:secret_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset:\\n - \\\"extract_lines_from_text\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_vulnerability_report_component\\\"\\n type: AgentComponent\\n prompt_id: \\\"secret_vulnerability_report_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:secret_vulnerability_lines_component.tool_responses\\\"\\n as: vulnerable_lines\\n - from: \\\"context:secret_vulnerability_source_file_component.tool_responses\\\"\\n as: vulnerability_source_code\\n toolset: []\\n ui_log_events:\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_fp_detection_agent\\\"\\n type: AgentComponent\\n prompt_id: \\\"secret_fp_detection_agent_prompt\\\"\\n prompt_version: \\\"^1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_report_component.final_answer\\\"\\n as: vulnerability_details\\n toolset:\\n - \\\"read_file\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"list_repository_tree\\\"\\n - \\\"find_files\\\"\\n - \\\"gitlab_blob_search\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\n - name: \\\"secret_post_results_to_gitlab_component\\\"\\n type: OneOffComponent\\n prompt_id: \\\"secret_post_results_to_gitlab_agent_prompt\\\"\\n prompt_version: \\\"1.0.0\\\"\\n inputs:\\n - from: \\\"context:secret_vulnerability_details_component.tool_responses\\\"\\n as: vulnerability_details_json\\n - from: \\\"context:secret_fp_detection_agent.final_answer\\\"\\n as: secret_fp_detection_analysis\\n toolset:\\n - \\\"post_secret_fp_analysis_to_gitlab\\\"\\n max_correction_attempts: 3\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters:\\n - from: \\\"secret_vulnerability_details_component\\\"\\n to: \\\"secret_vulnerability_source_file_component\\\"\\n - from: \\\"secret_vulnerability_source_file_component\\\"\\n to: \\\"secret_vulnerability_lines_component\\\"\\n - from: \\\"secret_vulnerability_lines_component\\\"\\n to: \\\"secret_vulnerability_report_component\\\"\\n - from: \\\"secret_vulnerability_report_component\\\"\\n to: \\\"secret_fp_detection_agent\\\"\\n - from: \\\"secret_fp_detection_agent\\\"\\n to: \\\"secret_post_results_to_gitlab_component\\\"\\n - from: \\\"secret_post_results_to_gitlab_component\\\"\\n to: \\\"end\\\"\\nflow:\\n entry_point: \\\"secret_vulnerability_details_component\\\"\\n\",\n \"slack_assistant\": \"version: \\\"v1\\\"\\nenvironment: chat\\ncomponents:\\n - name: \\\"slack_assistant\\\"\\n type: AgentComponent\\n prompt_id: \\\"slack_assistant_prompt\\\"\\n inputs:\\n - from: \\\"context:goal\\\"\\n as: \\\"goal\\\"\\n toolset:\\n - \\\"gitlab_api_get\\\"\\n - \\\"gitlab_graphql\\\"\\n - \\\"gitlab_issue_search\\\"\\n - \\\"get_issue\\\"\\n - \\\"get_merge_request\\\"\\n - \\\"get_wiki_page\\\"\\n - \\\"get_repository_file\\\"\\n - \\\"gitlab_documentation_search\\\"\\n ui_log_events:\\n - \\\"on_agent_final_answer\\\"\\n - \\\"on_tool_execution_success\\\"\\n - \\\"on_tool_execution_failed\\\"\\nrouters:\\n - from: \\\"slack_assistant\\\"\\n to: \\\"end\\\"\\nflow:\\n entry_point: \\\"slack_assistant\\\"\\nprompts:\\n - name: \\\"slack_assistant_prompt\\\"\\n prompt_id: \\\"slack_assistant_prompt\\\"\\n unit_primitives:\\n - duo_agent_platform\\n prompt_template:\\n system: |\\n You are a helpful GitLab assistant that people talk to in Slack.\\n\\n You receive the Slack thread as context (in <slack-thread-context> tags) and a user_context with the invoking user's identity and their group memberships. Use the groups to broaden your searches — search across multiple groups, not just the default namespace. When scoped searches return no results, always fall back to instance-wide search using `GET /api/v4/search?scope=issues&search=...` or `GET /api/v4/projects?search=...&search_namespaces=true`.\\n\\n Keep Slack responses short. Use bullet points and link to GitLab so people can click through. Format your responses using Slack mrkdwn syntax:\\n - *bold* for emphasis\\n - _italic_ for secondary emphasis\\n - `code` for inline code or commands\\n - ```multi-line code``` for code blocks\\n - <url|link text> for URLs (e.g., <https://gitlab.com/my-issue|View issue>)\\n - <#channel_id> to link channels\\n - <@user_id> to mention users\\n - <!subteam^group_id> to mention groups\\n - @here, @channel, @everyone for special mentions\\n - ~strikethrough~ to strikethrough text\\n - > quote for block quotes\\n - - item for bullet points\\n - \\\\n for line breaks\\n\\n You are currently *read-only* and act on behalf of the person who mentioned you. You can search and retrieve GitLab data (issues, projects, merge requests, users, etc.) but you cannot create, update, or delete anything. If someone asks you to create an issue or make changes, let them know this capability is not available yet and suggest they do it in GitLab directly.\\n\\n When a specific tool exists for the task (e.g. `get_issue`, `get_merge_request`, `get_wiki_page`, `get_repository_file`), prefer it over `gitlab_api_get` — it handles URL parsing and compound operations automatically. Use `gitlab_api_get` and `gitlab_graphql` as fallbacks for resources not covered by a specific tool.\\n\\n The GitLab API accepts URL-encoded project paths (like `gitlab-org%2Fgitlab`) wherever it accepts numeric project IDs. Use this when people reference projects by path.\\n user: |\\n {{goal}}\\n placeholder: history\\n\",\n};\n","import { gql } from \"./graphql\";\n\nconst LIST_AI_CATALOG_ITEMS_QUERY = `\nquery listAiCatalogItems(\n $itemTypes: [AiCatalogItemType!]\n $search: String\n $first: Int\n $after: String\n) {\n aiCatalogItems(\n itemTypes: $itemTypes\n search: $search\n first: $first\n after: $after\n ) {\n nodes {\n id\n name\n description\n itemType\n foundational\n public\n createdAt\n updatedAt\n softDeleted\n project { id, nameWithNamespace }\n latestVersion {\n id\n createdAt\n updatedAt\n createdBy { id, name, username }\n }\n }\n pageInfo { hasNextPage, hasPreviousPage, startCursor, endCursor }\n }\n}`;\n\nconst GET_AI_CATALOG_ITEM_QUERY = `\nquery getAiCatalogItem($id: AiCatalogItemID!) {\n aiCatalogItem(id: $id) {\n id\n name\n description\n itemType\n foundational\n public\n createdAt\n updatedAt\n softDeleted\n project { id, nameWithNamespace }\n latestVersion {\n id\n createdAt\n updatedAt\n createdBy { id, name, username, webUrl }\n }\n userPermissions { adminAiCatalogItem, reportAiCatalogItem }\n }\n}`;\n\nconst LIST_PROJECT_CONFIGURED_ITEMS_QUERY = `\nquery listProjectConfiguredItems(\n $projectId: ProjectID!\n $itemTypes: [AiCatalogItemType!]\n $includeFoundationalConsumers: Boolean\n $first: Int\n $after: String\n) {\n aiCatalogConfiguredItems(\n projectId: $projectId\n itemTypes: $itemTypes\n includeFoundationalConsumers: $includeFoundationalConsumers\n first: $first\n after: $after\n ) {\n nodes {\n id\n item {\n id\n name\n description\n itemType\n foundational\n public\n createdAt\n updatedAt\n softDeleted\n project { id, nameWithNamespace }\n latestVersion {\n id\n createdAt\n createdBy { name, username }\n }\n }\n pinnedItemVersion { id, humanVersionName }\n }\n pageInfo { hasNextPage, hasPreviousPage, startCursor, endCursor }\n }\n}`;\n\nconst ENABLE_AI_CATALOG_ITEM_MUTATION = `\nmutation enableAiCatalogItem($input: AiCatalogItemConsumerCreateInput!) {\n aiCatalogItemConsumerCreate(input: $input) {\n errors\n itemConsumer {\n id\n project { id, name, webUrl }\n group { id, name, webUrl }\n }\n }\n}`;\n\nconst DISABLE_AI_CATALOG_ITEM_MUTATION = `\nmutation disableAiCatalogItem($input: AiCatalogItemConsumerDeleteInput!) {\n aiCatalogItemConsumerDelete(input: $input) {\n errors\n success\n }\n}`;\n\nconst FIND_ITEM_CONSUMER_FOR_DISABLE_QUERY = `\nquery findItemConsumer(\n $projectId: ProjectID!\n $itemTypes: [AiCatalogItemType!]\n) {\n aiCatalogConfiguredItems(\n projectId: $projectId\n itemTypes: $itemTypes\n includeFoundationalConsumers: true\n first: 100\n ) {\n nodes { id, item { id } }\n }\n}`;\n\nconst RESOLVE_PROJECT_IDS_FOR_TOOLS_QUERY = `\nquery resolveProjectIds($projectPath: ID!) {\n project(fullPath: $projectPath) {\n id\n namespace { id }\n }\n}`;\n\nfunction normalizeItemGid(id: string): string {\n if (id.startsWith(\"gid://\")) return id;\n if (!/^\\d+$/.test(id)) throw new Error(`Invalid catalog item ID: \"${id}\"`);\n return `gid://gitlab/Ai::Catalog::Item/${id}`;\n}\n\nexport async function resolveProjectGid(\n instanceUrl: string,\n token: string,\n projectPath: string\n): Promise<string> {\n const result = await gql(instanceUrl, token, RESOLVE_PROJECT_IDS_FOR_TOOLS_QUERY, {\n projectPath,\n });\n return result.project.id;\n}\n\nexport async function listAiCatalogItems(\n instanceUrl: string,\n token: string,\n itemTypes: string[],\n options?: { search?: string; first?: number; after?: string }\n): Promise<Record<string, unknown>> {\n const variables: Record<string, unknown> = {\n itemTypes,\n first: options?.first ?? 20,\n };\n if (options?.search) variables.search = options.search;\n if (options?.after) variables.after = options.after;\n const result = await gql(instanceUrl, token, LIST_AI_CATALOG_ITEMS_QUERY, variables);\n return result.aiCatalogItems;\n}\n\nexport async function getAiCatalogItem(\n instanceUrl: string,\n token: string,\n itemId: string\n): Promise<Record<string, unknown>> {\n const gid = normalizeItemGid(itemId);\n const result = await gql(instanceUrl, token, GET_AI_CATALOG_ITEM_QUERY, { id: gid });\n return result.aiCatalogItem;\n}\n\nexport async function listProjectAiCatalogItems(\n instanceUrl: string,\n token: string,\n projectPath: string,\n itemTypes: string[],\n options?: { first?: number; after?: string }\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const variables: Record<string, unknown> = {\n projectId: projectGid,\n itemTypes,\n includeFoundationalConsumers: true,\n first: options?.first ?? 20,\n };\n if (options?.after) variables.after = options.after;\n const result = await gql(instanceUrl, token, LIST_PROJECT_CONFIGURED_ITEMS_QUERY, variables);\n return result.aiCatalogConfiguredItems;\n}\n\nexport async function enableAiCatalogItemForProject(\n instanceUrl: string,\n token: string,\n projectPath: string,\n itemId: string\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const gid = normalizeItemGid(itemId);\n const result = await gql(instanceUrl, token, ENABLE_AI_CATALOG_ITEM_MUTATION, {\n input: { itemId: gid, target: { projectId: projectGid } },\n });\n if (result.aiCatalogItemConsumerCreate.errors.length > 0) {\n throw new Error(\n `Failed to enable item: ${result.aiCatalogItemConsumerCreate.errors.join(\", \")}`\n );\n }\n return result.aiCatalogItemConsumerCreate;\n}\n\nexport async function disableAiCatalogItemForProject(\n instanceUrl: string,\n token: string,\n projectPath: string,\n itemId: string\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const gid = normalizeItemGid(itemId);\n const consumerResult = await gql(instanceUrl, token, FIND_ITEM_CONSUMER_FOR_DISABLE_QUERY, {\n projectId: projectGid,\n itemTypes: [\"AGENT\", \"FLOW\", \"THIRD_PARTY_FLOW\"],\n });\n const consumer = consumerResult.aiCatalogConfiguredItems.nodes.find(\n (n: any) => n.item.id === gid\n );\n if (!consumer?.id) throw new Error(\"Agent/flow is not enabled in this project\");\n const result = await gql(instanceUrl, token, DISABLE_AI_CATALOG_ITEM_MUTATION, {\n input: { id: consumer.id },\n });\n if (result.aiCatalogItemConsumerDelete.errors.length > 0) {\n throw new Error(\n `Failed to disable item: ${result.aiCatalogItemConsumerDelete.errors.join(\", \")}`\n );\n }\n return result.aiCatalogItemConsumerDelete;\n}\n","import { gql } from \"./graphql\";\nimport { resolveProjectGid } from \"./catalog-items\";\n\nconst CREATE_AGENT_MUTATION = `\nmutation AiCatalogAgentCreate($input: AiCatalogAgentCreateInput!) {\n aiCatalogAgentCreate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogAgentVersion {\n systemPrompt\n userPrompt\n tools { nodes { id, name, description } }\n mcpServers { nodes { id, name, url } }\n }\n }\n }\n }\n}`;\n\nconst UPDATE_AGENT_MUTATION = `\nmutation AiCatalogAgentUpdate($input: AiCatalogAgentUpdateInput!) {\n aiCatalogAgentUpdate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogAgentVersion {\n systemPrompt\n userPrompt\n tools { nodes { id, name, description } }\n mcpServers { nodes { id, name, url } }\n }\n }\n }\n }\n}`;\n\nconst LIST_BUILTIN_TOOLS_QUERY = `\nquery AiCatalogBuiltInTools {\n aiCatalogBuiltInTools(first: 1000) {\n nodes {\n id\n name\n title\n description\n }\n }\n}`;\n\nconst CREATE_FLOW_MUTATION = `\nmutation AiCatalogFlowCreate($input: AiCatalogFlowCreateInput!) {\n aiCatalogFlowCreate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogFlowVersion { definition }\n }\n }\n }\n}`;\n\nconst UPDATE_FLOW_MUTATION = `\nmutation AiCatalogFlowUpdate($input: AiCatalogFlowUpdateInput!) {\n aiCatalogFlowUpdate(input: $input) {\n errors\n item {\n id\n name\n description\n itemType\n public\n project { id, nameWithNamespace, webUrl }\n latestVersion {\n id\n humanVersionName\n released\n ... on AiCatalogFlowVersion { definition }\n }\n }\n }\n}`;\n\nfunction normalizeItemGid(id: string): string {\n if (id.startsWith(\"gid://\")) return id;\n if (!/^\\d+$/.test(id)) throw new Error(`Invalid catalog item ID: \"${id}\"`);\n return `gid://gitlab/Ai::Catalog::Item/${id}`;\n}\n\nexport async function createAgent(\n instanceUrl: string,\n token: string,\n projectPath: string,\n params: {\n name: string;\n description: string;\n public: boolean;\n systemPrompt: string;\n userPrompt?: string;\n tools?: string[];\n mcpTools?: string[];\n mcpServers?: string[];\n release?: boolean;\n }\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const input: Record<string, unknown> = {\n projectId: projectGid,\n name: params.name,\n description: params.description,\n public: params.public,\n systemPrompt: params.systemPrompt,\n };\n if (params.userPrompt) input.userPrompt = params.userPrompt;\n if (params.tools?.length) input.tools = params.tools;\n if (params.mcpTools?.length) input.mcpTools = params.mcpTools;\n if (params.mcpServers?.length) input.mcpServers = params.mcpServers;\n if (params.release !== undefined) input.release = params.release;\n const result = await gql(instanceUrl, token, CREATE_AGENT_MUTATION, { input });\n if (result.aiCatalogAgentCreate.errors.length > 0) {\n throw new Error(`Failed to create agent: ${result.aiCatalogAgentCreate.errors.join(\", \")}`);\n }\n return result.aiCatalogAgentCreate.item;\n}\n\nexport async function updateAgent(\n instanceUrl: string,\n token: string,\n itemId: string,\n params: {\n name?: string;\n description?: string;\n public?: boolean;\n systemPrompt?: string;\n userPrompt?: string;\n tools?: string[];\n mcpTools?: string[];\n mcpServers?: string[];\n release?: boolean;\n versionBump?: \"MAJOR\" | \"MINOR\" | \"PATCH\";\n }\n): Promise<Record<string, unknown>> {\n const gid = normalizeItemGid(itemId);\n const input: Record<string, unknown> = { id: gid };\n if (params.name !== undefined) input.name = params.name;\n if (params.description !== undefined) input.description = params.description;\n if (params.public !== undefined) input.public = params.public;\n if (params.systemPrompt !== undefined) input.systemPrompt = params.systemPrompt;\n if (params.userPrompt !== undefined) input.userPrompt = params.userPrompt;\n if (params.tools !== undefined) input.tools = params.tools;\n if (params.mcpTools !== undefined) input.mcpTools = params.mcpTools;\n if (params.mcpServers !== undefined) input.mcpServers = params.mcpServers;\n if (params.release !== undefined) input.release = params.release;\n if (params.versionBump) input.versionBump = params.versionBump;\n const result = await gql(instanceUrl, token, UPDATE_AGENT_MUTATION, { input });\n if (result.aiCatalogAgentUpdate.errors.length > 0) {\n throw new Error(`Failed to update agent: ${result.aiCatalogAgentUpdate.errors.join(\", \")}`);\n }\n return result.aiCatalogAgentUpdate.item;\n}\n\nexport async function listBuiltInTools(\n instanceUrl: string,\n token: string\n): Promise<Array<{ id: string; name: string; title: string; description: string }>> {\n const result = await gql(instanceUrl, token, LIST_BUILTIN_TOOLS_QUERY, {});\n return result.aiCatalogBuiltInTools?.nodes ?? [];\n}\n\nexport async function createFlow(\n instanceUrl: string,\n token: string,\n projectPath: string,\n params: {\n name: string;\n description: string;\n public: boolean;\n definition: string;\n release?: boolean;\n }\n): Promise<Record<string, unknown>> {\n const projectGid = await resolveProjectGid(instanceUrl, token, projectPath);\n const input: Record<string, unknown> = {\n projectId: projectGid,\n name: params.name,\n description: params.description,\n public: params.public,\n definition: params.definition,\n };\n if (params.release !== undefined) input.release = params.release;\n const result = await gql(instanceUrl, token, CREATE_FLOW_MUTATION, { input });\n if (result.aiCatalogFlowCreate.errors.length > 0) {\n throw new Error(`Failed to create flow: ${result.aiCatalogFlowCreate.errors.join(\", \")}`);\n }\n return result.aiCatalogFlowCreate.item;\n}\n\nexport async function updateFlow(\n instanceUrl: string,\n token: string,\n itemId: string,\n params: {\n name?: string;\n description?: string;\n public?: boolean;\n definition?: string;\n release?: boolean;\n versionBump?: \"MAJOR\" | \"MINOR\" | \"PATCH\";\n }\n): Promise<Record<string, unknown>> {\n const gid = normalizeItemGid(itemId);\n const input: Record<string, unknown> = { id: gid };\n if (params.name !== undefined) input.name = params.name;\n if (params.description !== undefined) input.description = params.description;\n if (params.public !== undefined) input.public = params.public;\n if (params.definition !== undefined) input.definition = params.definition;\n if (params.release !== undefined) input.release = params.release;\n if (params.versionBump) input.versionBump = params.versionBump;\n const result = await gql(instanceUrl, token, UPDATE_FLOW_MUTATION, { input });\n if (result.aiCatalogFlowUpdate.errors.length > 0) {\n throw new Error(`Failed to update flow: ${result.aiCatalogFlowUpdate.errors.join(\", \")}`);\n }\n return result.aiCatalogFlowUpdate.item;\n}\n","export type { CatalogAgent, FlowInputDef, McpServerInfo } from \"./types\";\n\nexport {\n fetchCatalogAgents,\n executeFlow,\n getWorkflowStatus,\n getFlowDefinition,\n} from \"./flow-execution\";\n\nexport {\n listAiCatalogItems,\n getAiCatalogItem,\n listProjectAiCatalogItems,\n enableAiCatalogItemForProject,\n disableAiCatalogItemForProject,\n} from \"./catalog-items\";\n\nexport { createAgent, updateAgent, listBuiltInTools, createFlow, updateFlow } from \"./catalog-crud\";\n\nexport { fetchMcpServers, listMcpServerTools, discoverMcpToolNames } from \"./mcp-servers\";\n","import { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport os from \"os\";\n\nexport interface AuthInfo {\n token: string;\n instanceUrl: string;\n}\n\nexport function readAuth(): AuthInfo | null {\n try {\n const authPath = join(os.homedir(), \".local\", \"share\", \"opencode\", \"auth.json\");\n const data = JSON.parse(readFileSync(authPath, \"utf-8\"));\n const gitlab = data?.gitlab;\n if (!gitlab) return null;\n const token =\n gitlab.type === \"oauth\" ? gitlab.access : gitlab.type === \"api\" ? gitlab.key : null;\n if (!token) return null;\n const instanceUrl =\n gitlab.enterpriseUrl ?? process.env.GITLAB_INSTANCE_URL ?? \"https://gitlab.com\";\n return { token, instanceUrl };\n } catch {\n return null;\n }\n}\n\nexport interface PluginContext {\n getAuth: () => AuthInfo | null;\n ensureAuth: () => AuthInfo | null;\n getFlowAgents: () => Map<string, import(\"./types\").CatalogAgent>;\n getCachedAgents: () => import(\"./types\").CatalogAgent[];\n getNamespaceId: () => number | undefined;\n refreshAgents: () => Promise<void>;\n}\n","import type { ModelCacheEntry } from \"gitlab-ai-provider\";\nimport type { CatalogAgent } from \"./catalog\";\n\nexport function resolveModelId(entry: ModelCacheEntry): string {\n const ref = entry.selectedModelRef ?? entry.discovery?.defaultModel?.ref;\n if (!ref) return \"duo-workflow-default\";\n return `duo-workflow-${ref.replace(/[/_]/g, \"-\")}`;\n}\n\nexport function buildAgentEntries(agents: CatalogAgent[], entry: ModelCacheEntry) {\n const modelId = resolveModelId(entry);\n return Object.fromEntries(\n agents.map((agent) => [\n `gitlab-${agent.identifier}`,\n {\n name: agent.name,\n description: agent.description,\n mode: \"primary\",\n model: { providerID: \"gitlab\", modelID: modelId },\n permission: { \"*\": \"allow\" },\n options: {\n workflowDefinition: agent.workflowDefinition,\n gitlabFoundational: agent.foundational,\n },\n },\n ])\n );\n}\n","export const FLOW_DISPATCH_GUIDELINES = [\n `## GitLab Flow Dispatch Guidelines`,\n ``,\n `CRITICAL: You must NEVER call gitlab_execute_project_flow or gitlab_get_flow_definition directly.`,\n `Flows are ALWAYS executed via the Task tool with subagent_type \"general\".`,\n `When the user's message contains flow dispatch instructions (starting with \"IMPORTANT: You MUST\"),`,\n `follow those instructions exactly — call the Task tool with the provided parameters.`,\n ``,\n `### Multiple Flows or Resources`,\n `When multiple flows need to run (multiple @mentions, or batch across resources), dispatch them`,\n `via a SINGLE \"general\" subagent. The general subagent can execute multiple tool calls in parallel,`,\n `so all flows fire simultaneously. Do NOT dispatch multiple Task calls — use ONE Task with a prompt`,\n `that lists all the flows to execute, so the subagent runs them concurrently.`,\n ``,\n `### Batch Operations (Multiple Resources)`,\n `If the user asks to run flows on multiple resources (e.g., \"for each MR\"), first list the`,\n `resources yourself using GitLab API tools, then dispatch ONE general subagent whose prompt`,\n `includes all flow executions (N flows x M resources) to run in parallel.`,\n].join(\"\\n\");\n\nexport const FLOW_SCHEMA_REFERENCE = `## Flow YAML Schema Reference\n\n### Top-level structure (all required unless noted):\n version: \"v1\" # Always \"v1\"\n environment: ambient # Always \"ambient\"\n components: [...] # Array of components (min 1)\n routers: [...] # Array of routers connecting components\n flow:\n entry_point: \"component_name\" # First component to run\n inputs: [...] # Optional: additional context inputs\n prompts: [...] # Optional: inline prompt definitions\n\n### Component types:\n\n1. DeterministicStepComponent — runs ONE tool, no LLM call:\n - name: \"fetch_data\" # alphanumeric + underscore only\n type: DeterministicStepComponent\n tool_name: \"get_merge_request\"\n inputs: # map tool parameters\n - { from: \"context:goal\", as: \"merge_request_iid\" }\n - { from: \"context:project_id\", as: \"project_id\" }\n\n2. OneOffComponent — single LLM call + tool execution:\n - name: \"process_data\"\n type: OneOffComponent\n prompt_id: \"my_prompt\" # references inline prompt\n prompt_version: null # null = use inline prompt from prompts section\n toolset: [\"read_file\", \"edit_file\"]\n inputs:\n - { from: \"context:fetch_data.tool_responses\", as: \"data\" }\n max_correction_attempts: 3 # retries on tool failure (default 3)\n\n3. AgentComponent — multi-turn LLM reasoning loop:\n - name: \"analyze\"\n type: AgentComponent\n prompt_id: \"my_agent_prompt\"\n prompt_version: null\n toolset: [\"read_file\", \"grep\"]\n inputs:\n - { from: \"context:goal\", as: \"user_goal\" }\n ui_log_events: [\"on_agent_final_answer\"]\n\n### IOKey syntax (inputs/from values):\n \"context:goal\" # The flow goal (user input)\n \"context:project_id\" # Project ID (auto-injected)\n \"context:<component_name>.tool_responses\" # Tool output from a component\n \"context:<component_name>.final_answer\" # Agent's final text answer\n \"context:<component_name>.execution_result\" # OneOff execution result\n { from: \"context:x\", as: \"var_name\" } # Rename for prompt template\n { from: \"true\", as: \"flag\", literal: true } # Literal value\n\n### Router patterns:\n Direct: { from: \"step1\", to: \"step2\" }\n To end: { from: \"last_step\", to: \"end\" }\n Conditional: { from: \"step1\", condition: { input: \"context:step1.final_answer.decision\", routes: { \"yes\": \"step2\", \"no\": \"end\" } } }\n\n### Inline prompts (in prompts section):\n - prompt_id: \"my_prompt\"\n name: \"My Prompt\"\n unit_primitives: [\"duo_agent_platform\"] # Always this value\n prompt_template:\n system: \"You are a helpful assistant. {{var_name}} is available.\"\n user: \"Process: {{data}}\"\n placeholder: \"history\" # Optional, for AgentComponent conversation history\n\n### Tool names: use names from gitlab_list_builtin_tools (e.g., \"read_file\", \"get_merge_request\", \"create_merge_request_note\").`;\n\nexport const FLOW_EXAMPLE_LINEAR = `## Example: Simple linear flow (fetch MR → analyze → post comment)\n\\`\\`\\`yaml\nversion: \"v1\"\nenvironment: ambient\ncomponents:\n - name: fetch_mr\n type: DeterministicStepComponent\n tool_name: build_review_merge_request_context\n inputs:\n - { from: \"context:project_id\", as: \"project_id\" }\n - { from: \"context:goal\", as: \"merge_request_iid\" }\n ui_log_events: [\"on_tool_execution_success\", \"on_tool_execution_failed\"]\n - name: analyze_and_comment\n type: OneOffComponent\n prompt_id: review_prompt\n prompt_version: null\n toolset: [\"create_merge_request_note\"]\n inputs:\n - { from: \"context:fetch_mr.tool_responses\", as: \"mr_data\" }\n - { from: \"context:project_id\", as: \"project_id\" }\n - { from: \"context:goal\", as: \"merge_request_iid\" }\n max_correction_attempts: 3\n ui_log_events: [\"on_tool_execution_success\"]\nrouters:\n - { from: fetch_mr, to: analyze_and_comment }\n - { from: analyze_and_comment, to: end }\nflow:\n entry_point: fetch_mr\nprompts:\n - prompt_id: review_prompt\n name: MR Review Prompt\n unit_primitives: [\"duo_agent_platform\"]\n prompt_template:\n system: |\n You review merge requests. Analyze the MR data and post a concise review comment.\n Focus on code quality, potential bugs, and improvements.\n user: \"Review MR !{{merge_request_iid}} in project {{project_id}}: {{mr_data}}\"\n\\`\\`\\``;\n\nexport const FLOW_EXAMPLE_CONDITIONAL = `## Example: Conditional flow (gather data → decide → branch)\n\\`\\`\\`yaml\nversion: \"v1\"\nenvironment: ambient\ncomponents:\n - name: gather_context\n type: DeterministicStepComponent\n tool_name: get_vulnerability_details\n inputs:\n - { from: \"context:goal\", as: \"vulnerability_id\" }\n ui_log_events: [\"on_tool_execution_success\"]\n - name: evaluate\n type: AgentComponent\n prompt_id: eval_prompt\n prompt_version: null\n toolset: []\n inputs:\n - { from: \"context:gather_context.tool_responses\", as: \"vuln_data\" }\n ui_log_events: [\"on_agent_final_answer\"]\n - name: create_fix\n type: AgentComponent\n prompt_id: fix_prompt\n prompt_version: null\n toolset: [\"read_file\", \"edit_file\", \"grep\"]\n inputs:\n - { from: \"context:gather_context.tool_responses\", as: \"vuln_data\" }\n ui_log_events: [\"on_agent_final_answer\", \"on_tool_execution_success\"]\nrouters:\n - { from: gather_context, to: evaluate }\n - from: evaluate\n condition:\n input: \"context:evaluate.final_answer\"\n routes:\n \"fix_needed\": create_fix\n \"false_positive\": end\n default_route: end\n - { from: create_fix, to: end }\nflow:\n entry_point: gather_context\nprompts:\n - prompt_id: eval_prompt\n name: Vulnerability Evaluator\n unit_primitives: [\"duo_agent_platform\"]\n prompt_template:\n system: |\n Evaluate if a vulnerability needs fixing. Respond with exactly \"fix_needed\" or \"false_positive\".\n user: \"Evaluate: {{vuln_data}}\"\n - prompt_id: fix_prompt\n name: Fix Generator\n unit_primitives: [\"duo_agent_platform\"]\n prompt_template:\n system: |\n You fix security vulnerabilities. Read the relevant code and apply the fix.\n user: \"Fix this vulnerability: {{vuln_data}}\"\n placeholder: history\n\\`\\`\\``;\n","import type { CatalogAgent } from \"./types\";\nimport type { AuthInfo } from \"./auth\";\nimport { FLOW_DISPATCH_GUIDELINES } from \"./prompts\";\n\nexport function buildFlowSubagentPrompt(\n flow: CatalogAgent,\n projectPath: string,\n projectUrl: string\n): string {\n return [\n `You execute the \"${flow.name}\" GitLab flow. Project: ${projectPath} (${projectUrl}).`,\n ``,\n `STEP 1: Call gitlab_get_flow_definition with consumer_id=${flow.consumerId}, foundational=${!!flow.foundational}.`,\n `Parse the YAML config:`,\n `- In \"components\", find { from: \"context:goal\", as: \"<name>\" }. The \"as\" value is what the goal parameter must contain:`,\n ` \"merge_request_iid\" -> just the number (e.g. 14)`,\n ` \"pipeline_url\"/\"url\"/\"issue_url\" -> full URL (e.g. ${projectUrl}/-/merge_requests/5)`,\n ` \"vulnerability_id\" -> just the ID number`,\n ` \"goal\" -> free-form text`,\n `- In \"flow.inputs\", find additional_context categories (skip \"agent_platform_standard_context\").`,\n ``,\n `STEP 2: Resolve the goal to the EXACT value the flow expects (from step 1).`,\n `The goal parameter has a 10000 char limit and is used directly as the flow parameter — pass ONLY the raw value, never a sentence.`,\n `Use GitLab API tools if needed to look up IDs or construct URLs from the user's message.`,\n ``,\n `STEP 3: Gather additional_context values (if any from step 1) using available tools.`,\n ``,\n `STEP 4: Call gitlab_execute_project_flow with:`,\n ` project_id: \"${projectPath}\"`,\n ` consumer_id: ${flow.consumerId}`,\n ` goal: <resolved value from step 2>`,\n ` additional_context (if needed): [{\"Category\":\"<cat>\",\"Content\":\"{\\\\\"field\\\\\":\\\\\"val\\\\\"}\"}]`,\n ``,\n `STEP 5: Call gitlab_get_workflow_status with the workflow_id. Report status and URL: ${projectUrl}/-/automate/agent-sessions/<id>`,\n ].join(\"\\n\");\n}\n\nexport function makeChatMessageHook(\n getAuthCache: () => AuthInfo | null,\n flowAgents: Map<string, CatalogAgent>,\n getProjectPath: () => string | undefined\n) {\n return async (_input: any, output: any) => {\n const projectPath = getProjectPath();\n const indicesToRemove: number[] = [];\n const flowMentions: Array<{\n idx: number;\n flow: CatalogAgent;\n displayName: string;\n }> = [];\n\n for (let i = 0; i < output.parts.length; i++) {\n const part = output.parts[i] as any;\n if (part.type !== \"agent\") continue;\n\n const flow = flowAgents.get(part.name);\n if (!flow || !flow.consumerId || !projectPath) continue;\n\n flowMentions.push({ idx: i, flow, displayName: part.name });\n\n if (i + 1 < output.parts.length) {\n const next = output.parts[i + 1] as any;\n if (\n next.type === \"text\" &&\n next.synthetic &&\n next.text?.includes(\"call the task tool with subagent\")\n ) {\n indicesToRemove.push(i + 1);\n }\n }\n }\n\n if (flowMentions.length === 0) {\n return;\n }\n\n const authCache = getAuthCache();\n if (flowMentions.length === 1) {\n const { idx, flow } = flowMentions[0];\n const baseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n const projectUrl = `${baseUrl}/${projectPath}`;\n\n const rawText =\n output.parts\n .filter((p: any) => p.type === \"text\" && !p.synthetic)\n .map((p: any) => p.text)\n .join(\" \")\n .trim() || \"Execute the flow\";\n\n const subagentPrompt =\n buildFlowSubagentPrompt(flow, projectPath!, projectUrl) + `\\n\\nUser goal: \"${rawText}\"`;\n\n const resultText = [\n `IMPORTANT: You MUST call the Task tool RIGHT NOW to dispatch a subagent. Do NOT execute these steps yourself.`,\n ``,\n `Call the Task tool with:`,\n ` subagent_type: \"general\"`,\n ` description: \"Execute ${flow.name} flow\"`,\n ` prompt: ${JSON.stringify(subagentPrompt)}`,\n ``,\n `Do not do anything else. Just call the Task tool with the above parameters.`,\n ].join(\"\\n\");\n\n const original = output.parts[idx] as any;\n output.parts[idx] = { ...original, type: \"text\", text: resultText } as any;\n delete (output.parts[idx] as any).name;\n delete (output.parts[idx] as any).source;\n\n for (const rmIdx of indicesToRemove.reverse()) {\n output.parts.splice(rmIdx, 1);\n }\n return;\n }\n\n const baseUrl = authCache?.instanceUrl?.replace(/\\/$/, \"\") ?? \"https://gitlab.com\";\n const projectUrl = `${baseUrl}/${projectPath}`;\n\n const flowNames = new Set(flowMentions.map((m) => m.displayName));\n let rawText =\n output.parts\n .filter((p: any) => p.type === \"text\" && !p.synthetic)\n .map((p: any) => p.text)\n .join(\" \")\n .trim() || \"Execute the flows\";\n\n for (const name of flowNames) {\n rawText = rawText\n .replace(new RegExp(`@${name.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")}`, \"g\"), \"\")\n .trim();\n }\n rawText = rawText.replace(/\\s{2,}/g, \" \").trim() || \"Execute the flows\";\n\n const flowList = flowMentions.map(\n ({ flow, displayName }, i) =>\n `${i + 1}. \"${displayName}\" — consumer_id=${flow.consumerId}, foundational=${!!flow.foundational}`\n );\n\n const batchPrompt = [\n `Execute ${flowMentions.length} GitLab flows on project ${projectPath} (${projectUrl}).`,\n `User goal: \"${rawText}\"`,\n ``,\n `Flows to execute:`,\n ...flowList,\n ``,\n `EXECUTION PLAN:`,\n `1. Call gitlab_get_flow_definition for ALL flows listed above in a SINGLE response (${flowMentions.length} tool calls at once).`,\n ` Parse each YAML to find what \"context:goal\" maps to (the \"as\" field in components).`,\n ``,\n `2. If the user's goal involves multiple resources (e.g., \"for each MR\"), list them using GitLab API tools.`,\n ``,\n `3. Call gitlab_execute_project_flow for EVERY flow+resource combination in a SINGLE response.`,\n ` For each call, set the goal to the EXACT value the flow expects (e.g., just \"14\" for merge_request_iid).`,\n ` project_id: \"${projectPath}\"`,\n ` You MUST emit ALL execute calls in ONE response — do NOT wait for one to finish before calling the next.`,\n ``,\n `4. Collect all workflow_ids from step 3. Call gitlab_get_workflow_status for ALL of them in a SINGLE response.`,\n ``,\n `5. Present a summary table: flow name, resource, status, URL (${projectUrl}/-/automate/agent-sessions/<id>).`,\n ``,\n `CRITICAL: In steps 1, 3, and 4 you MUST make multiple tool calls in the SAME response for parallel execution.`,\n ].join(\"\\n\");\n\n const combinedText = [\n `IMPORTANT: You MUST call the Task tool RIGHT NOW with subagent_type \"general\" to dispatch all flows in parallel.`,\n `Do NOT call flow tools yourself. Do NOT dispatch multiple Task calls — use ONE.`,\n ``,\n `Call the Task tool with:`,\n ` subagent_type: \"general\"`,\n ` description: \"Execute ${flowMentions.length} flows in parallel\"`,\n ` prompt: ${JSON.stringify(batchPrompt)}`,\n ``,\n `Do not do anything else. Just call the Task tool with the above parameters.`,\n ].join(\"\\n\");\n\n const firstIdx = flowMentions[0].idx;\n const original = output.parts[firstIdx] as any;\n output.parts[firstIdx] = { ...original, type: \"text\", text: combinedText } as any;\n delete (output.parts[firstIdx] as any).name;\n delete (output.parts[firstIdx] as any).source;\n\n for (let i = flowMentions.length - 1; i >= 1; i--) {\n indicesToRemove.push(flowMentions[i].idx);\n }\n\n for (const idx of [...new Set(indicesToRemove)].sort((a, b) => b - a)) {\n output.parts.splice(idx, 1);\n }\n };\n}\n\nexport function makeChatParamsHook(gitlabAgentNames: Set<string>) {\n return async (input: any, _output: any) => {\n if (!gitlabAgentNames.has(input.agent)) return;\n const model = input.model as any;\n const modelId = model?.modelID ?? model?.id ?? \"\";\n const isDWS = modelId.includes(\"duo-workflow\");\n if (!isDWS) {\n const name = model?.name ?? modelId ?? \"unknown\";\n throw new Error(\n `GitLab agent \"${input.agent}\" requires an Agent Platform model but the current model is \"${name}\". ` +\n `Please switch to an Agent Platform model (duo-workflow-*) in the model picker to use GitLab agents.`\n );\n }\n };\n}\n\nexport function makeSystemTransformHook(\n flowAgents: Map<string, CatalogAgent>,\n getAuthCache: () => AuthInfo | null\n) {\n return async (_input: any, output: any) => {\n if (flowAgents.size) {\n output.system.push(FLOW_DISPATCH_GUIDELINES);\n }\n if (getAuthCache()) {\n output.system.push(\n `## Project Knowledge\\nProject memory tools are available (gitlab_memory_load, gitlab_memory_record, gitlab_memory_recall). Say \"bootstrap project memory\" to initialize or refresh project knowledge.`\n );\n }\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport { executeFlow, getWorkflowStatus, getFlowDefinition } from \"../catalog\";\nimport type { PluginContext } from \"../auth\";\n\nconst z = tool.schema;\n\nexport function makeFlowTools(ctx: PluginContext): Record<string, any> {\n return {\n gitlab_execute_project_flow: tool({\n description:\n \"Execute a GitLab DAP flow on a project.\\n\" +\n \"Triggers a flow via the Duo Workflow Service REST API.\\n\" +\n \"The flow runs asynchronously and is visible in the GitLab UI.\\n\" +\n \"Returns the workflow record with ID and status.\\n\" +\n \"The additional_context parameter accepts flow-specific inputs as a JSON array of {Category, Content} objects.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n consumer_id: z.number().describe(\"AI Catalog ItemConsumer numeric ID\"),\n goal: z.string().describe(\"User prompt/goal for the flow, include relevant URLs\"),\n additional_context: z\n .string()\n .optional()\n .describe(\n 'JSON array of flow inputs: [{\"Category\":\"merge_request\",\"Content\":\"{\\\\\"url\\\\\":\\\\\"https://...\\\\\"}\"}]'\n ),\n issue_id: z.number().optional().describe(\"Issue IID for context\"),\n merge_request_id: z.number().optional().describe(\"Merge request IID for context\"),\n },\n execute: async (args: {\n project_id: string;\n consumer_id: number;\n goal: string;\n additional_context?: string;\n issue_id?: number;\n merge_request_id?: number;\n }) => {\n const auth = ctx.ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n\n let flowInputs: Array<{ Category: string; Content: string }> | undefined;\n if (args.additional_context) {\n try {\n flowInputs = JSON.parse(args.additional_context);\n } catch {\n return \"Error: additional_context must be a valid JSON array\";\n }\n }\n\n try {\n const result = await executeFlow(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n args.consumer_id,\n args.goal,\n {\n issueId: args.issue_id,\n mergeRequestId: args.merge_request_id,\n namespaceId: ctx.getNamespaceId(),\n flowInputs,\n }\n );\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error executing flow: ${err.message}`;\n }\n },\n }),\n\n gitlab_get_flow_definition: tool({\n description:\n \"Get the YAML configuration of a GitLab DAP flow.\\n\" +\n \"Returns the flow config YAML which contains the flow.inputs section\\n\" +\n \"describing what additional_context categories and fields the flow requires.\\n\" +\n \"Use this before executing a flow to understand what inputs to gather.\\n\" +\n \"Set foundational=true for GitLab built-in flows, foundational=false for custom flows.\",\n args: {\n consumer_id: z.number().describe(\"AI Catalog ItemConsumer numeric ID\"),\n foundational: z\n .boolean()\n .describe(\"true for GitLab foundational flows, false for custom flows\"),\n },\n execute: async (args: { consumer_id: number; foundational: boolean }) => {\n const auth = ctx.ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n\n const flow = [...ctx.getFlowAgents().values()].find(\n (f) => f.consumerId === args.consumer_id\n );\n\n try {\n const result = await getFlowDefinition(auth.instanceUrl, auth.token, {\n consumerId: args.consumer_id,\n flowName: flow?.name,\n foundational: args.foundational,\n catalogItemVersionId: flow?.catalogItemVersionId,\n itemIdentifier: flow?.identifier,\n workflowDefinition: flow?.workflowDefinition,\n });\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error getting flow definition: ${err.message}`;\n }\n },\n }),\n\n gitlab_get_workflow_status: tool({\n description:\n \"Get the status and latest messages of a GitLab DAP workflow.\\n\" +\n \"Use this to monitor a running flow after executing it.\\n\" +\n \"Returns the workflow status, latest checkpoint messages, and timestamps.\\n\" +\n \"Poll every 10 seconds until status is completed, failed, or cancelled.\",\n args: {\n workflow_id: z\n .number()\n .describe(\"Workflow numeric ID (from gitlab_execute_project_flow result)\"),\n },\n execute: async (args: { workflow_id: number }) => {\n const auth = ctx.ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n\n try {\n const result = await getWorkflowStatus(auth.instanceUrl, auth.token, args.workflow_id);\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error getting workflow status: ${err.message}`;\n }\n },\n }),\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport { createAgent, updateAgent, listBuiltInTools, createFlow, updateFlow } from \"../catalog\";\nimport { validateFlowYaml } from \"../flow-validator\";\nimport { FLOW_SCHEMA_REFERENCE, FLOW_EXAMPLE_LINEAR, FLOW_EXAMPLE_CONDITIONAL } from \"../prompts\";\nimport type { PluginContext } from \"../auth\";\n\nconst z = tool.schema;\n\nexport function makeCatalogCrudTools(ctx: PluginContext): Record<string, any> {\n return {\n gitlab_create_agent: tool({\n description:\n \"Create a new custom agent in the GitLab AI Catalog.\\n\" +\n \"First call: set confirmed=false (or omit). The tool returns without creating anything and \" +\n \"instructs you to ask the user for agent properties using the question tool.\\n\" +\n \"Second call: after the user confirms, set confirmed=true to actually create the agent.\\n\" +\n \"After creation, use gitlab_enable_project_agent to enable it on a project.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n name: z.string().describe(\"Display name for the agent\"),\n description: z.string().describe(\"Description of what the agent does\"),\n public: z.boolean().describe(\"Whether the agent is publicly visible in the AI Catalog\"),\n system_prompt: z.string().describe(\"System prompt that defines the agent's behavior\"),\n user_prompt: z.string().optional().describe(\"User prompt template (optional)\"),\n tools: z\n .array(z.string())\n .optional()\n .describe(\n \"Array of built-in tool Global IDs from gitlab_list_builtin_tools. \" +\n 'Must be full GIDs like \"gid://gitlab/Ai::Catalog::BuiltInTool/1\", NOT tool names.'\n ),\n mcp_tools: z.array(z.string()).optional().describe(\"Array of MCP tool names to enable\"),\n mcp_servers: z\n .array(z.string())\n .optional()\n .describe(\n \"Array of MCP server Global IDs from gitlab_list_project_mcp_servers. \" +\n 'Must be full GIDs like \"gid://gitlab/Ai::Catalog::McpServer/1\", NOT server names.'\n ),\n release: z\n .boolean()\n .optional()\n .describe(\"Whether to release the version immediately (default: false)\"),\n confirmed: z\n .boolean()\n .optional()\n .describe(\n \"Set to true only after the user has reviewed and confirmed all parameters. Omit or set false on first call.\"\n ),\n },\n execute: async (args) => {\n if (!args.confirmed) {\n return [\n \"STOP: Do not create the agent yet. You must ask the user to confirm the configuration first.\",\n \"\",\n \"Follow these steps NOW:\",\n \"1. Call gitlab_list_builtin_tools and gitlab_list_project_mcp_servers to discover options.\",\n \"2. Use the question tool to ask the user ALL 4 of these (in one call):\",\n \" - Agent name (suggest one, allow custom input)\",\n \" - Visibility: Public or Private\",\n \" - Tools: group by category (Search, Issues, MRs, Epics, Files, Git, CI/CD, Security, Audit, Planning, Wiki, API) as multi-select\",\n \" - MCP servers: multi-select from available servers\",\n \"3. Generate a system prompt and show it to the user for approval.\",\n \"4. Call gitlab_create_agent again with confirmed=true after the user approves.\",\n ].join(\"\\n\");\n }\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await createAgent(auth.instanceUrl, auth.token, args.project_id, {\n name: args.name,\n description: args.description,\n public: args.public,\n systemPrompt: args.system_prompt,\n userPrompt: args.user_prompt,\n tools: args.tools,\n mcpTools: args.mcp_tools,\n mcpServers: args.mcp_servers,\n release: args.release,\n });\n await ctx.refreshAgents();\n return JSON.stringify(result, null, 2);\n },\n }),\n\n gitlab_update_agent: tool({\n description:\n \"Update an existing custom agent in the GitLab AI Catalog.\\n\" +\n \"Only provided fields are updated; omitted fields remain unchanged.\",\n args: {\n id: z.string().describe(\"Agent ID (numeric or full GID)\"),\n name: z.string().optional().describe(\"New display name\"),\n description: z.string().optional().describe(\"New description\"),\n public: z.boolean().optional().describe(\"Whether publicly visible\"),\n system_prompt: z.string().optional().describe(\"New system prompt\"),\n user_prompt: z.string().optional().describe(\"New user prompt template\"),\n tools: z\n .array(z.string())\n .optional()\n .describe(\n 'New set of built-in tool Global IDs (full GIDs like \"gid://gitlab/Ai::Catalog::BuiltInTool/1\")'\n ),\n mcp_tools: z.array(z.string()).optional().describe(\"New set of MCP tool names\"),\n mcp_servers: z\n .array(z.string())\n .optional()\n .describe(\n 'New set of MCP server Global IDs (full GIDs like \"gid://gitlab/Ai::Catalog::McpServer/1\")'\n ),\n release: z.boolean().optional().describe(\"Whether to release the latest version\"),\n version_bump: z.enum([\"MAJOR\", \"MINOR\", \"PATCH\"]).optional().describe(\"Version bump type\"),\n },\n execute: async (args) => {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await updateAgent(auth.instanceUrl, auth.token, args.id, {\n name: args.name,\n description: args.description,\n public: args.public,\n systemPrompt: args.system_prompt,\n userPrompt: args.user_prompt,\n tools: args.tools,\n mcpTools: args.mcp_tools,\n mcpServers: args.mcp_servers,\n release: args.release,\n versionBump: args.version_bump,\n });\n await ctx.refreshAgents();\n return JSON.stringify(result, null, 2);\n },\n }),\n\n gitlab_list_builtin_tools: tool({\n description:\n \"List available built-in GitLab tools that can be assigned to custom agents.\\n\" +\n \"Returns tool IDs, names, and descriptions. Use the IDs when creating or updating agents.\",\n args: {},\n execute: async () => {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const tools = await listBuiltInTools(auth.instanceUrl, auth.token);\n if (!tools.length) return \"No built-in tools available.\";\n return JSON.stringify(tools, null, 2);\n },\n }),\n\n gitlab_design_flow: tool({\n description:\n \"Interactive flow design tool. Returns the flow YAML schema reference, examples, and instructions.\\n\" +\n \"Use this BEFORE gitlab_create_flow to design the flow definition interactively with the user.\\n\" +\n \"The tool also validates generated YAML against the flow_v2 JSON schema.\",\n args: {\n action: z\n .enum([\"get_schema\", \"validate\"])\n .describe(\n '\"get_schema\" returns the schema reference and examples. \"validate\" validates a YAML definition.'\n ),\n definition: z\n .string()\n .optional()\n .describe(\"YAML definition to validate (required when action=validate)\"),\n },\n execute: async (args) => {\n if (args.action === \"validate\") {\n if (!args.definition) return \"Error: definition is required for validate action.\";\n const result = validateFlowYaml(args.definition);\n if (result.valid) return \"VALID: Flow definition passes schema validation.\";\n return `INVALID: ${result.errors.length} error(s):\\n${result.errors.map((e, i) => ` ${i + 1}. ${e}`).join(\"\\n\")}`;\n }\n return [\n \"Follow this multi-round workflow to design a flow:\",\n \"\",\n \"ROUND 1: Call gitlab_list_builtin_tools to discover available tool names for the flow.\",\n \" Then use the question tool to ask the user:\",\n \" - Flow name\",\n \" - Visibility: Public or Private\",\n \" - What the flow should do (step-by-step description)\",\n \" - What GitLab resource it operates on (MR, issue, pipeline, vulnerability, etc.)\",\n \"\",\n \"ROUND 2: Based on the user's answers, propose a component architecture in plain text:\",\n \" - List each step with its type (DeterministicStep, OneOff, or Agent)\",\n \" - Explain what each step does and what tools it uses\",\n \" - Show the routing (linear or conditional)\",\n \" Ask the user to confirm or adjust.\",\n \"\",\n \"ROUND 3: Generate the full YAML definition using the schema below.\",\n \" Call gitlab_design_flow with action='validate' to check it.\",\n \" Show the validated YAML to the user for final approval.\",\n \" Then call gitlab_create_flow with confirmed=true.\",\n \"\",\n \"=== FLOW YAML SCHEMA ===\",\n FLOW_SCHEMA_REFERENCE,\n \"\",\n \"=== EXAMPLE: Linear flow ===\",\n FLOW_EXAMPLE_LINEAR,\n \"\",\n \"=== EXAMPLE: Conditional flow ===\",\n FLOW_EXAMPLE_CONDITIONAL,\n ].join(\"\\n\");\n },\n }),\n\n gitlab_create_flow: tool({\n description:\n \"Create a custom flow in the GitLab AI Catalog.\\n\" +\n \"First call: set confirmed=false (or omit). Returns instructions to use gitlab_design_flow first.\\n\" +\n \"Second call: after the user confirms, set confirmed=true to create the flow.\\n\" +\n \"After creation, use gitlab_enable_project_flow to enable it on a project.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n name: z.string().describe(\"Display name for the flow\"),\n description: z.string().describe(\"Description of what the flow does\"),\n public: z.boolean().describe(\"Whether publicly visible in the AI Catalog\"),\n definition: z.string().describe(\"Flow YAML definition (validated via gitlab_design_flow)\"),\n release: z.boolean().optional().describe(\"Whether to release the version immediately\"),\n confirmed: z\n .boolean()\n .optional()\n .describe(\"Set true only after user has reviewed the YAML\"),\n },\n execute: async (args) => {\n if (!args.confirmed) {\n return [\n \"STOP: Do not create the flow yet.\",\n \"\",\n \"Call gitlab_design_flow with action='get_schema' first to get the interactive workflow.\",\n \"Follow the multi-round design process, then call this tool with confirmed=true.\",\n ].join(\"\\n\");\n }\n const validation = validateFlowYaml(args.definition);\n if (!validation.valid) {\n return `Flow YAML validation failed:\\n${validation.errors.map((e, i) => ` ${i + 1}. ${e}`).join(\"\\n\")}\\n\\nFix the errors and try again.`;\n }\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await createFlow(auth.instanceUrl, auth.token, args.project_id, {\n name: args.name,\n description: args.description,\n public: args.public,\n definition: args.definition,\n release: args.release,\n });\n await ctx.refreshAgents();\n const json = JSON.stringify(result, null, 2);\n return `${json}\\n\\nFlow created successfully. Ask the user if they want to enable it on the current project using gitlab_enable_project_flow.`;\n },\n }),\n\n gitlab_update_flow: tool({\n description:\n \"Update an existing custom flow in the GitLab AI Catalog.\\n\" +\n \"Only provided fields are updated; omitted fields remain unchanged.\\n\" +\n \"Use gitlab_design_flow with action='validate' to check YAML before updating.\",\n args: {\n id: z.string().describe(\"Flow ID (numeric or full GID)\"),\n name: z.string().optional().describe(\"New display name\"),\n description: z.string().optional().describe(\"New description\"),\n public: z.boolean().optional().describe(\"Whether publicly visible\"),\n definition: z.string().optional().describe(\"New flow YAML definition\"),\n release: z.boolean().optional().describe(\"Whether to release the latest version\"),\n version_bump: z.enum([\"MAJOR\", \"MINOR\", \"PATCH\"]).optional().describe(\"Version bump type\"),\n },\n execute: async (args) => {\n if (args.definition) {\n const validation = validateFlowYaml(args.definition);\n if (!validation.valid) {\n return `Flow YAML validation failed:\\n${validation.errors.map((e, i) => ` ${i + 1}. ${e}`).join(\"\\n\")}\\n\\nFix the errors and try again.`;\n }\n }\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"Not authenticated\");\n const result = await updateFlow(auth.instanceUrl, auth.token, args.id, {\n name: args.name,\n description: args.description,\n public: args.public,\n definition: args.definition,\n release: args.release,\n versionBump: args.version_bump,\n });\n await ctx.refreshAgents();\n return JSON.stringify(result, null, 2);\n },\n }),\n };\n}\n","import Ajv from \"ajv\";\nimport yaml from \"js-yaml\";\nimport flowSchema from \"../vendor/schemas/flow_v2.json\";\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nexport function validateFlowYaml(yamlString: string): ValidationResult {\n let parsed: Record<string, unknown>;\n try {\n parsed = yaml.load(yamlString) as Record<string, unknown>;\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n return { valid: false, errors: [`Invalid YAML syntax: ${msg}`] };\n }\n\n if (!parsed || typeof parsed !== \"object\") {\n return { valid: false, errors: [\"YAML must be an object\"] };\n }\n\n parsed.yaml_definition = yamlString;\n\n const ajv = new Ajv({ allErrors: true, strict: false });\n const validate = ajv.compile(flowSchema);\n const valid = validate(parsed);\n\n if (!valid && validate.errors) {\n const errors = validate.errors.map((e) => {\n const path = e.instancePath || \"/\";\n return `${path}: ${e.message}`;\n });\n return { valid: false, errors };\n }\n\n return { valid: true, errors: [] };\n}\n","{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"title\": \"Flow Registry v1 Configuration Schema\",\n \"description\": \"JSON Schema for validating Flow Registry v1 YAML configuration files\",\n \"type\": \"object\",\n \"required\": [\n \"version\",\n \"environment\",\n \"components\",\n \"routers\",\n \"flow\",\n \"yaml_definition\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"version\": {\n \"type\": \"string\",\n \"const\": \"v1\",\n \"description\": \"Framework version - must be 'v1' for current stable version\"\n },\n \"environment\": {\n \"type\": \"string\",\n \"enum\": [\n \"ambient\"\n ],\n \"description\": \"Flow environment declaring expected level of interaction between human and AI agent\"\n },\n \"components\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"description\": \"List of components that make up the flow\",\n \"items\": {\n \"oneOf\": [\n {\n \"$ref\": \"#/definitions/AgentComponent\"\n },\n {\n \"$ref\": \"#/definitions/DeterministicStepComponent\"\n },\n {\n \"$ref\": \"#/definitions/OneOffComponent\"\n }\n ]\n }\n },\n \"routers\": {\n \"type\": \"array\",\n \"description\": \"Define how components connect to each other\",\n \"items\": {\n \"$ref\": \"#/definitions/Router\"\n }\n },\n \"flow\": {\n \"type\": \"object\",\n \"description\": \"Specify the entry point component and other flow options\",\n \"properties\": {\n \"entry_point\": {\n \"type\": \"string\",\n \"description\": \"Name of first component to run. Examples: 'main_agent', 'initial_step'\",\n \"pattern\": \"^[a-zA-Z0-9_]+$\"\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"Optional additional context schema definitions that can be passed to the flow (in addition to the 'goal')\",\n \"items\": {\n \"$ref\": \"#/definitions/FlowInputCategory\"\n }\n }\n },\n \"additionalProperties\": false\n },\n \"prompts\": {\n \"type\": \"array\",\n \"description\": \"List of inline prompt templates for flow components to use\",\n \"items\": {\n \"$ref\": \"#/definitions/LocalPrompt\"\n }\n },\n \"yaml_definition\": {\n \"type\": \"string\"\n }\n },\n \"definitions\": {\n \"ComponentName\": {\n \"type\": \"string\",\n \"pattern\": \"^[a-zA-Z0-9_]+$\",\n \"description\": \"Component name must use alphanumeric characters or underscore. Must not include characters such as : and . Examples: 'my_agent', 'step1', 'dataProcessor'\"\n },\n \"AgentComponent\": {\n \"type\": \"object\",\n \"required\": [\n \"name\",\n \"type\",\n \"prompt_id\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"$ref\": \"#/definitions/ComponentName\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"AgentComponent\"\n },\n \"prompt_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the prompt template from either the prompt registry or locally defined prompts\"\n },\n \"prompt_version\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"^[~^]?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$\",\n \"description\": \"Semantic version constraint (e.g., '^1.0.0')\"\n },\n {\n \"type\": \"null\",\n \"description\": \"Use locally defined prompt from flow YAML\"\n }\n ]\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"List of input data sources\",\n \"default\": [\n \"context:goal\"\n ],\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Simple input reference\"\n },\n {\n \"$ref\": \"#/definitions/InputMapping\"\n }\n ]\n }\n },\n \"toolset\": {\n \"type\": \"array\",\n \"description\": \"List of tools available to the agent. Can be tool names or objects with tool options. Examples: ['read_file', {'create_merge_request_note': {'force_internal': true}}]\",\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Tool name from tools registry\"\n },\n {\n \"type\": \"object\",\n \"description\": \"Tool with options. Key is tool name, value is options object\",\n \"minProperties\": 1,\n \"maxProperties\": 1,\n \"additionalProperties\": {\n \"type\": \"object\",\n \"description\": \"Tool-specific options as key-value pairs\",\n \"additionalProperties\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"array\",\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n },\n {\n \"type\": \"object\",\n \"additionalProperties\": {\n \"oneOf\": [\n {\n \"type\": \"string\"\n },\n {\n \"type\": \"number\"\n },\n {\n \"type\": \"boolean\"\n },\n {\n \"type\": \"null\"\n }\n ]\n }\n }\n ]\n }\n }\n }\n ]\n }\n },\n \"ui_log_events\": {\n \"type\": \"array\",\n \"description\": \"UI logging configuration\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"on_agent_final_answer\",\n \"on_tool_execution_success\",\n \"on_tool_execution_failed\"\n ]\n }\n },\n \"ui_role_as\": {\n \"type\": \"string\",\n \"enum\": [\n \"agent\",\n \"tool\"\n ],\n \"description\": \"Display role in UI\"\n }\n }\n },\n \"DeterministicStepComponent\": {\n \"type\": \"object\",\n \"required\": [\n \"name\",\n \"type\",\n \"tool_name\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"$ref\": \"#/definitions/ComponentName\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"DeterministicStepComponent\"\n },\n \"tool_name\": {\n \"type\": \"string\",\n \"description\": \"Name of the single tool to execute\"\n },\n \"toolset\": {\n \"type\": \"array\",\n \"description\": \"Toolset containing the tool to be executed\",\n \"items\": {\n \"type\": \"string\"\n }\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"List of input data sources to extract tool parameters\",\n \"default\": [],\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Simple input reference. Examples: 'context:goal'\"\n },\n {\n \"$ref\": \"#/definitions/InputMapping\"\n }\n ]\n }\n },\n \"ui_log_events\": {\n \"type\": \"array\",\n \"description\": \"UI logging configuration for displaying tool execution\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"on_tool_execution_success\",\n \"on_tool_execution_failed\"\n ]\n }\n },\n \"ui_role_as\": {\n \"type\": \"string\",\n \"enum\": [\n \"agent\",\n \"tool\"\n ],\n \"default\": \"tool\",\n \"description\": \"Display role in UI\"\n }\n }\n },\n \"OneOffComponent\": {\n \"type\": \"object\",\n \"required\": [\n \"name\",\n \"type\",\n \"prompt_id\",\n \"toolset\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"name\": {\n \"$ref\": \"#/definitions/ComponentName\"\n },\n \"type\": {\n \"type\": \"string\",\n \"const\": \"OneOffComponent\"\n },\n \"prompt_id\": {\n \"type\": \"string\",\n \"description\": \"ID of the prompt template from either the prompt registry or locally defined prompts\"\n },\n \"prompt_version\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"pattern\": \"^[~^]?\\\\d+\\\\.\\\\d+\\\\.\\\\d+(?:-[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?(?:\\\\+[0-9A-Za-z-]+(?:\\\\.[0-9A-Za-z-]+)*)?$\",\n \"description\": \"Semantic version constraint. Examples: '1.0.0' (exact), '^1.2.3' (compatible)\"\n },\n {\n \"type\": \"null\",\n \"description\": \"Use locally defined prompt from flow YAML\"\n }\n ]\n },\n \"toolset\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"description\": \"List of tools available to the component. Examples: ['read_file', 'list_dir', 'edit_file']\",\n \"items\": {\n \"type\": \"string\",\n \"description\": \"Tool name from tools registry\"\n }\n },\n \"inputs\": {\n \"type\": \"array\",\n \"description\": \"List of input data sources\",\n \"default\": [\n \"context:goal\"\n ],\n \"items\": {\n \"oneOf\": [\n {\n \"type\": \"string\",\n \"description\": \"Simple input reference. Examples: 'context:goal'\"\n },\n {\n \"$ref\": \"#/definitions/InputMapping\"\n }\n ]\n }\n },\n \"max_correction_attempts\": {\n \"type\": \"integer\",\n \"minimum\": 0,\n \"default\": 3,\n \"description\": \"Maximum number of retry attempts for failed tool executions\"\n },\n \"ui_log_events\": {\n \"type\": \"array\",\n \"description\": \"UI logging configuration for displaying tool execution progress\",\n \"items\": {\n \"type\": \"string\",\n \"enum\": [\n \"on_tool_call_input\",\n \"on_tool_execution_success\",\n \"on_tool_execution_failed\"\n ]\n }\n }\n }\n },\n \"InputMapping\": {\n \"type\": \"object\",\n \"required\": [\n \"from\",\n \"as\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"from\": {\n \"type\": \"string\",\n \"description\": \"Source of the input data. Examples: 'context:goal'\"\n },\n \"as\": {\n \"type\": \"string\",\n \"description\": \"Variable name to use in prompt template. Examples: 'user_goal'\"\n },\n \"literal\": {\n \"type\": \"boolean\",\n \"description\": \"Whether the 'from' value should be treated as a literal value\"\n }\n }\n },\n \"Router\": {\n \"type\": \"object\",\n \"required\": [\n \"from\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"from\": {\n \"type\": \"string\",\n \"description\": \"Source component name. Examples: 'main_agent', 'data_processor'\"\n },\n \"to\": {\n \"type\": \"string\",\n \"description\": \"Target component name or 'end'. Examples: 'next_step', 'error_handler', 'end'\"\n },\n \"condition\": {\n \"$ref\": \"#/definitions/RouterCondition\"\n }\n },\n \"oneOf\": [\n {\n \"required\": [\n \"to\"\n ]\n },\n {\n \"required\": [\n \"condition\"\n ]\n }\n ]\n },\n \"RouterCondition\": {\n \"type\": \"object\",\n \"required\": [\n \"input\",\n \"routes\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"input\": {\n \"type\": \"string\",\n \"description\": \"Input to evaluate for routing decision\"\n },\n \"routes\": {\n \"type\": \"object\",\n \"description\": \"Mapping of condition values to target components\",\n \"patternProperties\": {\n \".*\": {\n \"type\": \"string\",\n \"description\": \"Target component name or 'end'\"\n }\n }\n }\n }\n },\n \"LocalPrompt\": {\n \"type\": \"object\",\n \"required\": [\n \"prompt_id\",\n \"name\",\n \"prompt_template\",\n \"unit_primitives\"\n ],\n \"additionalProperties\": false,\n \"properties\": {\n \"prompt_id\": {\n \"type\": \"string\",\n \"description\": \"Unique identifier for the local prompt\"\n },\n \"name\": {\n \"type\": \"string\",\n \"description\": \"name for the local prompt\"\n },\n \"prompt_template\": {\n \"$ref\": \"#/definitions/PromptTemplate\"\n },\n \"params\": {\n \"type\": \"object\",\n \"properties\": {\n \"timeout\": {\n \"type\": \"integer\",\n \"minimum\": 1,\n \"description\": \"Timeout in seconds for prompt execution\"\n },\n \"vertex_location\": {\n \"type\": \"string\",\n \"description\": \"Vertex AI location for the flow\"\n }\n },\n \"additionalProperties\": false\n },\n \"unit_primitives\": {\n \"type\": \"array\",\n \"description\": \"Unit primitives configuration\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n }\n },\n \"PromptTemplate\": {\n \"type\": \"object\",\n \"additionalProperties\": false,\n \"properties\": {\n \"system\": {\n \"type\": \"string\",\n \"description\": \"System message template\"\n },\n \"user\": {\n \"type\": \"string\",\n \"description\": \"User message template\"\n },\n \"placeholder\": {\n \"type\": \"string\",\n \"enum\": [\n \"history\"\n ],\n \"description\": \"Message placeholder for conversation history\"\n }\n }\n },\n \"FlowInputCategory\": {\n \"type\": \"object\",\n \"required\": [\n \"category\",\n \"input_schema\"\n ],\n \"additionalProperties\": false,\n \"description\": \"Defines a category of additional context inputs that can be passed to the flow\",\n \"properties\": {\n \"category\": {\n \"type\": \"string\",\n \"description\": \"Category name for the additional context. Examples: 'merge_request_info', 'pipeline_info'\"\n },\n \"input_schema\": {\n \"type\": \"object\",\n \"description\": \"Schema definition for the inputs in this category\",\n \"patternProperties\": {\n \".*\": {\n \"$ref\": \"#/definitions/FlowInputField\"\n }\n }\n }\n }\n },\n \"FlowInputField\": {\n \"type\": \"object\",\n \"required\": [\n \"type\"\n ],\n \"additionalProperties\": false,\n \"description\": \"Schema definition for a single input field\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\",\n \"description\": \"JSON Schema type for the field. Examples: 'string'\"\n },\n \"format\": {\n \"type\": \"string\",\n \"description\": \"Optional JSON Schema format specifier. Examples: 'uri', 'email', 'date-time'\"\n },\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Optional description of the field's purpose\"\n }\n }\n }\n }\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport {\n listAiCatalogItems,\n getAiCatalogItem,\n listProjectAiCatalogItems,\n enableAiCatalogItemForProject,\n disableAiCatalogItemForProject,\n} from \"../catalog\";\nimport type { AuthInfo } from \"../auth\";\n\nconst z = tool.schema;\n\nfunction makeItemTools(\n itemType: \"AGENT\" | \"FLOW\",\n label: string,\n getAuth: () => AuthInfo | null,\n ensureAuth: () => AuthInfo | null,\n onChanged?: () => Promise<void>\n) {\n const itemTypes = [itemType];\n const Label = label.charAt(0).toUpperCase() + label.slice(1);\n\n return {\n [`gitlab_list_${label}s`]: tool({\n description: `List ${label}s in the GitLab AI Catalog.\\nReturns ${label}s with name, description, visibility, foundational flag, and version info.\\nSupports search and cursor-based pagination.`,\n args: {\n search: z\n .string()\n .optional()\n .describe(`Search query to filter ${label}s by name or description`),\n first: z.number().optional().describe(\"Number of items to return (default 20)\"),\n after: z.string().optional().describe(\"Cursor for pagination (from pageInfo.endCursor)\"),\n },\n execute: async (args: { search?: string; first?: number; after?: string }) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await listAiCatalogItems(auth.instanceUrl, auth.token, itemTypes, args);\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_get_${label}`]: tool({\n description: `Get details of a specific ${label} from the AI Catalog.\\nReturns full details including name, description, visibility, versions, creator, and permissions.\\nAccepts either a full Global ID (gid://gitlab/Ai::Catalog::Item/123) or just the numeric ID.`,\n args: {\n [`${label}_id`]: z.string().describe(`${Label} ID: full GID or numeric ID`),\n },\n execute: async (args: Record<string, string>) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await getAiCatalogItem(auth.instanceUrl, auth.token, args[`${label}_id`]);\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_list_project_${label}s`]: tool({\n description: `List ${label}s enabled for a specific project.\\nReturns all configured ${label}s including foundational ones.\\nEach result includes the ${label} details and its consumer configuration.`,\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n first: z.number().optional().describe(\"Number of items to return (default 20)\"),\n after: z.string().optional().describe(\"Cursor for pagination\"),\n },\n execute: async (args: { project_id: string; first?: number; after?: string }) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await listProjectAiCatalogItems(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n itemTypes,\n { first: args.first, after: args.after }\n );\n return JSON.stringify(result, null, 2);\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_enable_project_${label}`]: tool({\n description: `Enable a ${label} in a project.\\nRequires Maintainer or Owner role.\\nEnabling in a project also enables at the group level.\\nFoundational ${label}s cannot be enabled this way (use admin settings).`,\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n [`${label}_id`]: z.string().describe(`${Label} ID: full GID or numeric ID`),\n },\n execute: async (args: Record<string, string>) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await enableAiCatalogItemForProject(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n args[`${label}_id`]\n );\n await onChanged?.();\n return (\n JSON.stringify(result, null, 2) +\n \"\\n\\nNote: Restart opencode for the @ menu to reflect changes.\"\n );\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n\n [`gitlab_disable_project_${label}`]: tool({\n description: `Disable a ${label} in a project.\\nRequires Maintainer or Owner role.\\nResolves the consumer ID internally from the ${label} ID.`,\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n [`${label}_id`]: z.string().describe(`${Label} ID: full GID or numeric ID`),\n },\n execute: async (args: Record<string, string>) => {\n const auth = ensureAuth();\n if (!auth) return \"Error: GitLab authentication not available\";\n try {\n const result = await disableAiCatalogItemForProject(\n auth.instanceUrl,\n auth.token,\n args.project_id,\n args[`${label}_id`]\n );\n await onChanged?.();\n return (\n JSON.stringify(result, null, 2) +\n \"\\n\\nNote: Restart opencode for the @ menu to reflect changes.\"\n );\n } catch (err: any) {\n return `Error: ${err.message}`;\n }\n },\n }),\n };\n}\n\nexport function makeCatalogItemTools(ctx: {\n getAuth: () => AuthInfo | null;\n ensureAuth: () => AuthInfo | null;\n refreshAgents: () => Promise<void>;\n}): Record<string, any> {\n return {\n ...makeItemTools(\"AGENT\", \"agent\", ctx.getAuth, ctx.ensureAuth, ctx.refreshAgents),\n ...makeItemTools(\"FLOW\", \"flow\", ctx.getAuth, ctx.ensureAuth, ctx.refreshAgents),\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport type { CatalogAgent, McpServerInfo } from \"../types\";\n\nconst z = tool.schema;\n\nexport function makeMcpTools(getCachedAgents: () => CatalogAgent[]): Record<string, any> {\n return {\n gitlab_list_project_mcp_servers: tool({\n description:\n \"List MCP servers available through agents enabled for a project.\\n\" +\n \"Returns deduplicated servers with name, URL, auth type, connection status, and which agents use them.\",\n args: {\n project_id: z.string().describe('Project path (e.g., \"gitlab-org/gitlab\")'),\n },\n execute: async (_args: { project_id: string }) => {\n const serverMap = new Map<string, McpServerInfo & { usedBy: string[] }>();\n\n for (const agent of getCachedAgents()) {\n if (!agent.mcpServers?.length) continue;\n for (const server of agent.mcpServers) {\n const existing = serverMap.get(server.id);\n if (existing) {\n if (!existing.usedBy.includes(agent.name)) existing.usedBy.push(agent.name);\n } else {\n serverMap.set(server.id, { ...server, usedBy: [agent.name] });\n }\n }\n }\n\n const servers = [...serverMap.values()];\n if (!servers.length) {\n return \"No MCP servers found for agents enabled in this project.\";\n }\n return JSON.stringify(servers, null, 2);\n },\n }),\n };\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport {\n createWikiPage,\n updateWikiPage,\n getWikiPage,\n deleteWikiPage,\n listWikiPages,\n searchWikiPages,\n} from \"../wiki\";\nimport type { PluginContext } from \"../auth\";\nimport type { WikiPage } from \"../wiki\";\n\nconst z = tool.schema;\n\nconst PREFIX = \"agents\";\nconst ARCHIVE_DIR = `${PREFIX}/memory/archive`;\n\nconst MEMORY_TYPES = [\n \"facts\",\n \"decisions\",\n \"patterns\",\n \"architecture\",\n \"conventions\",\n \"troubleshooting\",\n \"people-and-contexts\",\n \"plans\",\n] as const;\n\nconst MEMORY_DIRS: Record<string, string[]> = {\n all: MEMORY_TYPES.map((t) => `${PREFIX}/memory/${t}`),\n ...Object.fromEntries(MEMORY_TYPES.map((t) => [t, [`${PREFIX}/memory/${t}`]])),\n archive: [ARCHIVE_DIR],\n};\n\nconst RECORD_TYPES = [\n \"fact\",\n \"decision\",\n \"pattern\",\n \"architecture\",\n \"convention\",\n \"troubleshooting\",\n \"people\",\n \"plan\",\n] as const;\n\nconst RECORD_DIR: Record<string, string> = {\n fact: `${PREFIX}/memory/facts`,\n decision: `${PREFIX}/memory/decisions`,\n pattern: `${PREFIX}/memory/patterns`,\n architecture: `${PREFIX}/memory/architecture`,\n convention: `${PREFIX}/memory/conventions`,\n troubleshooting: `${PREFIX}/memory/troubleshooting`,\n people: `${PREFIX}/memory/people-and-contexts`,\n plan: `${PREFIX}/memory/plans`,\n};\n\nconst PROJECT_ID_DESC =\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.';\n\nfunction today(): string {\n return new Date().toISOString().slice(0, 10);\n}\n\nfunction shortHash(): string {\n return Math.random().toString(36).slice(2, 8);\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/(^-|-$)/g, \"\")\n .slice(0, 50);\n}\n\nfunction titleFromContent(content: string): string {\n const first = content\n .split(\"\\n\")[0]\n .replace(/^[#*\\->\\s]+/, \"\")\n .trim();\n return first.slice(0, 80) || \"untitled\";\n}\n\nfunction validateProjectId(projectId: string): string | null {\n if (!projectId.includes(\"/\")) {\n return `Invalid project_id \"${projectId}\". Must be the full project path containing at least one slash (e.g., \"my-group/my-project\"), not just the project name.`;\n }\n return null;\n}\n\nfunction resolveScope(args: { scope?: string; group_id?: string; project_id?: string }): {\n scope: \"projects\" | \"groups\";\n id: string | number;\n} {\n if (args.scope === \"groups\" && args.group_id) {\n return { scope: \"groups\", id: args.group_id };\n }\n return { scope: \"projects\", id: args.project_id! };\n}\n\nexport function makeMemoryTools(ctx: PluginContext): Record<string, any> {\n function authAndValidate(projectId: string) {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"GitLab authentication not available\");\n const err = validateProjectId(projectId);\n if (err) throw new Error(err);\n return auth;\n }\n\n return {\n gitlab_memory_load: tool({\n description:\n \"Load project memory to understand context, known facts, past decisions, and observed patterns.\\n\" +\n \"Use this at the start of complex tasks to check what is already known about the project.\\n\" +\n \"Returns accumulated knowledge from previous sessions.\\n\" +\n \"Each entry includes its slug (page path) which can be used with gitlab_memory_update or gitlab_memory_archive.\\n\\n\" +\n \"BOOTSTRAP WORKFLOW — when user says 'bootstrap project memory':\\n\" +\n \"1. Get project path from run_git_command('remote', ['-v']) — NEVER guess.\\n\" +\n \"2. Call this tool to check if memory exists.\\n\" +\n \"3. If empty: gather knowledge (README, gitlab_get_project, gitlab_list_issues, gitlab_list_merge_requests, gitlab_list_pipelines, gitlab_list_project_members), then record using ALL THREE types:\\n\" +\n \" - type='fact': project overview, tech stack, dependencies, CI/CD config, open issues summary, open MRs summary\\n\" +\n \" - type='architecture': system design, module structure, key abstractions, data flow\\n\" +\n \" - type='decision': key architectural choices found in the codebase (framework choices, config patterns, deployment strategy)\\n\" +\n \" - type='convention': coding standards, naming patterns, commit conventions, review process\\n\" +\n \" - type='pattern': recurring observations (CI patterns, common failures, release cycle)\\n\" +\n \" - type='troubleshooting': known issues, workarounds, pipeline failures, common errors\\n\" +\n \" - type='people': team members, roles, ownership areas, key contacts\\n\" +\n \" Fire parallel gitlab_memory_record calls — each creates its own page.\\n\" +\n \"4. If exists: show summary, gather current state, compare with stored records, use gitlab_memory_update for stale, gitlab_memory_archive for outdated, gitlab_memory_record for new.\\n\" +\n \"5. Log session with gitlab_memory_log_session.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n type: z\n .enum([\"all\", ...MEMORY_TYPES, \"archive\"])\n .optional()\n .describe(\n 'Which memory to load: \"all\" (default), \"facts\", \"decisions\", \"patterns\", \"architecture\", \"conventions\", \"troubleshooting\", \"people-and-contexts\", or \"archive\"'\n ),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n type?: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n const memType = args.type ?? \"all\";\n const dirs = MEMORY_DIRS[memType];\n if (!dirs) return `Unknown memory type: ${memType}`;\n\n try {\n const allPages = (await listWikiPages(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n true\n )) as WikiPage[];\n\n const sections: string[] = [];\n for (const dir of dirs) {\n const label = dir.split(\"/\").pop()!;\n const pages = allPages.filter((p) => p.slug.startsWith(dir + \"/\") && p.content);\n if (pages.length === 0) continue;\n\n const entries = pages.map((p) => `### ${p.slug}\\n${p.content}`).join(\"\\n\\n---\\n\\n\");\n sections.push(\n `## ${label.charAt(0).toUpperCase() + label.slice(1)} (${pages.length})\\n\\n${entries}`\n );\n }\n\n if (sections.length === 0)\n return \"No project memory found. Use gitlab_memory_record to start building project knowledge.\";\n return sections.join(\"\\n\\n---\\n\\n\");\n } catch (err: any) {\n return `Error loading memory: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_record: tool({\n description:\n \"Record knowledge in project memory. Each record creates its own page — safe for parallel writes.\\n\" +\n \"Types:\\n\" +\n \" fact — stable truths (tech stack, dependencies, deploy targets, project metadata)\\n\" +\n \" decision — architectural choices with reasoning (why X over Y)\\n\" +\n \" pattern — recurring observations that may evolve into skills\\n\" +\n \" architecture — system design, module structure, data flow, key abstractions\\n\" +\n \" convention — coding standards, naming patterns, review process, commit conventions\\n\" +\n \" troubleshooting — known issues, workarounds, debugging tips, common errors\\n\" +\n \" people — team members, roles, ownership areas, contact context\\n\" +\n \" plan — implementation plans, feature designs, task breakdowns, roadmap items\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n type: z.enum([...RECORD_TYPES]).describe(\"Type of knowledge to record\"),\n content: z.string().describe(\"The knowledge to record (markdown)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n type: string;\n content: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n const dir = RECORD_DIR[args.type];\n if (!dir) return `Unknown memory type: ${args.type}`;\n\n const date = today();\n const title = titleFromContent(args.content);\n const slug = `${dir}/${date}-${slugify(title)}-${shortHash()}`;\n\n const header = `*Recorded: ${date} | Type: ${args.type}*\\n\\n`;\n const body = header + args.content;\n\n try {\n await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, body);\n return `Recorded ${args.type} in project memory: ${slug}`;\n } catch (err: any) {\n return `Error recording ${args.type}: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_update: tool({\n description:\n \"Update an existing memory record with new content.\\n\" +\n \"Use this to correct stale facts, update issue counts, or refine decisions.\\n\" +\n \"The slug is the page path shown in gitlab_memory_load output (e.g., agents/memory/facts/2026-04-05-project-overview).\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n slug: z\n .string()\n .describe(\n 'Page slug from gitlab_memory_load output (e.g., \"agents/memory/facts/2026-04-05-project-overview\")'\n ),\n content: z.string().describe(\"New content to replace the existing record (markdown)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n slug: string;\n content: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n await getWikiPage(auth.instanceUrl, auth.token, scope, id, args.slug);\n } catch {\n return `Memory record not found: ${args.slug}. Use gitlab_memory_load to see available records.`;\n }\n\n const date = today();\n const header = `*Updated: ${date}*\\n\\n`;\n\n try {\n await updateWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n args.slug,\n header + args.content\n );\n return `Updated memory record: ${args.slug}`;\n } catch (err: any) {\n return `Error updating memory: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_archive: tool({\n description:\n \"Archive an outdated memory record.\\n\" +\n \"Moves the record to the archive directory so it is no longer loaded by default.\\n\" +\n \"Archived records are still searchable via gitlab_memory_recall and loadable via gitlab_memory_load(type='archive').\\n\" +\n \"Use this for facts that are no longer true, decisions that were reversed, or patterns that stopped occurring.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n slug: z\n .string()\n .describe(\n 'Page slug to archive (e.g., \"agents/memory/facts/2026-04-05-open-issues-summary\")'\n ),\n reason: z\n .string()\n .optional()\n .describe(\n 'Why this record is being archived (e.g., \"issue was fixed\", \"no longer relevant\")'\n ),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n slug: string;\n reason?: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n let originalContent: string;\n try {\n const page = await getWikiPage(auth.instanceUrl, auth.token, scope, id, args.slug);\n originalContent = page.content;\n } catch {\n return `Memory record not found: ${args.slug}. Use gitlab_memory_load to see available records.`;\n }\n\n const date = today();\n const suffix = args.slug.split(\"/\").slice(3).join(\"/\");\n const archiveSlug = `${ARCHIVE_DIR}/${suffix}`;\n const reasonLine = args.reason ? `\\n*Reason: ${args.reason}*` : \"\";\n const archiveHeader = `*Archived: ${date} | Original: ${args.slug}*${reasonLine}\\n\\n`;\n\n try {\n await createWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n archiveSlug,\n archiveHeader + originalContent\n );\n await deleteWikiPage(auth.instanceUrl, auth.token, scope, id, args.slug);\n return `Archived: ${args.slug} → ${archiveSlug}`;\n } catch (err: any) {\n return `Error archiving memory: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_consolidate: tool({\n description:\n \"Review all memory records and get consolidation instructions.\\n\" +\n \"Loads all records of the specified type and returns them with their slugs,\\n\" +\n \"along with instructions to identify and fix stale, duplicate, or contradictory entries.\\n\" +\n \"Use this periodically to keep project memory clean and accurate.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n type: z\n .enum([\"all\", ...MEMORY_TYPES])\n .optional()\n .describe('Which memory to consolidate: \"all\" (default) or a specific type'),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n type?: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n const memType = args.type ?? \"all\";\n const dirs = MEMORY_DIRS[memType];\n if (!dirs) return `Unknown memory type: ${memType}`;\n\n try {\n const allPages = (await listWikiPages(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n true\n )) as WikiPage[];\n\n const entries: Array<{ slug: string; content: string }> = [];\n for (const dir of dirs) {\n const pages = allPages.filter((p) => p.slug.startsWith(dir + \"/\") && p.content);\n for (const p of pages) {\n entries.push({ slug: p.slug, content: p.content });\n }\n }\n\n if (entries.length === 0) return \"No memory records to consolidate.\";\n\n const listing = entries\n .map((e, i) => `### [${i + 1}] ${e.slug}\\n${e.content}`)\n .join(\"\\n\\n---\\n\\n\");\n\n const instructions = [\n `## Memory Consolidation Review`,\n ``,\n `Found **${entries.length} records** to review. For each record:`,\n ``,\n `1. **Stale?** — Is the information still current? If not, either:`,\n ` - Call \\`gitlab_memory_update(slug, new_content)\\` with corrected info`,\n ` - Call \\`gitlab_memory_archive(slug, reason)\\` if no longer relevant`,\n ``,\n `2. **Duplicate?** — Does another record cover the same information?`,\n ` - Keep the better one, archive the other`,\n ``,\n `3. **Contradictory?** — Do two records disagree?`,\n ` - Verify which is correct, update one, archive the other`,\n ``,\n `4. **Mergeable?** — Are there many small records about the same topic?`,\n ` - Create one consolidated record, archive the originals`,\n ``,\n `After reviewing, log a session with gitlab_memory_log_session summarizing what was cleaned up.`,\n ``,\n `---`,\n ``,\n listing,\n ].join(\"\\n\");\n\n return instructions;\n } catch (err: any) {\n return `Error loading memory for consolidation: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_recall: tool({\n description:\n \"Search project knowledge for relevant information.\\n\" +\n \"Searches across all memory pages, session logs, and skills.\\n\" +\n \"Use this to check if something is already known before investigating.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n query: z.string().describe(\"What to search for\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n query: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n const results = await searchWikiPages(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n args.query\n );\n if (results.length === 0) return `No knowledge found matching \"${args.query}\".`;\n return results\n .map((r) => {\n const category = r.path.includes(\"/memory/\")\n ? \"memory\"\n : r.path.includes(\"/skills\")\n ? \"skill\"\n : \"other\";\n const snippet = (r.data ?? \"\").slice(0, 200).replace(/\\n/g, \" \");\n return `[${category}] ${r.path}: ${snippet}`;\n })\n .join(\"\\n\\n\");\n } catch (err: any) {\n return `Error searching knowledge: ${err.message}`;\n }\n },\n }),\n\n gitlab_memory_log_session: tool({\n description:\n \"Log a session summary including what was accomplished, what was learned, and any suggestions.\\n\" +\n \"Use this at the end of significant work sessions to preserve context for future sessions.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n title: z.string().describe('Brief session title (e.g., \"fix-ai-gateway-healthcheck\")'),\n summary: z\n .string()\n .describe(\n \"Session summary in markdown (what happened, what was learned, what went wrong)\"\n ),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n title: string;\n summary: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const date = today();\n const slug = `${PREFIX}/memory/sessions/${date}-${slugify(args.title)}-${shortHash()}`;\n\n try {\n await createWikiPage(auth.instanceUrl, auth.token, scope, id, slug, args.summary);\n return `Session logged: ${slug}`;\n } catch (err: any) {\n return `Error logging session: ${err.message}`;\n }\n },\n }),\n };\n}\n","export interface WikiPage {\n slug: string;\n title: string;\n content: string;\n format: string;\n encoding: string;\n}\n\nexport interface WikiPageSummary {\n slug: string;\n title: string;\n format: string;\n}\n\nexport interface WikiSearchResult {\n basename: string;\n data: string;\n path: string;\n filename: string;\n ref: string;\n startline: number;\n project_id: number;\n}\n\ntype Scope = \"projects\" | \"groups\";\n\nfunction wikiApi(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n path = \"\"\n): { url: string; headers: Record<string, string> } {\n const base = instanceUrl.replace(/\\/$/, \"\");\n const encodedId = encodeURIComponent(String(id));\n return {\n url: `${base}/api/v4/${scope}/${encodedId}/wikis${path}`,\n headers: {\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n },\n };\n}\n\nasync function handleResponse<T>(res: Response): Promise<T> {\n if (res.ok) return res.json() as Promise<T>;\n const status = res.status;\n if (status === 404)\n throw new Error(\n \"Page not found. Use gitlab_wiki_list to see available pages, or gitlab_wiki_write to create it.\"\n );\n if (status === 403)\n throw new Error(\n \"Permission denied. The wiki may not be enabled for this project. Enable it in Settings > General > Visibility.\"\n );\n if (status === 422)\n throw new Error(\"Invalid page title or content. Check that the slug and content are valid.\");\n if (status === 401) throw new Error(\"Authentication failed. Check your GitLab token.\");\n const text = await res.text();\n throw new Error(`Wiki API error (${status}): ${text}`);\n}\n\nexport async function listWikiPages(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n withContent?: boolean\n): Promise<WikiPageSummary[] | WikiPage[]> {\n const { url, headers } = wikiApi(instanceUrl, token, scope, id);\n const fullUrl = withContent ? `${url}?with_content=1` : url;\n const res = await fetch(fullUrl, { headers });\n return handleResponse(res);\n}\n\nexport async function getWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string\n): Promise<WikiPage> {\n const encodedSlug = encodeURIComponent(slug);\n const { url, headers } = wikiApi(instanceUrl, token, scope, id, `/${encodedSlug}`);\n const res = await fetch(url, { headers });\n return handleResponse(res);\n}\n\nexport async function createWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n title: string,\n content: string,\n format = \"markdown\"\n): Promise<WikiPage> {\n const { url, headers } = wikiApi(instanceUrl, token, scope, id);\n const res = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ title, content, format }),\n });\n return handleResponse(res);\n}\n\nexport async function updateWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string,\n content: string,\n title?: string\n): Promise<WikiPage> {\n const encodedSlug = encodeURIComponent(slug);\n const { url, headers } = wikiApi(instanceUrl, token, scope, id, `/${encodedSlug}`);\n const body: Record<string, string> = { content };\n if (title) body.title = title;\n const res = await fetch(url, {\n method: \"PUT\",\n headers,\n body: JSON.stringify(body),\n });\n return handleResponse(res);\n}\n\nexport async function deleteWikiPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string\n): Promise<void> {\n const encodedSlug = encodeURIComponent(slug);\n const { url, headers } = wikiApi(instanceUrl, token, scope, id, `/${encodedSlug}`);\n const res = await fetch(url, { method: \"DELETE\", headers });\n if (!res.ok) await handleResponse(res);\n}\n\nexport async function searchWikiPages(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n query: string\n): Promise<WikiSearchResult[]> {\n const base = instanceUrl.replace(/\\/$/, \"\");\n const encodedId = encodeURIComponent(String(id));\n const url = `${base}/api/v4/${scope}/${encodedId}/search?scope=wiki_blobs&search=${encodeURIComponent(query)}`;\n const res = await fetch(url, {\n headers: { Authorization: `Bearer ${token}` },\n });\n return handleResponse(res);\n}\n","import { tool } from \"@opencode-ai/plugin\";\nimport {\n getWikiPage,\n createWikiPage,\n updateWikiPage,\n deleteWikiPage,\n listWikiPages,\n} from \"../wiki\";\nimport type { PluginContext } from \"../auth\";\nimport type { WikiPageSummary } from \"../wiki\";\n\nconst z = tool.schema;\n\nconst PREFIX = \"agents\";\nconst SKILLS_PREFIX = `${PREFIX}/skills`;\nconst DRAFTS_PREFIX = `${PREFIX}/skills-drafts`;\nconst SKILLS_INDEX = `${SKILLS_PREFIX}/index`;\nconst DRAFTS_INDEX = `${DRAFTS_PREFIX}/index`;\n\nconst PROJECT_ID_DESC =\n 'FULL project path with namespace (e.g., \"gitlab-org/gitlab\"). Must contain a slash. Never use just the project name.';\n\ntype Scope = \"projects\" | \"groups\";\n\nfunction resolveScope(args: { scope?: string; group_id?: string; project_id?: string }): {\n scope: Scope;\n id: string | number;\n} {\n if (args.scope === \"groups\" && args.group_id) {\n return { scope: \"groups\", id: args.group_id };\n }\n return { scope: \"projects\", id: args.project_id! };\n}\n\nfunction validateProjectId(projectId: string): string | null {\n if (!projectId.includes(\"/\")) {\n return `Invalid project_id \"${projectId}\". Must be the full project path containing at least one slash (e.g., \"my-group/my-project\"), not just the project name.`;\n }\n return null;\n}\n\ninterface IndexEntry {\n name: string;\n description: string;\n source?: string;\n draft: boolean;\n}\n\nfunction parseIndex(content: string): IndexEntry[] {\n const entries: IndexEntry[] = [];\n const blocks = content.split(/^## /m).filter(Boolean);\n for (const block of blocks) {\n const lines = block.trim().split(\"\\n\");\n const name = lines[0].trim();\n if (!name) continue;\n const rest = lines.slice(1).join(\"\\n\").trim();\n const descLines: string[] = [];\n let source: string | undefined;\n for (const line of rest.split(\"\\n\")) {\n if (line.startsWith(\"Source:\")) {\n source = line.slice(7).trim();\n } else if (line.trim()) {\n descLines.push(line);\n }\n }\n entries.push({ name, description: descLines.join(\"\\n\"), source, draft: false });\n }\n return entries;\n}\n\nfunction formatIndex(entries: IndexEntry[]): string {\n return entries\n .map((e) => {\n let block = `## ${e.name}\\n${e.description}`;\n if (e.source) block += `\\nSource: ${e.source}`;\n return block;\n })\n .join(\"\\n\\n\");\n}\n\nasync function readIndex(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n indexSlug: string\n): Promise<IndexEntry[]> {\n try {\n const page = await getWikiPage(instanceUrl, token, scope, id, indexSlug);\n return parseIndex(page.content);\n } catch {\n return [];\n }\n}\n\nasync function writeIndex(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n indexSlug: string,\n entries: IndexEntry[]\n): Promise<void> {\n const content = formatIndex(entries);\n try {\n await updateWikiPage(instanceUrl, token, scope, id, indexSlug, content);\n } catch {\n await createWikiPage(instanceUrl, token, scope, id, indexSlug, content || \"# Skills Index\");\n }\n}\n\nasync function upsertIndexEntry(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n indexSlug: string,\n entry: IndexEntry\n): Promise<void> {\n const entries = await readIndex(instanceUrl, token, scope, id, indexSlug);\n const idx = entries.findIndex((e) => e.name === entry.name);\n if (idx >= 0) {\n entries[idx] = entry;\n } else {\n entries.push(entry);\n }\n await writeIndex(instanceUrl, token, scope, id, indexSlug, entries);\n}\n\nasync function removeIndexEntry(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n indexSlug: string,\n name: string\n): Promise<void> {\n const entries = await readIndex(instanceUrl, token, scope, id, indexSlug);\n const filtered = entries.filter((e) => e.name !== name);\n if (filtered.length !== entries.length) {\n await writeIndex(instanceUrl, token, scope, id, indexSlug, filtered);\n }\n}\n\nfunction extractSkillNames(pages: WikiPageSummary[], prefix: string): string[] {\n const skillSuffix = \"/SKILL\";\n const names = new Set<string>();\n for (const p of pages) {\n if (p.slug.startsWith(prefix + \"/\") && p.slug.endsWith(skillSuffix)) {\n const middle = p.slug.slice(prefix.length + 1, -skillSuffix.length);\n if (middle && !middle.includes(\"/\")) {\n names.add(middle);\n }\n }\n }\n return [...names];\n}\n\nasync function rebuildIndex(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n prefix: string,\n indexSlug: string\n): Promise<IndexEntry[]> {\n const pages = await listWikiPages(instanceUrl, token, scope, id);\n const actualNames = extractSkillNames(pages, prefix);\n const currentEntries = await readIndex(instanceUrl, token, scope, id, indexSlug);\n\n const indexed = new Set(currentEntries.map((e) => e.name));\n const actual = new Set(actualNames);\n\n let dirty = false;\n\n const removed = currentEntries.filter((e) => !actual.has(e.name));\n if (removed.length > 0) dirty = true;\n\n const added: string[] = [];\n for (const name of actualNames) {\n if (!indexed.has(name)) {\n added.push(name);\n dirty = true;\n }\n }\n\n if (!dirty && added.length === 0) return currentEntries;\n\n const kept = currentEntries.filter((e) => actual.has(e.name));\n for (const name of added) {\n kept.push({\n name,\n description: \"(auto-indexed — update description with gitlab_skill_save)\",\n draft: prefix === DRAFTS_PREFIX,\n });\n }\n\n await writeIndex(instanceUrl, token, scope, id, indexSlug, kept);\n return kept;\n}\n\nasync function upsertPage(\n instanceUrl: string,\n token: string,\n scope: Scope,\n id: string | number,\n slug: string,\n content: string\n): Promise<void> {\n try {\n await updateWikiPage(instanceUrl, token, scope, id, slug, content);\n } catch {\n await createWikiPage(instanceUrl, token, scope, id, slug, content);\n }\n}\n\nexport function makeSkillTools(ctx: PluginContext): Record<string, any> {\n function authAndValidate(projectId: string) {\n const auth = ctx.ensureAuth();\n if (!auth) throw new Error(\"GitLab authentication not available\");\n const err = validateProjectId(projectId);\n if (err) throw new Error(err);\n return auth;\n }\n\n return {\n gitlab_skill_list: tool({\n description:\n \"List available project skills and optionally draft skills.\\n\" +\n \"Skills define step-by-step procedures for common tasks (e.g., incident retros, debugging, deployments).\\n\" +\n \"Auto-rebuilds the skill index if it is out of sync with actual skill pages.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n include_drafts: z.boolean().optional().describe(\"Also list draft skills (default: false)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n include_drafts?: boolean;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n const published = await rebuildIndex(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n SKILLS_PREFIX,\n SKILLS_INDEX\n );\n\n let drafts: IndexEntry[] = [];\n if (args.include_drafts) {\n drafts = await rebuildIndex(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n DRAFTS_PREFIX,\n DRAFTS_INDEX\n );\n drafts = drafts.map((e) => ({ ...e, draft: true }));\n }\n\n const all = [...published, ...drafts];\n if (all.length === 0) return \"No skills found. Use gitlab_skill_save to create one.\";\n return JSON.stringify(all, null, 2);\n } catch (err: any) {\n return `Error listing skills: ${err.message}`;\n }\n },\n }),\n\n gitlab_skill_load: tool({\n description:\n \"Load a specific skill by name.\\n\" +\n \"Skills contain step-by-step instructions for common tasks.\\n\" +\n \"Checks published skills first, then falls back to draft skills.\\n\" +\n \"Returns the SKILL content and lists available reference pages.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n name: z.string().describe('Skill name (e.g., \"incident-retro\", \"helm-rollback\")'),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const prefixes = [SKILLS_PREFIX, DRAFTS_PREFIX];\n for (const prefix of prefixes) {\n try {\n const page = await getWikiPage(\n auth.instanceUrl,\n auth.token,\n scope,\n id,\n `${prefix}/${args.name}/SKILL`\n );\n\n const pages = await listWikiPages(auth.instanceUrl, auth.token, scope, id);\n const refPrefix = `${prefix}/${args.name}/references/`;\n const refs = pages\n .filter((p) => p.slug.startsWith(refPrefix))\n .map((p) => p.slug.slice(refPrefix.length));\n\n const isDraft = prefix === DRAFTS_PREFIX;\n let result = isDraft ? `[DRAFT SKILL]\\n\\n${page.content}` : page.content;\n if (refs.length > 0) {\n result += `\\n\\n---\\nAvailable references: ${refs.join(\", \")}`;\n result += `\\nLoad with: gitlab_skill_load_reference(name=\"${args.name}\", reference=\"<name>\")`;\n }\n return result;\n } catch {\n continue;\n }\n }\n return `Skill \"${args.name}\" not found. Use gitlab_skill_list to see available skills.`;\n },\n }),\n\n gitlab_skill_save: tool({\n description:\n \"Create or update a skill.\\n\" +\n \"Skills define step-by-step procedures for common tasks.\\n\" +\n \"Use draft=true for skills that haven't been proven yet.\\n\" +\n \"Updates the skill index with the provided description.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n name: z.string().describe('Skill name (e.g., \"incident-retro\")'),\n content: z.string().describe(\"Skill content in markdown\"),\n description: z.string().describe(\"Short description for the skill index (1-2 sentences)\"),\n draft: z.boolean().optional().describe(\"Save as draft skill (default: false)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n content: string;\n description: string;\n draft?: boolean;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const prefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;\n const indexSlug = args.draft ? DRAFTS_INDEX : SKILLS_INDEX;\n const slug = `${prefix}/${args.name}/SKILL`;\n const label = args.draft ? \"draft \" : \"\";\n\n try {\n await upsertPage(auth.instanceUrl, auth.token, scope, id, slug, args.content);\n await upsertIndexEntry(auth.instanceUrl, auth.token, scope, id, indexSlug, {\n name: args.name,\n description: args.description,\n source: \"project\",\n draft: !!args.draft,\n });\n return `Saved ${label}skill: ${args.name}`;\n } catch (err: any) {\n return `Error saving skill: ${err.message}`;\n }\n },\n }),\n\n gitlab_skill_promote: tool({\n description:\n \"Promote a draft skill to published.\\n\" +\n \"Moves all skill pages from drafts to published and updates both indexes.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n name: z.string().describe(\"Skill name to promote\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n try {\n const pages = await listWikiPages(auth.instanceUrl, auth.token, scope, id, true);\n const draftPrefix = `${DRAFTS_PREFIX}/${args.name}/`;\n const draftPages = (pages as any[]).filter(\n (p) => p.slug.startsWith(draftPrefix) && p.content\n );\n\n if (draftPages.length === 0) {\n return `Draft skill \"${args.name}\" not found. Use gitlab_skill_list(include_drafts=true) to see available drafts.`;\n }\n\n const draftIndex = await readIndex(auth.instanceUrl, auth.token, scope, id, DRAFTS_INDEX);\n const entry = draftIndex.find((e) => e.name === args.name);\n const description = entry?.description ?? \"(promoted from draft)\";\n\n for (const page of draftPages) {\n const newSlug = page.slug.replace(DRAFTS_PREFIX, SKILLS_PREFIX);\n await upsertPage(auth.instanceUrl, auth.token, scope, id, newSlug, page.content);\n await deleteWikiPage(auth.instanceUrl, auth.token, scope, id, page.slug);\n }\n\n await removeIndexEntry(auth.instanceUrl, auth.token, scope, id, DRAFTS_INDEX, args.name);\n await upsertIndexEntry(auth.instanceUrl, auth.token, scope, id, SKILLS_INDEX, {\n name: args.name,\n description,\n source: \"project\",\n draft: false,\n });\n\n return `Promoted skill \"${args.name}\" from draft to published.`;\n } catch (err: any) {\n return `Error promoting skill: ${err.message}`;\n }\n },\n }),\n\n gitlab_skill_discover: tool({\n description:\n \"Search for skills available in the group wiki.\\n\" +\n \"Reads the group-level skill index and filters by query.\\n\" +\n \"Use gitlab_skill_install to copy a discovered skill to your project.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n query: z.string().describe(\"Search query (matches skill name and description)\"),\n group_id: z.string().describe(\"Group path to search for shared skills\"),\n },\n execute: async (args: { project_id: string; query: string; group_id: string }) => {\n const auth = authAndValidate(args.project_id);\n\n try {\n const entries = await readIndex(\n auth.instanceUrl,\n auth.token,\n \"groups\",\n args.group_id,\n SKILLS_INDEX\n );\n\n if (entries.length === 0) {\n return `No skills found in group \"${args.group_id}\" wiki. The group skill index (${SKILLS_INDEX}) is empty or does not exist.`;\n }\n\n const q = args.query.toLowerCase();\n const matches = entries.filter(\n (e) => e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q)\n );\n\n if (matches.length === 0) {\n return `No skills matching \"${args.query}\" in group \"${args.group_id}\". Available skills:\\n${entries.map((e) => `- ${e.name}: ${e.description}`).join(\"\\n\")}`;\n }\n\n return (\n `Found ${matches.length} skill(s) in group \"${args.group_id}\":\\n\\n` +\n matches\n .map(\n (e) =>\n `**${e.name}**: ${e.description}\\nInstall: gitlab_skill_install(name=\"${e.name}\", group_id=\"${args.group_id}\")`\n )\n .join(\"\\n\\n\")\n );\n } catch (err: any) {\n return `Error discovering skills: ${err.message}`;\n }\n },\n }),\n\n gitlab_skill_install: tool({\n description:\n \"Install a skill from a group wiki into the project wiki.\\n\" +\n \"Copies all skill pages (SKILL + references) from the group to the project.\\n\" +\n \"Updates the project skill index with the installed skill.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n name: z.string().describe('Skill name to install (e.g., \"incident-retro\")'),\n group_id: z.string().describe(\"Group path to install from\"),\n draft: z.boolean().optional().describe(\"Install as draft (default: false)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n group_id: string;\n draft?: boolean;\n }) => {\n const auth = authAndValidate(args.project_id);\n const projectScope = resolveScope(args);\n\n try {\n const groupPages = await listWikiPages(\n auth.instanceUrl,\n auth.token,\n \"groups\",\n args.group_id,\n true\n );\n\n const sourcePrefix = `${SKILLS_PREFIX}/${args.name}/`;\n const skillPages = (groupPages as any[]).filter(\n (p) => p.slug.startsWith(sourcePrefix) && p.content\n );\n\n if (skillPages.length === 0) {\n return `Skill \"${args.name}\" not found in group \"${args.group_id}\" wiki.`;\n }\n\n const targetPrefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;\n const targetIndex = args.draft ? DRAFTS_INDEX : SKILLS_INDEX;\n\n for (const page of skillPages) {\n const newSlug = page.slug.replace(SKILLS_PREFIX, targetPrefix);\n await upsertPage(\n auth.instanceUrl,\n auth.token,\n projectScope.scope,\n projectScope.id,\n newSlug,\n page.content\n );\n }\n\n const groupIndex = await readIndex(\n auth.instanceUrl,\n auth.token,\n \"groups\",\n args.group_id,\n SKILLS_INDEX\n );\n const entry = groupIndex.find((e) => e.name === args.name);\n const description = entry?.description ?? \"(installed from group)\";\n\n await upsertIndexEntry(\n auth.instanceUrl,\n auth.token,\n projectScope.scope,\n projectScope.id,\n targetIndex,\n {\n name: args.name,\n description,\n source: `group:${args.group_id}`,\n draft: !!args.draft,\n }\n );\n\n return `Installed skill \"${args.name}\" from group \"${args.group_id}\" into project. ${skillPages.length} page(s) copied.`;\n } catch (err: any) {\n return `Error installing skill: ${err.message}`;\n }\n },\n }),\n\n gitlab_skill_delete: tool({\n description:\n \"Delete a skill and remove it from the index.\\n\" +\n \"Removes all pages under the skill directory (SKILL + references).\\n\" +\n \"Wiki git history preserves deleted content.\",\n args: {\n project_id: z.string().describe(PROJECT_ID_DESC),\n name: z.string().describe(\"Skill name to delete\"),\n draft: z\n .boolean()\n .optional()\n .describe(\"Delete from drafts instead of published (default: false)\"),\n scope: z.enum([\"projects\", \"groups\"]).optional().describe(\"Scope (default: projects)\"),\n group_id: z.string().optional().describe(\"Group path (required when scope is groups)\"),\n },\n execute: async (args: {\n project_id: string;\n name: string;\n draft?: boolean;\n scope?: string;\n group_id?: string;\n }) => {\n const auth = authAndValidate(args.project_id);\n const { scope, id } = resolveScope(args);\n\n const prefix = args.draft ? DRAFTS_PREFIX : SKILLS_PREFIX;\n const indexSlug = args.draft ? DRAFTS_INDEX : SKILLS_INDEX;\n const skillPrefix = `${prefix}/${args.name}/`;\n\n try {\n const pages = await listWikiPages(auth.instanceUrl, auth.token, scope, id);\n const skillPages = pages.filter((p) => p.slug.startsWith(skillPrefix));\n\n if (skillPages.length === 0) {\n return `Skill \"${args.name}\" not found. Use gitlab_skill_list to see available skills.`;\n }\n\n for (const page of skillPages) {\n await deleteWikiPage(auth.instanceUrl, auth.token, scope, id, page.slug);\n }\n\n await removeIndexEntry(auth.instanceUrl, auth.token, scope, id, indexSlug, args.name);\n\n return `Deleted skill \"${args.name}\" (${skillPages.length} page(s) removed).`;\n } catch (err: any) {\n return `Error deleting skill: ${err.message}`;\n }\n },\n }),\n };\n}\n"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EACb,6BAA6B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAC7B,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAChB,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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","names":["key","yamlLoad","fetchMcpServers","data","nodes","normalizeItemGid","os","baseUrl","projectUrl","rawText","original","import_plugin","import_js_yaml","yaml","Ajv","z","import_plugin","z","import_plugin","z","import_plugin","z","import_plugin","z","PREFIX","PROJECT_ID_DESC","resolveScope","validateProjectId"]}
|