import type { MarketClient } from './client.js'; import type { AssetInstallMetadata } from './contract.js'; import { type AssetDependencies, type AssetType } from './schemas.js'; export interface PackDependencySpecs { npm?: string[]; asset?: string[]; skill?: string[]; } export interface ParsedPackDependencies { npmDependencies: Record; assetDependencies: Record; skillDependencies: Record; } export interface PackPolicy { readPackageJsonDependencies: boolean; omitUnchangedInstalledFiles: boolean; } export type FetchFileManifest = (name: string, range: string) => Promise>; export interface PackAssetOptions { cwd?: string; dependencies: ParsedPackDependencies; policy?: PackPolicy; /** * Fetch `path → etag` (md5) for a dependency's files given the declared range (see * `fileManifestForRange`). Pack matches local files against these hashes by content — * independent of path, so renamed installed files are omitted too and recorded as aliases. * Omit this (or a failing fetch) and the dependency's files are kept. */ fetchFileManifest?: FetchFileManifest; } export interface PackedAsset { sourcePath: string; zip: Uint8Array; npmDependencies: Record; assetDependencies: AssetDependencies; skillDependencies: Record; omittedUnchangedInstalledFiles: boolean; /** Number of zip entries dropped because a `.gitignore` inside the zip excluded them. */ gitignoredFiles: number; /** Dependencies whose file index could not be fetched: files kept, aliases untouched. */ skippedDependencies: string[]; /** Dependency files whose canonical bytes were found nowhere (locally modified or deleted). */ missingDependencyFiles: Array<{ name: string; path: string; }>; } /** md5 hex — the same digest R2 serves as every file's etag, so local bytes match server hashes. */ export declare function md5(bytes: Uint8Array): string; /** * A `FetchFileManifest` backed by the Market API: `path → etag` (md5) per dependency file. Without * a local lockfile the installed version is unknown, so a non-exact range merges the file indexes * of every published version satisfying it (newest wins per path) — a hash match identifies the * file regardless of which version it came from. Content addressing keeps mistakes safe: a stale * hash simply fails to match and the file is kept. */ export declare function fileManifestForRange(asset: MarketClient['asset']): FetchFileManifest; export declare function packAsset(zipFilter: string, opts: PackAssetOptions): Promise; export declare function parsePackDependencies(specs: PackDependencySpecs): ParsedPackDependencies; export declare function packPolicyForType(type: AssetType | undefined): PackPolicy | undefined; export declare function packPolicyFromInstallMetadata(metadata: AssetInstallMetadata | undefined): PackPolicy; /** * Parse `name@range` specs (npm or asset deps) into a name→range record. The * range is optional and defaults to `*`. A leading `@` is treated as a scope * marker, so `@scope/pkg@^1.0.0` splits into `@scope/pkg` and `^1.0.0`. */ export declare function parseVersionedDeps(specs: string[], kind: 'npm' | 'asset'): Record; /** * Parse `label=source` specs into a label→source record. The source is passed * verbatim to `skills add` (a GitHub/git ref or a local path), so only the * first `=` is treated as the separator. */ export declare function parseSkillDeps(specs: string[]): Record; interface DependencyFile { name: string; canonicalPath: string; } interface DependencyFileEntry extends DependencyFile { /** md5 hex of the file's canonical content — its R2 etag, from the file index. */ hash: string; } export interface DependencyFileIndex { files: DependencyFileEntry[]; /** Dependencies whose manifest was fetched — only their aliases are re-derived. */ fetched: Set; } interface DependencyLayout { /** Project paths holding a dependency file — exactly one per dependency file found. */ omit: Set; /** The declared dependencies with re-resolved aliases (fetched deps only; others untouched). */ assetDependencies: AssetDependencies; /** Dependency files whose canonical bytes were found nowhere (locally modified or deleted). */ missing: DependencyFile[]; } /** * Resolve where each dependency file lives in the project, by content hash. Exactly one project * copy is claimed per dependency file: the already-recorded alias target if its bytes still match * (stable across runs), else the canonical path, else the lexicographically first matching copy — * that copy is omitted from packs and recorded as the alias; further identical copies are the * user's own content. Stale aliases drop: a renamed file that was since modified ships as user * content and reinstall restores the canonical path. */ export declare function resolveDependencyLayout(declared: AssetDependencies, index: DependencyFileIndex, hashesByPath: Map): DependencyLayout; export interface AssetDependencySync { projectRoot: string; /** Whether package.json was rewritten. */ changed: boolean; assetDependencies: AssetDependencies; /** Dependency files whose canonical bytes were found nowhere (locally modified or deleted). */ missing: Array<{ name: string; path: string; }>; /** Dependencies left untouched because their manifest could not be fetched. */ skipped: string[]; } /** * Update the aliases in package.json `assetDependencies` to match where each dependency's files * currently live — the standalone form of what pack does before omitting (`market sync`). Renamed * files gain an alias, files back at their canonical path lose theirs, and dependencies whose * manifest cannot be fetched are reported as skipped rather than blindly rewritten. */ export declare function syncAssetDependencies(cwd: string, fetchFileManifest: FetchFileManifest): Promise; export {}; //# sourceMappingURL=pack.d.ts.map