import { type MergeableRecord } from './util/objects';
import { type LogLevelName } from './util/log';
import Joi from 'joi';
import type { BuiltInDefinitions } from './dataflow/environments/built-in-config';
import type { KnownParser } from './r-bridge/parser';
import type { DeepPartial, DeepWritable, Paths, PathValue } from 'ts-essentials';
import type { DataflowProcessors } from './dataflow/processor';
import type { ParentInformation } from './r-bridge/lang-4.x/ast/model/processing/decorate';
import type { FlowrAnalyzerContext } from './project/context/flowr-analyzer-context';
import { ProjectKind } from './project/context/project-kind';
import type { BuiltInFlowrPluginArgs, BuiltInFlowrPluginName } from './project/plugins/plugin-registry';
import { type FlowrGasConfig } from './gas';
import type { InputClassifierConfig } from './queries/catalog/input-sources-query/simple-input-classifier';
export declare enum VariableResolve {
    /** Don't resolve constants at all */
    Disabled = "disabled",
    /** Use alias tracking to resolve */
    Alias = "alias",
    /** Only resolve directly assigned builtin constants */
    Builtin = "builtin"
}
/**
 * How a constrained dependency (e.g. `Imports: quantmod (>= 0.4-9)`) is resolved to a concrete version
 * against the signature database (see `solver.sigdb.versionSelection`).
 */
export declare enum VersionSelection {
    /** Resolve to the newest version satisfying the constraint (default; preserves the historic behavior). */
    Newest = "newest",
    /** Resolve to the oldest version satisfying the constraint. */
    Oldest = "oldest",
    /** Resolve to the version installed on the analyzing system (needs R; falls back to `newest` when unavailable). */
    System = "system"
}
/**
 * How to infer the working directory from a script
 */
export declare enum InferWorkingDirectory {
    /** Don't infer the working directory */
    No = "no",
    /** Infer the working directory from the main script */
    MainScript = "main-script",
    /** Infer the working directory from the active script */
    ActiveScript = "active-script",
    /** Infer the working directory from any script */
    AnyScript = "any-script"
}
/**
 * How to handle fixed strings in a source path
 */
export declare enum DropPathsOption {
    /** Don't drop any parts of the sourced path */
    No = "no",
    /** try to drop everything but the filename */
    Once = "once",
    /** try to drop every folder of the path */
    All = "all"
}
export interface FlowrLaxSourcingOptions extends MergeableRecord {
    /**
     * search for filenames matching in the lowercase
     */
    readonly ignoreCapitalization: boolean;
    /**
     * try to infer the working directory from the main or any script to analyze.
     */
    readonly inferWorkingDirectory: InferWorkingDirectory;
    /**
     * Additionally search in these paths
     */
    readonly searchPath: string[];
    /**
     * Allow to drop the first or all parts of the sourced path,
     * if it is relative.
     */
    readonly dropPaths: DropPathsOption;
    /**
     * How often the same file can be sourced within a single run?
     * Please be aware: in case of cyclic sources this may not reach a fixpoint so give this a sensible limit.
     */
    readonly repeatedSourceLimit?: number;
    /**
     * sometimes files may have a different name in the source call (e.g., due to later replacements),
     * with this setting you can provide a list of replacements to apply for each sourced file.
     * Every replacement consists of a record that maps a regex to a replacement string.
     * @example
     * ```ts
     * [
     *      { }, // no replacement -> still try the original name/path
     *      { '.*\\.R$': 'main.R' }, // replace all .R files with main.R
     *      { '\s' : '_' }, // replace all spaces with underscores
     *      { '\s' : '-', 'oo': 'aa' }, // replace all spaces with dashes and oo with aa
     * ]
     * ```
     *
     * Given a `source("foo bar.R")` this configuration will search for (in this order):
     * - `foo bar.R` (original name)
     * - `main.R` (replaced with main.R)
     * - `foo_bar.R` (replaced spaces)
     * - `faa-bar.R` (replaced spaces and oo)
     */
    readonly applyReplacements?: Record<string, string>[];
    /** Assume a sourced file is always there, making what it defines certain instead of conditional on the `source` call. */
    readonly assumeFilesExist?: boolean;
}
export type ConfigPlugin<T extends BuiltInFlowrPluginName | string> = T | string | (T extends BuiltInFlowrPluginName ? [T, BuiltInFlowrPluginArgs<T>] : [string, unknown[]]);
/** One {@link FlowrConfig.specializeConfig} entry: a config overwrite, optionally `inherit`ing another kind's overwrite (own keys win). */
export type SpecializeConfigEntry = DeepPartial<FlowrConfig> & {
    readonly inherit?: ProjectKind;
};
/**
 * The configuration file format for flowR.
 * @see {@link FlowrConfig.default} for the default configuration.
 * @see {@link FlowrConfig.Schema} for the Joi schema for validation.
 */
