1// The model the data layer builds and the templates render.23export interface Config {4 name: string;5 root: string;6 state: string;7 allowedSigners: string;8 cacheDir: string;9 baseUrl: string;10 ssh: string;11 sitesUrl: string;12 previewsUrl: string;13 only: string | null;14 maxCommits: number;15 maxFiles: number;16 maxBlob: number;17 maxDiffLines: number;18 maxRaw: number;19}2021export interface Person {22 name: string;23 email: string;24 date: string;25}2627export interface Stats {28 files: number;29 add: number;30 del: number;31}3233export interface DiffLine {34 t: '+' | '-' | ' ' | '\\';35 text: string;36 o: number | null;37 n: number | null;38}3940export interface Hunk {41 header: string;42 lines: DiffLine[];43}4445export interface DiffFile {46 status: 'A' | 'D' | 'M' | 'R' | 'C';47 path: string;48 oldPath: string | null;49 newPath: string | null;50 binary: boolean;51 hunks: Hunk[];52 add: number;53 del: number;54 truncated?: boolean;55 nlines?: number;56 mode?: string | null;57 // Set when the commit is too large to show patches: counts only.58 omitted?: boolean;59 // Old and new blob ids, from the index line (full with --full-index).60 oids?: [string, string];61}6263export interface Verification {64 ok: boolean;65 signer: string | null;66 key?: string | null;67 reason?: string;68}6970export interface Metric {71 name: string;72 value: number;73 unit: string | null;74}7576export interface Attestation {77 payload: string;78 signature: string;79 commit?: string;80 tree?: string;81 result?: string;82 exit?: string;83 started?: string;84 duration?: string;85 runner?: string;86 system?: string;87 env?: string;88 script?: string;89 logHash?: string;90 log: string[];91 // What .forge/ci wrote to $FORGE_METRICS, in its order.92 metrics: Metric[];93 object?: string;94 via?: string | null;95 verification: Verification;96}9798export interface CiStatus {99 state: 'pass' | 'fail' | 'unverified';100 latest: Attestation;101 count: number;102}103104export interface CommitMeta {105 tree: string;106 parents: string[];107 author: Person;108 committer: Person;109 subject: string;110 body: string;111 stats: Stats;112}113114export interface Commit extends CommitMeta {115 sha: string;116 short: string;117 ci: CiStatus | null;118 reviews: Review[];119 files?: DiffFile[];120 omitted?: boolean;121 // Jev's stored answers, if any (lib/jev-commits.ts).122 jev?: CommitLabel | null;123}124125// A commit as Jev sorted it: its kind, its risk when moderate or high, and126// whether its message may not describe its diff; for release notes, its127// section and whether users would notice it.128export interface CommitLabel {129 kind: string;130 risk: 'moderate' | 'high' | null;131 // Jev's expected risk on RISK's 0 to 3 scale, one decimal; null unanswered.132 riskScore: number | null;133 mismatch: boolean;134 section: string | null;135 userFacing: boolean;136}137138export interface Revision {139 n: number;140 ts: number;141 sha: string;142 user: string | null;143 base: string | null;144 prev?: number | null;145 // How the revision page shows what changed since `prev`: the diff between146 // the tips when the base stayed put, else `range` (git range-diff output).147 view?: 'diff' | 'range' | null;148 range?: string | null;149 // What Jev says the revision changed, e.g. "behavior change in 2 of 4150 // commits" (lib/jev-reviews.ts); `kind` is the label shown.151 summary?: { kind: string; text: string } | null;152}153154// `forge approve`: a line in the review log. Keyed by tree, like CI.155export interface Approval {156 ts: number;157 user: string;158 sha: string;159 tree: string;160 rev: number | null;161 // The tip still has the tree that was approved.162 current: boolean;163}164165// `forge comment`: <repo>.git/forge/comments/<review>/<n>.166export interface ReviewComment {167 n: number;168 ts: number;169 user: string;170 // The review's tip when the comment was made, and its revision.171 sha: string;172 rev: number | null;173 // A line comment: the new-side line of the file at sha, and its text then.174 path: string | null;175 line: number | null;176 text: string | null;177 body: string;178 outdated: boolean;179 // The line shows in the combined diff, where the comment appears inline.180 inDiff: boolean;181 // An outdated comment Jev says a later revision likely addressed: that revision.182 addressed?: number | null;183 // From forge critique: the model that wrote it, and blocking or note.184 agent: string | null;185 severity: 'blocking' | 'note' | null;186}187188// What landing a live review on its target needs (lib/rules.ts) and has.189export interface ReviewGate {190 // forge.requireapproval: the forge refuses a landing that falls short.191 required: boolean;192 ok: boolean;193 // .forge/approvals is on the target.194 rules: boolean;195 needs: { line: number; text: string; paths: string[]; have: string[]; agent: boolean; agentOk: boolean; ok: boolean }[];196 // Every changed file is under a "none" rule.197 free: boolean;198 errors: string[];199}200201// The latest verified agent review of a review (lib/critique.ts).202export interface ReviewAgent {203 sha: string;204 model: string;205 signer: string | null;206 started: string;207 scope: string;208 findings: number;209 open: number;210 // It reviewed the tip's tree.211 current: boolean;212 resolved: number;213}214215export interface ReviewLog {216 id: number;217 branch: string;218 created: { ts: number; user: string } | null;219 opts: Record<string, string>;220 draft: boolean;221 revs: Revision[];222 deleted: { ts: number; user: string } | null;223 // Every approval as logged; after settle(), each person's latest (lib/discussion.ts).224 approvals: Approval[];225 comments: ReviewComment[];226}227228export type ReviewStatus = 'open' | 'draft' | 'merged' | 'closed';229230export interface ReviewCi {231 pass: number;232 total: number;233 state: 'pass' | 'fail' | 'partial';234}235236export interface Review extends ReviewLog {237 live: boolean;238 tip: string;239 merged: boolean;240 explicit: string | null;241 floor: string;242 parent: Review | null;243 children: Review[];244 commits: string[];245 target: string;246 status: ReviewStatus;247 updated: number | null;248 author: string | null;249 revisions: Revision[];250 layer: Commit[];251 ci: ReviewCi | null;252 title: string;253 combinedBase: string | null;254 combinedStats: Stats;255 combined?: DiffFile[];256 previews: Preview[];257 gate?: ReviewGate | null;258 agent?: ReviewAgent | null;259}260261export interface SiteDeploy {262 sha: string;263 tree: string;264 date: string;265 subject: string;266 source: string | null;267 builtBy: string | null;268 signed?: 'good' | 'bad' | 'unknown' | null;269 signer?: string | null;270}271272export interface Site {273 name: string;274 url: string;275 history: SiteDeploy[];276}277278export interface Preview extends Site {279 branch: string;280}281282// A release's files (lib/releases.ts): refs/releases/<tag>.283export interface ReleaseFile {284 name: string;285 size: number;286 // From SHA256SUMS, which pre-receive checked against the file.287 sha256: string | null;288 href: string;289}290291export interface ReleaseFiles {292 tag: string;293 sha: string;294 date: string;295 // The tag's commit when it was published.296 source: string | null;297 builtBy: string | null;298 files: ReleaseFile[];299 sums: string;300 sig: string;301 // SHA256SUMS.sig checked against allowed_signers.302 signed: 'good' | 'bad' | 'unknown' | null;303 signer: string | null;304}305306export interface Ref {307 name: string;308 sha: string;309 type: string;310 date: string;311 subject: string;312 author: string;313}314315export interface Branch {316 name: string;317 sha: string;318 date: string;319 subject: string;320 author: string;321 behind: number;322 ahead: number;323 isDefault: boolean;324 review?: Review | null;325}326327export interface Tag {328 name: string;329 sha: string;330 type: string;331 date: string;332 subject: string;333}334335export interface TreeEntry {336 name: string;337 path: string;338 mode: string;339 type: string;340 oid: string;341 size: number | null;342}343344export interface Tree {345 dirs: Map<string, TreeEntry[]>;346 dirOids: Map<string, string>;347 blobs: TreeEntry[];348}349350export interface Both {351 path: string;352 href: string;353}354355export interface RepoUrls {356 home: Both;357 log: (branch: string) => Both;358 tree: (branch: string, path?: string) => Both;359 blob: (branch: string, path: string) => Both;360 blobSource: (branch: string, path: string) => Both;361 blobBase: (branch: string) => Both;362 raw: (branch: string, path: string) => Both;363 files: (branch: string) => Both;364 search: Both;365 code: Both;366 commit: (sha: string) => Both;367 refs: Both;368 branchMenu: (kind: string) => Both;369 reviews: Both;370 review: (id: number) => Both;371 reviewDiff: (id: number) => Both;372 revision: (id: number, n: number) => Both;373 sites: Both;374 download: (tag: string, file: string) => Both;375 // Charts from the lake (lib/insights.ts), and the files they draw from.376 insights: Both;377 releases: Both;378 wiki: (path?: string) => Both;379 atom: Both;380 site: (site: string) => string;381 preview: (site: string, branch: string) => string;382 cloneSsh: string;383 cloneHttp: string | null;384}385386export interface RepoCounts {387 reviews?: number;388 // Tags: the releases page lists each one's notes, and its files if it has a release.389 releases?: number;390 sites?: number;391 wiki?: number;392}393394export interface RepoSummary {395 owner: string;396 name: string;397 dir: string;398 description: string;399 defaultBranch: string;400 lastCommit: string;401 slug: string;402 urls: RepoUrls;403 // No git-daemon-export-ok: only its owner, collaborators and readers may404 // read it, and the public build leaves it out.405 private: boolean;406 counts?: RepoCounts;407 sites?: SiteLink[];408 // What the repo is, by Jev (lib/jev-commits.ts).409 topic?: string | null;410 // Its newest release with files, for the pins on its owner's page.411 release?: { tag: string; date: string; href: string } | null;412 // Its shelf on the index, from the bare repo's category file (its owner's413 // word, lowercase; '' when there is none).414 category: string;415}416417export interface SiteLink {418 name: string;419 url: string;420 date?: string | null;421}422423export interface Readme {424 path: string;425 oid: string;426 html: string | null;427 text: string;428}429430export interface WikiPage {431 path: string;432 oid: string;433 slug: string;434 title: string;435 html: string;436}437438export interface Blob {439 type: string;440 data: Buffer;441}442443export interface Repo extends RepoSummary {444 branches: Branch[];445 tags: Tag[];446 commits: Map<string, Commit>;447 logs: Map<string, string[]>;448 trees: Map<string, Tree>;449 blobData: Map<string, Blob>;450 reviews: Review[];451 sites: Site[];452 previews: Preview[];453 // By tag.454 releaseFiles: Map<string, ReleaseFiles>;455 readme: Readme | null;456 wiki: WikiPage[];457 loadDiffs: (commits: Commit[]) => void;458 loadBlobs: (oids: string[]) => Map<string, Blob>;459 combinedDiff: (review: Review) => DiffFile[];460 diff: (from: string, to: string) => DiffFile[];461 // Render markdown that lives at `path` on `branch`, resolving its relative links.462 markdown: (branch: string, path: string, text: string) => string;463}