/** * LocalIndex — SQLite-backed IAssetIndex implementation. * * Storage: ~/.skaile/index.db by default; override with `SKAILE_INDEX_PATH`. * Library checkouts live separately under `~/.skaile/libraries//` and * are controlled by `SKAILE_LIBRARIES_DIR`. * * All four entity tables (libraries, asset_definitions, instances, assignments) * are created on first open. See db.ts for DDL. * * @docLink packages/library/concepts#local-index */ import type { IAssetKindRegistry } from "@skaile/workspaces/plugins"; import type { InstallManifest } from "@skaile/workspaces/types"; import { type AssetFetcher } from "../install/install-from-manifest.js"; import type { AssetDefinition, AssetFilter, Assignment, CreateInstanceInput, IAssetIndex, Instance, InstanceFilter, PinPolicy, SyncResult, UpdateInstanceInput } from "../library.js"; import type { AddLibraryInput, Library } from "../user-library.js"; import { type LibraryDb } from "./db.js"; export interface LocalIndexOptions { /** Override the library checkouts directory (where `library init` places dirs). */ libraryDir?: string; /** Override the absolute path to the index SQLite file (default: ~/.skaile/index.db). */ indexPath?: string; /** Kind registry for provider-version tracking and kind validation. */ kindRegistry?: IAssetKindRegistry; } /** * SQLite-backed implementation of {@link IAssetIndex}. * * Backed by `@libsql/client`, so it runs on both Node and Bun. Stores data at * `~/.skaile/index.db` by default; override with `SKAILE_INDEX_PATH` (or via * the constructor `indexPath` option). Library checkouts live separately at * `resolveLibraryDir()` (default `~/.skaile/libraries/`). * * The constructor is synchronous — it only resolves the storage path. The * SQLite connection is opened lazily on first use (`@libsql/client` is * async-only). Always call {@link LocalIndex.close} in a `finally` block to * release the connection. * * @docLink packages/library/concepts#local-index */ export declare class LocalIndex implements IAssetIndex { private readonly dbPath; private dbHandleRef; private dbPromise; private _kindRegistry; /** Absolute path to the library checkouts directory. */ private readonly libraryDir; /** * Construct a LocalIndex. Synchronous — does not open the DB. * * @param optionsOrDir - Either a `LocalIndexOptions` object or a string * path (legacy signature: treated as the libraryDir, with the index file * landing at `/index.db`). */ constructor(optionsOrDir?: string | LocalIndexOptions); /** * Lazily open the SQLite DB on first use. The `??=` dedupes concurrent * first calls so the DB is opened exactly once, with no race. */ private ensureDb; /** The kind registry bound to this library (if any). */ get kinds(): IAssetKindRegistry | undefined; /** Close the underlying SQLite connection. Call in tests / cleanup. */ close(): void; /** Internal access for LibraryManager. Do not call from user code. */ dbHandle(): Promise; listSources(): Promise; addSource(input: AddLibraryInput): Promise; removeSource(id: string): Promise; syncSource(id: string): Promise; /** * Insert or update a cached asset definition. * * Not on the IAssetIndex interface -- used by catalog sources (Task 1.5) * and tests. INSERT OR REPLACE semantics. */ upsertAssetDef(def: AssetDefinition): Promise; /** * Delete this library's cached asset defs whose ref is not in `keepRefs`. * Makes a sync authoritative: a def re-keyed under a new publisher (e.g. * `@skills/x` → `@acme/x`) leaves no stale duplicate behind. Returns the * number of rows removed. * * Not on the IAssetIndex interface — used by catalog sources. */ pruneAssetDefs(libraryId: string, keepRefs: string[]): Promise; getAssetDef(ref: string): Promise; listAssetDefs(filter?: AssetFilter): Promise; createInstance(input: CreateInstanceInput): Promise; /** * Install an asset from a pointer-only {@link InstallManifest}. * * This is the pointer-only install path: the caller obtains the manifest * from a catalog source (`RemoteCatalogSource.getInstallManifest(ref)` — * a `RemoteCatalogSource`-only method, not on the `ICatalogSource` * contract), and `install` then: * * 1. fetches the asset bytes directly from the upstream repo at the * pinned commit and verifies every per-file + the composite SHA256 * (via {@link installFromManifest}); * 2. records an {@link Instance} row carrying `sourceCommitSha` so the * install is auditable and re-verifiable. * * Not part of the {@link IAssetIndex} interface — `LocalIndex`-only, since * the platform variant resolves install bytes differently. * * @param manifest - The pointer-only install manifest from the Catalog. * @param opts.libraryRoot - Filesystem root to install asset bytes under. * Defaults to an `installed/` subdirectory of the library storage dir. * @param opts.fetcher - Pluggable byte fetcher (tests inject a mock); * defaults to `fetchAssetFilesFromGitHub`. * @param opts.config - Initial Instance config. Defaults to `{}`. * @param opts.defPin - Pin policy for the Instance. Defaults to `exact` * (a pointer-only install is pinned to an immutable commit). * @returns The created Instance plus its on-disk install path. */ install(manifest: InstallManifest, opts?: { libraryRoot?: string; fetcher?: AssetFetcher; config?: Record; defPin?: PinPolicy; createdBy?: string; }): Promise<{ instance: Instance; installPath: string; }>; getInstance(id: string): Promise; listInstances(filter?: InstanceFilter): Promise; /** Map every cached asset def's version-stripped ref base to its kind. */ private buildInstanceKindMap; updateInstance(id: string, patch: UpdateInstanceInput): Promise; deleteInstance(id: string, opts?: { cascade?: boolean; }): Promise; assign(workspaceId: string, instanceId: string, pin: PinPolicy): Promise; unassign(assignmentId: string): Promise; listAssignments(workspaceId: string): Promise; getConsumptionGraph(instanceId: string): Promise; } //# sourceMappingURL=library.d.ts.map