export interface FlowrConfig extends MergeableRecord {
    readonly logLevel?: LogLevelName;
    /**
     * Whether source calls should be ignored, causing {@link processSourceCall}'s behavior to be skipped
     */
    readonly ignoreSourceCalls: boolean;
    /**
     * Whether load calls should be ignored, causing {@link processLoadCall}'s behavior to be skipped
     */
    readonly ignoreLoadCalls: boolean;
    /** Configure language semantics and how flowR handles them */
    readonly semantics: {
        /** Semantics regarding the handling of the environment */
        readonly environment: {
            /** Do you want to overwrite (parts) of the builtin definition? */
            readonly overwriteBuiltIns: {
                /** Should the default configuration still be loaded? */
                readonly loadDefaults?: boolean;
                /** The definitions to load */
                readonly definitions: BuiltInDefinitions;
            };
        };
    };
    /** Plugins to load by default when creating a new FlowrAnalyzer */
    readonly defaultPlugins: ConfigPlugin<string>[];
    /** Configuration options for the REPL */
    readonly repl: {
        /** Whether to show quick stats in the REPL after each evaluation */
        quickStats: boolean;
        /** This instruments the dataflow processors to count how often each processor is called */
        dfProcessorHeat: boolean;
        /** Whether to show dim inline hints (e.g. `:help`) on the empty prompt; automatically disabled on non-interactive terminals */
        hints: boolean;
        /** Plugins to load in REPL mode */
        plugins: (ConfigPlugin<string> | 'flowr:default')[];
        /** Automatically use the file protocol for inputs that look like paths (default `true`) */
        autoUseFileProtocol?: boolean;
        /** Whether `:query` closes with the line stating how long the queries took (default `true`, `:query*` never prints it) */
        queryStats?: boolean;
        /** Whether `:version` grays out the plugins that did not activate during the last analysis (default `false`) */
        showPlugins?: boolean;
    };
    readonly project: {
        /** Whether to resolve unknown paths loaded by the r project disk when trying to source/analyze files */
        resolveUnknownPathsOnDisk: boolean;
        /** Whether a directory that cannot be traversed during file discovery (e.g. due to permissions) aborts the analysis; when `false` (the default) such paths are logged and skipped. */
        failOnInaccessiblePath?: boolean;
        /** Overwrite the {@link ProjectKind} flowR would otherwise infer from the analyzed files, e.g. when auto-detection guesses wrong. */
        useProjectType?: ProjectKind;
        /**
         * The packages considered part of R itself, used e.g. by the project query to classify dependencies. If
         * unset, flowR derives them (for the assumed R version) from the signature database via `baseRPackages`.
         */
        basePackages?: string[];
        /**
         * Files a framework loads on its own, without any `source()` call (e.g. `global.R` in a shiny app), in load
         * order. Entries are case-insensitive globs (`R/*.R`) matched against the path, a plain name matches any file
         * with that name; entries matching nothing are warned about. Usually set per {@link ProjectKind} via
         * {@link FlowrConfig.specializeConfig}.
         */
        implicitSources?: string[];
        /** Scoping options for the default project discovery. */
        discovery?: {
            /** Collect every file below the project root (greedy) instead of only the files the detected {@link ProjectKind} needs (default `false`). */
            full?: boolean;
            /** Per-{@link ProjectKind} include/exclude glob overrides layered on the default scoping. */
            perKind?: Partial<Record<ProjectKind, {
                include?: string[];
                exclude?: string[];
            }>>;
            /** Case-insensitive globs that drop matching files from the intelligent discovery, regardless of kind (e.g. `.Renviron` to ignore environment files). */
            ignore?: string[];
        };
        /** Overrides for the signals flowR uses to classify the {@link ProjectKind}; unset fields keep the built-in defaults. */
        classification?: {
            /** DESCRIPTION `Type:` values that mark a shiny app (default `shiny`, `shiny-app`, `shinyapp`). */
            shinyDescriptionTypes?: string[];
            /** File names a shiny app is assembled from (default `app.R`, `ui.R`, `server.R`, `global.R`). */
            shinyEntryFiles?: string[];
            /** Regex source evidencing shiny usage in an entry file. */
            shinyUsagePattern?: string;
            /** File extensions marking a notebook (default `ipynb`, `rmd`, `rmarkdown`, `qmd`, `rnw`). */
            notebookExtensions?: string[];
        };
    };
    /** Linter configuration, usually specialized per {@link ProjectKind} via {@link FlowrConfig.specializeConfig}. */
    readonly linter: {
        /** Rule names excluded from the *default* rule set (a rule requested explicitly still runs). */
        readonly disabledRules: string[];
    };
    /**
     * Teaches the {@link InputSourcesQuery|input-sources} analysis (and with it the `problematic-inputs` linter)
     * about further frameworks. Everything here is *added* to what flowR already knows, so a shiny app keeps its
     * `input` even when you declare your own. Usually set per {@link ProjectKind} via {@link specializeConfig}.
     * @see {@link InputClassifierConfig} - for what the entries mean
     */
    readonly inputSources?: DeepWritable<InputClassifierConfig<string[]>>;
    /**
     * Overwrite (parts of) this configuration depending on the {@link ProjectKind} flowR detects for the project,
     * e.g. to give a shiny app its implicit sources. An entry may `inherit` another kind's overwrite (merged first,
     * with the entry's own keys winning) to avoid repeating it. Resolve it with {@link FlowrConfig.forKind}.
     */
    readonly specializeConfig?: Partial<Record<ProjectKind, SpecializeConfigEntry>>;
    /**
     * The engines to use for interacting with R code. Currently, supports {@link TreeSitterEngineConfig} and {@link RShellEngineConfig}.
     * An empty array means all available engines will be used.
     */
    readonly engines: EngineConfig[];
    /**
     * The default engine to use for interacting with R code. If this is undefined, an arbitrary engine from {@link engines} will be used.
     */
    readonly defaultEngine?: EngineConfig['type'];
    /** How to resolve constants, constraints, cells, … */
    readonly solver: {
        /**
         * How to resolve variables and their values
         */
        readonly variables: VariableResolve;
        /**
         * Should we include eval(parse(text="...")) calls in the dataflow graph?
         */
        readonly evalStrings: boolean;
        /**
         * Track user-created environments (`new.env()`, `assign(..., envir=e)`, `get(..., envir=e)`,
         * `local({}, envir=e)`, `e$x <- v`, `attach(e)`) with precise per-variable envState.
         * When disabled all envir-style calls fall through to the conservative global treatment.
         */
        readonly trackEnvironments: boolean;
        /** Resolving `library()`/`use()` exports from a signature database (e.g. the bundled `flowr-sigdb`). */
        readonly sigdb: {
            /** Resolve library exports from a signature database (default `true`); when `false` no database is consulted. */
            readonly enabled: boolean;
            /** Load the project's declared dependencies from its metadata files (`DESCRIPTION` Imports/Depends, `rproject.toml`, `uvr.toml`, `renv.lock`, `rv.lock`, `uvr.lock`) into the dependency context (default `true`); when `false` these files are not read, so neither the undefined-symbol linter nor {@link linkDescriptionDependencies} sees any project-declared dependency. */
            readonly loadProjectDependencies: boolean;
            /** Parse the database up front rather than on the first package load (default `false`, ignored if disabled). */
            readonly eagerlyLoad: boolean;
            /** Add a vertex for every export on load rather than on demand (default `false`); keeps the graph small. */
            readonly eagerlyLoadExports: boolean;
            /**
             * The R version analysis assumes when resolving versioned (base-R) package exports: a pin like `"4.5"`,
             * or `"auto"` to detect the locally installed R (falling back to {@link DefaultAssumedRVersion} when the
             * engine reports none, e.g. the tree-sitter engine). Resolve it with {@link resolveAssumedRVersion}.
             */
            readonly assumedRVersion?: string;
            /** Eagerly attach base-R namespaces (from a signature database) so bare base calls resolve without `library()` (default `false`; changes every analysis; needs a base-R signature database). */
            readonly linkBaseR: boolean;
            /** Eagerly attach the namespaces of the project's declared `DESCRIPTION` dependencies (Imports/Depends) so their exports resolve without an explicit `library()` (default `false`; changes every analysis; needs a signature database resolving the declared packages). */
            readonly linkDescriptionDependencies: boolean;
            /** Add a lightweight `Reads` edge from a bare base-R call to its signature-database function vertex (`built-in:pkg:fn`); base-R qualification stays edge-free unless this is on (default `false`; adds edges to every base call). */
            readonly linkBaseRCalls?: boolean;
            /** Add a lightweight `Reads` edge from a resolved package call (`pkg::fn`/attached export) to its signature-database function vertex (default `false`). */
            readonly linkPackageCalls?: boolean;
            /** Decompress the hot shards (base + most-downloaded) in a background task on startup, so the first `library()` lookup is warm (default `false`; useful for long-running servers/REPLs, not one-shot runs). */
            readonly warmInBackground?: boolean;
            /** Extra directories (or bundle/manifest files) searched for signature databases, alongside the shipped default and `$FLOWR_SIGDB_DIR`. A downloaded full-history bundle placed here is mounted automatically. */
            readonly additionalPaths?: string[];
            /** GitHub `owner/repo` the full-history bundle is downloaded from (`:signature download`); default `flowr-analysis/flowr`, release tag `sigdb-v<flowR-version>`. */
            readonly downloadRepo?: string;
            /** On startup, compare the cache against the committed `sigdb.remote.json` link file and re-download changed shards in the background (default `false`; needs network, so opt-in — a `git pull` that updates the pointer then re-syncs automatically). */
            readonly autoSync?: boolean;
            /** When a project constrains a dependency, resolve to the `newest` (default) or `oldest` version satisfying the constraint, or the `system`-installed version (needs R; falls back to `newest` when unavailable). Base-R packages always resolve against the assumed R version. */
            readonly versionSelection?: VersionSelection;
            /** Force an exact version for specific packages (mapping a package name to a version), overriding both the project constraint and the {@link versionSelection} policy; a version missing from the database falls back with a warning (default `{}`). */
            readonly versionOverrides?: Record<string, string>;
            /**
             * Recovering a package no signature database knows (a CRAN-archived one like `maptools`) from the copy
             * installed on this machine: its `DESCRIPTION` states the version, its `NAMESPACE` the exports. Opt-in,
             * as it reads directories outside the analyzed project and ties the analysis to what is installed here.
             */
            readonly installedLibrary?: {
                /** Consult installed packages at all (default `false`). */
                readonly enabled: boolean;
                /** The library directories to search; when empty they are discovered as configured below (default `[]`). */
                readonly paths?: string[];
                /** Search the libraries `R_LIBS_USER`/`R_LIBS`/`R_LIBS_SITE` name (default `true`, ignored when {@link paths} is given). */
                readonly useEnvironment?: boolean;
                /** Search a project-local `renv`/`packrat` library (default `true`, ignored when {@link paths} is given). */
                readonly useProjectLibrary?: boolean;
                /** How far to descend into the nested layout of a project-local library (default `3`). */
                readonly maxDepth?: number;
                /** Only recover packages whose name matches one of these regular expressions; empty means any (default `[]`). */
                readonly packages?: string[];
            };
        };
        /** Policies for reasoning about dependency versions (independent of how the signature database is loaded). */
        readonly versionManagement?: {
            /** Groups of packages that must resolve to the same version (like the base packages, which share the R version); version guessing intersects each group so its members stay mutually compatible (default `[]`). */
            readonly linkedVersionGroups?: string[][];
        };
        /** These keys are only intended for use within code, allowing to instrument the dataflow analyzer! */
        readonly instrument: {
            /**
             * Modify the dataflow processors used during dataflow analysis.
             * Make sure that all processors required for correct analysis are still present!
             * This may have arbitrary consequences on the analysis precision and performance, consider focusing on decorating existing processors instead of replacing them.
             */
            dataflowExtractors?: (extractor: DataflowProcessors<ParentInformation>, ctx: FlowrAnalyzerContext) => DataflowProcessors<ParentInformation>;
        };
        /**
         * If lax source calls are active, flowR searches for sourced files much more freely,
         * based on the configurations you give it.
         * This option is only in effect if {@link ignoreSourceCalls} is set to false.
         */
        readonly resolveSource?: FlowrLaxSourcingOptions;
        /**
         * The configuration for flowR's slicer
         */
        slicer?: {
            /**
             * The maximum number of iterations to perform on a single function call during slicing
             */
            readonly threshold?: number;
            /**
             * If set, the slicer will gain an additional post-pass
             */
            readonly autoExtend?: boolean;
        };
    };
    /**
     * Configuration options for abstract interpretation
     */
    readonly abstractInterpretation: {
        /**
         * The threshold for the number of visitations of a node at which widening should be performed to ensure the termination of the fixpoint iteration
         */
        readonly wideningThreshold: number;
        /**
         * The configuration of the shape inference for data frames
         */
        readonly dataFrame: {
            /**
             * The maximum number of columns names to infer for data frames before over-approximating the column names to top
             */
            readonly maxColNames: number;
            /**
             * Configuration options for reading data frame shapes from loaded external data files, such as CSV files
             */
            readonly readLoadedData: {
                /**
                 * Whether data frame shapes should be extracted from loaded external data files, such as CSV files
                 */
                readonly readExternalFiles: boolean;
                /**
                 * The maximum number of lines to read when extracting data frame shapes from loaded files, such as CSV files
                 */
                readonly maxReadLines: number;
            };
        };
    };
    readonly incremental: {
        /**
         * Always take the incremental path, regardless of heuristics
         */
        readonly alwaysIncremental: boolean;
        readonly parsing: {
            readonly activated: boolean;
            readonly heuristics: {
                readonly activated: boolean;
                /**
                 * Skip reparsing entirely if the file's modification time is unchanged since the last parse
                 */
                readonly mtime: boolean;
                /**
                 * Only consider incremental parsing for files with at least this many lines
                 */
                readonly linesFrom: number;
                /**
                 * Only consider incremental parsing for files with at least this many bytes
                 */
                readonly bytesFrom: number;
                /**
                 * Always take the incremental path whenever there is a computed edit region, regardless of the other thresholds
                 */
                readonly alwaysWithEdits: boolean;
                /**
                 * Only apply these heuristics once the project has at least this many files loaded
                 */
                readonly minFiles: number;
            };
        };
    };
    /**
     * Resource-usage guard (gas) configuration.
     * Gas checks are disabled by default (all feature factors are `0`).
     * Set a `feature factor > 0` to enable checking for that feature.
     * @see {@link FlowrGasConfig}
     * @see {@link ReadOnlyFlowrAnalyzerGasContext}
     */
    readonly gas: FlowrGasConfig;
}
export type ValidFlowrConfigPaths = Paths<FlowrConfig, {
    depth: 9;
}>;
/** Whether library exports should be resolved from a signature database (`solver.sigdb.enabled`). */
export declare function isSigDbEnabled(config: FlowrConfig | undefined): boolean;
/**
 * R version assumed for analysis when `solver.sigdb.assumedRVersion` is `"auto"` and none could be detected.
 * Kept in step with the newest base-R release in the bundled sigdb (see `newestRVersion` in the generated
 * base-package cache) so the default hits the precomputed base-package fast path.
 */
