UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

67 lines (66 loc) • 5.73 kB
import { type PathRuleBase, type PathRuleBases, type PersistedRule, type RuleBehavior, type RuleScope, type ScopeRootIdentity } from "./permission-rule-model.js"; import { type DenyFace, type JudgedPathRow, type PathRowReach } from "../tools/fs/read-deny.js"; import { type ToolPolicy } from "./tool-policy.js"; export { judgeRuleRows, rowsWhereTheyLead } from "../tools/fs/read-deny.js"; export type { PathRowsHit, TargetViews } from "./path-guard-rows.js"; /** One path rule as a binding reads it: the parsed rule, its text, and — for a deny rule that guards a face of the * engine's deny tables — those faces (absent: the rule is judged on its own tool's calls only). */ export interface PathRuleSpec { readonly parsed: Pick<PersistedRule, "match" | "command" | "behavior" | "tool">; readonly ruleText: string; readonly faces?: readonly DenyFace[]; } /** A rule bound to its anchors: a deny-table row (`faces` empty for a rule that guards no table face), its three-valued * reach over an absolute spelling, and the spec it was bound from. `unanchored` names the base words its pattern needs * that the anchors do not supply (the rule reads `unreadable` everywhere: a gate lane fails closed on it; a deny table * cannot judge it and leaves it to the gate). */ export interface BoundPathRule<S extends PathRuleSpec = PathRuleSpec> extends JudgedPathRow { readonly spec: S; /** The rule's behavior (a deny table takes the `deny` rows that guard a face). */ readonly behavior: RuleBehavior; readonly reach: (absolutePath: string) => PathRowReach; readonly unanchored?: readonly PathRuleBase[]; } /** * The ONE binding of path rules to their anchors (`anchors`: one set for every spec, or a set per spec). Each row resolves * its pattern once against its anchors and reads an absolute spelling under the anchors' family — a row installed on a win * root reads `C:\proj\x`, `C:/proj/x` and `c:\proj\x` as one path; a row whose anchors name no tree reads the spelling's * own family. The head (where the row's reach starts) is spelled for the environment, so a leg can judge the row where * the head leads. */ export declare function bindPathRules<S extends PathRuleSpec>(specs: readonly S[], anchors: PathRuleBases | ((spec: S) => PathRuleBases)): BoundPathRule<S>[]; /** A caller policy's anchors on the leg it is installed on: the declared `pathBases` word by word, else the leg's — `/x` * at the declared root (else the leg's root), a relative pattern at the declared cwd (else the `/x` anchor), `~/` at the * declared home (else the leg environment's). `install` absent (a policy called outside a Runner leg): the declaration * alone. */ export declare function policyAnchors(declared: PathRuleBases, install: PathRuleBases | undefined): PathRuleBases; /** A stored row's anchors: a PROJECT row's `/x` and relative words at the row's own scope root (the project it was written * for), a global or session row's at the chain's top leg; `~/` at the top leg's home for every row. */ export declare function persistedRowAnchors(scope: RuleScope, chainTop: PathRuleBases): PathRuleBases; /** A leg's root as an identity for project coverage ({@link ScopeRootIdentity}): its canonical root, and each project * row's scope root resolved through the leg's resolution (`leads`, each location once per leg) — so a row written under * one spelling of the project's directory applies to a leg rooted at another spelling of it. `undefined` when the leg * has no canonical root (the spellings alone are compared). */ export declare function projectScopeIdentity(rules: readonly Pick<PersistedRule, "scope">[], canonicalRoot: string | undefined, leads: HeadLeads): Promise<ScopeRootIdentity | undefined>; /** A leg's resolution of the locations rule heads pass through: each location resolved once (twins are not refreshed * within a leg — a link re-pointed mid-leg is met through the row as spelled, and at its new location from the next * prepare; a location that does not resolve has no twin). `resolve` settles the parts of the given rows and answers * every location settled so far. */ export interface HeadLeads { resolve(rows: readonly Pick<JudgedPathRow, "head">[]): Promise<ReadonlyMap<string, string | undefined>>; } export declare function createHeadLeads(leadsTo: (part: string) => Promise<string | undefined>): HeadLeads; /** * INSTALL a policy on a leg: its path rules are anchored at `anchors` (the leg's root and home; the policy's declared * `pathBases` still win word by word) — once, for every judgment of the policy from then on: its `check` (the copy of each * request it hands its inner check carries `ToolCallRequest.pathRuleAnchors`), the deny-table rows * (`ToolPolicy.pathRules` answers with this installation's rows whatever it is given), and every child the leg hands * the policy to as a parent constraint. A policy with no path rules is returned as it is. Installing an installed policy * installs what it was installed FROM; one policy installed at the same anchors is one object (identity is the * installation). Every member the policy carries rides as it holds it; the decision its `check` answers is untouched. */ export declare function installPolicyAnchors(policy: ToolPolicy | undefined, anchors: PathRuleBases): ToolPolicy | undefined; /** The policy an installation was installed from (`undefined`: not an installation). */ export declare function installedFrom(policy: ToolPolicy | undefined): ToolPolicy | undefined; /** The anchors an installation was installed at (`undefined`: not an installation). */ export declare function installationAnchorsOf(policy: ToolPolicy | undefined): PathRuleBases | undefined;