import { VersionHistory } from '../../cache/versions.ts';
import { type SharedInput } from '../../io/async_line_iterator.ts';
import type { NetworkSetting } from '../../io/network.ts';
import type { AdmissionRules, Decision, HideReason, ProfileScripts } from '../../policy/types.ts';
import { type ProcessPermissions } from '../../process/config.ts';
import { type EnvEntries } from '../../secrets/config.ts';
import type { ShellArray } from '../../shell/array.ts';
import { Terminal, type JobOutput } from '../../shell/console/index.ts';
import type { Descriptor, StreamOwner } from '../../shell/descriptors.ts';
import type { JobTable, JobWaits } from '../../shell/job_table/index.ts';
import type { AliasExpansion } from '../../shell/types.ts';
import type { ShellVar } from '../../shell/variable.ts';
import type { Limit, MountMode } from '../../types.ts';
import { type Visibility } from '../../types.ts';
import { type IdSource } from '../../utils/ids.ts';
import type { StatusWriter } from '../types.ts';
import { type FunctionSite } from './functions.ts';
import { commandsToDict, type DecisionJSON, type ScriptJSON } from './serialize.ts';
/**
 * Read one entry of a session record, ignoring anything inherited from
 * `Object.prototype`. Shell names are script-controlled, so a plain
 * `record[name]` lookup would hand back `Object.prototype` (or one of
 * its methods) for a name like `__proto__` or `toString`; Python's dicts
 * have no such shadow, so this guard is the TypeScript side only.
 */
export declare function sessionEntry<T>(record: Record<string, T>, name: string): T | undefined;
/**
 * Write one entry of a session record as an own property. A plain
 * `record[name] = value` on the name `__proto__` runs the inherited
 * setter instead: it silently drops a string value and rewrites the
 * record's prototype for an array one.
 */
export declare function setSessionEntry<T>(record: Record<string, T>, name: string, value: T): void;
/**
 * A copy of `record` with a null prototype. Session records (env,
 * functions, arrays) hold script-controlled names, so they must not
 * inherit from `Object.prototype`: on a plain object, reading a name
 * like `toString` hands back an inherited function and assigning
 * `__proto__` runs the inherited setter instead of storing the value.
 * With no prototype, every name is an ordinary key. Python's dicts
 * need no equivalent.
 */
export declare function ownRecord<T>(record?: Record<string, T>): Record<string, T>;
export interface SessionInit {
    sessionId: string;
    cwd?: string;
    logicalCwd?: string | undefined;
    vars?: Record<string, ShellVar>;
    createdAt?: number;
    functions?: Record<string, string>;
    readonlyFunctions?: Set<string>;
    exportedFunctions?: Set<string>;
    lastExitCode?: number;
    positionalArgs?: string[];
    scriptName?: string | null;
    shellOptions?: Record<string, boolean>;
    /**
     * Per-mount mode caps for this session. `null` (the default) means
     * no restriction: every mount in the workspace is reachable at its own
     * mode. When provided, a mount absent from the map is invisible
     * (dispatch / handle_command / Files reject it with a capability error)
     * and a present mount is narrowed to the weaker of its own mode and
     * the session's mode. The workspace always implicitly grants its own
     * infrastructure mounts (implicit scratch root, observer, /dev).
     */
    mountModes?: ReadonlyMap<string, MountMode> | null;
    /**
     * What exists for this session: the profile's hides, shows, hidden
     * variables, process scope and allow list, compiled once. The views
     * and the op boundary read it; fork carries it, toJSON serializes.
     * A field left out hides nothing, as `DEFAULT_VISIBILITY` says.
     */
    visibility?: Partial<Visibility>;
    /**
     * The operator's reasons for grouped hides: never rendered to the
     * agent (a reason on ENOENT would confirm the path exists),
     * persisted so the host's read-back entry points survive a restart.
     */
    hideReasons?: readonly HideReason[];
    /**
     * The session's own command tier (`profiles.<n>.commands` tightened
     * by the inline document): allow patterns, ask and deny rules. A
     * durable restriction like visibility, so it persists.
     */
    commands?: AdmissionRules | null;
    /**
     * The profile's policy programs by method, run by ScriptPolicy at
     * that method. A durable restriction like commands, so it persists.
     */
    scripts?: ProfileScripts;
    /**
     * The name of the profile the session runs under, null for an
     * unrestricted session. What an owner-rendering command prints as the
     * group. Stamped by the profile like script, so it persists.
     */
    profile?: string | null;
    commandLimits?: Readonly<Record<string, Limit>>;
    /**
     * Where the session's lines may connect besides the workspace's
     * network, from its profile. A durable restriction like commands.
     */
    network?: NetworkSetting | null;
    processes?: ProcessPermissions;
    processId?: number | null;
    shellPid?: number | null;
    processDepth?: number;
    shellNesting?: number;
    /**
     * The host's standing answers to asked lines (design 3.9): session
     * state like functions and cwd, persisted, read and written through
     * the manager by id so a fork shares them, never another session's.
     */
    decisions?: readonly Decision[];
    generation?: number;
    lastBgJobId?: number | null;
}
/**
 * Variable records for a plain name/value map. The one conversion from
 * the shape an embedder speaks (a process environment) to the shape the
 * session stores.
 *
 * Every seeded name is exported, because a process environment is by
 * definition the exported set: these are the names the embedder means a
 * child runtime to inherit, and `envSnapshot` hands on only what carries
 * the attribute. Seeding them plain would leave them visible to `$X` and
 * invisible to every runtime, which is not what an embedder passing an
 * env record is asking for.
 */