export declare const DefaultAssumedRVersion = "4.5.3";
/**
 * The R version analysis should assume when resolving versioned (base-R) exports (see `solver.sigdb.assumedRVersion`):
 * an explicit pin wins, otherwise a real `detected` version (from the engine's `rVersion()`, ignoring `none`/`unknown`),
 * otherwise {@link DefaultAssumedRVersion}. Pure and synchronous, so a resolver can call it per lookup.
 */
export declare function resolveAssumedRVersion(config: FlowrConfig | undefined, detected?: string): string;
export interface TreeSitterEngineConfig extends MergeableRecord {
    readonly type: 'tree-sitter';
    /**
     * The path to the tree-sitter-r WASM binary to use. If this is undefined, {@link DEFAULT_TREE_SITTER_R_WASM_PATH} will be used.
     */
    readonly wasmPath?: string;
    /**
     * The path to the tree-sitter WASM binary to use. If this is undefined, the path specified by the tree-sitter package will be used.
     */
    readonly treeSitterWasmPath?: string;
    /**
     * Whether to use the lax parser for parsing R code (allowing for syntax errors). If this is undefined, the strict parser will be used.
     */
    readonly lax?: boolean;
}
export interface RShellEngineConfig extends MergeableRecord {
    readonly type: 'r-shell';
    /**
     * The path to the R executable to use. If this is undefined, {@link DEFAULT_R_PATH} will be used.
     */
    readonly rPath?: string;
}
export type EngineConfig = TreeSitterEngineConfig | RShellEngineConfig;
export type KnownEngines = {
    [T in EngineConfig['type']]?: KnownParser;
};
export declare const FlowrDefaultPlugins: string[];
export declare const FlowrConfig: {
    readonly name: "FlowrConfig";
    /**
     * The default configuration for flowR, used when no config file is found or when a config file is missing some options.
     * You can use this as a base for your own config and only specify the options you want to change.
     */
    readonly default: (this: void) => FlowrConfig;
    /**
     * The Joi schema for validating a config file, use this to validate your config file before using it. You can also use this to generate documentation for the config file format.
     */
    readonly Schema: Joi.ObjectSchema<any>;
    /**
     * Parses the given JSON string as a flowR config file, returning the resulting config object if the parsing and validation were successful, or `undefined` if there was an error.
     */
    readonly parse: (this: void, jsonString: string) => FlowrConfig | undefined;
    /**
     * Creates a new flowr config that has the updated values.
     */
    readonly amend: (this: void, config: FlowrConfig, amendmentFunc: (config: DeepWritable<FlowrConfig>) => FlowrConfig | void) => FlowrConfig;
    /**
     * Clones the given flowr config object.
     */
    readonly clone: (this: void, config: FlowrConfig) => FlowrConfig;
    /**
     * Loads the flowr config from the given file or the default locations.
     * Please note that you can also use this without a path parameter to
     * infer the config from flowR's default locations.
     * This is mostly useful for user-facing features.
     */
    readonly fromFile: (this: void, configFile?: string, configWorkingDirectory?: string) => FlowrConfig;
    /**
     * Resolves the configuration for the given {@link ProjectKind} by applying the matching
     * {@link FlowrConfig.specializeConfig} entry to every key it names. What you configured wins over the entry, which in
     * turn wins over flowR's default; a value that differs from the default counts as configured.
     * Returns `config` itself if the kind has no entry, so callers can use this freely.
     */
    readonly forKind: (this: void, config: FlowrConfig, kind: ProjectKind) => FlowrConfig;
    /** The overwrite {@link FlowrConfig.forKind} applies for `kind` (with {@link SpecializeConfigEntry.inherit} resolved), or `undefined`. */
    readonly specializationFor: (this: void, config: FlowrConfig, kind: ProjectKind) => DeepPartial<FlowrConfig> | undefined;
    /**
     * Gets the configuration for the given engine type from the config.
     */
    readonly getForEngine: <T extends EngineConfig["type"]>(this: void, config: FlowrConfig, engine: T) => (EngineConfig & {
        type: T;
    }) | undefined;
    /**
     * Every key `config` changed against the {@link FlowrConfig.default|default}, as `a.b.c=<json>` lines.
     * A whole configuration is a long document while an edit to it is usually one line, which is what makes
     * this the form to hand around: a link, a command line, a bug report.
     * @see {@link FlowrConfig.applyPaths} - to read them back
     * @example
     * ```ts
     * FlowrConfig.changedPaths(config); // ['solver.sigdb.enabled=false']
     * ```
     */
    readonly changedPaths: (this: void, config: FlowrConfig) => string[];
    /**
     * The inverse of {@link FlowrConfig.changedPaths}: the default configuration with those keys set again.
     * A line that names no known key, or whose value is not readable, is skipped rather than guessed at.
     */
    readonly applyPaths: (this: void, paths: Iterable<string>, base?: FlowrConfig) => FlowrConfig;
    /**
     * Returns a new config object with the given value set at the given key, where the key is a dot-separated path to the value in the config object.
     * @see {@link setInConfigInPlace} for a version that modifies the config object in place instead of returning a new one.
     * @example
     * ```ts
     * const config = FlowrConfig.default();
     * const newConfig = FlowrConfig.setInConfig(config, 'solver.variables', VariableResolve.Builtin);
     * console.log(config.solver.variables); // Output: "alias"
     * console.log(newConfig.solver.variables); // Output: "builtin"
     * ```
     */
    readonly setInConfig: <Path extends ValidFlowrConfigPaths>(this: void, config: FlowrConfig, key: Path, value: PathValue<FlowrConfig, Path>) => FlowrConfig;
    /**
     * Modifies the given config object in place by setting the given value at the given key, where the key is a dot-separated path to the value in the config object.
     * @see {@link setInConfig} for a version that returns a new config object instead of modifying the given one in place.
     */
    readonly setInConfigInPlace: <Path extends ValidFlowrConfigPaths>(this: void, config: FlowrConfig, key: Path, value: PathValue<FlowrConfig, Path>) => void;
};
/** Path to the user-global `flowr.json`, read as a fallback when no project config is found. */
export declare function globalConfigFilePath(): string;
/** Persist `dbPath` into `solver.sigdb.additionalPaths` in the global config (creating it, preserving the user's raw JSON); idempotent, returns the file written. */
export declare function persistSigDbPathToGlobalConfig(dbPath: string): string;
