/**
 * @remnic/core — Live Connectors Framework (issue #683 PR 1/N)
 *
 * Defines the contract that every "live" connector (Drive, Notion, Gmail,
 * GitHub, ...) must satisfy. A live connector is **continuous**: it runs on a
 * schedule, persists a cursor to disk, and ingests *new* documents since the
 * last sync. This is distinct from one-shot importers in
 * `packages/remnic-core/src/importers/` which transform an entire export file
 * in a single pass.
 *
 * This module is intentionally pure types + interfaces. No I/O. No schedule
 * wiring. Concrete connectors (PRs 2–5), the maintenance scheduler hookup
 * (separate PR), and the CLI surface (PR 6) are deferred.
 *
 * Naming caveat: `packages/remnic-core/src/connectors/` is already scoped to
 * the Codex marketplace integration. The live-connector framework lives under
 * the `live/` subdirectory to avoid collision. Do not import Codex symbols
 * from here, and do not import live-connector symbols from the Codex code.
 */
/**
 * Free-form connector configuration. Validated by each connector's
 * `validateConfig` implementation. Stored alongside the cursor in the state
 * store. MUST be JSON-serializable: no functions, no class instances, no
 * circular references.
 *
 * Connectors MUST NOT persist secrets here — credentials belong in OS keychain
 * / OAuth token storage (PR 2 design).
 */
type ConnectorConfig = Record<string, unknown>;
/**
 * Opaque cursor describing "where the last sync left off". Each connector
 * defines what `kind` and `value` mean (e.g. Drive: `{kind: "pageToken",
 * value: "..."}`, Gmail: `{kind: "historyId", value: "..."}`). The orchestrator
 * treats it as opaque and only round-trips it through the state store.
 *
 * `updatedAt` is an ISO 8601 timestamp set by the framework when the cursor is
 * written. It is informational — connectors MUST NOT use it to decide
 * monotonicity. They own the `value` semantics.
 */
interface ConnectorCursor {
    /** Connector-defined cursor kind (e.g. `"pageToken"`, `"historyId"`, `"sinceTs"`). */
    readonly kind: string;
    /** Connector-defined opaque cursor value. */
    readonly value: string;
    /** ISO 8601 timestamp of when this cursor was last written. */
    readonly updatedAt: string;
}
/**
 * Provenance for a connector-ingested document. Required so downstream recall
 * can attribute facts back to their origin and avoid re-ingesting on the next
 * incremental pass.
 */
interface ConnectorDocumentSource {
    /** Stable connector id (matches `LiveConnector.id`). */
    readonly connector: string;
    /** Source-system identifier (Drive file id, Notion page id, Gmail msg id, ...). */
    readonly externalId: string;
    /** Optional source-system revision/version (etag, page version, history id). */
    readonly externalRevision?: string;
    /** Optional canonical URL pointing back at the source document. */
    readonly externalUrl?: string;
    /** ISO 8601 timestamp of when the connector fetched this document. */
    readonly fetchedAt: string;
}
/**
 * A single document yielded by an incremental sync. Connectors are responsible
 * for chunking large source documents themselves if needed; the orchestrator
 * ingests `content` as a unit.
 */
interface ConnectorDocument {
    /** Connector-local stable id for this document. SHOULD match `source.externalId`. */
    readonly id: string;
    /** Optional human-readable title. */
    readonly title?: string;
    /** Body content. Plaintext or Markdown — connectors document their format. */
    readonly content: string;
    /** Provenance. Required. */
    readonly source: ConnectorDocumentSource;
}
/**
 * Arguments passed to `syncIncremental`. The framework owns cursor/config
 * lifecycle; connectors only read these and return the next cursor.
 */
interface SyncIncrementalArgs {
    /** Last persisted cursor, or `null` on the first ever sync. */
    readonly cursor: ConnectorCursor | null;
    /** Validated connector config (already passed through `validateConfig`). */
    readonly config: ConnectorConfig;
    /** Optional abort signal. Connectors SHOULD honor it for cooperative cancellation. */
    readonly abortSignal?: AbortSignal;
}
/**
 * Result of a single incremental sync pass.
 *
 * `newDocs` MAY be empty (no new documents since the last cursor). `nextCursor`
 * MUST always be returned — even on no-op syncs the framework persists it so
 * `updatedAt` reflects the most recent attempt.
 */
interface SyncIncrementalResult {
    readonly newDocs: ConnectorDocument[];
    readonly nextCursor: ConnectorCursor;
}
/**
 * The contract every live connector implements.
 *
 * Connectors MUST be:
 *   - **Idempotent**: re-running with the same cursor MUST NOT duplicate
 *     documents. The `source.externalId` + `source.externalRevision` pair is
 *     used downstream for dedup.
 *   - **Read-only on the source**: live connectors never mutate the upstream
 *     system (no marking emails read, no editing Notion pages).
 *   - **Cancellable**: long-running syncs SHOULD periodically check
 *     `abortSignal.aborted` and bail cleanly.
 *   - **Privacy-aware**: connectors MUST NOT log document content. Logging
 *     metadata (counts, ids, timings) is fine.
 */
interface LiveConnector {
    /**
     * Stable connector id. MUST match `CONNECTOR_ID_PATTERN` — lowercase
     * alphanumeric plus dash, 1–64 chars, must start AND end with alphanumeric
     * (no leading or trailing dash). The registry enforces this.
     */
    readonly id: string;
    /** Short human-readable name shown in CLI / status output. */
    readonly displayName: string;
    /** Optional longer description. */
    readonly description?: string;
    /**
     * Validate raw user-supplied config. MUST throw on malformed input — never
     * silently default. The returned object is what gets persisted and passed
     * back to `syncIncremental`. Connectors SHOULD strip unknown fields.
     */
    validateConfig(raw: unknown): ConnectorConfig;
    /**
     * Run one incremental sync pass. See `SyncIncrementalArgs` /
     * `SyncIncrementalResult` for the contract.
     */
    syncIncremental(args: SyncIncrementalArgs): Promise<SyncIncrementalResult>;
}
/**
 * Regex enforcing the connector-id naming rule. Exported so connectors and
 * tests can validate ids consistently with the registry.
 *
 * Rule: lowercase alphanumeric + dash, 1..64 chars, must start AND end with
 * alphanumeric (no leading or trailing dash). Single-char ids are allowed.
 */
declare const CONNECTOR_ID_PATTERN: RegExp;
/**
 * Returns `true` if `id` is a syntactically valid connector id.
 */
declare function isValidConnectorId(id: unknown): id is string;

export { type ConnectorConfig as C, type LiveConnector as L, type SyncIncrementalResult as S, type ConnectorDocument as a, type ConnectorCursor as b, CONNECTOR_ID_PATTERN as c, type ConnectorDocumentSource as d, type SyncIncrementalArgs as e, isValidConnectorId as i };
