/** * S3-backed skill store. * * Layout (curator-compatible): * skills/.json — one JSON-serialized SkillDefinition per object * index.json — { lastUpdated, skills: SkillIndexItem[] } * * The index document is upserted on every write and rebuilt from a bucket * listing when missing or unparsable (self-healing). Concurrent writers can * race the index read-modify-write; the rebuild path recovers from any * resulting drift, matching curator's production behavior. * * @aws-sdk/client-s3 is an optional peer — loaded lazily with the same * createRequire pattern as memory's @juspay/hippocampus so importing * NeuroLink core never requires the AWS SDK. Tests (and hosts with * pre-configured clients) inject a SkillS3ObjectOps implementation instead. */ import type { SkillDefinition, SkillIndexItem, SkillS3ObjectOps, SkillS3StorageConfig, SkillStore } from "../types/index.js"; export declare class S3SkillStore implements SkillStore { private readonly config; /** Test/host seam — omit to build ops from @aws-sdk/client-s3 lazily. */ private readonly injectedOps?; private readonly prefix; private ops; /** Last parsed index + its ETag, revalidated with If-None-Match reads. */ private cachedIndexDoc; private cachedIndexEtag; constructor(config: SkillS3StorageConfig, /** Test/host seam — omit to build ops from @aws-sdk/client-s3 lazily. */ injectedOps?: SkillS3ObjectOps | undefined); invalidate(): void; private getOps; private skillKey; private indexKey; /** Resources live beside the skill object: skills//. */ private resourceKey; getResource(id: string, resourcePath: string): Promise; get(id: string): Promise; put(skill: SkillDefinition): Promise; delete(id: string): Promise; index(): Promise; private writeIndex; /** * Raw index.json read. Returns the body (with its ETag when available), * null body when the object is absent, or notModified when a * conditional read reported the cached copy unchanged. */ private readIndexObject; /** * Read index.json (ETag-revalidated when the ops support conditional * reads — an unchanged index costs a 304, not a download); when missing * or unparsable, rebuild it from a listing of the skills/ prefix and * persist the rebuilt document (self-heal). */ private readOrRebuildIndex; }