Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Docs: a workspace knowledge base people and agents write together | 1 | /** |
| The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook. | 2 | * Docs: the workspace's written knowledge, kept by the artifacts service |
| 3 | * (`services/artifacts`). Spaces hold trees of pages; each page is a CRDT | |
| Docs: a workspace knowledge base people and agents write together | 4 | * document (Yjs) edited live over a socket, saved with a Markdown |
| The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were. | 5 | * rendition that search, agents, export and the read view use. |
| Docs: a workspace knowledge base people and agents write together | 6 | * |
| 7 | * Wire shapes are snake_case end to end: the site, agents and the live | |
| 8 | * socket all carry the same objects. | |
| 9 | * | |
| 10 | * Access, in one place: | |
| 11 | * | |
| 12 | * - A space has a kind: `workspace` (every member gets `default_role`), | |
| 13 | * `team` (the team's members get `default_role`) or `private` (only the | |
| 14 | * people, agents and teams listed as its members). | |
| 15 | * - Members are listed with a role: view < comment < edit < manage. A | |
| 16 | * person's role is the highest of the space's base role (when it applies | |
| 17 | * to them) and every listing that names them or one of their teams. | |
| 18 | * Workspace owners manage every workspace and team space; a private space | |
| 19 | * is its members' alone. | |
| 20 | * - An agent never sees or changes more than the person it acts for (the | |
| 21 | * `viewer` on every agent call). It reads what that person can read, | |
| 22 | * narrowed further to what every person in the `audience` can read; it | |
| 23 | * suggests where that person can comment; and it edits directly only | |
| 24 | * where that person can edit AND the space lets agents edit | |
| 25 | * (`agent_mode: "edit"`). Otherwise its edit becomes a suggestion. | |
| 26 | */ | |
| 27 | import type { MemberProfile, Principal } from "./chat"; | |
| 28 | import type { ServiceBinding } from "./clients"; | |
| 29 | import type { User } from "./identity"; | |
| 30 | import type { Result } from "./result"; | |
| 31 | ||
| 32 | /** What someone may do in a space, weakest first. */ | |
| 33 | export type DocRole = "view" | "comment" | "edit" | "manage"; | |
| 34 | export const DOC_ROLES: readonly DocRole[] = ["view", "comment", "edit", "manage"]; | |
| 35 | ||
| 36 | export const DOC_ROLE_LABELS: Record<DocRole, string> = { | |
| 37 | view: "Can view", | |
| 38 | comment: "Can comment", | |
| 39 | edit: "Can edit", | |
| 40 | manage: "Full access", | |
| 41 | }; | |
| 42 | ||
| 43 | export const DOC_ROLE_SUMMARIES: Record<DocRole, string> = { | |
| 44 | view: "Read pages and their history.", | |
| 45 | comment: "Read pages and comment on them.", | |
| 46 | edit: "Write and organize pages, and accept or reject suggestions.", | |
| 47 | manage: "Edit, and change who has access and how agents work here.", | |
| 48 | }; | |
| 49 | ||
| 50 | /** Who a space is for. */ | |
| 51 | export type DocSpaceKind = "workspace" | "team" | "private"; | |
| 52 | ||
| 53 | export const DOC_SPACE_KIND_LABELS: Record<DocSpaceKind, string> = { | |
| 54 | workspace: "Everyone in the workspace", | |
| 55 | team: "A team", | |
| 56 | private: "Only its members", | |
| 57 | }; | |
| 58 | ||
| 59 | /** How agents change pages in a space: as tracked suggestions (the default), or directly. */ | |
| 60 | export type DocAgentMode = "suggest" | "edit"; | |
| 61 | ||
| 62 | export const DOC_AGENT_MODE_LABELS: Record<DocAgentMode, string> = { | |
| 63 | suggest: "Suggest changes", | |
| 64 | edit: "Edit directly", | |
| 65 | }; | |
| 66 | ||
| 67 | /** A key for a space member: `user:<id>`, `agent:<id>` or `team:<slug>`. */ | |
| 68 | export type DocMemberKey = string; | |
| 69 | ||
| 70 | export type DocSpace = { | |
| 71 | id: string; | |
| 72 | workspace_id: string; | |
| 73 | /** Unique in the workspace; in the URL: `/<workspace>/-/docs/<slug>`. */ | |
| 74 | slug: string; | |
| 75 | name: string; | |
| 76 | description: string | null; | |
| 77 | /** An emoji, or null for the default book. */ | |
| 78 | icon: string | null; | |
| 79 | kind: DocSpaceKind; | |
| 80 | /** The team's slug, for a team space. */ | |
| 81 | team: string | null; | |
| 82 | /** What every workspace member (workspace) or team member (team) gets; null for a private space. */ | |
| 83 | default_role: DocRole | null; | |
| 84 | agent_mode: DocAgentMode; | |
| The docs service answers folio_page with a folio and what its page shows around it, a space can let its editors share what is in it, and someone asking for access to an artifact is told to wait when they already asked for it in the last day. | 85 | /** People with edit access may share what is in it (Artifacts), as people with full access can. Off unless turned on. */ |
| 86 | editors_can_share: boolean; | |
| Docs: a workspace knowledge base people and agents write together | 87 | /** The workspace's General space, made the first time Docs is opened. Can't be archived. */ |
| 88 | is_default: boolean; | |
| 89 | /** Projects (repositories, `owner/name`) the space is about: Docs filters by them. */ | |
| 90 | projects: string[]; | |
| 91 | created_by: Principal; | |
| 92 | created_at: string; | |
| 93 | archived_at: string | null; | |
| 94 | /** The viewer's role in it. */ | |
| 95 | viewer_role: DocRole; | |
| 96 | /** Pages in it that are not in the trash. */ | |
| 97 | page_count: number; | |
| 98 | }; | |
| 99 | ||
| 100 | /** A space member, as the space's settings show it. */ | |
| 101 | export type DocSpaceMember = { | |
| 102 | key: DocMemberKey; | |
| 103 | kind: "user" | "agent" | "team"; | |
| 104 | /** Username, agent handle or team slug. */ | |
| 105 | name: string; | |
| 106 | display_name: string; | |
| 107 | avatar: string | null; | |
| 108 | avatar_seed?: string | null; | |
| 109 | role: DocRole; | |
| 110 | }; | |
| 111 | ||
| 112 | /** Enough to link to a page. */ | |
| 113 | export type DocPageRef = { | |
| 114 | id: string; | |
| 115 | space_id: string; | |
| 116 | space_slug: string; | |
| 117 | title: string; | |
| 118 | /** An emoji, or null for the default page icon. */ | |
| 119 | icon: string | null; | |
| 120 | /** `<title-slug>-<id>`: the last part of the page's URL. */ | |
| 121 | slug: string; | |
| 122 | /** `/<workspace>/-/docs/<space>/<slug>`. */ | |
| 123 | path: string; | |
| 124 | }; | |
| 125 | ||
| 126 | export type DocPage = DocPageRef & { | |
| 127 | parent_id: string | null; | |
| 128 | position: number; | |
| 129 | /** A cover image's URL, or a CSS gradient name (`gradient:<n>`); null for none. */ | |
| 130 | cover: string | null; | |
| 131 | created_by: MemberProfile; | |
| 132 | created_at: string; | |
| 133 | updated_by: MemberProfile | null; | |
| 134 | updated_at: string; | |
| 135 | /** When it went to the trash; null when it is not there. */ | |
| 136 | archived_at: string | null; | |
| 137 | has_children: boolean; | |
| 138 | /** Projects (`owner/name`) the page is about, besides its space's. */ | |
| 139 | projects: string[]; | |
| 140 | owners: MemberProfile[]; | |
| 141 | /** The first lines of its text, for cards. */ | |
| 142 | excerpt: string; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 143 | /** Whether code it cites changed since someone last marked it current: possibly out of date. */ |
| 144 | stale: boolean; | |
| 145 | }; | |
| 146 | ||
| 147 | // ── Citations and staleness ─────────────────────────────────────────────── | |
| 148 | // | |
| 149 | // A page can cite code: a path (a file, a folder, or a glob like | |
| 150 | // `src/export/**`) in a repository, optionally naming what at that path it | |
| 151 | // describes (a symbol, an endpoint, an environment variable). Citations | |
| 152 | // come from the page's text (the editor's citation chips, and links to | |
| 153 | // files in a repository: `/<owner>/<repo>/blob/<ref>/<path>`) and from | |
| 154 | // the page's header ("Describes"). When a merged pull request or a push | |
| 155 | // to a repository's default branch changes a cited path, the page is | |
| 156 | // marked possibly out of date with that change, until someone with edit | |
| 157 | // access marks it current again (or an agent updates it). | |
| 158 | ||
| 159 | /** What a citation names at its path. */ | |
| 160 | export type DocCitationKind = "path" | "symbol" | "endpoint" | "env"; | |
| 161 | export const DOC_CITATION_KINDS: readonly DocCitationKind[] = ["path", "symbol", "endpoint", "env"]; | |
| 162 | ||
| 163 | export const DOC_CITATION_KIND_LABELS: Record<DocCitationKind, string> = { | |
| 164 | path: "A file or folder", | |
| 165 | symbol: "A symbol", | |
| 166 | endpoint: "An endpoint", | |
| 167 | env: "An environment variable", | |
| 168 | }; | |
| 169 | ||
| 170 | export type DocCitation = { | |
| 171 | /** `owner/name`, lowercased. */ | |
| 172 | repo: string; | |
| 173 | /** A file, a folder (everything under it), or a glob (`*`, `**`, `?`). */ | |
| 174 | path: string; | |
| 175 | kind: DocCitationKind; | |
| 176 | /** The symbol, endpoint (`POST /v1/export`) or variable (`EXPORT_BUCKET`), for those kinds. */ | |
| 177 | label: string | null; | |
| 178 | /** The commit it was cited at, when known. */ | |
| 179 | ref: string | null; | |
| 180 | /** From the page's text, or from its header's "Describes". */ | |
| 181 | source: "body" | "header"; | |
| 182 | }; | |
| 183 | ||
| 184 | /** One entry of a page's "Describes": a repository and a path in it. */ | |
| 185 | export type DocDescribes = { repo: string; path: string }; | |
| 186 | ||
| 187 | /** A change that made a page possibly out of date. */ | |
| 188 | export type DocStaleChange = { | |
| 189 | /** | |
| 190 | * False when the viewer can't read the repository: then `repo`, `pull`, | |
| 191 | * `commit` and `paths` are blank, and the page only says that a change | |
| 192 | * they can't see touched code it cites. | |
| 193 | */ | |
| 194 | visible: boolean; | |
| 195 | repo: string | null; | |
| 196 | commit: string | null; | |
| 197 | /** The merged pull request, when the change came from one. */ | |
| 198 | pull: { number: number; title: string | null } | null; | |
| 199 | /** The cited paths it changed (the changed files, at most 20). */ | |
| 200 | paths: string[]; | |
| 201 | /** When it was noticed. RFC 3339. */ | |
| 202 | at: string; | |
| 203 | }; | |
| 204 | ||
| 205 | /** Why a page is possibly out of date: every change since it was last marked current, newest first. */ | |
| 206 | export type DocStaleness = { since: string; changes: DocStaleChange[] }; | |
| 207 | ||
| 208 | /** A page an agent may bring up to date, with what changed. */ | |
| 209 | export type DocStalePage = { | |
| 210 | page: DocPageRef & { updated_at: string }; | |
| 211 | space: { id: string; slug: string; name: string; agent_mode: DocAgentMode }; | |
| 212 | can: DocAgentAbilities; | |
| 213 | owners: MemberProfile[]; | |
| 214 | citations: DocCitation[]; | |
| 215 | /** Changes in repositories the viewer (and audience) can read; newest first. */ | |
| 216 | changes: DocStaleChange[]; | |
| 217 | since: string; | |
| 218 | }; | |
| 219 | ||
| 220 | // ── A project's docs ────────────────────────────────────────────────────── | |
| 221 | // | |
| 222 | // A repository's `docs/` folder (and README.md), shown read-only in Docs | |
| 223 | // next to the workspace's spaces and found by the same search. It is read | |
| 224 | // from the default branch and kept up to date on every push to it. Each | |
| 225 | // reader sees only the repositories they can read. Changes go through the | |
| 226 | // repository: "Edit in Code" opens the file. | |
| 227 | ||
| 228 | export type DocRepoFile = { | |
| 229 | /** From the repository's root: `docs/guide/setup.md`, `README.md`. */ | |
| 230 | path: string; | |
| 231 | /** Its first heading, or its file name. */ | |
| 232 | title: string; | |
| 233 | }; | |
| 234 | ||
| 235 | export type DocRepoSpace = { | |
| 236 | id: string; | |
| 237 | /** `owner/name`, as the repository is named now. */ | |
| 238 | repo: string; | |
| 239 | default_branch: string; | |
| 240 | /** The commit it was read at; null until it has been. */ | |
| 241 | commit: string | null; | |
| 242 | indexed_at: string | null; | |
| 243 | added_by: MemberProfile; | |
| 244 | files: DocRepoFile[]; | |
| 245 | /** Whether the viewer may stop showing it (whoever added it, or an owner). */ | |
| 246 | can_remove: boolean; | |
| Docs: a workspace knowledge base people and agents write together | 247 | }; |
| 248 | ||
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 249 | export type DocRepoPage = { |
| 250 | space: DocRepoSpace; | |
| 251 | file: DocRepoFile & { | |
| 252 | markdown: string; | |
| 253 | /** `/<workspace>/-/docs/repo/<owner>/<name>/<path>`. */ | |
| 254 | href: string; | |
| 255 | /** The file in Code, on the default branch. */ | |
| 256 | code_href: string; | |
| 257 | }; | |
| 258 | }; | |
| 259 | ||
| Docs: a workspace knowledge base people and agents write together | 260 | /** A page as the sidebar's tree lists it: flat, ordered by `position` within each parent. */ |
| 261 | export type DocTreeNode = { | |
| 262 | id: string; | |
| 263 | parent_id: string | null; | |
| 264 | position: number; | |
| 265 | title: string; | |
| 266 | icon: string | null; | |
| 267 | slug: string; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 268 | /** Possibly out of date (see `DocPage.stale`). */ |
| 269 | stale?: boolean; | |
| Docs: a workspace knowledge base people and agents write together | 270 | }; |
| 271 | ||
| 272 | export type DocsSidebarSpace = DocSpace & { pages: DocTreeNode[] }; | |
| 273 | ||
| 274 | export type DocsSidebar = { | |
| 275 | spaces: DocsSidebarSpace[]; | |
| 276 | favorites: DocPageRef[]; | |
| 277 | /** The pages the viewer opened last, newest first. */ | |
| 278 | recent: DocPageRef[]; | |
| 279 | /** Whether the viewer may make spaces (members of the workspace may). */ | |
| 280 | can_create_space: boolean; | |
| 281 | trash_count: number; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 282 | /** Pages the viewer can read that are possibly out of date. */ |
| 283 | stale_count: number; | |
| 284 | /** Projects' docs folders shown in Docs, those whose repository the viewer can read. */ | |
| 285 | repos: DocRepoSpace[]; | |
| Docs: a workspace knowledge base people and agents write together | 286 | }; |
| 287 | ||
| 288 | export type DocsHome = { | |
| 289 | /** Recently edited pages the viewer can read, newest first. */ | |
| 290 | recent: DocPage[]; | |
| 291 | /** Pages the viewer made or owns. */ | |
| 292 | mine: DocPage[]; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 293 | /** Pages possibly out of date, most recently flagged first. */ |
| 294 | stale: DocPage[]; | |
| Docs: a workspace knowledge base people and agents write together | 295 | spaces: DocSpace[]; |
| 296 | /** Every project some space or page is linked to, for the filter. */ | |
| 297 | projects: string[]; | |
| 298 | /** The project the lists are filtered to, or null. */ | |
| 299 | project: string | null; | |
| 300 | }; | |
| 301 | ||
| 302 | /** A tracked change an agent proposed. `blocks` targets name top-level block ids from `page_markdown`. */ | |
| 303 | export type DocEditTarget = | |
| 304 | /** Add to the end of the page. */ | |
| 305 | | { kind: "append" } | |
| 306 | /** Replace the whole page. */ | |
| 307 | | { kind: "document" } | |
| 308 | /** Replace a section: the heading whose text matches (case-insensitive) and everything under it, up to the next heading of the same or a higher level. The new Markdown should include the heading if it is to stay. */ | |
| 309 | | { kind: "section"; heading: string } | |
| 310 | /** Replace top-level blocks `from_block` through `to_block`, inclusive (with any blocks nested under them). */ | |
| 311 | | { kind: "blocks"; from_block: string; to_block: string }; | |
| 312 | ||
| 313 | export type DocSuggestionStatus = "open" | "accepted" | "rejected" | "stale"; | |
| 314 | ||
| 315 | export type DocSuggestion = { | |
| 316 | id: string; | |
| 317 | page_id: string; | |
| 318 | /** The agent that suggested it. */ | |
| 319 | author: MemberProfile; | |
| 320 | /** The person it acted for. */ | |
| 321 | asked_by: MemberProfile | null; | |
| 322 | target: DocEditTarget; | |
| 323 | /** The target's Markdown when it was suggested. */ | |
| 324 | before_markdown: string; | |
| 325 | /** What it proposes instead. */ | |
| 326 | after_markdown: string; | |
| 327 | /** Why, in a line. */ | |
| 328 | note: string | null; | |
| 329 | status: DocSuggestionStatus; | |
| 330 | created_at: string; | |
| 331 | decided_by: MemberProfile | null; | |
| 332 | decided_at: string | null; | |
| 333 | /** The top-level blocks it covers now, so the editor can mark them; empty for an append or when the target is gone. */ | |
| 334 | block_ids: string[]; | |
| 335 | }; | |
| 336 | ||
| 337 | export type DocVersionKind = "created" | "edit" | "agent" | "suggestion" | "restore"; | |
| 338 | ||
| 339 | export type DocVersion = { | |
| 340 | id: string; | |
| 341 | page_id: string; | |
| 342 | created_at: string; | |
| 343 | /** Everyone whose changes are in it, people and agents. */ | |
| 344 | authors: MemberProfile[]; | |
| 345 | kind: DocVersionKind; | |
| 346 | /** "Suggested by @inky, accepted by @ana"; "Restored from Oct 3, 14:02". */ | |
| 347 | note: string | null; | |
| 348 | }; | |
| 349 | ||
| 350 | export type DocDiffLine = { op: "same" | "add" | "del"; text: string }; | |
| 351 | ||
| 352 | export type DocVersionDetail = DocVersion & { | |
| 353 | markdown: string; | |
| 354 | /** Against the version before it (or nothing, for the first). */ | |
| 355 | diff: DocDiffLine[]; | |
| 356 | }; | |
| 357 | ||
| 358 | export type DocPageDetail = { | |
| 359 | page: DocPage; | |
| 360 | space: DocSpace; | |
| 361 | /** The page's ancestors, root first. */ | |
| 362 | breadcrumbs: DocPageRef[]; | |
| 363 | /** As last saved: the read view, and what the editor shows before the socket connects. */ | |
| 364 | markdown: string; | |
| 365 | role: DocRole; | |
| 366 | backlinks: DocPageRef[]; | |
| 367 | children: DocPageRef[]; | |
| 368 | favorite: boolean; | |
| 369 | /** When the viewer last opened it, before now. */ | |
| 370 | last_viewed_at: string | null; | |
| 371 | suggestions: DocSuggestion[]; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 372 | /** Code the page cites: from its text and its header. */ |
| 373 | citations: DocCitation[]; | |
| 374 | /** The header's "Describes" list. */ | |
| 375 | describes: DocDescribes[]; | |
| 376 | /** Why it is possibly out of date; null when it isn't. */ | |
| 377 | staleness: DocStaleness | null; | |
| Docs: a workspace knowledge base people and agents write together | 378 | }; |
| 379 | ||
| 380 | export type DocSearchHit = DocPageRef & { | |
| 381 | space_name: string; | |
| 382 | /** Text around the match; `[[` and `]]` mark matched words. */ | |
| 383 | snippet: string; | |
| 384 | updated_at: string; | |
| 385 | projects: string[]; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 386 | /** Set for a file from a project's docs folder (then `id` is `repo:<space>:<path>` and `path` its address in Docs). */ |
| 387 | repo_file?: { repo: string; path: string } | null; | |
| Docs index by meaning: passages of every page and project doc, embedded on save and recalled for agents; hybrid search for people | 388 | /** The heading of the passage that matched, when search found one (`mode: "hybrid"`). */ |
| 389 | heading?: string | null; | |
| 390 | /** How it was found: by its words, by meaning (the semantic index), or both. */ | |
| 391 | matched?: "words" | "meaning" | "both" | null; | |
| Docs: a workspace knowledge base people and agents write together | 392 | }; |
| 393 | ||
| 394 | export type DocTemplate = { | |
| 395 | id: string; | |
| 396 | name: string; | |
| 397 | description: string; | |
| 398 | icon: string; | |
| 399 | /** Built in (meeting notes, RFC, ...) rather than saved by the workspace. */ | |
| 400 | builtin: boolean; | |
| 401 | markdown: string; | |
| 402 | created_by: Principal | null; | |
| 403 | }; | |
| 404 | ||
| 405 | /** One top-level block, as agents see a page. */ | |
| 406 | export type DocBlockOutline = { | |
| 407 | id: string; | |
| 408 | /** BlockNote's type: `heading`, `paragraph`, `bulletListItem`, `codeBlock`, `callout`, ... */ | |
| 409 | type: string; | |
| 410 | /** For a heading. */ | |
| 411 | level: number | null; | |
| 412 | /** The block and anything nested under it. */ | |
| 413 | markdown: string; | |
| 414 | }; | |
| 415 | ||
| 416 | /** What an agent may do on a page, for the person it acts for. */ | |
| 417 | export type DocAgentAbilities = { read: boolean; suggest: boolean; edit: boolean }; | |
| 418 | ||
| 419 | export type DocAgentPage = { | |
| 420 | page: DocPageRef & { updated_at: string }; | |
| 421 | space: { id: string; slug: string; name: string; agent_mode: DocAgentMode }; | |
| 422 | markdown: string; | |
| 423 | blocks: DocBlockOutline[]; | |
| 424 | can: DocAgentAbilities; | |
| 425 | }; | |
| 426 | ||
| 427 | /** Who will see what an agent says; it reads only what they all can. */ | |
| 428 | export type DocAudience = | |
| 429 | /** These people (by user id), e.g. a DM's or a private channel's members. */ | |
| 430 | | { kind: "people"; user_ids: string[] } | |
| 431 | /** Everyone in the workspace, e.g. a public channel: only workspace-wide spaces. */ | |
| 432 | | { kind: "workspace" }; | |
| 433 | ||
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 434 | /** An agent's edit to a page. */ |
| 435 | export type DocAgentEdit = { | |
| 436 | target: DocEditTarget; | |
| 437 | markdown: string; | |
| 438 | note?: string | null; | |
| 439 | /** The edit brings the page up to date with the code it cites: once applied, the page is no longer possibly out of date. */ | |
| 440 | marks_current?: boolean | null; | |
| 441 | }; | |
| 442 | ||
| Docs: a workspace knowledge base people and agents write together | 443 | /** What `apply_edit` did: applied it, or filed a suggestion because it may not edit there. */ |
| 444 | export type DocAgentEditResult = | |
| 445 | | { mode: "applied"; version_id: string | null; page: DocPageRef } | |
| 446 | | { mode: "suggested"; suggestion: DocSuggestion; page: DocPageRef }; | |
| 447 | ||
| 448 | export type NewDocSpace = { | |
| 449 | name: string; | |
| 450 | slug?: string | null; | |
| 451 | description?: string | null; | |
| 452 | icon?: string | null; | |
| 453 | kind: DocSpaceKind; | |
| 454 | team?: string | null; | |
| 455 | default_role?: DocRole | null; | |
| 456 | agent_mode?: DocAgentMode | null; | |
| 457 | projects?: string[] | null; | |
| The docs service answers folio_page with a folio and what its page shows around it, a space can let its editors share what is in it, and someone asking for access to an artifact is told to wait when they already asked for it in the last day. | 458 | editors_can_share?: boolean | null; |
| Docs: a workspace knowledge base people and agents write together | 459 | }; |
| 460 | ||
| 461 | export type DocSpaceChange = Partial<Omit<NewDocSpace, "kind">> & { kind?: DocSpaceKind; archived?: boolean }; | |
| 462 | ||
| 463 | export type NewDocPage = { | |
| 464 | space_id: string; | |
| 465 | parent_id?: string | null; | |
| 466 | title?: string | null; | |
| 467 | icon?: string | null; | |
| 468 | /** A built-in template's id (`builtin:<name>`) or a saved one's. */ | |
| 469 | template_id?: string | null; | |
| 470 | /** Starting Markdown, when there is no template. */ | |
| 471 | markdown?: string | null; | |
| 472 | projects?: string[] | null; | |
| 473 | }; | |
| 474 | ||
| 475 | export type DocPageChange = { | |
| 476 | title?: string; | |
| 477 | icon?: string | null; | |
| 478 | cover?: string | null; | |
| 479 | projects?: string[]; | |
| 480 | /** Member keys (`user:<id>`, `agent:<id>`). */ | |
| 481 | owners?: string[]; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 482 | /** Replaces the header's "Describes" list (at most 20). */ |
| 483 | describes?: DocDescribes[]; | |
| Docs: a workspace knowledge base people and agents write together | 484 | }; |
| 485 | ||
| 486 | /** Where a page goes: under `parent_id` (null for the top of the space), before `before_id` (null for the end). */ | |
| 487 | export type DocMove = { space_id?: string | null; parent_id: string | null; before_id?: string | null }; | |
| 488 | ||
| 489 | export type DocSearchQuery = { | |
| 490 | query: string; | |
| 491 | space_id?: string | null; | |
| 492 | /** `owner/name`: pages linked to it, or in a space linked to it. */ | |
| 493 | project?: string | null; | |
| 494 | limit?: number | null; | |
| Docs index by meaning: passages of every page and project doc, embedded on save and recalled for agents; hybrid search for people | 495 | /** |
| 496 | * `words` (the default): titles and text by their words, as you type. | |
| 497 | * `hybrid`: words and meaning (the semantic index) together, each hit | |
| 498 | * with the passage and heading that matched; the Docs search page. | |
| 499 | */ | |
| 500 | mode?: "words" | "hybrid" | null; | |
| Docs: a workspace knowledge base people and agents write together | 501 | }; |
| 502 | ||
| 503 | /** | |
| 504 | * The comment operations of the editor's thread store (BlockNote's | |
| 505 | * `RESTYjsThreadStore`), applied by the page's room to the `threads` map in | |
| 506 | * the page's Yjs document, so every open editor sees them at once. | |
| 507 | */ | |
| 508 | export type DocThreadAction = | |
| 509 | | { op: "create"; body: unknown; metadata?: unknown; page_level?: boolean } | |
| 510 | /** Anchors a thread to the text between two Yjs relative positions (JSON). */ | |
| 511 | | { op: "anchor"; thread_id: string; anchor: unknown; head: unknown } | |
| 512 | | { op: "comment"; thread_id: string; body: unknown; metadata?: unknown } | |
| 513 | | { op: "edit_comment"; thread_id: string; comment_id: string; body: unknown; metadata?: unknown } | |
| 514 | | { op: "delete_comment"; thread_id: string; comment_id: string; soft?: boolean } | |
| 515 | | { op: "delete_thread"; thread_id: string } | |
| 516 | | { op: "resolve" | "unresolve"; thread_id: string } | |
| 517 | | { op: "react" | "unreact"; thread_id: string; comment_id: string; emoji: string }; | |
| 518 | ||
| 519 | /** A comment thread, as agents and the inbox see it. */ | |
| 520 | export type DocThread = { | |
| 521 | id: string; | |
| 522 | /** The text it is on; null for a comment on the whole page. */ | |
| 523 | quote: string | null; | |
| 524 | resolved: boolean; | |
| 525 | comments: { id: string; author: MemberProfile; text: string; created_at: string }[]; | |
| 526 | }; | |
| 527 | ||
| 528 | /** A file put in a page: served from the usercontent origin. */ | |
| 529 | export type DocFile = { id: string; url: string; name: string; content_type: string; bytes: number }; | |
| 530 | ||
| 531 | /** | |
| 532 | * What a page's live socket carries besides the Yjs protocol (binary | |
| 533 | * frames: y-protocols sync and awareness). These are JSON text frames. | |
| 534 | */ | |
| 535 | export type DocsLiveEvent = | |
| 536 | | { type: "page.updated"; page: DocPage } | |
| 537 | | { type: "page.archived"; page_id: string } | |
| 538 | | { type: "suggestion.created" | "suggestion.updated"; suggestion: DocSuggestion } | |
| 539 | | { type: "version.created"; version: DocVersion } | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 540 | /** Whether it is possibly out of date changed: ask for the page again (what each reader sees of why depends on what they can read). */ |
| 541 | | { type: "page.staleness" } | |
| Docs: a workspace knowledge base people and agents write together | 542 | /** The viewer's role changed, or their access ended (`role` null). */ |
| 543 | | { type: "access"; role: DocRole | null }; | |
| 544 | ||
| 545 | /** | |
| 546 | * Header the site sets on a forwarded live socket and on uploads: the | |
| The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook. | 547 | * viewer, as JSON. Trusted only because the artifacts service is reachable |
| Docs: a workspace knowledge base people and agents write together | 548 | * through service bindings alone. |
| 549 | */ | |
| 550 | export const DOCS_VIEWER_HEADER = "x-g1t-docs-viewer"; | |
| 551 | ||
| 552 | /** The largest file a page takes, in bytes. */ | |
| 553 | export const DOC_MAX_FILE_BYTES = 25 * 1024 * 1024; | |
| 554 | ||
| 555 | /** The name of the Yjs XML fragment that holds a page's blocks. */ | |
| 556 | export const DOC_FRAGMENT = "document-store"; | |
| 557 | /** The name of the Yjs map that holds a page's comment threads. */ | |
| 558 | export const DOC_THREADS = "threads"; | |
| 559 | ||
| Agents recall what Docs say before they answer or work, and each has required reading | 560 | /** One passage of Docs, recalled for an agent: a section of a page or of a repository's docs. */ |
| 561 | export type DocPassage = { | |
| 562 | /** The page; null for a repository's docs file. */ | |
| 563 | page: DocPageRef | null; | |
| 564 | /** A repository's docs file: `owner/name`, its path, and where it reads in Docs. */ | |
| 565 | repo_file: { repo: string; path: string; href: string } | null; | |
| 566 | space_name: string; | |
| 567 | /** The heading the passage sits under, if any. */ | |
| 568 | heading: string | null; | |
| 569 | /** The passage as Markdown, at most about 1,500 characters. */ | |
| 570 | text: string; | |
| 571 | /** How close it is, 0 to 1. */ | |
| 572 | score: number; | |
| 573 | updated_at: string; | |
| 574 | /** The page is marked possibly out of date. */ | |
| 575 | stale: boolean; | |
| 576 | }; | |
| 577 | ||
| Docs: a workspace knowledge base people and agents write together | 578 | export type DocsApi = { |
| 579 | // ── The site ───────────────────────────────────────────────────────── | |
| 580 | ||
| 581 | /** Spaces with their page trees, favorites, recent pages. Makes the General space the first time. */ | |
| 582 | sidebar(workspace: string, viewer: User): Promise<Result<DocsSidebar>>; | |
| 583 | home(workspace: string, viewer: User, options?: { project?: string | null }): Promise<Result<DocsHome>>; | |
| 584 | space(workspace: string, spaceSlug: string, viewer: User): Promise<Result<{ space: DocSpace; members: DocSpaceMember[]; pages: DocPage[] }>>; | |
| 585 | createSpace(workspace: string, viewer: User, input: NewDocSpace): Promise<Result<DocSpace>>; | |
| 586 | /** Manage role only. */ | |
| 587 | updateSpace(workspace: string, spaceId: string, viewer: User, change: DocSpaceChange): Promise<Result<DocSpace>>; | |
| 588 | /** Adds, changes (`role`) or removes (`role` null) a member. Manage role only; the last manager stays. */ | |
| 589 | setSpaceMember(workspace: string, spaceId: string, viewer: User, member: DocMemberKey, role: DocRole | null): Promise<Result<DocSpaceMember[]>>; | |
| 590 | ||
| 591 | /** A page, and the viewer's role in it; records the view. Not found when they can't read it. */ | |
| 592 | page(workspace: string, pageId: string, viewer: User): Promise<Result<DocPageDetail>>; | |
| 593 | createPage(workspace: string, viewer: User, input: NewDocPage): Promise<Result<DocPage>>; | |
| 594 | updatePage(workspace: string, pageId: string, viewer: User, change: DocPageChange): Promise<Result<DocPage>>; | |
| 595 | /** Edit role in both spaces. Refuses moving a page under itself. */ | |
| 596 | movePage(workspace: string, pageId: string, viewer: User, move: DocMove): Promise<Result<DocPage>>; | |
| 597 | duplicatePage(workspace: string, pageId: string, viewer: User): Promise<Result<DocPage>>; | |
| 598 | /** To the trash, with every page under it. */ | |
| 599 | archivePage(workspace: string, pageId: string, viewer: User): Promise<Result<DocPage>>; | |
| 600 | restorePage(workspace: string, pageId: string, viewer: User): Promise<Result<DocPage>>; | |
| 601 | /** For good: only from the trash, manage role. */ | |
| 602 | deletePage(workspace: string, pageId: string, viewer: User): Promise<Result<boolean>>; | |
| 603 | trash(workspace: string, viewer: User): Promise<Result<DocPage[]>>; | |
| 604 | favorite(workspace: string, pageId: string, viewer: User, on: boolean): Promise<Result<boolean>>; | |
| 605 | ||
| 606 | search(workspace: string, viewer: User, query: DocSearchQuery): Promise<Result<DocSearchHit[]>>; | |
| 607 | ||
| 608 | versions(workspace: string, pageId: string, viewer: User): Promise<Result<DocVersion[]>>; | |
| 609 | version(workspace: string, pageId: string, versionId: string, viewer: User): Promise<Result<DocVersionDetail>>; | |
| 610 | /** Makes the page what it was then, as a new version. Edit role. */ | |
| 611 | restoreVersion(workspace: string, pageId: string, versionId: string, viewer: User): Promise<Result<DocVersion>>; | |
| 612 | ||
| 613 | templates(workspace: string, viewer: User): Promise<Result<DocTemplate[]>>; | |
| 614 | /** Saves a page as one of the workspace's templates. */ | |
| 615 | saveTemplate(workspace: string, viewer: User, input: { page_id: string; name: string; description?: string | null }): Promise<Result<DocTemplate>>; | |
| 616 | deleteTemplate(workspace: string, templateId: string, viewer: User): Promise<Result<boolean>>; | |
| 617 | ||
| 618 | exportPage(workspace: string, pageId: string, viewer: User): Promise<Result<{ filename: string; markdown: string }>>; | |
| 619 | /** Every page in a space as Markdown, at paths that follow the tree. */ | |
| 620 | exportSpace(workspace: string, spaceId: string, viewer: User): Promise<Result<{ name: string; files: { path: string; markdown: string }[] }>>; | |
| 621 | ||
| 622 | suggestions(workspace: string, pageId: string, viewer: User): Promise<Result<DocSuggestion[]>>; | |
| 623 | /** Accept (applies it to the live document, attributed to both) or reject. Edit role. */ | |
| 624 | decideSuggestion(workspace: string, suggestionId: string, viewer: User, decision: "accept" | "reject"): Promise<Result<DocSuggestion>>; | |
| 625 | acceptAll(workspace: string, pageId: string, viewer: User): Promise<Result<DocSuggestion[]>>; | |
| 626 | ||
| 627 | /** A comment operation from the editor; comment role (deleting others' comments or threads needs edit). */ | |
| 628 | thread(workspace: string, pageId: string, viewer: User, action: DocThreadAction): Promise<Result<unknown>>; | |
| 629 | threads(workspace: string, pageId: string, viewer: User): Promise<Result<DocThread[]>>; | |
| 630 | ||
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 631 | /** Clears "possibly out of date": the page says what the code does now. Edit role. */ |
| 632 | markCurrent(workspace: string, pageId: string, viewer: User): Promise<Result<boolean>>; | |
| 633 | /** Pages the viewer can read that are possibly out of date, most recently flagged first; `repo` (`owner/name`) narrows to changes there. */ | |
| 634 | stalePages(workspace: string, viewer: User, options?: { repo?: string | null }): Promise<Result<DocPage[]>>; | |
| 635 | ||
| 636 | /** | |
| 637 | * Shows a repository's `docs/` folder and README.md in Docs, read from | |
| 638 | * its default branch. Any member who can read the repository may; the | |
| 639 | * files are read at once and again on every push to the default branch. | |
| 640 | */ | |
| 641 | addRepoSpace(workspace: string, viewer: User, repo: string): Promise<Result<DocRepoSpace>>; | |
| 642 | /** Stops showing it. Whoever added it, or a workspace owner. */ | |
| 643 | removeRepoSpace(workspace: string, viewer: User, id: string): Promise<Result<boolean>>; | |
| 644 | /** One file of a project's docs, for a viewer who can read the repository; not found otherwise. */ | |
| 645 | repoPage(workspace: string, viewer: User, repo: string, path: string): Promise<Result<DocRepoPage>>; | |
| Docs index by meaning: passages of every page and project doc, embedded on save and recalled for agents; hybrid search for people | 646 | /** |
| 647 | * Indexes the workspace's pages and projects' docs for agents' recall | |
| 648 | * again, in batches in the background. Workspace owners. True when a run | |
| 649 | * started (false: one is already going). | |
| 650 | */ | |
| 651 | reindexDocs(workspace: string, viewer: User): Promise<Result<boolean>>; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 652 | |
| Docs: a workspace knowledge base people and agents write together | 653 | // ── Agents (services/agents) ───────────────────────────────────────── |
| 654 | // | |
| 655 | // Each takes the agent and the person it acts for (`viewer`, the asker). | |
| 656 | // The service checks the agent is a live agent of the workspace and caps | |
| 657 | // everything by the viewer's access; `audience`, when given, narrows | |
| 658 | // reads further to what every person in it can read. A page the agent | |
| 659 | // may not read is not found, exactly as one that does not exist. | |
| 660 | ||
| 661 | /** Spaces the agent may read for the viewer (and audience), with what it may do in each. */ | |
| 662 | spacesForAgent(workspace: string, agentId: string, viewer: User, audience?: DocAudience | null): Promise<Result<(Pick<DocSpace, "id" | "slug" | "name" | "description" | "kind" | "agent_mode" | "projects"> & { can: DocAgentAbilities })[]>>; | |
| 663 | /** A page's Markdown and its top-level blocks (ids for `blocks` targets). */ | |
| 664 | pageMarkdown(workspace: string, agentId: string, viewer: User, pageId: string, audience?: DocAudience | null): Promise<Result<DocAgentPage>>; | |
| 665 | /** Full-text search over pages every reader can read; at most 20, best first. */ | |
| 666 | searchForAgent(workspace: string, agentId: string, viewer: User, query: DocSearchQuery, audience?: DocAudience | null): Promise<Result<DocSearchHit[]>>; | |
| 667 | /** Files a tracked suggestion; people with edit access accept or reject it inline. Needs the viewer's comment role. Notifies the page's owners. */ | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 668 | suggestEdit(workspace: string, agentId: string, viewer: User, pageId: string, edit: DocAgentEdit): Promise<Result<DocSuggestion>>; |
| Docs: a workspace knowledge base people and agents write together | 669 | /** |
| 670 | * Applies an edit to the live document when the space lets agents edit | |
| 671 | * and the viewer can edit; otherwise files it as a suggestion (and says | |
| 672 | * so in `mode`). Attributed to the agent in the page's history. | |
| 673 | */ | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 674 | applyEdit(workspace: string, agentId: string, viewer: User, pageId: string, edit: DocAgentEdit): Promise<Result<DocAgentEditResult>>; |
| Docs: a workspace knowledge base people and agents write together | 675 | /** |
| 676 | * A new page, written by the agent: in `space_id` (the General space | |
| 677 | * when null), under `parent_id`. Needs the viewer's edit role there | |
| 678 | * (whatever the space's agent mode: a new page changes nothing anyone | |
| 679 | * wrote). `source` links where it came from ("write this up"). | |
| 680 | */ | |
| 681 | createPageAsAgent( | |
| 682 | workspace: string, | |
| 683 | agentId: string, | |
| 684 | viewer: User, | |
| 685 | input: { space_id?: string | null; parent_id?: string | null; title: string; icon?: string | null; markdown: string; source?: { title: string; href: string } | null }, | |
| 686 | ): Promise<Result<DocPageRef>>; | |
| Agents recall what Docs say before they answer or work, and each has required reading | 687 | /** |
| 688 | * What the workspace's Docs say about `query`, for an agent about to | |
| 689 | * answer: the passages closest in meaning (and, where meaning finds too | |
| 690 | * little, in words), each with the page and heading it came from. Only | |
| 691 | * from spaces the viewer can read and, with `audience`, everyone it | |
| 692 | * covers; repository docs only from repositories they can all read. | |
| 693 | * `spaces` narrows to these space ids first (an agent's required | |
| 694 | * reading) and fills from the rest. Empty when nothing is close enough. | |
| 695 | */ | |
| 696 | recallForAgent( | |
| 697 | workspace: string, | |
| 698 | agentId: string, | |
| 699 | viewer: User, | |
| 700 | input: { query: string; limit?: number | null; spaces?: string[] | null }, | |
| 701 | audience?: DocAudience | null, | |
| 702 | ): Promise<Result<DocPassage[]>>; | |
| Docs: a workspace knowledge base people and agents write together | 703 | /** A page's comment threads, for an agent asked about them. */ |
| 704 | threadsForAgent(workspace: string, agentId: string, viewer: User, pageId: string, audience?: DocAudience | null): Promise<Result<DocThread[]>>; | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 705 | /** |
| 706 | * Pages possibly out of date that the agent may read for the viewer (and | |
| 707 | * audience), each with the changes that made it so: for a documenter | |
| 708 | * routine to bring them up to date. At most 50, most recently flagged | |
| 709 | * first. | |
| 710 | * | |
| 711 | * - `repo` (`owner/name`): only pages made stale by a change there. | |
| 712 | * - `since` (RFC 3339): only pages flagged at or after it. | |
| 713 | * | |
| 714 | * Changes in repositories the viewer can't read are left out, and a page | |
| 715 | * whose every change is one of those is left out too: an agent never | |
| 716 | * learns of code its person can't see. To update a page, read it | |
| 717 | * (`pageMarkdown`), then `applyEdit` or `suggestEdit` with | |
| 718 | * `marks_current: true`: the page is marked current when the edit is | |
| 719 | * applied (at once, or when a person accepts the suggestion). | |
| 720 | */ | |
| 721 | stalePagesForAgent( | |
| 722 | workspace: string, | |
| 723 | agentId: string, | |
| 724 | viewer: User, | |
| 725 | options?: { repo?: string | null; since?: string | null }, | |
| 726 | audience?: DocAudience | null, | |
| 727 | ): Promise<Result<DocStalePage[]>>; | |
| Docs: a workspace knowledge base people and agents write together | 728 | }; |
| 729 | ||
| 730 | async function rpc<T>(service: ServiceBinding, method: string, args: object): Promise<T> { | |
| 731 | const response = await service.fetch(`https://service/rpc/${method}`, { | |
| 732 | method: "POST", | |
| 733 | headers: { "content-type": "application/json" }, | |
| 734 | body: JSON.stringify(args), | |
| 735 | }); | |
| 736 | if (!response.ok) throw new Error(`${method} failed with status ${response.status}`); | |
| 737 | return (await response.json()) as T; | |
| 738 | } | |
| 739 | ||
| 740 | export function docsClient(service: ServiceBinding): DocsApi { | |
| 741 | const call = <T>(method: string, args: object) => rpc<T>(service, method, args); | |
| 742 | return { | |
| 743 | sidebar: (workspace, viewer) => call("sidebar", { workspace, viewer }), | |
| 744 | home: (workspace, viewer, options) => call("home", { workspace, viewer, project: options?.project ?? null }), | |
| 745 | space: (workspace, spaceSlug, viewer) => call("space", { workspace, space: spaceSlug, viewer }), | |
| 746 | createSpace: (workspace, viewer, input) => call("create_space", { workspace, viewer, input }), | |
| 747 | updateSpace: (workspace, spaceId, viewer, change) => call("update_space", { workspace, space_id: spaceId, viewer, change }), | |
| 748 | setSpaceMember: (workspace, spaceId, viewer, member, role) => call("set_space_member", { workspace, space_id: spaceId, viewer, member, role }), | |
| 749 | page: (workspace, pageId, viewer) => call("page", { workspace, page_id: pageId, viewer }), | |
| 750 | createPage: (workspace, viewer, input) => call("create_page", { workspace, viewer, input }), | |
| 751 | updatePage: (workspace, pageId, viewer, change) => call("update_page", { workspace, page_id: pageId, viewer, change }), | |
| 752 | movePage: (workspace, pageId, viewer, move) => call("move_page", { workspace, page_id: pageId, viewer, move }), | |
| 753 | duplicatePage: (workspace, pageId, viewer) => call("duplicate_page", { workspace, page_id: pageId, viewer }), | |
| 754 | archivePage: (workspace, pageId, viewer) => call("archive_page", { workspace, page_id: pageId, viewer }), | |
| 755 | restorePage: (workspace, pageId, viewer) => call("restore_page", { workspace, page_id: pageId, viewer }), | |
| 756 | deletePage: (workspace, pageId, viewer) => call("delete_page", { workspace, page_id: pageId, viewer }), | |
| 757 | trash: (workspace, viewer) => call("trash", { workspace, viewer }), | |
| 758 | favorite: (workspace, pageId, viewer, on) => call("favorite", { workspace, page_id: pageId, viewer, on }), | |
| 759 | search: (workspace, viewer, query) => call("search", { workspace, viewer, query }), | |
| 760 | versions: (workspace, pageId, viewer) => call("versions", { workspace, page_id: pageId, viewer }), | |
| 761 | version: (workspace, pageId, versionId, viewer) => call("version", { workspace, page_id: pageId, version_id: versionId, viewer }), | |
| 762 | restoreVersion: (workspace, pageId, versionId, viewer) => call("restore_version", { workspace, page_id: pageId, version_id: versionId, viewer }), | |
| 763 | templates: (workspace, viewer) => call("templates", { workspace, viewer }), | |
| 764 | saveTemplate: (workspace, viewer, input) => call("save_template", { workspace, viewer, input }), | |
| 765 | deleteTemplate: (workspace, templateId, viewer) => call("delete_template", { workspace, template_id: templateId, viewer }), | |
| 766 | exportPage: (workspace, pageId, viewer) => call("export_page", { workspace, page_id: pageId, viewer }), | |
| 767 | exportSpace: (workspace, spaceId, viewer) => call("export_space", { workspace, space_id: spaceId, viewer }), | |
| 768 | suggestions: (workspace, pageId, viewer) => call("suggestions", { workspace, page_id: pageId, viewer }), | |
| 769 | decideSuggestion: (workspace, suggestionId, viewer, decision) => call("decide_suggestion", { workspace, suggestion_id: suggestionId, viewer, decision }), | |
| 770 | acceptAll: (workspace, pageId, viewer) => call("accept_all", { workspace, page_id: pageId, viewer }), | |
| 771 | thread: (workspace, pageId, viewer, action) => call("thread", { workspace, page_id: pageId, viewer, action }), | |
| 772 | threads: (workspace, pageId, viewer) => call("threads", { workspace, page_id: pageId, viewer }), | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 773 | markCurrent: (workspace, pageId, viewer) => call("mark_current", { workspace, page_id: pageId, viewer }), |
| 774 | stalePages: (workspace, viewer, options) => call("stale_pages", { workspace, viewer, repo: options?.repo ?? null }), | |
| 775 | addRepoSpace: (workspace, viewer, repo) => call("add_repo_space", { workspace, viewer, repo }), | |
| 776 | removeRepoSpace: (workspace, viewer, id) => call("remove_repo_space", { workspace, viewer, id }), | |
| 777 | repoPage: (workspace, viewer, repo, path) => call("repo_page", { workspace, viewer, repo, path }), | |
| Docs index by meaning: passages of every page and project doc, embedded on save and recalled for agents; hybrid search for people | 778 | reindexDocs: (workspace, viewer) => call("reindex_docs", { workspace, viewer }), |
| Docs: a workspace knowledge base people and agents write together | 779 | spacesForAgent: (workspace, agentId, viewer, audience) => call("spaces_for_agent", { workspace, agent_id: agentId, viewer, audience: audience ?? null }), |
| 780 | pageMarkdown: (workspace, agentId, viewer, pageId, audience) => | |
| 781 | call("page_markdown", { workspace, agent_id: agentId, viewer, page_id: pageId, audience: audience ?? null }), | |
| 782 | searchForAgent: (workspace, agentId, viewer, query, audience) => call("search_for_agent", { workspace, agent_id: agentId, viewer, query, audience: audience ?? null }), | |
| 783 | suggestEdit: (workspace, agentId, viewer, pageId, edit) => call("suggest_edit", { workspace, agent_id: agentId, viewer, page_id: pageId, edit }), | |
| 784 | applyEdit: (workspace, agentId, viewer, pageId, edit) => call("apply_edit", { workspace, agent_id: agentId, viewer, page_id: pageId, edit }), | |
| 785 | createPageAsAgent: (workspace, agentId, viewer, input) => call("create_page_as_agent", { workspace, agent_id: agentId, viewer, input }), | |
| Agents recall what Docs say before they answer or work, and each has required reading | 786 | recallForAgent: (workspace, agentId, viewer, input, audience) => |
| 787 | call("recall_for_agent", { workspace, agent_id: agentId, viewer, ...input, audience: audience ?? null }), | |
| Docs: a workspace knowledge base people and agents write together | 788 | threadsForAgent: (workspace, agentId, viewer, pageId, audience) => |
| 789 | call("threads_for_agent", { workspace, agent_id: agentId, viewer, page_id: pageId, audience: audience ?? null }), | |
| Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store | 790 | stalePagesForAgent: (workspace, agentId, viewer, options, audience) => |
| 791 | call("stale_pages_for_agent", { workspace, agent_id: agentId, viewer, repo: options?.repo ?? null, since: options?.since ?? null, audience: audience ?? null }), | |
| Docs: a workspace knowledge base people and agents write together | 792 | }; |
| 793 | } |