/** * Registry activity timestamps (T12512): "probed" and "opened" are different * facts and live in different columns. * * - `last_probed_at` — a health check, `nexus sync` or git state probe looked * at the project. Says nothing about whether anyone uses it. * - `last_opened_at` — a real CLI command ran inside the project. Written at * most once per {@link OPENED_WRITE_INTERVAL_MS}: a read decides, and only a * stale value costs a primary-key update, so a read-only command does not * take the write lock on every run. * * `last_seen` records identity and location writes to the registry row: * registration, a new or moved checkout, reconcile, rename and index stats. * It is NOT bumped on every command (the per-command encounter returns early * when the checkout is already current), so on its own it is not "last used". * Neither writer here touches it. * * ## Activity * * Any "recently active / recently used" decision reads ONE value: * {@link projectLastActivity} = max(`last_seen`, `last_opened_at`, * `last_probed_at`), or {@link projectLastActivitySql} in a query. Temp-project * GC, name disambiguation and the Studio project list all use it. * * @task T12512 * @epic T12496 */ import { type SQL } from 'drizzle-orm'; import type { NodeSQLiteDatabase } from 'drizzle-orm/node-sqlite'; /** Minimum interval between two `last_opened_at` writes for one project. */ export declare const OPENED_WRITE_INTERVAL_MS = 60000; /** Registry timestamp columns that together make up a project's activity. */ export declare const ACTIVITY_COLUMNS: readonly ["last_seen", "last_opened_at", "last_probed_at"]; /** * Normalise a registry timestamp to ISO-8601 UTC so values written by * `datetime('now')` (`YYYY-MM-DD HH:MM:SS`, UTC) and by `toISOString()` * compare correctly. * * @param value - Stored timestamp, or `null`/`undefined`. * @returns An ISO-8601 string, or `null` when absent or unparseable. */ export declare function normalizeRegistryTimestamp(value: string | null | undefined): string | null; /** * A project's last activity: the newest of `lastSeen`, `lastOpenedAt` and * `lastProbedAt` (T12512). The single accessor for "recently active". * * @param p - Registry timestamps (the camel-case `NexusProject` fields). * @returns The newest as ISO-8601, or `null` when none parses. * @example * ```ts * projectLastActivity({ lastSeen: '2026-01-01 00:00:00', lastOpenedAt: '2026-09-29T10:00:00.000Z' }); * // '2026-09-29T10:00:00.000Z' * ``` */ export declare function projectLastActivity(p: { lastSeen: string | null | undefined; lastOpenedAt?: string | null; lastProbedAt?: string | null; }): string | null; /** * SQL text for a project's last activity over `nexus_project_registry` * columns, for raw-SQL readers (Studio). Only the columns in `available` are * used, so a store not yet migrated (no `last_opened_at`) still reads. * Space-separated `datetime('now')` values are made comparable by `replace`. * * @param available - Column names present on the table. * @returns A SQL expression. */ export declare function projectLastActivitySqlText(available: ReadonlySet): string; /** * Drizzle SQL for a project's last activity (every column exists on a * migrated store). Order by it, descending, for "most recently active first". */ export declare const projectLastActivitySql: SQL; /** Registry handle subset the activity writers need. */ export type ProjectActivityHandle = Pick; /** * Record that a health check, sync or git probe looked at these projects. * * @param db - Global registry handle. * @param projectIds - Probed project ids (duplicates are fine). * @param now - Probe instant. * @returns Number of registry rows updated. * @example * ```ts * markProjectsProbed(db, ['a1b2c3d4e5f6'], new Date()); * ``` */ export declare function markProjectsProbed(db: ProjectActivityHandle, projectIds: readonly string[], now?: Date): number; /** * Record real CLI use of a project, unless it was recorded within the last * {@link OPENED_WRITE_INTERVAL_MS}. * * @param db - Global registry handle. * @param projectId - The project the command ran in. * @param now - Command instant. * @returns `written`, `throttled`, or `unregistered` (no registry row). * @example * ```ts * markProjectOpened(db, 'a1b2c3d4e5f6'); * ``` */ export declare function markProjectOpened(db: ProjectActivityHandle, projectId: string, now?: Date): 'written' | 'throttled' | 'unregistered'; //# sourceMappingURL=project-activity.d.ts.map