export declare function varsFromEnv(env: Record<string, string>): Record<string, ShellVar>;
/**
 * Variable records for a stored session's two halves, the restore side
 * of `toJSON`. `env` carries every scalar and `attrs` the letter cluster
 * for the names that have one, so a name in `attrs` alone is bash's
 * declared-but-unset third state (`export Z`) and restores with no value.
 *
 * Not `varsFromEnv`: that one reads a bare record as a *process*
 * environment and exports all of it, which is right for an embedder
 * handing over an env record and wrong here, where the attributes were
 * recorded. Restoring through it promoted every plain `X=hello` to an
 * exported one on the first reload.
 */
export declare function varsFromDict(env: Record<string, string>, attrs: Record<string, string>): Record<string, ShellVar>;
/**
 * Variable records for a workspace env block.
 *
 * The declaration side of the env plane: a bare string is the literal
 * short form (exported, like `varsFromEnv`), a mapping is coerced
 * through `EnvVar`, and a managed entry becomes bash's third
 * state -- exported, unset -- carrying the pointer as `ManagedRef`.
 * After this translation the session vars are the only truth the fill
 * step reads.
 */
export declare function varsFromEntries(entries: EnvEntries): Record<string, ShellVar>;
/** The wire shape `varsToFields` writes and `varsFromFields` reads. */
export interface VarFields {
    env?: Record<string, string>;
    var_attrs?: Record<string, string>;
    managed?: Record<string, {
        from: string;
        ref: string;
        key: string;
        fetch?: string;
    }>;
}
/**
 * The stored shape of a bare variable table.
 *
 * The three keys a stored session writes (`toJSON`): `env` holds the
 * plain scalars, `var_attrs` the letter clusters, `managed` the
 * pointers -- and a managed name serializes as its pointer, never its
 * value, the same rule the session codec states. This exists for the
 * workspace env template, a variable table with no session around it,
 * so a snapshot or copy can carry the declaration.
 */
export declare function varsToFields(table: Record<string, ShellVar>): VarFields;
/**
 * The variable table a `varsToFields` payload restores.
 *
 * `varsFromDict` reads the two plain halves; each managed name then
 * restores declared-but-unfetched, its value forced back to null so a
 * payload that smuggles one in is discarded rather than trusted --
 * exactly how `fromJSON` restores a stored session's vars.
 */
