/** * E2 skill first-class object (docs/plans/2026-05-30-e2-skill-object.md). * * A `skill` is a reusable, agent-followable capability: an `instructions` body * plus an optional `trigger` ("when to apply"), evolving via the supersede delta * lifecycle. "Executable" is scoped to an agent-followable INSTRUCTION that, once * exported into the agent's in-force rules (AGENTS.md / CLAUDE.md) via * `exportSkills`, is executed by the agent reading it. Literal code/command * execution is deferred (security; a future sandbox). The distinguishing * capability is therefore the EXPORT renderer, not a runtime. * * Reuses the process/decision supersede machinery verbatim (superseded_by self-FK * + CAS + INSERT-preflight + server-derived version + change_summary + supersede * tenant-match trigger). It DROPS process's `steps` (a skill's content is a single * `instructions` body) and ADDS `trigger` (stored in the `trigger_text` column - * `trigger` is a SQLite reserved keyword). * * The `skills` table is the source of truth (survives memory decay); the memory * mirror is for recall. memory_id is NULLABLE with ON DELETE SET NULL. * * Lifecycle: active -> superseded (a newer version replaces it) or active -> * closed (retired). Export renders ACTIVE skills only. */ export type SkillStatus = 'active' | 'superseded' | 'closed'; export declare const VALID_SKILL_STATES: ReadonlySet; /** Field caps (untrusted at the HTTP/SDK boundary). instructions is a body, so a * larger cap than the 4096 short-field convention. */ export declare const MAX_SKILL_NAME_LEN = 256; export declare const MAX_SKILL_INSTRUCTIONS_LEN = 8192; export declare const MAX_SKILL_TRIGGER_LEN = 1024; /** Aggregate bound on a single export render (plan-eng-critic: cap the unbounded * export body). Realistic active-skill counts are tens; 1000 is a generous bound. */ export declare const MAX_EXPORT_SKILLS = 1000; export interface Skill { id: number; /** Nullable: ON DELETE SET NULL lets memory deletion proceed without breaking * the skill row. */ memoryId: string | null; tenantId: string; skillName: string; instructions: string; /** Optional "when to apply"; stored in the trigger_text column. */ trigger: string | null; /** Server-derived: 1 on a fresh create, predecessor.version + 1 on supersede. */ version: number; status: SkillStatus; supersededBy: number | null; supersededAt: string | null; /** The per-version delta note; set on a successor row only (NULL on a v1). */ changeSummary: string | null; closedAt: string | null; createdAt: string; } export interface SaveSkillOpts { skillName: string; instructions: string; /** Optional "when to apply" trigger. */ trigger?: string; /** The delta note for a supersession; ignored (stored NULL) on a fresh create. */ changeSummary?: string; /** Table id of an ACTIVE skill this new version supersedes. */ supersedesSkillId?: number; /** Extra memory tags merged after ['skill']. */ extraTags?: string[]; } export interface ListSkillsOpts { status?: SkillStatus; limit?: number; } /** * Create a skill (or a new version that supersedes an existing one). Writes the * memory mirror + the skills row atomically inside writeEntry's SAVEPOINT. When * supersedesSkillId is given, the referenced ACTIVE row is preflighted (status + * version) BEFORE the INSERT, then CAS-UPDATEd -> superseded in the same SAVEPOINT; * the new version = predecessor.version + 1 (server-derived). */ export declare function saveSkill(hippoRoot: string, tenantId: string, opts: SaveSkillOpts, actor?: string): Skill; /** * Close (retire) an active skill. CAS guard WHERE status='active'; 0 changes * distinguishes not-found from not-active. A superseded row is terminal. */ export declare function closeSkill(hippoRoot: string, tenantId: string, id: number, actor?: string): Skill; export declare function loadSkillById(hippoRoot: string, tenantId: string, id: number): Skill | null; export declare function loadSkills(hippoRoot: string, tenantId: string, opts?: ListSkillsOpts): Skill[]; export declare function loadActiveSkills(hippoRoot: string, tenantId: string, opts?: { limit?: number; }): Skill[]; /** * Render the tenant's ACTIVE skills into ONE AGENTS.md / CLAUDE.md-style markdown * block (one H2 per skill, ordered by skill_name ASC for determinism), and RETURN * the string. Does NOT write any file. Returns '' when there are no active skills. * * skill_name is single-line (validated on save) so it cannot break the H2 header; * instructions are emitted verbatim (operator content). Bounded by MAX_EXPORT_SKILLS * active rows; each field is capped on save, so the rendered string is bounded. */ export declare function exportSkills(hippoRoot: string, tenantId: string): string; //# sourceMappingURL=skills.d.ts.map