/**
 * Core types for the resource registry and dispatch system.
 */
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
export type RiskLevel = "read" | "low_write" | "medium_write" | "high_write" | "destructive";
export type RetryPolicy = "safe" | "idempotency_key_required" | "do_not_retry";
export interface OperationPolicy {
    risk: RiskLevel;
    retryPolicy: RetryPolicy;
}
/**
 * @deprecated Use `requiresConfirmation()` instead. After the P3 elicitation
 * refactor, the blocking threshold is `medium_write` (not just `high_write`).
 * This function remains for backward compatibility only.
 */
export declare function isBlockingRisk(risk: RiskLevel): boolean;
/** Explicit numeric ordering of risk levels. */
export declare const RISK_SEVERITY: ReadonlyMap<RiskLevel, number>;
export type AutoApproveRisk = "none" | RiskLevel | "all";
/**
 * Returns true when the operation risk is at or below the auto-approve
 * threshold, meaning it should proceed without user confirmation.
 */
export declare function shouldAutoApprove(opRisk: RiskLevel, threshold: AutoApproveRisk): boolean;
/**
 * Returns true when the risk level requires blocking the operation on clients
 * that lack elicitation support (medium_write and above).
 */
export declare function requiresConfirmation(risk: RiskLevel): boolean;
export interface HarnessClientInterface {
    readonly account: string;
}
export interface RegistryDispatchInterface {
    dispatch(client: HarnessClientInterface, resourceType: string, operation: string, input: Record<string, unknown>, signal?: AbortSignal): Promise<unknown>;
    getResource(resourceType: string): ResourceDefinition;
}
/**
 * Context passed to EndpointSpec.preflight hooks. Uses structural interfaces
 * so this module does not import HarnessClient/Registry (which would create a
 * cycle). Hooks that need concrete-only methods can narrow:
 *   `const hc = client as unknown as HarnessClient;`
 */
export interface PreflightContext {
    client: HarnessClientInterface;
    input: Record<string, unknown>;
    registry: RegistryDispatchInterface;
    signal?: AbortSignal;
}
export type ToolsetName = "pipelines" | "agents" | "services" | "environments" | "infrastructure" | "connectors" | "secrets" | "logs" | "audit" | "delegates" | "repositories" | "registries" | "templates" | "dashboards" | "idp" | "pull-requests" | "feature-flags" | "gitops" | "chaos" | "ccm" | "sei" | "scs" | "sto" | "dbops" | "access_control" | "settings" | "platform" | "visualizations" | "governance" | "freeze" | "overrides" | "ai-evals" | "iacm";
export type ProductName = "harness" | "fme";
export type OperationName = "list" | "get" | "create" | "update" | "delete";
export type ResourceScope = "project" | "org" | "account";
/**
 * Lightweight field descriptor for body schemas.
 * Pure data (not Zod) — serializable to JSON for harness_describe output.
 */
export interface BodyFieldSpec {
    /** Field name as the API expects it */
    name: string;
    /** Data type hint */
    type: "string" | "number" | "boolean" | "object" | "array" | "yaml";
    /** Whether the field is required for the operation to succeed */
    required: boolean;
    /** Brief description (shown to agents) */
    description: string;
    /** For "object" type: nested fields */
    fields?: BodyFieldSpec[];
    /** For "array" type: item type description */
    itemType?: string;
}
/**
 * Body schema for a write operation (create/update/execute action).
 * Advisory — bodyBuilder still does actual transformation.
 */
export interface BodySchema {
    /** Brief description of what the body represents */
    description: string;
    /** The fields the body expects */
    fields: BodyFieldSpec[];
}
/**
 * Descriptor for a filter field that can be used in list operations.
 */
export interface FilterFieldSpec {
    /** Field name as it appears in the API */
    name: string;
    /** Human-readable description for LLMs */
    description: string;
    /** Value type — defaults to "string" when omitted */
    type?: "string" | "number" | "boolean";
    /** Allowed values, if the field is constrained to a known set */
    enum?: string[];
    /** When true, this filter is mandatory for the list operation to succeed.
     *  The registry validates required filters before making the API call. */
    required?: boolean;
}
/**
 * Declarative rule for expanding shorthand input keys into full nested structures.
 * Applied before runtime input resolution so the template matcher sees the expanded form.
 */
export interface InputExpansionRule {
    /** Input key that triggers the expansion (e.g. "branch", "tag") */
    triggerKey: string;
    /** Structure to merge into inputs. Use "$value" as placeholder for the trigger key's value. */
    expand: Record<string, unknown>;
    /** If set, skip expansion when user already provided this key (prevents double-expand). */
    skipIfPresent?: string;
}
/**
 * Config type for pathBuilder (avoids circular import).
 */
