import type { SessionManager } from '../workspace/session/manager.ts'; import type { Session } from '../workspace/session/session.ts'; import type { Policies } from '../policy/policies.ts'; import type { EntryGate, PathSpec } from '../types.ts'; import { MountMode } from '../types.ts'; /** * Bind `session` for the duration of `fn`. * * `owner` names the manager the session belongs to; omitting it keeps * the owner already bound, so a nested bind inside a line (a * background job's fork) stays attributed to the workspace running it. */ export declare function runWithSession(session: Session, fn: () => Promise, owner?: SessionManager): Promise; export declare function getCurrentSession(): Session | null; /** * Every session whose binding is live in this context, oldest first. * * On an isolating runtime this is the bound session alone, so a fold * over it computes exactly what `getCurrentSession` implies. On the * fallback storage it is every concurrently bound session, which is * what lets a security predicate merge toward the most restrictive * answer instead of trusting the newest binding: every predicate here * fails open on "no session", so a frame another task shadows or * settles past must keep counting while it is live. */ export declare function liveSessions(): Session[]; /** * The bound session, but only when `owner` published it. * * A session carries one workspace's cwd, env and mount grants, so a * second workspace re-entered mid-line must resolve its own session * rather than adopt this one. The owner is the disambiguator, so every * live binding is searched, newest first: on the fallback storage a * concurrent workspace's bind shadowing the newest frame must not hide * this owner's own session. */ export declare function getCurrentSessionFor(owner: SessionManager): Session | null; /** * Whether the current session hides any paths at all. * * For a summarizing fast path (du -s asks the backend for one total) * that must not be trusted when hidden leaves could be inside it. Show * entries do not trip it: a show without a covering hide restricts * nothing, and modes never change what a walk enumerates. */ export declare function hiddenPathsActive(): boolean; /** * Whether the current session hides anything at or under this path: * the per-operand form of `hiddenPathsActive`. * * The native fast paths (find's native op, du's summarize total) * classify the raw backend tree, so they fork to the guarded walk when * a hide could cover an entry inside the subtree they answer for, and * stay on when none can: one hidden `.env` under `/repo` must not * force `find` on `/s3` off its native op. */ export declare function hiddenPathsIntersect(virtual: string): boolean; export declare const DEFAULT_UMASK = 18; /** * The file-creation mask of the session bound to this context, read by * the creators that run inside a command handler (`mkdir`, which cannot * be handed the session) the way `pathAllowed` reads the hidden-paths * spec. bash's default when no session is bound; ORed across live * sessions otherwise, since a mask can only clear more bits, failing * toward the tighter mode. */ export declare function sessionUmask(): number; /** * Whether the bound session's `shopt -s dotglob` is on. Read inside * pathname expansion, which runs in every backend's resolveGlob and so * cannot be handed the session: a name starting with `.` is matched * only by a pattern that also starts with `.`, unless dotglob relaxes * it. False when no session is bound (bash's default), and unanimous * across live sessions otherwise: dotfiles entering a match set is the * surprising direction, so one session's opt-in must not widen a * concurrent one's expansion. */ export declare function dotglobActive(): boolean; /** * Whether a session's path axis leaves this path visible: its hides, * re-opened where a deeper show entry says so. The explicit-session * form of `pathAllowed`, for a door that holds the session rather than * running under it: the admission gate drops a hidden operand before * any policy reads it, so a rule or an ask never names a path the * session cannot see. */ export declare function sessionPathAllowed(sess: Session, virtual: string): boolean; /** * Whether the current session's hides leave this path visible: * enumeration surfaces filter names through it and the doors answer * ENOENT (EACCES for creates) when it says no, so hiding reads as * nonexistence, never as a denial that leaks the name. True when no * session is bound. This is how a profile keeps a session away from a * mount, since naming mounts only narrows their modes. Every live * session must leave the path visible, so on the fallback storage a * hide stays in force while its command's frame is shadowed, and a * concurrent settle cannot wipe it into visibility. */ export declare function pathAllowed(virtual: string): boolean; /** * Bind the admitted command's entry gate for the duration of `fn`: the * run of that one command. * * Bound by the dispatcher once the gate let the command through, so a * nested line (`xargs`, `find -exec`, `eval`) binds its own and the outer * command gets its gate back when it returns, and a pipeline stage in * its own async context never sees a sibling's. */ export declare function runWithAdmission(gate: EntryGate, fn: () => Promise): Promise; /** * The entry gate of the command running in this context, null when no * admitted command is bound (a command constructed outside the * dispatcher, or a line no gate judged). * * On an isolating runtime one gate is live and answers as bound. On * the fallback storage several commands' gates can be live at once * with nothing to say whose op is asking, so they merge toward * refusal: an entry must pass every live gate's `check`, a rule counts * as granted only when every live gate carries it (a once-grant nodded * for one line must not authorize another's op door), and `scoped` is * true when any live gate scopes, keeping walks off the unfiltered * native fast paths. */ export declare function getAdmission(): EntryGate | null; /** * Whether a path rule in force reads the running command's paths. * * The twin of `hiddenPathsActive` for the rule arms: a backend's native * find or du classifies the raw tree, so an entry a rule refuses would be * listed or summed past the gate; the readdir walk passes every entry * through it instead. False when no admitted command is bound. */ export declare function pathRulesActive(): boolean; /** * Bind the workspace's admission policies for the duration of `fn`: * the run of one command. * * Bound by command dispatch around routing, the same window the * admission gate binds in, so the command tier's policy guard can fire * `preOps` for the backend I/O a handler performs. Read at wrap or * call time by `withPolicyGuard`; unset outside a dispatched command * (a generic invoked directly in a test), where the guard is inert. */ export declare function runWithOpPolicies(policies: Policies, fn: () => Promise): Promise; /** * Unbind the op policies for the duration of `fn`: a delegated * sub-command whose door the caller has already cleared. * * find's `-delete` admits each removal itself, in find's own refusal * voice, and then delegates the mutation to `rm`; without the * suspension the delegated slot would admit the same deletion a second * time, so a counting or budget policy would see one removal twice. */ export declare function runWithSuspendedOpPolicies(fn: () => Promise): Promise; /** * The policies bound to the running command, null outside one. * * The newest live armed set. On an isolating runtime the live set is * the innermost binding, so a suspension answers null exactly as * bound. On the fallback storage a suspension yields to any * concurrently armed frame, because disarming another command's op * doors is the worse failure: find's delegated `rm` then double-admits * its removal (an over-count, failing closed) instead of a concurrent * command's ops running unguarded. */ export declare function getOpPolicies(): Policies | null; /** * Bind the executing mount's prefix and configured mode for the * duration of `fn`: the run of one command. * * Bound by `Mount.executeCmd` around the handler, so the mode guard on * the command tier's I/O can resolve `effectivePathMode` for every path * a handler mutates: the write-command gate admits a command when any * shown subtree grants writes, and this binding is how each individual * write is then held to its own region's mode. */ export declare function runWithMountGate(prefix: string, mode: MountMode, fn: () => Promise): Promise; /** * The gate of the mount serving `virtual`: its [prefix, configured * mode], null outside a mount's command (a generic invoked directly in * a test, or the scratch tier). * * The reader selects among every live gate by the path itself: the * longest prefix covering it wins, the way the mount table routes, and * two live gates at one prefix (two workspaces sharing a fallback * runtime) answer with the weaker mode, failing toward refusal. On an * isolating runtime one binding is live and every caller asks about a * path that mount serves; on the fallback storage (a browser with no * AsyncLocalStorage) overlapping commands on different mounts hold * gates concurrently, and the path is what keeps one from being judged * against the other's. A path no live gate covers answers null, the * same inert reading an unbound context gives. */ export declare function mountGateFor(virtual: string): readonly [string, MountMode] | null; /** * Bind a statement's expanded redirect targets to the command node they * belong to, for the duration of `fn` (that node's run). * * The redirect layer expands the targets before the command executes (a * `$()` in one runs exactly once there), so the admission gate deep in * command dispatch cannot re-derive them; it reads them here instead. * Keyed by the node object itself so a nested line expanded on the way * to the command (a `$()` operand, an `eval`) never inherits the outer * statement's targets. */ export declare function runWithRedirectPaths(node: object, paths: readonly PathSpec[], fn: () => Promise): Promise; /** * The redirect targets bound to this command node, empty for any other * node or when none are bound. * * The node is the disambiguator, so every live binding is searched, * newest first: on the fallback storage a concurrent statement's bind * shadowing the newest frame must not hide this node's own targets. */ export declare function redirectPathsFor(node: object): readonly PathSpec[]; /** * Whether a path is a redirect target the command door already judged * for the statement writing it now. * * The op doors ask this, and unlike `redirectPathsFor` it takes no node, * because by the time the shell writes the file the node has returned * and a door sees only a path. The binding is what keeps that honest: it * exists only while one statement's targets are being written, and a * statement whose targets a rule refused never reaches the write at all. * So a bound target is one the line was admitted with, and re-deriving a * verdict for it from a door that knows neither the line nor the nod it * holds can only get it wrong. Every live binding counts, because a * target is only ever bound after its own line's door judged it: on the * fallback storage a concurrent statement's frame must not shadow this * one's targets into a re-derived refusal. */ export declare function redirectTargetJudged(virtual: string): boolean; /** * The mount mode after narrowing by the current session's profile. The * mount's own mode is the strongest one available; a profile's mode can * only weaken it (a READ mount stays read-only whatever the profile says). * A mount the profile does not name keeps its own mode. */ export declare function effectiveMountMode(mountPrefix: string, mountMode: MountMode): MountMode; export declare function effectivePathMode(virtual: string, mountPrefix: string, mountMode: MountMode): MountMode; export declare function strongestModeUnder(mountPrefix: string, mountMode: MountMode): MountMode; export declare function readonlyBelow(virtual: string, mountPrefix: string, mountMode: MountMode): string | null; /** * Refuse a service-addressed write unless the whole mount's effective * mode grants writes. * * For bespoke commands whose write is addressed by a service id rather * than a path (trello's card writes): the admission gate lets them run * while any shown subtree grants writes, but an id names no path a * per-path check could judge, so only the mount-wide grant counts and * a write-granting carve-out alone refuses, failing toward refusal. * Inert outside a mount's command. `mountPrefix` is the asking * command's own (`opts.mountPrefix`), which is what lets the fallback * storage select the right gate; the isolating runtimes answer from * the binding alone. */ export declare function requireMountWritable(mountPrefix: string): void; //# sourceMappingURL=session_context.d.ts.map