import { c as Profile, d as ProfilePosition, S as SkillRef, w as PresentationLinkView } from './index-CTzpbW81.cjs'; import { S as SifaApiConfig, A as ApiFetchOptions, C as CreateResult, W as WriteResult } from './org-DmtI6C4A.cjs'; import { n as ProfileView } from './types-DAEkBwRB.cjs'; import { S as SummarizeProfileViewOptions, P as ProfileSummary } from './profile-summary-C557t4hr.cjs'; import { j as EntitySearchResponse, E as EntitySearchResult, d as EntityMintDomainResponse, h as EntityResolveDomainResponse, m as EntitySelectRequest, o as EntitySelectResponse } from './feed-BMm9Pkew.cjs'; /** * Read the aggregated profile for a handle or DID. * * Returns `null` when the AppView has no profile for the given identifier * (HTTP 404). Throws {@link ApiError} on other non-2xx responses. * * Server-callable (Next.js RSC) and client-callable (Expo, browser). */ declare function fetchProfile(config: SifaApiConfig, handleOrDid: string, options?: ApiFetchOptions): Promise; /** * Public AT Fund link for a profile, if one is configured. Returns `null` * on any error or when the response payload's `url` field is missing or * non-string. */ declare function fetchAtFundLink(config: SifaApiConfig, did: string, options?: ApiFetchOptions): Promise; /** * Read the aggregated public profile view via the `id.sifa.getProfileView` * XRPC query. This is the AppView-only join (positions, education, skills, * endorsements, and more) exposed as a standard lexicon method, distinct from * the internal `/api/profile/*` REST surface. * * Returns `null` when the AppView has no profile for the actor * (`ProfileNotFound`). Throws {@link ApiError} on other non-2xx responses. * * Server-callable (Next.js RSC) and client-callable (Expo, browser). */ declare function fetchGetProfileView(config: SifaApiConfig, actor: string, options?: ApiFetchOptions): Promise; /** * Fetch the aggregated public profile via `id.sifa.getProfileView` and reduce it * to a compact {@link ProfileSummary} (identity, headline, current role/employer, * top skills). Convenience over `fetchGetProfileView` + `summarizeProfileView`, * for third-party surfaces that only want the headline facts. * * Returns `null` when the AppView has no profile for the actor. Server-callable * (Next.js RSC) and client-callable (Expo, browser). */ declare function fetchProfileSummary(config: SifaApiConfig, actor: string, options?: SummarizeProfileViewOptions & ApiFetchOptions): Promise; /** * Create a new `id.sifa.profile.position` record on the authenticated * user's PDS. The AppView signs and writes via the user's OAuth session. * * `data` should be a lexicon-shaped position record (without `createdAt` * or `rkey`; the AppView fills both). Validate with * `ProfilePositionRecordSchema.omit({ createdAt: true })` before calling * if you want client-side guarantees. * * Never throws -- inspect `result.success` and use `result.error` / * `result.pdsHost` for UI messaging. */ declare function createPosition(config: SifaApiConfig, data: Record, options?: ApiFetchOptions): Promise; /** Update an existing position by `rkey`. */ declare function updatePosition(config: SifaApiConfig, rkey: string, data: Record, options?: ApiFetchOptions): Promise; /** Delete a position by `rkey`. */ declare function deletePosition(config: SifaApiConfig, rkey: string, options?: ApiFetchOptions): Promise; /** Mark a position as the user's primary (current) role. */ declare function setPositionPrimary(config: SifaApiConfig, rkey: string, options?: ApiFetchOptions): Promise; /** Clear the "primary" flag on a position. */ declare function unsetPositionPrimary(config: SifaApiConfig, rkey: string, options?: ApiFetchOptions): Promise; /** * Add a skill link to a position. Idempotent: if the skill is already * linked, resolves to `{ success: true }` without a network call. * * Implementation note: the AppView only exposes whole-record PUTs, so * this helper rebuilds the position body with the new skills list. */ declare function linkSkillToPosition(config: SifaApiConfig, position: ProfilePosition, skillRef: SkillRef, options?: ApiFetchOptions): Promise; /** Remove a skill link from a position. */ declare function unlinkSkillFromPosition(config: SifaApiConfig, position: ProfilePosition, skillRef: SkillRef, options?: ApiFetchOptions): Promise; /** * Create a new `id.sifa.profile.education` record on the authenticated * user's PDS. */ declare function createEducation(config: SifaApiConfig, data: Record, options?: ApiFetchOptions): Promise; /** Update an existing education record by `rkey`. */ declare function updateEducation(config: SifaApiConfig, rkey: string, data: Record, options?: ApiFetchOptions): Promise; /** Delete an education record by `rkey`. */ declare function deleteEducation(config: SifaApiConfig, rkey: string, options?: ApiFetchOptions): Promise; /** * Generic record-create escape hatch. Most callers should prefer the * dedicated section helpers (`createPosition`, `createEducation`, etc.) * which take typed payloads and ship matching hooks. Use this when the * lexicon doesn't yet have a dedicated endpoint (certifications, * projects, publications, volunteering, honors, languages, courses). * * `collection` is a `id.sifa.profile.*` collection NSID. Routes to * `POST /api/profile/records/`. */ declare function createRecord(config: SifaApiConfig, collection: string, data: Record, options?: ApiFetchOptions): Promise; /** Generic record-update escape hatch. See {@link createRecord}. */ declare function updateRecord(config: SifaApiConfig, collection: string, rkey: string, data: Record, options?: ApiFetchOptions): Promise; /** Generic record-delete escape hatch. See {@link createRecord}. */ declare function deleteRecord(config: SifaApiConfig, collection: string, rkey: string, options?: ApiFetchOptions): Promise; interface ReceivedEndorsement { endorserDid: string; /** Absent when the endorser has no Sifa profile yet. */ endorserHandle?: string; endorserDisplayName?: string; endorserAvatar?: string; skillUri?: string; skillCid?: string; skillName: string; comment?: string; createdAt: string; } interface ReceivedEndorsementsPage { endorsements: ReceivedEndorsement[]; cursor?: string; } /** * Confirmed endorsements a DID has received, newest first. * * Only confirmed ones exist here: the AppView inner-joins against the * confirmation records, so an endorsement the subject has not accepted is * absent rather than pending. Public -- no credentials needed. * * Returns an empty page on failure so a surface that merely decorates a page * cannot break it. */ declare function fetchReceivedEndorsements(config: SifaApiConfig, did: string, options?: { limit?: number; } & ApiFetchOptions): Promise; interface ReciprocitySkill { name: string; uri: string; /** Absent until the firehose indexes the skill; the AppView resolves it. */ cid?: string; } interface ReciprocityCandidate { did: string; handle: string; displayName?: string; avatar?: string; skills: ReciprocitySkill[]; } /** * Someone the signed-in user follows on Sifa whose skills they could endorse. * * The AppView picks: it filters people already dismissed and anyone blocked, * requires at least one skill, and rotates the choice every twelve hours so * the same person is not offered indefinitely. * * `null` means there is nobody left to suggest -- a real state, not an error. * Failures also yield `null` so a broken suggestion never breaks the homepage. */ declare function fetchReciprocityCandidate(config: SifaApiConfig, options?: ApiFetchOptions): Promise; /** A received endorsement the subject has neither confirmed nor dismissed. */ interface PendingEndorsement { endorserDid: string; /** * Endorser's handle, when the AppView has resolved one. Absent when the * endorser has no Sifa profile yet -- an endorsement can come from any AT * Protocol app -- so the UI needs a fallback for having no name to show. */ endorserHandle?: string; rkey: string; /** * AT-URI of the endorsement record. The confirm mutation needs a strongRef, * so the AppView hands this back rather than making callers rebuild it. */ uri: string; /** * CID of the endorsement record, when the AppView has it. Often absent: * an endorsement written by another AT Protocol app can be indexed without * its CID ever reaching us. Pass it through to confirm when present; the * AppView resolves it from the endorser's PDS when it is not. */ cid?: string; /** Absent when this endorsement proposes a skill the subject does not have. */ skillUri?: string; skillCid?: string; /** * True when accepting this will add `skillName` to the profile as well as * publishing the endorsement. The UI must say so: it is a bigger action than * confirming an endorsement of a skill already listed. */ proposesNewSkill?: boolean; skillName: string; comment?: string; createdAt: string; } interface PendingEndorsementsPage { endorsements: PendingEndorsement[]; cursor?: string; } /** Body accepted by {@link dismissEndorsement}. */ interface DismissEndorsementInput { endorserDid: string; rkey: string; } /** * Endorsements awaiting the signed-in user's decision. Requires credentials -- * the AppView reads the subject DID from the session, not from a parameter, so * there is no way to read someone else's inbox. * * Returns an empty page on failure so a broken inbox degrades to "nothing * pending" rather than breaking the surface hosting it. */ declare function fetchPendingEndorsements(config: SifaApiConfig, options?: ApiFetchOptions): Promise; /** * Take a received endorsement out of the inbox. * * This writes nothing to any PDS. An endorsement only displays once the subject * has confirmed it, so declining is already the default state -- the dismissal * is a local flag that stops it reappearing, not a published rejection. */ declare function dismissEndorsement(config: SifaApiConfig, data: DismissEndorsementInput, options?: ApiFetchOptions): Promise; /** * Hide a keytrace claim (verified-account claim discovered on the * user's external accounts) from the user's profile. The claim itself * stays in the index; only its display is suppressed. */ declare function hideKeytraceClaim(config: SifaApiConfig, rkey: string, options?: ApiFetchOptions): Promise; /** Restore a previously-hidden keytrace claim. */ declare function unhideKeytraceClaim(config: SifaApiConfig, rkey: string, options?: ApiFetchOptions): Promise; /** * Make a Marque-registered domain public in the owner's Links section. Marque * domains are owner-only by default; this reveals one. `domain` is the * at.marque.domain rkey (the domain name itself). */ declare function revealMarqueDomain(config: SifaApiConfig, domain: string, options?: ApiFetchOptions): Promise; /** Make a previously-revealed Marque domain owner-only again. */ declare function unrevealMarqueDomain(config: SifaApiConfig, domain: string, options?: ApiFetchOptions): Promise; /** * Which claim a listed speaker makes about a topic. Phase 1 has no confirmed * data, so groups are named by the CLAIM, never a "proven" label: * - `spoke_about_it` — has a topic-matching delivery (or, with a topic set, * a matching presentation plus at least one delivery) * - `skilled` — holds the matching canonical skill but has no matching talk * (only appears when a topic is supplied) * - `open_to_speaking` — opted in but has never delivered (only appears when * no topic is supplied) */ type SpeakerGroup = 'spoke_about_it' | 'skilled' | 'open_to_speaking'; /** One person in the speaker directory. Everyone listed has opted in. */ interface SpeakerCard { did: string; handle: string; displayName: string | null; avatar: string | null; headline: string | null; currentRole: string | null; currentCompany: string | null; deliveryCount: number; group: SpeakerGroup; matchedTopics: string[]; /** * Self-reported event names from the speaker's own presentationDelivery * records — unconfirmed in Phase 1. `eventsSelfReported` is always true; * the web layer labels these as such. */ recentEvents: string[]; eventsSelfReported: boolean; /** * Up to 3 of the speaker's most-recent talks (self-reported), newest first. * `rkey` builds the talk-page URL via `buildTalkSlug(title, rkey)`. Optional: * absent from responses served before this field shipped, so consumers should * default to an empty list. */ recentTalks?: { title: string; rkey: string; }[]; } interface SpeakersResponse { speakers: SpeakerCard[]; } /** The reusable talk, or a standalone delivery when it has no parent talk. */ interface TalkEvent { eventName: string | null; date: string | null; } /** Compact speaker card embedded in a talk row. */ interface TalkSpeaker { did: string; handle: string; displayName: string | null; avatar: string | null; headline: string | null; currentRole: string | null; currentCompany: string | null; } interface TalkRow { /** * `presentation` = a reusable `id.sifa.profile.presentation` record. * `delivery` = a standalone presentationDelivery with no parent presentation. */ kind: 'presentation' | 'delivery'; rkey: string; title: string | null; snippet: string | null; links: PresentationLinkView[]; writeupUri: string | null; speaker: TalkSpeaker; events: TalkEvent[]; eventsSelfReported: boolean; deliveryCount: number; matchedTopics: string[]; } interface TalksResponse { talks: TalkRow[]; } interface SpeakerDirectoryFilters { /** Free-text topic (canonical skill name/slug/alias, talk title, or event). */ topic?: string; /** Max rows to return; the API caps this at 50. */ limit?: number; } /** * Speaker directory (Phase 1, read-only POC). Everyone returned has opted in to * speaking; past deliveries are a ranking signal, not an inclusion path. An * optional `topic` filters to people who hold the matching canonical skill, * have a matching presentation, or have a matching delivery. Results come * grouped and ordered by the API. * * Returns an empty list on any error so callers can render a graceful state. */ declare function fetchSpeakers(config: SifaApiConfig, filters?: SpeakerDirectoryFilters, options?: ApiFetchOptions): Promise; /** * Talk directory (Phase 1, read-only POC). Lists talks by opted-in speakers, * delivered-first, then latest delivery date. Same optional `topic` filter as * {@link fetchSpeakers}. Returns an empty list on any error. */ declare function fetchTalks(config: SifaApiConfig, filters?: SpeakerDirectoryFilters, options?: ApiFetchOptions): Promise; /** * Organization typeahead. Returns curated entities first, then the PDL crawl, * deduped by domain. Empty input returns an empty result without a network call. */ declare function fetchEntitySearch(config: SifaApiConfig, query: string, limit?: number, options?: ApiFetchOptions): Promise; /** * Record a selection: promote a PDL row into a canonical entity (dedupe by * domain) or bump an existing entity's usage counter. Returns the entity plus * its portable `entityRef` (null for PDL-only entities). Requires a session. */ declare function selectEntity(config: SifaApiConfig, body: EntitySelectRequest, options?: ApiFetchOptions): Promise; /** * Grow-on-demand: when the local typeahead misses, resolve the query live via * Wikidata, import the org-class matches, and return them. Requires a session. * Empty input returns an empty array without a network call. */ declare function importSearchEntities(config: SifaApiConfig, query: string, options?: ApiFetchOptions): Promise; /** * Grow-on-demand by domain, Branch 1: when a domain-shaped typeahead query * misses locally, resolve any notable company whose official website is that * domain (Wikidata reverse P856), importing the matches. Read-only w.r.t. * minting. `canMint` tells the caller whether to offer the user-initiated * "Add " affordance. Requires a session. */ declare function resolveEntityDomain(config: SifaApiConfig, domain: string, options?: ApiFetchOptions): Promise; /** * Grow-on-demand by domain, Branch 2 (user-initiated): mint a crawled-tier * entity from the domain's own homepage (or resolve it to a notable company if * one exists). Throws on a non-2xx response (domain not mintable, or the site * yielded nothing usable). Requires a session. */ declare function mintEntityDomain(config: SifaApiConfig, domain: string, options?: ApiFetchOptions): Promise; /** * Counts confirmed endorsements received by a DID. The backend's * `GET /api/endorsement/:did` already returns only confirmed endorsements * (via inner join with `endorsementConfirmations`), so this helper just * returns the array length. Failures return 0 so callers can route safely. * * Public endpoint -- no credentials needed. */ declare function fetchEndorsementCount(config: SifaApiConfig, did: string, options?: ApiFetchOptions): Promise; interface FetchNetworkStreamCountOptions extends ApiFetchOptions { /** * Pass the caller's `Cookie` header on Next.js RSC server-side calls. * Required for authenticated server fetches because `credentials: 'include'` * does not propagate browser cookies in RSC. * * When omitted, the request falls back to `credentials: 'include'` so * client-side calls work without extra plumbing. */ cookieHeader?: string; } /** * Counts items in the authenticated user's network stream digest. The * underlying `GET /api/stream/network` endpoint may 404 while the feature * is in development; in that case (and on any other error) this returns * 0 so callers can route safely to a fallback experience. */ declare function fetchNetworkStreamCount(config: SifaApiConfig, did: string, options?: FetchNetworkStreamCountOptions): Promise; /** A node in the personal network graph. */ interface NetworkMapNode { did: string; handle: string; displayName: string; avatar: string | null; /** Number of edges this node participates in within the rendered graph. */ degree: number; /** Phase 2: community detection cluster id. */ cluster?: number; /** Phase 2: pre-computed layout coordinates. */ x?: number; y?: number; } /** A directed edge in the personal network graph. */ interface NetworkMapEdge { source: string; target: string; mutual: boolean; /** Networks this edge was observed in, e.g. `['sifa', 'bluesky']`. */ sources: string[]; } /** The graph payload itself, decoupled from response metadata. */ interface NetworkMapGraphData { nodes: NetworkMapNode[]; edges: NetworkMapEdge[]; /** Phase 2: cluster metadata for legend rendering. */ clusters?: Array<{ id: number; label: string; color: string; }>; } /** Cached graph response. */ interface NetworkMapResponse { generatedAt: string; expiresAt: string; graph: NetworkMapGraphData; stats: { totalNodes: number; totalEdges: number; mutualCount: number; sources: Record; }; } /** Async job tracking generation progress. */ interface NetworkMapGenerationJob { jobId: string; did: string; status: 'pending' | 'complete' | 'failed'; /** 0..100 */ progress: number; createdAt: string; completedAt?: string; error?: string; /** * Queue position when the job is still pending and not yet picked up * by the worker. 0 = next to run. Absent for in-flight or terminal * jobs (and for any backend that doesn't yet report position). */ position?: number; /** * Estimated remaining seconds, derived server-side from the median * historical duration for the user's follow-count bucket multiplied * by `position + 1`. Absent when no historical data exists yet. */ etaSeconds?: number; } /** Returned by `initiateNetworkMapGeneration` when a new job was started or one was already running. */ interface NetworkMapPendingJob { jobId: string; status: 'pending' | 'cached'; } /** Discriminate the union returned by `initiateNetworkMapGeneration`. */ declare function isNetworkMapResponse(value: NetworkMapPendingJob | NetworkMapResponse): value is NetworkMapResponse; /** * Kick off a personal network-map computation. The backend returns the * cached map immediately when fresh, otherwise it returns a job id that * the caller polls via `checkNetworkMapJobStatus`. */ declare function initiateNetworkMapGeneration(config: SifaApiConfig, options?: ApiFetchOptions): Promise; /** * Poll the status of an in-flight generation job. Throws on 404 (unknown * or expired job) — callers may want to treat that as terminal failure. */ declare function checkNetworkMapJobStatus(config: SifaApiConfig, jobId: string, options?: ApiFetchOptions): Promise; /** * Fetch the most recent cached network map for the authenticated user. * Returns `null` when no map has ever been generated (404). */ declare function fetchNetworkMap(config: SifaApiConfig, options?: ApiFetchOptions): Promise; export { unhideKeytraceClaim as $, fetchGetProfileView as A, fetchNetworkMap as B, fetchNetworkStreamCount as C, type DismissEndorsementInput as D, fetchPendingEndorsements as E, type FetchNetworkStreamCountOptions as F, fetchProfile as G, fetchProfileSummary as H, fetchReceivedEndorsements as I, fetchReciprocityCandidate as J, fetchSpeakers as K, fetchTalks as L, hideKeytraceClaim as M, type NetworkMapEdge as N, importSearchEntities as O, type PendingEndorsementsPage as P, initiateNetworkMapGeneration as Q, type ReceivedEndorsementsPage as R, type SpeakerCard as S, type TalkEvent as T, isNetworkMapResponse as U, linkSkillToPosition as V, mintEntityDomain as W, resolveEntityDomain as X, revealMarqueDomain as Y, selectEntity as Z, setPositionPrimary as _, type ReciprocityCandidate as a, unlinkSkillFromPosition as a0, unrevealMarqueDomain as a1, unsetPositionPrimary as a2, updateEducation as a3, updatePosition as a4, updateRecord as a5, type NetworkMapGenerationJob as b, type NetworkMapGraphData as c, type NetworkMapNode as d, type NetworkMapPendingJob as e, type NetworkMapResponse as f, type PendingEndorsement as g, type ReceivedEndorsement as h, type ReciprocitySkill as i, type SpeakerDirectoryFilters as j, type SpeakerGroup as k, type SpeakersResponse as l, type TalkRow as m, type TalkSpeaker as n, type TalksResponse as o, checkNetworkMapJobStatus as p, createEducation as q, createPosition as r, createRecord as s, deleteEducation as t, deletePosition as u, deleteRecord as v, dismissEndorsement as w, fetchAtFundLink as x, fetchEndorsementCount as y, fetchEntitySearch as z };