export type PathBuilderConfig = {
    HARNESS_ACCOUNT_ID?: string;
    HARNESS_ORG?: string;
    HARNESS_PROJECT?: string;
};
/**
 * Specifies how a single CRUD operation maps to the Harness API.
 */
export interface EndpointSpec {
    method: HttpMethod;
    /** Optional dynamic method override. When set, takes precedence over `method`. */
    methodBuilder?: (input: Record<string, unknown>) => HttpMethod;
    /** Path template, e.g. "/pipeline/api/pipelines/{pipelineIdentifier}". Ignored when pathBuilder is set. */
    path: string;
    /** Optional dynamic path builder. When set, used instead of path + pathParams for account-scoped or multi-endpoint resources. */
    pathBuilder?: (input: Record<string, unknown>, config: PathBuilderConfig) => string;
    /** Maps tool input field names to path param placeholders */
    pathParams?: Record<string, string>;
    /** Maps tool input field names to query param names */
    queryParams?: Record<string, string>;
    /** Static query parameters always included in the request (not derived from input) */
    staticQueryParams?: Record<string, string>;
    /** Default query params to include if not overridden by input */
    defaultQueryParams?: Record<string, string>;
    /**
     * When true, if `orgIdentifier` (or custom `scopeParams.org`) is still unset after scope
     * resolution, set it from `input.org_id` or `config.HARNESS_ORG`. Used for account-scoped
     * resources whose NG endpoints require `orgIdentifier` on the query string (e.g. POST /ng/api/projects).
     */
    injectOrgQueryFallback?: boolean;
    /** Override default scope query param names (e.g. for APIs using snake_case) */
    scopeParams?: {
        account?: string;
        org?: string;
        project?: string;
    };
    /** For POST/PUT: how to build the request body from tool input */
    bodyBuilder?: (input: Record<string, unknown>) => unknown;
    /** Static headers to merge into the request (e.g. Content-Type override) */
    headers?: Record<string, string>;
    /** For GET: extract the useful part from the raw response */
    responseExtractor?: (raw: unknown, input?: Record<string, unknown>) => unknown;
    /** Request binary (ArrayBuffer) response instead of JSON. Used for ZIP download endpoints. */
    responseType?: "json" | "buffer";
    /** Description shown in harness_describe output */
    description?: string;
    /** Optional body schema for write operations — exposed via harness_describe */
    bodySchema?: BodySchema;
    /**
     * When the bodyBuilder wraps user fields inside a single key
     * (e.g. `{ project: { identifier, name } }`), set this to the wrapper key
     * so required-field validation checks the inner object, not the wrapper.
     */
    bodyWrapperKey?: string;
    /**
     * When true, do not inject orgIdentifier/projectIdentifier into POST/PUT
     * bodies. Some APIs take scope only in query/path and reject extra body fields.
     */
    skipScopeBodyInjection?: boolean;
    /** Declares the risk level and retry behavior for this operation. */
    operationPolicy: OperationPolicy;
    /**
     * Declarative input expansion rules. When present, matching shorthand keys
     * in user input are expanded into full nested structures before resolution.
     */
    inputExpansions?: InputExpansionRule[];
    /** When true, the API uses 1-based pagination. The registry adds 1 to the
     *  0-based `page` value from harness_list before sending the request. */
    pageOneIndexed?: boolean;
    /** When an API error message matches one of these patterns, return an empty
     *  list/result instead of throwing. Useful for backends that return 500 for
     *  "no data" scenarios (e.g. disconnected GitOps agent). */
    emptyOnErrorPatterns?: RegExp[];
    /** When true, omit the automatic `accountIdentifier` query param from the
     *  request URL. Some APIs (e.g. SEI) use only the `Harness-Account` header. */
    headerBasedScoping?: boolean;
    /**
     * When true, inject `accountIdentifier` from config into the POST/PUT request body.
     * Required for gRPC-gateway APIs (e.g. GitOps) where `body: "*"` means the entire
     * JSON body IS the proto message — query-param-only accountIdentifier is invisible
     * to the handler.
     */
    injectAccountInBody?: boolean | string;
    /**
     * Optional preflight hook that runs before the request is sent.
     * Use for server-side invariants (e.g. duplicate-check before creating a
     * resource). Throw from the hook to block the operation — the error message
     * is surfaced directly to the agent.
     *
     * Typed loosely to avoid a circular import back into the registry/dispatcher.
     * The runtime shape is `{ client: HarnessClient, input, registry: Registry, signal? }`.
     */
    preflight?: (ctx: PreflightContext) => Promise<void>;
    /**
     * When true, the MCP layer controls ELK→Mongo fallback for this endpoint:
     *  1. First request sent with `enforce_elasticsearch=true` (ELK path).
     *  2. On failure (4xx except 401/403, 5xx, or timeout), retried with
     *     `enforce_elasticsearch=false` (Mongo path).  A 404 often means the
     *     ES index doesn't exist yet; a 400 may be ES-specific.
     * The response includes `_data_source: "elasticsearch" | "mongodb"` so the caller
     * knows which backend served the data.
     * Only applicable to ssca-manager endpoints that accept the `enforce_elasticsearch` query param.
     */
    elkFallback?: boolean;
    /**
     * When true, harness_list will NOT run the global compactItems whitelist pass
     * on this response's `items`. Use this when `responseExtractor` already
     * produces a minimal, hand-picked projection and further compaction would
     * strip intentional display fields (e.g. `severity`, `requested_by`).
     */
    skipCompact?: boolean;
}
/**
 * Declarative definition of a Harness resource type and how it maps to CRUD endpoints.
 */
