import { IKnowledgeStore } from "../../store/dist/index.js";
import { IEmbedder } from "../../embeddings/dist/index.js";

//#region packages/server/src/curated-adapter.interface.d.ts
/**
 * Abstraction for curated knowledge storage.
 * The default implementation uses the filesystem; alternative implementations
 * could use databases, cloud storage, or other backends.
 */
interface ICuratedAdapter {
  /** One-time initialization (e.g. ensure base directory exists). */
  initialize(): Promise<void>;
  /**
   * Read a file by its relative path (e.g. "decisions/my-entry.md").
   * Returns the raw file content, or null if the file does not exist.
   */
  read(relativePath: string): Promise<string | null>;
  /**
   * Write content to a relative path. Creates parent directories as needed.
   * @param options.exclusive If true, fail if the file already exists.
   */
  write(relativePath: string, content: string, options?: {
    exclusive?: boolean;
  }): Promise<void>;
  /**
   * Delete a file by relative path. Returns true if the file existed, false otherwise.
   */
  delete(relativePath: string): Promise<boolean>;
  /**
   * List entries, optionally filtered by a category prefix.
   * Returns objects with the relative path and file size in bytes.
   */
  list(categoryPrefix?: string): Promise<Array<{
    path: string;
    size: number;
  }>>;
  /**
   * Check whether a path exists.
   */
  exists(relativePath: string): Promise<boolean>;
  /**
   * List subdirectories in the base directory.
   * Returns directory names only (not full paths).
   */
  listDirectories(): Promise<string[]>;
  /** Clean up any resources. */
  close(): Promise<void>;
}
//#endregion
//#region packages/server/src/curated-manager.d.ts
type CuratedCategory = string;
interface CuratedEntry {
  path: string;
  title: string;
  category: string;
  tags: string[];
  version: number;
  created: string;
  updated: string;
  contentPreview: string;
}
interface CuratedFrontmatter {
  title: string;
  category: string;
  tags: string[];
  created: string;
  updated: string;
  version: number;
  origin: 'curated';
  changelog: Array<{
    version: number;
    date: string;
    reason: string;
  }>;
}
type DeterministicCuratedWriteResult = {
  path: string;
  status: 'created' | 'updated' | 'unchanged';
  version: number;
};
/**
 * Manages curated knowledge files — the LLM's persistent memory.
 * Files are stored as markdown in a .ai/curated/ directory with YAML frontmatter.
 */
