import { type Keychain } from "../lib/keychain.js"; /** @internal — test hook. */ export declare function _setKeychainForTests(k: Keychain | null): void; /** @internal — test hook. Forces the next request to re-read keychain + config. */ export declare function _resetClientAuthCacheForTests(): void; /** * 0839 F-004 — production-grade cache invalidation. * * The auth cache (`_authCache`) loads BOTH the bearer token and the active * tenant from the keychain + config exactly once per process. After * `vskill auth login` mutates the keychain, the same-process cache still * holds pre-login state — so a script doing `vskill auth login && vskill * orgs list` from a single Node process never sees the new token. The same * applies on logout: a stale cache would keep sending the just-revoked * token until the process exits. * * This function is intentionally exported as a non-test primitive so * `auth.ts` can call it after `setVskillToken`, `clearVskillToken`, etc. * It is internally identical to `_resetClientAuthCacheForTests`; we keep * both names so the test hook stays explicit and the production callsite * reads correctly. */ export declare function invalidateAuthCache(): void; export interface BuildHeadersOptions { /** Per-call tenant override (CLI --tenant flag). */ tenantOverride?: string | null; } /** * Build the standard request headers for a verified-skill API call: * - Content-Type / User-Agent (always) * - Authorization: Bearer (when a token is stored) * - X-Vskill-Tenant: (when an active tenant is set or overridden) * * Callers may pass extra headers via `extra`; those win over defaults. */ export declare function buildRequestHeaders(extra?: Record, opts?: BuildHeadersOptions): Record; export interface SkillSearchResult { name: string; author: string; repoUrl?: string; tier: string; score: number; description: string; installs: number; /** GitHub stars (returned by search API) */ githubStars: number; command?: string | null; pluginName?: string | null; isTainted?: boolean; /** Trust tier (T0-T4) */ trustTier?: "T0" | "T1" | "T2" | "T3" | "T4"; /** Certification tier */ certTier?: "CERTIFIED" | "VERIFIED"; /** True when the skill is on the blocklist (known malicious) */ isBlocked?: boolean; /** Threat classification (e.g. "credential-theft", "prompt-injection") */ threatType?: string; /** Severity level (e.g. "critical", "high") */ severity?: string; /** Install count from the vskill registry */ vskillInstalls?: number; /** GitHub owner slug (e.g., "openclaw") */ ownerSlug?: string; /** GitHub repo slug (e.g., "openclaw") */ repoSlug?: string; /** Skill folder name (e.g., "gog") */ skillSlug?: string; /** Current published version (semver) */ currentVersion?: string; /** Alternate repos containing the same skill from the same org */ alternateRepos?: Array<{ ownerSlug: string; repoSlug: string; repoUrl: string; }>; } export interface SkillDetail { name: string; author: string; tier: string; score: number; version: string; sha: string; description: string; content?: string; installs: number; updatedAt: string; repoUrl?: string; /** Trust tier classification (T0-T4) */ trustTier?: string; /** Composite trust score (0-100) */ trustScore?: number; /** Whether author-repo ownership is verified */ provenanceVerified?: boolean; command?: string | null; pluginName?: string | null; } export interface SubmissionResponse { /** Submission ID (present for new + duplicate submissions) */ id?: string; state?: string; createdAt?: string; /** True when an identical pending submission already exists */ duplicate?: boolean; /** Skill ID (present when skill is already verified) */ skillId?: string; skillName?: string; /** True when skill already passed verification */ alreadyVerified?: boolean; /** True when skill/submission is blocked */ blocked?: boolean; submissionId?: string; } export interface SubmissionRequest { repoUrl: string; skillName?: string; skillPath?: string; email?: string; source?: string; } export declare function apiRequest(path: string, options?: RequestInit & { tenantOverride?: string | null; }): Promise; export interface SearchResponse { results: SkillSearchResult[]; hasMore: boolean; } /** * Search for skills in the registry. * Uses the edge-first search endpoint which is resilient to DB load. */ export declare function searchSkills(query: string, options?: { limit?: number; }): Promise; /** * Get a single skill by name. * Supports both flat ("architect") and hierarchical ("owner/repo/architect") names. */ export declare function getSkill(name: string): Promise; /** * Submit a skill for verification. */ export declare function submitSkill(data: SubmissionRequest): Promise; /** * Get the status of a submission. */ export declare function getSubmission(id: string): Promise<{ id: string; status: string; result?: unknown; }>; export interface SkillVersionEntry { version: string; certTier: string; createdAt: string; contentHash?: string; certScore?: number; diffSummary?: string | null; } /** * List published versions for a skill. * Supports hierarchical names (owner/repo/skill). */ export declare function getVersions(name: string): Promise; export interface VersionDiffResult { from: string; to: string; diffSummary: string; contentDiff: string; } /** * Get a unified diff between two versions of a skill. * Uses the platform `?from=X&to=Y` endpoint. */ export declare function getVersionDiff(name: string, from: string, to: string): Promise; /** * Report a skill install to the platform with retry. * Respects VSKILL_NO_TELEMETRY=1 env var for opt-out. * Never throws — all errors are silently swallowed. * * @param skillName - The skill name to report (e.g., "architect") * @param repoUrl - Optional repo URL for fallback matching on the server */ export declare function reportInstall(skillName: string, repoUrl?: string, version?: string): Promise; /** * Report multiple skill installs in a single batch request. * More reliable than individual reportInstall calls for plugin installs. * Never throws — all errors are silently swallowed. * * @param skills - Array of { skillName, repoUrl? } to report */ export interface CheckUpdateItem { name: string; currentVersion: string; sha?: string; } export interface CheckUpdateResult { name: string; installed: string; latest: string | null; updateAvailable: boolean; versionBump?: string; diffSummary?: string; certTier?: string; certScore?: number; /** 0740: set when `outdated` could not read the on-disk version and fell * back to the lockfile pin. UI surfaces this as a soft hint without * breaking the update flow. */ warning?: string; } /** * Check multiple installed skills for available updates in a single request. * Throws on error — caller is responsible for handling failures. */ export declare function checkUpdates(skills: CheckUpdateItem[]): Promise; export type CompareFile = { filename: string; status: string; additions: number; deletions: number; patch?: string; }; export type CompareVersionsResult = { source: "github" | "local-content"; baseSha?: string; headSha?: string; files: CompareFile[]; githubCompareUrl?: string; }; /** * Fetch a multi-file diff between two versions of a skill. * Hits the platform `/versions/compare?from=X&to=Y` endpoint which returns * GitHub-backed compare data when both versions have valid SHAs (source:"github"), * or an LCS fallback on SKILL.md alone (source:"local-content"). */ export declare function compareVersions(skill: string, from: string, to: string): Promise; export declare function reportInstallBatch(skills: Array<{ skillName: string; repoUrl?: string; version?: string; }>): Promise; export interface TenantSummary { /** Stable tenant identifier (cuid). */ tenantId: string; /** URL-safe slug used in `X-Vskill-Tenant` and `vskill orgs use`. */ slug: string; /** Human-readable display name (org or user-friendly). */ name: string; /** Caller's role in the tenant (mirror of `OrgMember.role`). */ role: "owner" | "admin" | "member" | string; /** GitHub App installation id, when available. */ installationId?: string | number | null; } export interface ListTenantsResponse { tenants: TenantSummary[]; } /** * 0839 US-003 / US-004 — list tenants the authenticated user is a member of. * Backed by `GET /api/v1/account/tenants` (added in T-002, ADR-003). * * Anonymous calls are NOT allowed: when no token is present, the endpoint * returns 401 (the platform's `requireUserOrGithubBearer` rejects). Callers * that want anonymous-safe behaviour should check for a token first. */ export declare function listTenants(): Promise; export interface ExchangeForVskTokenResponse { token: string; expiresAt: string; scopes: string[]; userId: string; } /** * 0839 US-005 — exchange a `gho_*` token for a `vsk_*` API token. * Hits `POST /api/v1/auth/github/exchange-for-vsk-token`. The response * `token` is the plaintext `vsk_*` (returned ONCE — only the hash is * persisted server-side per AC-US5-02). * * Failures throw — callers (auth.ts) decide whether to fall back to * "legacy mode" (gho_-only) or surface the error. */ export declare function exchangeForVskToken(githubToken: string): Promise; /** * 0839 US-005 / AC-US5-06 — best-effort server-side revocation. The CLI * `auth logout` calls this AFTER clearing the local keychain; failure is * logged but never blocks logout. */ export declare function signOutAll(): Promise;