export interface ResourceDefinition {
    /** Unique key: "pipeline", "service", "connector", etc. */
    resourceType: string;
    /** Human-readable name: "Pipeline", "Service", etc. */
    displayName: string;
    /** Brief description for harness_describe output */
    description: string;
    /** Which toolset this resource belongs to (for HARNESS_TOOLSETS filtering) */
    toolset: string;
    /** Default scope level: "project" | "org" | "account" */
    scope: ResourceScope;
    /**
     * Scopes this resource can query when the caller passes `resource_scope`.
     * If omitted, the resource supports only its default `scope`.
     */
    supportedScopes?: readonly ResourceScope[];
    /**
     * When true, org/project params are only added if explicitly provided in input.
     * Use for resources that support multiple scopes (e.g., Harness Code repos/PRs
     * which can be account, org, or project scoped depending on where they live).
     * Default: false (scope params always added based on `scope` field).
     */
    scopeOptional?: boolean;
    /**
     * Override default scope query parameter names.
     * Standard NG API uses orgIdentifier / projectIdentifier.
     * Some APIs (e.g., Chaos) use organizationIdentifier instead.
     * STO uses accountId / orgId / projectId.
     * When `account` is set, an additional account param is injected from config.
     */
    scopeParams?: {
        account?: string;
        org?: string;
        project?: string;
    };
    /** Primary identifier field names: ["pipeline_id"], ["service_id"], etc. */
    identifierFields: string[];
    /** Additional filter fields for list operations */
    listFilterFields?: FilterFieldSpec[];
    /** Harness UI deep-link URL template */
    deepLinkTemplate?: string;
    /** Troubleshooting guidance for LLMs. Describes how to diagnose issues with this resource type. */
    diagnosticHint?: string;
    /**
     * Alternative search terms that should match this resource type.
     * Helps LLMs find SCS-specific types when searching with generic terms
     * like "artifact" or "repository". Matched at high priority (score 90)
     * in searchResources().
     */
    searchAliases?: string[];
    /**
     * Related resources that are commonly used together in multi-turn flows.
     * Helps LLMs understand the resource graph and retain context across turns.
     * Shown in harness_describe output.
     */
    relatedResources?: Array<{
        resourceType: string;
        relationship: string;
        description: string;
    }>;
    /** Execution guidance for LLMs. Describes how to discover and provide runtime inputs. */
    executeHint?: string;
    /** CRUD endpoint mappings */
    operations: Partial<Record<OperationName, EndpointSpec>>;
    /** Execute action mappings (e.g. run pipeline, toggle FF) */
    executeActions?: Record<string, EndpointSpec & {
        actionDescription: string;
    }>;
    /**
     * Product backend for this resource. Defaults to "harness" (uses HARNESS_BASE_URL).
     * Set to "fme" to use the Split.io API at https://api.split.io.
     */
    product?: ProductName;
    baseUrlOverride?: "fme";
    /**
     * When true, this resource uses header-based scoping (Harness-Account header)
     * instead of the standard `accountIdentifier` query param. Also prevents
     * automatic org/project injection into POST/PUT request bodies.
     * Used by SEI APIs which scope entirely via headers and query params.
     */
    headerBasedScoping?: boolean;
}
/**
 * A toolset groups related ResourceDefinitions together.
 */
export interface ToolsetDefinition {
    name: string;
    displayName: string;
    description: string;
    resources: ResourceDefinition[];
    /**
     * When true, this toolset is excluded by default (when HARNESS_TOOLSETS is
     * unset). Users must explicitly list it in HARNESS_TOOLSETS to enable it.
     * Useful for preview/experimental toolsets that shouldn't pollute the
     * default resource list.
     */
    optIn?: boolean;
}
//# sourceMappingURL=types.d.ts.map