import { type SkillTrigger, type TriggerEvaluation } from '@enterprise-skills/core'; /** * `enterprise-skills triggers` — bind a skill to the moment of risk * (docs/WIRING_PROBES_DESIGN.md §7, A6). * * `pre-deploy-check` was active in the pack and simply never invoked before * either infrastructure apply. This is the control that removes "somebody * remembers the trigger phrase at exactly the right moment" from the loop. * * The decision is computed in core and consumed by thin per-IDE hooks * (Cursor `beforeShellExecution`, Claude Code `PreToolUse`), so every editor * gets the same verdict instead of each re-implementing the rules. * * Exit codes are the hook contract: 0 allow, 2 ask, 1 block, 3 warn. A hook * that cannot parse our JSON can still branch on the exit code. */ export declare const TRIGGERS_CONFIG_PATH: string[]; export declare const TRIGGERS_STATE_PATH: string[]; export declare const EXIT_ALLOW = 0; export declare const EXIT_BLOCK = 1; export declare const EXIT_ASK = 2; export declare const EXIT_WARN = 3; export declare function triggersConfigPath(root: string): string; export declare function triggersStatePath(root: string): string; export interface TriggersLoad { triggers: SkillTrigger[]; errors: string[]; source: string | null; } export declare function loadTriggers(root: string): TriggersLoad; interface TriggerState { schema: 1; /** Satisfaction is scoped to a branch — "prompt once per branch" (§7). */ branch: string; satisfied: Record; } /** * Current branch, or a stable stand-in when git cannot answer. * * A detached HEAD or a non-git directory must not silently share one bucket * with every branch: `(unknown)` is its own scope, so satisfaction there never * leaks into a real branch's. */ export declare function currentBranch(root: string, gitImpl?: (args: string) => string): string; /** * Read the satisfaction record for THIS branch. A state file written on another * branch is discarded rather than migrated: switching branches is exactly when * the prior verification stops describing what is about to ship. */ export declare function readState(root: string, branch: string): TriggerState; /** * Environment variable the hooks use to hand over the command under test. * * The command is attacker-influenced BY CONSTRUCTION — it is whatever the agent * decided to run — so it must never travel as an argv token to a process spawned * with a shell. On Windows the `enterprise-skills` entry point is a `.cmd` shim, * which forces `shell: true`, and Node then joins argv into a command line: a * command containing `&` or `&&` executes its tail. That would put a command * injection inside the very gate meant to control the command (verified: a probe * command with `& echo INJECTED` ran). It also silently broke the gate, because * any command containing a space split into separate tokens and never matched. * * A shell does not re-scan an expanded variable's value for metacharacters, so * the env var is safe regardless of contents — the same fix already applied to * `ES_AGENT_PROMPT` in both agent executors. */ export declare const TRIGGER_COMMAND_ENV = "ES_TRIGGER_COMMAND"; export interface TriggersCheckOptions { command?: string; json?: boolean; cwd?: string; /** Injectable for tests. */ git?: (args: string) => string; env?: NodeJS.ProcessEnv; } export interface TriggersCheckResult extends TriggerEvaluation { branch: string; configErrors: string[]; } export declare function triggersCheckCommand(options?: TriggersCheckOptions): TriggersCheckResult | null; export interface TriggersSatisfyOptions { json?: boolean; cwd?: string; git?: (args: string) => string; } export declare function triggersSatisfyCommand(skills: string[], options?: TriggersSatisfyOptions): boolean; export interface TriggersStatusOptions { json?: boolean; cwd?: string; git?: (args: string) => string; } export declare function triggersStatusCommand(options?: TriggersStatusOptions): void; export interface TriggersInitOptions { cwd?: string; force?: boolean; } /** Seed `SKILL_TRIGGERS.yaml` from what is actually on disk (§7 generator). */ export declare function triggersInitCommand(options?: TriggersInitOptions): boolean; /** * Cheap, shallow detection — deliberately, so `init` stays fast. * * Terraform is detected from actual `.tf` FILES, not from a directory called * `infra/`. Testing this on the hub caught that: its `infra/` holds GitHub App * and LaunchOps config and not one line of HCL, so a directory-name signal * seeded a binding for a tool the project does not use. A binding that fires on * work the project never does is the fastest way to teach people to dismiss it. */ export declare function detectInfrastructure(root: string): { terraform: boolean; kubernetes: boolean; aws: boolean; docker: boolean; }; export declare function renderTriggersConfig(triggers: SkillTrigger[]): string; export {}; //# sourceMappingURL=triggers.d.ts.map