export declare function varsFromFields(data: VarFields): Record<string, ShellVar>;
export declare class SessionState {
    versions: VersionHistory;
    sessionId: string;
    cwd: string;
    logicalCwd: string | undefined;
    vars: Record<string, ShellVar>;
    createdAt: number;
    functions: Record<string, string>;
    readonlyFunctions: Set<string>;
    exportedFunctions: Set<string>;
    lastExitCode: number;
    pipeStatus: readonly number[];
    functionNames: readonly string[] | null;
    pipeStatusPending: readonly number[] | null;
    statusWriter: StatusWriter | null;
    ids: IdSource;
    randomState: number | null;
    randomSeed: string | null;
    randomLast: number;
    positionalArgs: string[];
    scriptName: string | null;
    exitTrap: string | null;
    exitTrapInherited: boolean;
    errTrap: string | null;
    returnTrap: string | null;
    errTrapHidden: boolean;
    returnTrapHidden: boolean;
    errTrapRunning: boolean;
    returnTrapRunning: boolean;
    trapStatus: number | null;
    tty: Terminal;
    jobOutput: JobOutput | null;
    jobWaits: JobWaits | null;
    jobTable: JobTable | null;
    shellOptions: Record<string, boolean>;
    errexitImmune: boolean;
    errexitIgnored: boolean;
    errexitExiting: boolean;
    localVars: Map<string, ShellVar | null> | null;
    getoptsPos: number;
    getoptsOptind: number | null;
    shopts: Record<string, boolean>;
    aliases: Record<string, string>;
    aliasMarks: Map<string, Map<string, string | null>>;
    expandAliasesMarks: Map<string, boolean>;
    aliasExpansion: AliasExpansion | null;
    aliasView: Readonly<Record<string, string>> | null;
    parseSeq: number;
    parseCurrent: number;
    parseRow: number;
    functionSites: Map<string, FunctionSite>;
    readonly terminal: StreamOwner;
    lineOpen: boolean;
    umask: number;
    descriptors: Map<number, Descriptor>;
    execStdout: string | null;
    execStdoutAppend: boolean;
    execStdoutInput: SharedInput | null;
    execStderr: string | null;
    execStderrAppend: boolean;
    execStderrInput: SharedInput | null;
    execStdin: SharedInput | null;
    execStdinUnreadable: boolean;
    execStdinIdentity: string | null;
    borrowed: SharedInput[];
    localFrames: Map<string, ShellVar | null>[];
    reached: [string, Map<string, ShellVar | null>, ShellVar | null][];
    localRandom: (string | null)[];
    mountModes: ReadonlyMap<string, MountMode> | null;
    visibility: Visibility;
    hideReasons: readonly HideReason[];
    commands: AdmissionRules | null;
    scripts: ProfileScripts;
    profile: string | null;
    commandLimits: Readonly<Record<string, Limit>>;
    network: NetworkSetting | null;
    terminalOutput: boolean;
    processes: ProcessPermissions;
    processId: number | null;
    shellPid: number | null;
    processDepth: number;
    shellNesting: number;
    decisions: readonly Decision[];
    generation: number;
    lastBgJobId: number | null;
    constructor(init: SessionInit);
    /**
     * Return a copy of this session with `overrides` applied. Mutable
     * containers (env, functions, readonlyVars, arrays, positionalArgs)
     * are shallow-copied so mutations on the fork do not leak back into
     * the source. Every field — including capability fields like
     * `mountModes` — is propagated, so callers cannot accidentally
     * forget one when adding new fields.
     *
     * A caller that moves the fork with `cwd` supplies a physical path
     * with no typed spelling behind it, so the source's logical name is
     * dropped rather than left describing where the fork is not — the same
     * reasoning as `shell_dirs.setCwd`. Deciding it here rather than at
     * each call site is what keeps `execute({cwd})` from reporting the
     * persistent session's old directory from `pwd`. `??` cannot express
     * this, since the value being chosen is `undefined`.
     */
    fork(overrides?: Partial<SessionInit>): SessionState;
    /**
     * A child shell of this session: a fork that reads on from here. `fork`
     * copies what a session keeps; a child shell (a command substitution, a
     * subshell) also inherits the reader's position, the aliases being
     * expanded and the local frames, and reseeds `$RANDOM` on its first draw
     * instead of replaying this session's seed. Mirrors Python.
     */
    subshell(): SessionState;
    /**
     * Start `$RANDOM` on a new sequence at its next draw, rather than seed it
     * from the value the variable holds now.
     */
    private drawAfresh;
    /**
     * A new shell started from this session, as a nested `bash` is. bash runs
     * a nested shell as a program of its own, which inherits the working
     * directory, the umask, the open files and the environment: the exported
     * variables, as plain exported strings (no array, no other attribute), and
     * the functions `export -f` marked. The rest starts as a fresh shell's
     * does: the other variables and functions, the aliases, the `set` and
     * `shopt` options, `$?`, `$!`, `$RANDOM`'s sequence, `getopts`'s place,
     * the call stack, any test its caller is in (`if bash -ec 'false; ...'`
     * still ends at `false`) and the startup variables, which bash never reads
     * from its environment: IFS is dropped and `STARTUP_VALUES` restart. A
     * managed variable not yet fetched crosses as its pointer, which the
     * nested shell fetches through. Mirrors Python.
     */
    newShell(): SessionState;
    /** Remove a function with its definition site and export mark. */
    removeFunction(name: string): void;
    /**
     * What `$0` expands to. Null is the shell itself; a nested `bash`/`sh`
     * sets it to the script it is running, or to the name given after
     * `-c`. An empty name is a name, so it is not folded into the default:
     * GNU `bash -c 'echo "[$0]"' ""` prints `[]`.
     */
    get argv0(): string;
    /**
     * The scalar variables, by name.
     *
     * A frozen read-only projection of `vars`, not a container: a writer
     * goes through `SessionView.set` (or `seedVar` when seeding a session
     * before it is narrowed), so a `pre_session` policy sees every write.
     * `state.ts` has always documented that rule; freezing the projection
     * is what stops it being walked around by assigning into storage, and
     * an assignment into a plain object would land in a throwaway and
     * vanish -- silent loss is the exact failure this store removes.
     */
    get env(): Readonly<Record<string, string>>;
    /** The indexed arrays, by name. Read-only, like `env`. */
    get arrays(): Readonly<Record<string, ShellArray>>;
    /** The associative arrays, by name. Read-only, like `env`. */
    get assocs(): Readonly<Record<string, Record<string, string>>>;
    /** The names `readonly` has marked. Read-only, like `env`. */
    get readonlyVars(): ReadonlySet<string>;
    openInputs(): SharedInput[];
    /** Close the readers among `inputs` that this shell no longer names and did not inherit. */
    releaseInputs(inputs: SharedInput[]): Promise<void>;
    /**
     * Close the readers this child shell opened, as it ends; the ones it
     * inherited stay with the shell that opened them. Mirrors Python's
     * close_inputs.
     */
    closeInputs(): Promise<void>;
    /**
     * The durable-field payload the session table and snapshots persist.
     * Keys are snake_case, byte-identical to Python's `SessionState.to_dict`,
     * so both languages can share one store (a py daemon creates the
     * session, a node kernel tier binds it).
     */
    toJSON(): Record<string, unknown>;
    toDict(): Record<string, unknown>;
    static fromDict(data: {
        session_id: string;
        cwd?: string;
        env?: Record<string, string>;
        var_attrs?: Record<string, string>;
        managed?: Record<string, {
            from: string;
            ref: string;
            key: string;
            fetch?: string;
        }> | null;
        created_at?: number;
        mount_modes?: Record<string, MountMode> | null;
        hidden_paths?: {
            paths?: string[];
            patterns?: string[];
        } | null;
        shown_paths?: {
            entries?: {
                path: string;
                mode?: MountMode;
            }[];
        } | null;
        hide_reasons?: {
            patterns?: string[];
            reason?: string;
        }[] | null;
        hidden_vars?: {
            names?: string[];
            patterns?: string[];
        } | null;
        commands?: ReturnType<typeof commandsToDict> | null;
        scripts?: Record<string, ScriptJSON[]> | null;
        profile?: string | null;
        command_limits?: unknown;
        network?: NetworkSetting | null;
        processes?: ProcessPermissions;
        decisions?: DecisionJSON[] | null;
        generation?: number;
        functions?: Record<string, string>;
        readonly_functions?: string[];
        exported_functions?: string[];
    }): SessionState;
}
//# sourceMappingURL=session.d.ts.map