declare class CuratedKnowledgeManager {
  readonly curatedDir: string;
  private readonly store;
  private readonly embedder;
  private readonly adapter;
  constructor(curatedDir: string, store: IKnowledgeStore, embedder: IEmbedder, adapter?: ICuratedAdapter);
  remember(title: string, content: string, category: CuratedCategory, tags?: string[]): Promise<{
    path: string;
  }>;
  upsertAutoKnowledge(relativePath: string, title: string, content: string, category: CuratedCategory, tags?: string[], reason?: string): Promise<DeterministicCuratedWriteResult>;
  update(relativePath: string, newContent: string, reason: string): Promise<{
    path: string;
    version: number;
  }>;
  forget(relativePath: string, _reason: string): Promise<{
    path: string;
  }>;
  /**
   * Get the git commit history for a curated knowledge entry.
   * Returns commits from newest to oldest.
   */
  history(relativePath: string, limit?: number): Promise<Array<{
    sha: string;
    date: string;
    message: string;
  }>>;
  /**
   * Get the diff between two versions of a curated knowledge entry.
   * If only toSha provided, shows that version's full content.
   * If both fromSha and toSha, shows unified diff between them.
   */
  diff(relativePath: string, fromSha?: string, toSha?: string): Promise<string>;
  /**
   * Recover a curated knowledge entry from git when the filesystem copy is missing.
   * Reads the latest committed version from the git ref and writes it back to the filesystem + vector store.
   * Returns null if no git ref exists for this path.
   */
  recover(relativePath: string): Promise<{
    path: string;
    version: number;
  } | null>;
  /**
   * Find git refs that have no corresponding filesystem file (orphaned refs).
   * These are entries that were deleted from filesystem but still have git history.
   * Useful for discovering recoverable entries.
   */
  listOrphaned(): Promise<Array<{
    ref: string;
    path: string;
    lastMessage: string;
  }>>;
  read(relativePath: string): Promise<CuratedEntry & {
    content: string;
  }>;
  list(filters?: {
    category?: CuratedCategory;
    tag?: string;
  }): Promise<CuratedEntry[]>;
  /**
   * Re-index all curated files into the vector store.
   * Call this after the indexer has run to restore curated vectors
   * that may have been lost, or to bulk-sync disk state to vectors.
   */
  reindexAll(): Promise<{
    indexed: number;
    errors: string[];
  }>;
  /**
   * Embed and upsert a batch of curated items. On embedder failure, recursively
   * retries with halved sub-batches to recover from worker-exit / oversized-batch
   * errors. Upsert failures are reported directly without recursive retry.
   * Returns the number of successfully indexed items.
   */
  private embedAndUpsertBatch;
  /**
   * Commit curated knowledge content to a git orphan ref.
   * Fires after successful filesystem write — never blocks or throws on failure.
   */
  private gitCommitKnowledge;
  /**
   * Delete the git ref for a curated knowledge entry.
   * Called after successful filesystem deletion.
   */
  private gitDeleteKnowledgeRef;
  private knowledgeRefForPath;
  private indexCuratedFile;
  private indexCuratedFileBestEffort;
  private discoverCategories;
  /**
   * Normalize and validate a relative path within .ai/curated/.
   * Returns the cleaned path (mutates nothing — caller must use the return value).
   */
  private guardPath;
  private validateCategoryName;
  private validateContentSize;
  private slugify;
  private normalizeTags;
  private sameTags;
  private ensureCategoryPath;
  /** Return a unique `category/slug.md` path, appending `-2`, `-3`, … on collision. */
  private uniqueRelativePath;
  private hash;
  private hashId;
  /**
   * Simple YAML frontmatter serializer (no gray-matter dependency).
   */
  private serializeFile;
  /**
   * Simple YAML frontmatter parser (no gray-matter dependency).
   */
  parseFile(raw: string): {
    frontmatter: CuratedFrontmatter;
    content: string;
  };
}
//#endregion
//#region packages/server/src/index.d.ts
interface CorsOriginResolution {
  allowOrigin: string | null;
  warn: boolean;
}
interface ResolveCorsOriginOptions {
  requestOrigin: string | undefined;
  configuredOrigin: string | undefined;
  allowAnyOrigin: boolean;
  fallbackOrigin: string;
}
interface SlidingWindowRateLimiter {
  allow: (key: string, now?: number) => boolean;
  getRetryAfterMs: (key: string, now?: number) => number;
}
declare function resolveCorsOrigin({
  requestOrigin,
  configuredOrigin,
  allowAnyOrigin,
  fallbackOrigin
}: ResolveCorsOriginOptions): CorsOriginResolution;
declare function createSlidingWindowRateLimiter({
  limit,
  windowMs
}: {
  limit: number;
  windowMs: number;
}): SlidingWindowRateLimiter;
type WorkspaceLogger = {
  debug: (msg: string, data?: Record<string, unknown>) => void;
  error: (msg: string, data?: Record<string, unknown>) => void;
  info: (msg: string, data?: Record<string, unknown>) => void;
  warn: (msg: string, data?: Record<string, unknown>) => void;
};
type WorkspaceRootBootstrapDeps<Config extends {
  allRoots?: string[];
}> = {
  config: Config;
  indexMode: string;
  log: WorkspaceLogger;
  rootsChangedNotificationSchema: unknown;
  reconfigureForWorkspace: (config: Config, workspaceRoot: string) => void;
  runInitialIndex: () => Promise<unknown> | undefined;
  server: {
    server: unknown;
  };
  startInit: () => void;
  timeoutMs?: number;
  getCwd?: () => string;
};
type WorkspaceRootConfig = {
  allRoots?: string[];
  sources?: Array<{
    path: string;
  }>;
};
type WorkspaceRootApplyDeps<Config extends WorkspaceRootConfig> = {
  config: Config;
  log: WorkspaceLogger;
  reconfigureForWorkspace: (config: Config, workspaceRoot: string) => void;
  roots: Array<{
    uri: string;
  }>;
};
declare function selectWorkspaceRoot<Config extends WorkspaceRootConfig>({
  config,
  roots
}: Pick<WorkspaceRootApplyDeps<Config>, 'config' | 'roots'>): string | null;
declare function applyWorkspaceRoots<Config extends WorkspaceRootConfig>({
  config,
  log,
  reconfigureForWorkspace,
  roots
}: WorkspaceRootApplyDeps<Config>): boolean;
declare function bootstrapWorkspaceRoots<Config extends {
  allRoots?: string[];
}>({
  config,
  indexMode,
  log,
  rootsChangedNotificationSchema,
  reconfigureForWorkspace,
  runInitialIndex,
  server,
  startInit,
  timeoutMs,
  getCwd
}: WorkspaceRootBootstrapDeps<Config>): Promise<void>;
declare function main(): Promise<void>;
//#endregion
export { CuratedKnowledgeManager, applyWorkspaceRoots, bootstrapWorkspaceRoots, createSlidingWindowRateLimiter, main, resolveCorsOrigin, selectWorkspaceRoot };