/** * Codeep Cloud — CLI authentication and stats reporting. * * Handles: * - `codeep account` login flow (device-code style, browser + poll) * - Sending usage stats to codeep.dev/api/stats after each agent run */ /** * Full `codeep account` flow. * Registers a code, opens browser, polls until authorized. * Saves github_id + username to config on success. */ export declare function runAccountFlow(): Promise; export interface StatsPayload { model: string; provider: string; command?: string; sessionId: string; sessionName?: string; messageCount?: number; cliVersion: string; projectName?: string; projectId?: string; language?: string; isGit?: boolean; /** * Whether this run was started from a phone rather than at the terminal. * * Recorded to answer whether a Codeep iOS app is worth building with * behaviour instead of opinion: "would you like an iOS app?" costs nothing * to say yes to, while actually driving a run from a phone — which the * Telegram inbox has allowed since 3.1.0 — is a thing somebody did. */ fromPhone?: boolean; inputTokens?: number; outputTokens?: number; /** Anthropic prompt caching: tokens written to cache (billed ~1.25× input). * Undefined for providers that don't report caching. */ cacheCreationTokens?: number; /** Anthropic prompt caching: tokens read from cache (billed ~0.1× input). * Undefined for providers that don't report caching. */ cacheReadTokens?: number; estimatedCost?: number; } export declare function ensureDeviceRegistered(): void; export declare function generateProjectId(projectRoot: string): string; /** * Fire-and-forget stats report. Only sends if github_id is configured. * Retries up to 2 times on network errors or 5xx responses. */ export declare function reportStats(payload: StatsPayload): void; export declare function reportStatsAsync(payload: StatsPayload): Promise; export interface CloudTask { id: number; project_name: string; title: string; description: string | null; type: 'bug' | 'feature' | 'task'; status: 'pending' | 'done'; } /** * Fetch pending tasks from codeep.dev for the current user. * Returns null if not linked or network error. */ export declare function fetchTasks(projectName?: string, projectId?: string): Promise; /** * Mark a task as done by ID. * Returns true on success, false if not linked or network error. */ export declare function markTaskDone(taskId: number): Promise; /** * Pull API keys from codeep.dev and save them to local config. * Returns the number of keys synced, or null on error. */ export declare function pullKeys(): Promise | null>; /** * Push local API keys to codeep.dev. * Returns true on success. */ export declare function pushKeys(keys: Record): Promise; /** * Purge ALL of the user's API keys stored on codeep.dev (cloud-only — local * keychain keys are untouched). A clean exit for anyone who synced keys and * later wants them off the server. Returns true on success. */ export declare function purgeKeys(): Promise; declare function globalDir(kind: 'personalities' | 'commands'): string; /** Read every .md in a global config dir into a { name → body } map. */ declare function readFileBundle(kind: 'personalities' | 'commands'): Record; /** Write a { name → body } map into a global config dir as .md * files. Only writes files that don't already exist (additive merge — * never clobber local edits). Returns the count of newly written files. */ declare function writeFileBundle(kind: 'personalities' | 'commands', items: Record): number; /** Apply the server's explicit deletion list. * * Only names the server named. Absence from `items` is deliberately NOT a * deletion signal: an expired session, the wrong account, or a truncated * response all yield an empty `items`, and deleting on absence would wipe * every local agent. Project-scoped agents in `.codeep/personalities/` are * not cloud-owned and are never touched — only the global directory is. * Every removal is backed up first, and a failed backup cancels the delete. */ declare function applyPersonalityTombstones(deleted: readonly string[]): number; declare function writePulledPersonalityBundle(items: Record): number; /** Why a sync attempt produced nothing. Reported so a silent failure cannot * look like a successful no-op — the two were indistinguishable when every * path returned `null`, and a user watching `codeep account sync` print * nothing had no way to tell which had happened. */ export type SyncFailure = 'not-linked' | 'unreachable' | 'rejected' | 'malformed' | 'unreadable' | 'unwritable'; /** Success carries a count (which may legitimately be 0 — nothing new), plus * how many local agents the server's tombstone list removed. */ export type SyncResult = { ok: true; count: number; removed: number; } | { ok: false; reason: SyncFailure; }; export declare function describeSyncFailure(reason: SyncFailure): string; export declare const pullPersonalities: () => Promise; export declare const getLastPersonalityPullBackupCount: () => number; export declare const pushPersonalities: () => Promise; export declare const pullCommands: () => Promise; export declare const pushCommands: () => Promise; /** * Sync session conversation history to codeep.dev. * Only user/assistant messages are sent — system messages are filtered out. * Fire-and-forget. Only sends if linked and sync_token is available. */ export declare function syncSession(payload: { sessionId: string; sessionName?: string; projectName?: string; projectId?: string; messages: { role: string; content: string; }[]; }): void; export declare function syncSessionAsync(payload: { sessionId: string; sessionName?: string; projectName?: string; projectId?: string; messages: { role: string; content: string; }[]; }): Promise; /** Summary of a remote session — no messages, just metadata for listing. */ export interface CloudSessionSummary { sessionId: string; sessionName: string | null; projectName: string | null; projectId: string | null; messageCount: number; updatedAt: string; } /** Full remote session — messages included (fetched on demand by id). */ export interface CloudSession extends CloudSessionSummary { messages: { role: string; content: string; }[]; } /** * List the user's cloud sessions (summaries only — no message bodies). * * The server supports three scopes via the `projectId` query param: * - omitted → all sessions for the user * - "none" → only personal (no-project) sessions * - → sessions scoped to that project * * Returns null if not linked or on network/server error. The caller decides * how to surface that (silently skip vs. notify). * * `telemetry` is NOT consulted here — reading your own previously-pushed * data back is not telemetry, and the user is explicitly asking for it * (via /cloud). The original push was already gated. */ export declare function listCloudSessions(projectId?: string): Promise; /** * Fetch a single cloud session by id, including the full message array. * * Used by `/cloud` → pick → resume: we pull the messages and write them * into the local `.codeep/sessions/` store via `saveSession`, so the * resumed session behaves identically to a locally-created one (shows * up in `/sessions`, survives restarts, re-syncs on next change). * * Returns null if not linked, not found (404), or network/server error. */ export declare function pullCloudSession(sessionId: string): Promise; /** * Sync progress.md content to codeep.dev. * Fire-and-forget. Only sends if linked (githubId + syncToken). */ export declare function syncProgress(payload: { projectName: string; projectId: string; content: string; }): void; export declare function pushLearning(preferences: object): Promise; export declare function pullLearning(): Promise<{ preferences: object; updatedAt: string; } | null>; export declare function pushProfiles(profiles: Record): Promise; export declare function pullProfiles(): Promise | null>; /** * Push the local global profile.md to the dashboard. `count` is 1 when it was * pushed and 0 when there is no local profile to push. */ export declare function pushUserProfileResult(): Promise; /** * Pull the dashboard profile.md — additive: writes only when no local profile * exists. `count` is 1 when written and 0 when skipped (nothing on the * dashboard, or a local profile already there). */ export declare function pullUserProfileResult(): Promise; /** Push the local global profile.md to the dashboard. False when nothing was * pushed, for whatever reason — see pushUserProfileResult for which. */ export declare function pushUserProfile(): Promise; /** Pull the dashboard profile.md — additive: writes only when no local profile * exists. Returns 1 if written, 0 if skipped, null on error / not linked. */ export declare function pullUserProfile(): Promise; export declare function syncMemoryNotes(projectName: string, notes: string[]): Promise; export declare const _globalDirForTest: typeof globalDir; export declare const _readFileBundleForTest: typeof readFileBundle; export declare const _writeFileBundleForTest: typeof writeFileBundle; export declare const _writePulledPersonalityBundleForTest: typeof writePulledPersonalityBundle; export declare const _applyPersonalityTombstonesForTest: typeof applyPersonalityTombstones; export {};