import {z} from 'zod' export type GetApiApiAgentDeploymentsDeploymentIdIssuesV2IssueIdArgs = {deploymentId: string, issueId: string, includeCodeSnippet?: boolean | undefined, includeIsArchived?: boolean | undefined}; export type GetApiApiAgentDeploymentsDeploymentIdIssuesV2IssueIdOptions = {baseUrl: string, SemgrepWebToken?: string | undefined, fetch?: typeof fetch | undefined}; export const protosIssuesV1IssuePrimaryRefItem = z.object({id: z.string().optional(), ref: z.string().optional()}); export const protosIssuesV1IssueRepository = z.object({name: z.string().optional(), id: z.string().optional(), type: z.enum(["SCM_TYPE_GITHUB", "SCM_TYPE_GITHUB_ENTERPRISE", "SCM_TYPE_GITLAB", "SCM_TYPE_GITLAB_SELFMANAGED", "SCM_TYPE_BITBUCKET", "SCM_TYPE_BITBUCKET_DATACENTER", "SCM_TYPE_AZURE_DEVOPS", "SCM_TYPE_UNKNOWN", "SCM_TYPE_HARNESS"]).optional(), primaryRef: protosIssuesV1IssuePrimaryRefItem.optional()}); export const protosIssuesV1IssueScan = z.object({id: z.string().optional(), meta: z.object({}).optional()}); export const protosTicketingV1ExternalTicket = z.object({url: z.string().optional(), externalSlug: z.string().optional(), id: z.string().optional(), linkedIssueIds: z.array(z.string()).optional()}); export const protosAiV1AutotriageFeedback = z.object({autotriageId: z.string().optional(), rating: z.enum(["RATING_GOOD", "RATING_BAD"]).optional(), note: z.string().optional()}); export const protosAiV1Autotriage = z.object({id: z.string().optional(), issueId: z.string().optional(), verdict: z.enum(["VERDICT_TRUE_POSITIVE", "VERDICT_FALSE_POSITIVE", "VERDICT_NO_VERDICT"]).optional(), reason: z.string().optional(), feedback: protosAiV1AutotriageFeedback.optional(), matchBasedId: z.string().optional(), memoryIdsReferenced: z.array(z.string()).optional(), memoryIdsRendered: z.array(z.string()).optional()}); export const protosAiV1SensitivityTags = z.object({id: z.string().optional(), path: z.string().optional(), tags: z.string().optional(), sensitivity: z.enum(["SENSITIVITY_HIGH_SENSITIVITY", "SENSITIVITY_LOW_SENSITIVITY", "SENSITIVITY_NEUTRAL_SENSITIVITY"]).optional()}); export const protosIssuesV1DataflowTracePosition = z.object({line: z.string().optional(), col: z.string().optional(), offset: z.string().optional()}); export const protosIssuesV1DataflowTraceLocation = z.object({path: z.string().optional(), start: protosIssuesV1DataflowTracePosition.optional(), end: protosIssuesV1DataflowTracePosition.optional(), locationUrl: z.string().optional()}); export const protosIssuesV1IssueDataflowTrace = z.object({taintSource: z.array(protosIssuesV1DataflowTraceLocation).optional(), intermediateVars: z.array(protosIssuesV1DataflowTraceLocation).optional(), taintSink: z.array(protosIssuesV1DataflowTraceLocation).optional()}); export const protosIssuesV1ActivityHistoryEventExceptionRequestDetails = z.object({actionSource: z.enum(["FINDING_EXCEPTION_REQUEST_SOURCE_SCM_COMMENT", "FINDING_EXCEPTION_REQUEST_SOURCE_SEMGREP_APPSEC_PLATFORM", "FINDING_EXCEPTION_REQUEST_SOURCE_API"]).optional()}); export const protosIssuesV1IssueActivityHistoryEvent = z.object({date: z.string().optional(), title: z.string().optional(), triageReason: z.string().optional(), note: z.string().optional(), actor: z.string().optional(), historyType: z.enum(["HISTORY_TYPE_STATUS", "HISTORY_TYPE_TRIAGE", "HISTORY_TYPE_AUTOTRIAGE", "HISTORY_TYPE_AUTOTRIAGE_FEEDBACK", "HISTORY_TYPE_AI_TAG", "HISTORY_TYPE_ANALYSIS_STARTED", "HISTORY_TYPE_REVIEW_COMMENT_SILENCED", "HISTORY_TYPE_TICKET_CREATED", "HISTORY_TYPE_TICKET_ATTEMPTED", "HISTORY_TYPE_GUIDANCE_REGENERATION", "HISTORY_TYPE_SCM_MENTION", "HISTORY_TYPE_CLICK_TO_FIX_PR_REQUESTED", "HISTORY_TYPE_CLICK_TO_FIX_PR_OPENED", "HISTORY_TYPE_CLICK_TO_FIX_PR_FAILED", "HISTORY_TYPE_CLICK_TO_FIX_PR_MERGED", "HISTORY_TYPE_EXCEPTION_REQUEST_CREATED", "HISTORY_TYPE_EXCEPTION_REQUEST_APPROVED", "HISTORY_TYPE_EXCEPTION_REQUEST_REJECTED"]).optional(), exceptionRequestDetails: protosIssuesV1ActivityHistoryEventExceptionRequestDetails.optional()}); export const protosIssuesV1IssueRelatedIssue = z.object({id: z.string().optional(), ref: z.string().optional(), pullRequestId: z.string().optional(), aggregateState: z.enum(["AGGREGATE_ISSUE_STATE_OPEN", "AGGREGATE_ISSUE_STATE_FIXED", "AGGREGATE_ISSUE_STATE_REMOVED", "AGGREGATE_ISSUE_STATE_IGNORED_APP", "AGGREGATE_ISSUE_STATE_IGNORED_CODE", "AGGREGATE_ISSUE_STATE_UNKNOWN", "AGGREGATE_ISSUE_STATE_REVIEWING", "AGGREGATE_ISSUE_STATE_FIXING", "AGGREGATE_ISSUE_STATE_PROVISIONALLY_IGNORED_APP"]).optional(), createdAt: z.string().optional()}); export const protosAiV1Autofix = z.object({id: z.string().optional(), fixCode: z.string().optional(), fixDiff: z.string().optional(), explanation: z.string().optional(), url: z.string().optional()}); export const protosAiV1Guidance = z.object({id: z.string().optional(), summary: z.string().optional(), guidanceText: z.string().optional(), memoryIdsUsed: z.array(z.string()).optional()}); export const protosAiV1Remediation = z.object({issueId: z.string().optional(), matchBasedId: z.string().optional(), autofix: protosAiV1Autofix.optional(), guidance: protosAiV1Guidance.optional()}); export const protosIssuesV1SupersededRule = z.object({product: z.enum(["RULE_TYPE_SAST", "RULE_TYPE_SCA", "RULE_TYPE_SECRETS"]).optional(), rulePath: z.string().optional()}); export const protosTicketingV1TicketAttempt = z.object({attemptedAt: z.string().optional(), responseMessage: z.string().optional()}); export const protosIssuesV1IssueSastAttributes = z.object({}); export const protosIssuesV1ScaAttributesFoundDependency = z.object({package: z.string().optional(), version: z.string().optional(), transitivity: z.enum(["UNKNOWN_TRANSITIVITY", "TRANSITIVE", "DIRECT"]).optional(), lockfileLineUrl: z.string().optional(), filePath: z.string().optional(), ecosystem: z.enum(["no_package_manager", "npm", "pypi", "gomod", "cargo", "maven", "gem", "composer", "nuget", "pub", "swiftpm", "hex", "cocoapods", "mix", "opam"]).optional(), manifestFilePath: z.string().optional()}); export const protosIssuesV1ScaAttributesFixRecommendation = z.object({package: z.string().optional(), version: z.string().optional()}); export const protosScaV1EpssScore = z.object({score: z.number().optional(), percentile: z.number().optional(), updatedAt: z.string().optional(), categorization: z.enum(["EPSS_PROBABILITY_LOW", "EPSS_PROBABILITY_MEDIUM", "EPSS_PROBABILITY_HIGH", "EPSS_PROBABILITY_NONE"]).optional()}); export const protosIssuesV1ScaMatchInfoTransitiveMatch = z.object({dependency: protosIssuesV1ScaAttributesFoundDependency.optional(), path: z.string().optional(), line: z.string().optional()}); export const protosIssuesV1ScaAttributesScaMatchInfo = z.object({matchKind: z.enum(["SCA_MATCH_KIND_LOCKFILE_ONLY", "SCA_MATCH_KIND_DIRECT_REACHABLE", "SCA_MATCH_KIND_DIRECT_UNREACHABLE", "SCA_MATCH_KIND_TRANSITIVE_REACHABLE", "SCA_MATCH_KIND_TRANSITIVE_UNREACHABLE", "SCA_MATCH_KIND_TRANSITIVE_UNDETERMINED"]).optional(), analyzedPackages: z.array(protosIssuesV1ScaAttributesFoundDependency).optional(), transitiveMatches: z.array(protosIssuesV1ScaMatchInfoTransitiveMatch).optional()}); export const protosIssuesV1ScaAttributesIntroducingDependency = z.object({package: z.string().optional(), version: z.string().optional()}); export const protosIssuesV1IssueScaAttributes = z.object({severity: z.enum(["SEVERITY_HIGH", "SEVERITY_MEDIUM", "SEVERITY_LOW", "SEVERITY_CRITICAL"]).optional(), vulnDatabaseIdentifier: z.string().optional(), reachability: z.enum(["REACHABILITY_CONDITIONALLY_REACHABLE", "REACHABILITY_ALWAYS_REACHABLE", "REACHABILITY_REACHABLE", "REACHABILITY_UNREACHABLE", "REACHABILITY_UNKNOWN"]).optional(), reachableCondition: z.string().optional(), cwes: z.array(z.string()).optional(), foundDependency: protosIssuesV1ScaAttributesFoundDependency.optional(), fixRecommendations: z.array(protosIssuesV1ScaAttributesFixRecommendation).optional(), bestFix: protosIssuesV1ScaAttributesFixRecommendation.optional(), epssScore: protosScaV1EpssScore.optional(), rulePublishDate: z.string().optional(), scaRuleKind: z.enum(["SCA_RULE_KIND_REACHABLE", "SCA_RULE_KIND_UPGRADE_ONLY", "SCA_RULE_KIND_MALICIOUS_DEPENDENCY", "SCA_RULE_KIND_LEGACY"]).optional(), scaMatchInfo: protosIssuesV1ScaAttributesScaMatchInfo.optional(), introducedBy: z.array(protosIssuesV1ScaAttributesIntroducingDependency).optional()}); export const protosSecretsV1HistoricalInfo = z.object({gitCommit: z.string().optional(), gitCommitTimestamp: z.string().optional(), gitBlob: z.string().optional()}); export const protosIssuesV1IssueSecretsAttributes = z.object({validationState: z.enum(["VALIDATION_STATE_CONFIRMED_VALID", "VALIDATION_STATE_CONFIRMED_INVALID", "VALIDATION_STATE_VALIDATION_ERROR", "VALIDATION_STATE_NO_VALIDATOR"]).optional(), secretType: z.string().optional(), historicalInfo: protosSecretsV1HistoricalInfo.optional()}); export const protosAiV1Codeowner: z.ZodType = z.object({id: z.string().optional(), name: z.string().optional(), isTeam: z.boolean().optional(), members: z.array(z.lazy(() => protosAiV1Codeowner)).optional()}); export const protosIssuesV1IssueCodeSnippet = z.object({path: z.string().optional(), content: z.string().optional()}); export const protosAiV1RuleExplanation = z.object({id: z.string().optional(), summary: z.string().optional(), explanation: z.string().optional()}); export const protosAiV1ExploitCondition = z.object({description: z.string().optional(), confirmed: z.boolean().optional()}); export const protosIssuesV1IssueExceptionRequestSummary = z.object({exceptionState: z.enum(["FINDING_EXCEPTION_REQUEST_STATE_REQUESTED", "FINDING_EXCEPTION_REQUEST_STATE_APPROVED", "FINDING_EXCEPTION_REQUEST_STATE_REJECTED"]).optional(), requesterLogin: z.string().optional(), requesterNote: z.string().optional(), requesterTriageReason: z.enum(["FINDING_TRIAGE_REASON_FALSE_POSITIVE", "FINDING_TRIAGE_REASON_NO_TIME", "FINDING_TRIAGE_REASON_ACCEPTABLE_RISK", "FINDING_TRIAGE_REASON_NO_TRIAGE_REASON", "FINDING_TRIAGE_REASON_UNKNOWN", "FINDING_TRIAGE_REASON_DUPLICATE"]).optional(), requesterActionSource: z.enum(["FINDING_EXCEPTION_REQUEST_SOURCE_SCM_COMMENT", "FINDING_EXCEPTION_REQUEST_SOURCE_SEMGREP_APPSEC_PLATFORM", "FINDING_EXCEPTION_REQUEST_SOURCE_API"]).optional(), reviewerLogin: z.string().optional(), requestId: z.string().optional(), reviewId: z.string().optional(), issueId: z.string().optional(), createdAt: z.string().optional(), reviewedAt: z.string().optional()}); export const protosIssuesV1Issue = z.object({id: z.string().optional(), createdAt: z.string().optional(), ref: z.string().optional(), syntacticId: z.string().optional(), matchBasedId: z.string().optional(), ruleId: z.string().optional(), status: z.enum(["ISSUE_STATUS_FIXED", "ISSUE_STATUS_MUTED", "ISSUE_STATUS_REMOVED", "ISSUE_STATUS_UNRESOLVED"]).optional(), repository: protosIssuesV1IssueRepository.optional(), firstSeenScan: protosIssuesV1IssueScan.optional(), triageState: z.enum(["FINDING_TRIAGE_STATE_UNTRIAGED", "FINDING_TRIAGE_STATE_IGNORED", "FINDING_TRIAGE_STATE_REOPENED", "FINDING_TRIAGE_STATE_UNKNOWN", "FINDING_TRIAGE_STATE_REVIEWING", "FINDING_TRIAGE_STATE_FIXING", "FINDING_TRIAGE_STATE_PROVISIONALLY_IGNORED"]).optional(), triageReason: z.enum(["FINDING_TRIAGE_REASON_FALSE_POSITIVE", "FINDING_TRIAGE_REASON_NO_TIME", "FINDING_TRIAGE_REASON_ACCEPTABLE_RISK", "FINDING_TRIAGE_REASON_NO_TRIAGE_REASON", "FINDING_TRIAGE_REASON_UNKNOWN", "FINDING_TRIAGE_REASON_DUPLICATE"]).optional(), relevantSince: z.string().optional(), aggregateState: z.enum(["AGGREGATE_ISSUE_STATE_OPEN", "AGGREGATE_ISSUE_STATE_FIXED", "AGGREGATE_ISSUE_STATE_REMOVED", "AGGREGATE_ISSUE_STATE_IGNORED_APP", "AGGREGATE_ISSUE_STATE_IGNORED_CODE", "AGGREGATE_ISSUE_STATE_UNKNOWN", "AGGREGATE_ISSUE_STATE_REVIEWING", "AGGREGATE_ISSUE_STATE_FIXING", "AGGREGATE_ISSUE_STATE_PROVISIONALLY_IGNORED_APP"]).optional(), note: z.string().optional(), externalTicket: protosTicketingV1ExternalTicket.optional(), vulnGroupKey: z.string().optional(), isBlocking: z.boolean().optional(), autotriage: protosAiV1Autotriage.optional(), aiTags: protosAiV1SensitivityTags.optional(), lineOfCodeUrl: z.string().optional(), codeSnippet: z.string().optional(), dataflowTrace: protosIssuesV1IssueDataflowTrace.optional(), commitUrl: z.string().optional(), activityHistory: z.array(protosIssuesV1IssueActivityHistoryEvent).optional(), relatedIssues: z.array(protosIssuesV1IssueRelatedIssue).optional(), remediation: protosAiV1Remediation.optional(), lastSeenScan: protosIssuesV1IssueScan.optional(), filePath: z.string().optional(), line: z.number().int().optional(), endLine: z.number().int().optional(), column: z.number().int().optional(), endColumn: z.number().int().optional(), severity: z.enum(["SEVERITY_HIGH", "SEVERITY_MEDIUM", "SEVERITY_LOW", "SEVERITY_CRITICAL"]).optional(), message: z.string().optional(), rulePath: z.string().optional(), confidence: z.enum(["CONFIDENCE_HIGH", "CONFIDENCE_MEDIUM", "CONFIDENCE_LOW"]).optional(), ruleUrl: z.string().optional(), ruleReferences: z.array(z.string()).optional(), ruleOrigin: z.enum(["RULE_ORIGIN_CUSTOM", "RULE_ORIGIN_COMMUNITY", "RULE_ORIGIN_PRO_RULES"]).optional(), ruleHashId: z.string().optional(), ruleCweNames: z.array(z.string()).optional(), ruleOwaspNames: z.array(z.string()).optional(), ruleset: z.string().optional(), policySlug: z.string().optional(), category: z.string().optional(), ruleSupersededBy: z.array(protosIssuesV1SupersededRule).optional(), issueType: z.enum(["ISSUE_TYPE_SAST", "ISSUE_TYPE_SCA", "ISSUE_TYPE_SECRETS", "ISSUE_TYPE_RESEARCH", "ISSUE_TYPE_AI_SAST"]).optional(), issueParentId: z.string().optional(), ticketAttempts: z.array(protosTicketingV1TicketAttempt).optional(), sastAttributes: protosIssuesV1IssueSastAttributes.optional(), scaAttributes: protosIssuesV1IssueScaAttributes.optional(), secretsAttributes: protosIssuesV1IssueSecretsAttributes.optional(), subcategories: z.array(z.string()).optional(), refUrl: z.string().optional(), codeowners: z.array(protosAiV1Codeowner).optional(), codeSnippets: z.array(protosIssuesV1IssueCodeSnippet).optional(), ruleExplanation: protosAiV1RuleExplanation.optional(), ruleDisplayName: z.string().optional(), clickToFixPrUrl: z.string().optional(), aiImpact: z.string().optional(), aiExploitConditions: z.array(protosAiV1ExploitCondition).optional(), clickToFixCommitMsg: z.string().optional(), exceptionRequest: protosIssuesV1IssueExceptionRequestSummary.optional(), clickToFixPrId: z.string().optional(), triagePermission: z.enum(["TRIAGE_PERMISSION_IGNORE", "TRIAGE_PERMISSION_REQUEST", "TRIAGE_PERMISSION_NONE"]).optional(), isArchived: z.boolean().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get Issue * * GET /api/agent/deployments/{deploymentId}/issues/v2/{issueId} * * Also accepts auth: SemgrepJWT */ export const getApiApiAgentDeploymentsDeploymentIdIssuesV2IssueId = async (args: GetApiApiAgentDeploymentsDeploymentIdIssuesV2IssueIdArgs, options: GetApiApiAgentDeploymentsDeploymentIdIssuesV2IssueIdOptions) => { const {baseUrl, fetch: fetchFn = fetch, SemgrepWebToken} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.includeCodeSnippet != null) query.append("includeCodeSnippet", String(args.includeCodeSnippet)) if (args.includeIsArchived != null) query.append("includeIsArchived", String(args.includeIsArchived)) if (SemgrepWebToken !== undefined) headers.set('authorization', `Bearer ${SemgrepWebToken}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/agent/deployments/${encodeURIComponent(String(args.deploymentId))}/issues/v2/${encodeURIComponent(String(args.issueId))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(protosIssuesV1Issue, await res.json()) };