/** * There is no storage "mode" either. * * This layer used to carry a declared local|remote|hybrid label. Nothing ever * branched on it: it was echoed into `storage status` and `storage sync-plan` * beside databaseConfigured/s3Configured, which are read from the actual * configuration. A declared label can contradict them (mode=remote with no * database URL), so it was a second, weaker answer to a question already * answered truthfully. What the store does is derived from what you configured: * on-box SQLite plus files, plus Postgres and/or S3 when their env vars are set. * * Deleting the label left the variable that used to hold it merely *unread*, which * is the worse failure and is now refused: see lib/retired-settings.ts. */ export declare const SKILLS_STORAGE_TABLES: readonly ["skills_sync_records", "skills_sync_cursors"]; export declare const STORAGE_TABLES: readonly ["skills_sync_records", "skills_sync_cursors"]; export type SkillsStorageTable = typeof SKILLS_STORAGE_TABLES[number]; export interface SkillsNativeStorageConfig { databaseUrl?: string; databaseSsl?: boolean; databaseSchema?: string; s3Bucket?: string; s3Prefix?: string; awsRegion?: string; s3Endpoint?: string; s3ForcePathStyle?: boolean; syncBatchSize: number; dryRun: boolean; } export declare const SKILLS_NATIVE_STORAGE_ENV: { readonly databaseUrl: "HASNA_SKILLS_DATABASE_URL"; readonly databaseSsl: "HASNA_SKILLS_DATABASE_SSL"; readonly databaseSchema: "HASNA_SKILLS_DATABASE_SCHEMA"; readonly s3Bucket: "HASNA_SKILLS_S3_BUCKET"; readonly s3Prefix: "HASNA_SKILLS_S3_PREFIX"; readonly awsRegion: "HASNA_SKILLS_AWS_REGION"; readonly s3Endpoint: "HASNA_SKILLS_S3_ENDPOINT"; readonly s3ForcePathStyle: "HASNA_SKILLS_S3_FORCE_PATH_STYLE"; readonly s3AccessKeyId: "HASNA_SKILLS_S3_ACCESS_KEY_ID"; readonly s3SecretAccessKey: "HASNA_SKILLS_S3_SECRET_ACCESS_KEY"; readonly s3SessionToken: "HASNA_SKILLS_S3_SESSION_TOKEN"; readonly syncBatchSize: "HASNA_SKILLS_SYNC_BATCH_SIZE"; readonly dryRun: "HASNA_SKILLS_SYNC_DRY_RUN"; }; export declare const SKILLS_NATIVE_STORAGE_FALLBACK_ENV: { readonly databaseUrl: "SKILLS_DATABASE_URL"; readonly databaseSsl: "SKILLS_DATABASE_SSL"; readonly databaseSchema: "SKILLS_DATABASE_SCHEMA"; readonly s3Bucket: "SKILLS_S3_BUCKET"; readonly s3Prefix: "SKILLS_S3_PREFIX"; readonly awsRegion: "SKILLS_AWS_REGION"; readonly s3Endpoint: "SKILLS_S3_ENDPOINT"; readonly s3ForcePathStyle: "SKILLS_S3_FORCE_PATH_STYLE"; readonly s3AccessKeyId: "SKILLS_S3_ACCESS_KEY_ID"; readonly s3SecretAccessKey: "SKILLS_S3_SECRET_ACCESS_KEY"; readonly s3SessionToken: "SKILLS_S3_SESSION_TOKEN"; readonly syncBatchSize: "SKILLS_SYNC_BATCH_SIZE"; readonly dryRun: "SKILLS_SYNC_DRY_RUN"; }; export declare const SKILLS_STORAGE_ENV: { readonly databaseUrl: "HASNA_SKILLS_DATABASE_URL"; readonly databaseSsl: "HASNA_SKILLS_DATABASE_SSL"; readonly databaseSchema: "HASNA_SKILLS_DATABASE_SCHEMA"; readonly s3Bucket: "HASNA_SKILLS_S3_BUCKET"; readonly s3Prefix: "HASNA_SKILLS_S3_PREFIX"; readonly awsRegion: "HASNA_SKILLS_AWS_REGION"; readonly s3Endpoint: "HASNA_SKILLS_S3_ENDPOINT"; readonly s3ForcePathStyle: "HASNA_SKILLS_S3_FORCE_PATH_STYLE"; readonly s3AccessKeyId: "HASNA_SKILLS_S3_ACCESS_KEY_ID"; readonly s3SecretAccessKey: "HASNA_SKILLS_S3_SECRET_ACCESS_KEY"; readonly s3SessionToken: "HASNA_SKILLS_S3_SESSION_TOKEN"; readonly syncBatchSize: "HASNA_SKILLS_SYNC_BATCH_SIZE"; readonly dryRun: "HASNA_SKILLS_SYNC_DRY_RUN"; }; export declare const SKILLS_STORAGE_FALLBACK_ENV: { readonly databaseUrl: "SKILLS_DATABASE_URL"; readonly databaseSsl: "SKILLS_DATABASE_SSL"; readonly databaseSchema: "SKILLS_DATABASE_SCHEMA"; readonly s3Bucket: "SKILLS_S3_BUCKET"; readonly s3Prefix: "SKILLS_S3_PREFIX"; readonly awsRegion: "SKILLS_AWS_REGION"; readonly s3Endpoint: "SKILLS_S3_ENDPOINT"; readonly s3ForcePathStyle: "SKILLS_S3_FORCE_PATH_STYLE"; readonly s3AccessKeyId: "SKILLS_S3_ACCESS_KEY_ID"; readonly s3SecretAccessKey: "SKILLS_S3_SECRET_ACCESS_KEY"; readonly s3SessionToken: "SKILLS_S3_SESSION_TOKEN"; readonly syncBatchSize: "SKILLS_SYNC_BATCH_SIZE"; readonly dryRun: "SKILLS_SYNC_DRY_RUN"; }; /** * Compatibility contract for the `./storage` subpath (`@hasna/skills/storage`). * * Consumers — including private SaaS embedders — compile against this subpath. * `version` is the contract version: it MUST be bumped on every breaking * removal or rename of a listed member. `values` are the runtime exports * (functions, classes, constants) and `types` the type-only exports the * subpath guarantees; `src/storage-boundary.test.ts` imports the subpath and * fails if a listed member is no longer exported, so a removal cannot land * silently. * * The retirement this contract exists to make unrepeatable: in 0.1.61 the * storage-mode label functions, their mode type, and the storage-mode env * variables were removed from both the main entrypoint and this subpath (see * the CHANGELOG entry for 0.1.61, "the deployment 'mode' concept is gone"). * Nothing replaced them with a successor — the mode concept is gone and must * not be reintroduced. The replacement for the old question ("which mode am I * in?") is configuration-derived status: call * `getSkillsNativeStorageStatus()` (aliases `getSkillsStorageStatus` / * `getStorageStatus`) and read `remote.databaseConfigured` / * `remote.s3Configured`. On-box SQLite and files are always present; Postgres * and S3 are used when, and only when, their variables are set. */ export declare const storageCapabilities: { readonly version: 1; readonly values: readonly ["SKILLS_NATIVE_STORAGE_ENV", "SKILLS_NATIVE_STORAGE_FALLBACK_ENV", "SKILLS_STORAGE_ENV", "SKILLS_STORAGE_FALLBACK_ENV", "SKILLS_STORAGE_TABLES", "STORAGE_TABLES", "SkillsPostgresSyncStore", "SkillsS3ObjectStore", "buildSkillsS3ObjectUrl", "createSkillsPostgresSyncStore", "createSkillsS3ObjectStore", "createSkillsSnapshotSyncRecord", "exportSkillsLocalSnapshot", "getSkillsNativeStorageStatus", "getSkillsStorageDatabaseEnv", "getSkillsStorageDatabaseUrl", "getSkillsStorageStatus", "getStorageDatabaseEnv", "getStorageDatabaseUrl", "getStorageStatus", "importSkillsLocalSnapshot", "planSkillsS3SnapshotUpload", "resolveSkillsNativeStorageConfig", "resolveStorageConfig", "signSkillsAwsV4Request", "skillsPostgresSyncSchemaSql", "storageCapabilities", "uploadSkillsSnapshotFilesToS3"]; readonly types: readonly ["AwsCredentials", "SignSkillsAwsV4RequestOptions", "SkillsFetch", "SkillsLocalSnapshot", "SkillsNativeStorageConfig", "SkillsNativeStorageStatus", "SkillsPostgresQueryClient", "SkillsS3ObjectStoreOptions", "SkillsS3PutObjectOptions", "SkillsS3SnapshotPlanEntry", "SkillsS3StoredObject", "SkillsSnapshotFile", "SkillsStorageTable", "SkillsSyncRecord"]; }; export declare function resolveSkillsNativeStorageConfig(env?: Record): SkillsNativeStorageConfig; export declare function resolveStorageConfig(env?: Record): SkillsNativeStorageConfig; export declare function getSkillsStorageDatabaseEnv(env?: Record): string; export declare function getStorageDatabaseEnv(env?: Record): string; export declare function getSkillsStorageDatabaseUrl(env?: Record): string | undefined; export declare function getStorageDatabaseUrl(env?: Record): string | undefined; export interface SkillsNativeStorageStatus { package: "skills"; tables: readonly SkillsStorageTable[]; env: { databaseUrl: string; s3Bucket: string; }; local: { dataDir: string; projectStateDir: string; feedbackDbPath: string; }; remote: { databaseConfigured: boolean; s3Configured: boolean; databaseEnv: string; s3BucketEnv: string; activeDatabaseEnv: string; activeS3BucketEnv: string; region: string; dryRun: boolean; }; } export declare function getSkillsNativeStorageStatus(options?: { targetDir?: string; env?: Record; }): SkillsNativeStorageStatus; export declare function getSkillsStorageStatus(options?: { targetDir?: string; env?: Record; }): SkillsNativeStorageStatus; export declare function getStorageStatus(options?: { targetDir?: string; env?: Record; }): SkillsNativeStorageStatus; export interface SkillsSnapshotFile { path: string; sizeBytes: number; sha256: string; contentBase64?: string; } export interface SkillsLocalSnapshot { schemaVersion: 1; exportedAt: string; files: SkillsSnapshotFile[]; } export declare function exportSkillsLocalSnapshot(targetDir?: string, options?: { includeFileContents?: boolean; }): SkillsLocalSnapshot; export declare function importSkillsLocalSnapshot(snapshot: SkillsLocalSnapshot, targetDir?: string, options?: { overwrite?: boolean; }): { written: number; skipped: number; }; export interface SkillsPostgresQueryClient { query(sql: string, values?: readonly unknown[]): Promise<{ rows: T[]; }>; } export interface SkillsSyncRecord { scope: string; kind: string; id: string; updatedAt: string; deletedAt?: string | null; source?: string | null; payload: Record; } export declare const skillsPostgresSyncSchemaSql: string; export declare class SkillsPostgresSyncStore { private readonly client; constructor(client: SkillsPostgresQueryClient); ensureSchema(): Promise; upsertRecords(records: readonly SkillsSyncRecord[]): Promise; pullUpdatedSince(params: { scope: string; since?: string; limit?: number; }): Promise; getCursor(scope: string, cursorName: string): Promise; setCursor(scope: string, cursorName: string, value: string): Promise; } export declare function createSkillsPostgresSyncStore(client: SkillsPostgresQueryClient): SkillsPostgresSyncStore; export declare function createSkillsSnapshotSyncRecord(snapshot: SkillsLocalSnapshot, options?: { scope?: string; id?: string; source?: string; }): SkillsSyncRecord; export interface AwsCredentials { accessKeyId: string; secretAccessKey: string; sessionToken?: string; } export interface SkillsS3ObjectStoreOptions { bucket: string; region?: string; prefix?: string; endpoint?: string; forcePathStyle?: boolean; credentials: AwsCredentials; fetch?: SkillsFetch; } export interface SkillsS3PutObjectOptions { key: string; body: Uint8Array | string; contentType?: string; } export interface SkillsS3StoredObject { key: string; url: string; etag?: string | null; sizeBytes: number; } export type SkillsFetch = (input: string | URL | Request, init?: RequestInit) => Promise; export declare class SkillsS3ObjectStore { private readonly options; private readonly fetchImpl; private readonly region; private readonly prefix; constructor(options: SkillsS3ObjectStoreOptions); objectKey(path: string): string; objectUrl(key: string): string; putObject(params: SkillsS3PutObjectOptions): Promise; getObject(key: string): Promise; } export declare function createSkillsS3ObjectStore(options: SkillsS3ObjectStoreOptions): SkillsS3ObjectStore; export interface SkillsS3SnapshotPlanEntry { path: string; key: string; sizeBytes: number; sha256: string; } export declare function planSkillsS3SnapshotUpload(snapshot: SkillsLocalSnapshot, options?: { prefix?: string; }): SkillsS3SnapshotPlanEntry[]; export declare function uploadSkillsSnapshotFilesToS3(snapshot: SkillsLocalSnapshot, store: SkillsS3ObjectStore): Promise; export interface SignSkillsAwsV4RequestOptions { method: string; url: string; region: string; service: string; headers?: Record; body?: Uint8Array | string; credentials: AwsCredentials; now?: Date; } export declare function signSkillsAwsV4Request(options: SignSkillsAwsV4RequestOptions): { headers: Record; canonicalRequest: string; stringToSign: string; }; export declare function buildSkillsS3ObjectUrl(params: { bucket: string; key: string; region?: string; endpoint?: string; forcePathStyle?: boolean; }): string;