Prettier leaves the two TypeScript mirrors Rust tests read alone
crates/contracts' datasets.rs and scopes.rs read packages/contracts/src/datasets.ts and scopes.ts line by line.
- G1t-Session:
- ses_01m57b7r6jew3aqgyfmhw6yah6
3 files+30−1370/3 viewed
| 20 | 20 | # Tables the deploy tool's tests read row by row (scripts/deploy/deploy.test.mjs). | |
| 21 | 21 | apps/docs/src/content/docs/architecture/services.md | |
| 22 | 22 | apps/docs/src/content/docs/guides/self-hosting-architecture.md | |
| 23 | + | # TypeScript mirrors that Rust tests read line by line (crates/contracts: datasets.rs, scopes.rs). | |
| 24 | + | packages/contracts/src/datasets.ts | |
| 25 | + | packages/contracts/src/scopes.ts |
| 97 | 97 | ||
| 98 | 98 | /** The catalog. One dataset per line: the Rust mirror test reads it that way. */ | |
| 99 | 99 | export const DATASETS: Record<DatasetId, DatasetSpec> = { | |
| 100 | − | work_items: { | |
| 101 | − | label: "Work items", | |
| 102 | − | service: "work", | |
| 103 | − | needs: "member", | |
| 104 | − | times: ["created_at", "closed_at"], | |
| 105 | − | dimensions: ["repo", "label", "state", "author_kind", "assignee_kind", "milestone"], | |
| 106 | − | measures: ["time_to_close_hours", "comments"], | |
| 107 | − | rates: ["closed"], | |
| 108 | − | }, | |
| 109 | − | pull_requests: { | |
| 110 | − | label: "Pull requests", | |
| 111 | − | service: "work", | |
| 112 | − | needs: "member", | |
| 113 | − | times: ["created_at", "merged_at", "closed_at"], | |
| 114 | − | dimensions: ["repo", "label", "state", "author_kind", "base_branch"], | |
| 115 | − | measures: ["cycle_time_hours", "time_to_first_review_hours", "review_count", "additions", "deletions", "changed_files"], | |
| 116 | − | rates: ["merged"], | |
| 117 | − | }, | |
| 118 | − | workflow_runs: { | |
| 119 | − | label: "Workflow runs", | |
| 120 | − | service: "actions", | |
| 121 | − | needs: "member", | |
| 122 | − | times: ["started_at", "completed_at"], | |
| 123 | − | dimensions: ["repo", "workflow", "branch", "event", "conclusion", "runner_kind"], | |
| 124 | − | measures: ["duration_seconds", "queue_seconds"], | |
| 125 | − | rates: ["succeeded"], | |
| 126 | − | }, | |
| 127 | − | deployments: { | |
| 128 | − | label: "Deployments", | |
| 129 | − | service: "deployments", | |
| 130 | − | needs: "member", | |
| 131 | − | times: ["created_at"], | |
| 132 | − | dimensions: ["repo", "project", "environment", "state"], | |
| 133 | − | measures: ["duration_seconds", "time_to_restore_hours"], | |
| 134 | − | rates: ["failed"], | |
| 135 | − | }, | |
| 136 | − | spend: { | |
| 137 | − | label: "Spend", | |
| 138 | − | service: "billing", | |
| 139 | − | needs: "billing", | |
| 140 | − | times: ["day"], | |
| 141 | − | dimensions: ["product", "project", "person", "model"], | |
| 142 | − | measures: ["amount_micros"], | |
| 143 | − | rates: [], | |
| 144 | − | }, | |
| 145 | − | agent_sessions: { | |
| 146 | − | label: "Agent sessions", | |
| 147 | − | service: "agents", | |
| 148 | − | needs: "member", | |
| 149 | − | times: ["started_at"], | |
| 150 | − | dimensions: ["agent", "repo", "outcome", "model", "trigger"], | |
| 151 | − | measures: ["duration_seconds", "cost_micros", "tokens"], | |
| 152 | − | rates: ["succeeded"], | |
| 153 | − | }, | |
| 100 | + | work_items: { label: "Work items", service: "work", needs: "member", times: ["created_at", "closed_at"], dimensions: ["repo", "label", "state", "author_kind", "assignee_kind", "milestone"], measures: ["time_to_close_hours", "comments"], rates: ["closed"] }, | |
| 101 | + | pull_requests: { label: "Pull requests", service: "work", needs: "member", times: ["created_at", "merged_at", "closed_at"], dimensions: ["repo", "label", "state", "author_kind", "base_branch"], measures: ["cycle_time_hours", "time_to_first_review_hours", "review_count", "additions", "deletions", "changed_files"], rates: ["merged"] }, | |
| 102 | + | workflow_runs: { label: "Workflow runs", service: "actions", needs: "member", times: ["started_at", "completed_at"], dimensions: ["repo", "workflow", "branch", "event", "conclusion", "runner_kind"], measures: ["duration_seconds", "queue_seconds"], rates: ["succeeded"] }, | |
| 103 | + | deployments: { label: "Deployments", service: "deployments", needs: "member", times: ["created_at"], dimensions: ["repo", "project", "environment", "state"], measures: ["duration_seconds", "time_to_restore_hours"], rates: ["failed"] }, | |
| 104 | + | spend: { label: "Spend", service: "billing", needs: "billing", times: ["day"], dimensions: ["product", "project", "person", "model"], measures: ["amount_micros"], rates: [] }, | |
| 105 | + | agent_sessions: { label: "Agent sessions", service: "agents", needs: "member", times: ["started_at"], dimensions: ["agent", "repo", "outcome", "model", "trigger"], measures: ["duration_seconds", "cost_micros", "tokens"], rates: ["succeeded"] }, | |
| 154 | 106 | }; | |
| 155 | 107 | ||
| 156 | 108 | /** The most rows a query returns. */ | |
| ⋯ | |||
| 264 | 216 | } | |
| 265 | 217 | const value = filter.value; | |
| 266 | 218 | const ok = | |
| 267 | − | typeof value === "string" || | |
| 268 | − | (typeof value === "number" && Number.isFinite(value)) || | |
| 269 | − | (Array.isArray(value) && value.every((item) => typeof item === "string")); | |
| 219 | + | typeof value === "string" || (typeof value === "number" && Number.isFinite(value)) || (Array.isArray(value) && value.every((item) => typeof item === "string")); | |
| 270 | 220 | if (!ok) return { error: "A filter's value is text, a number or a list of text." }; | |
| 271 | 221 | filters.push({ field: filter.field, op: filter.op as DatasetFilterOp, value: value as DatasetFilter["value"] }); | |
| 272 | 222 | } | |
| ⋯ | |||
| 274 | 224 | let range: DatasetRange | null = null; | |
| 275 | 225 | if (input.range != null) { | |
| 276 | 226 | if (typeof input.range === "string" && (DATASET_RANGE_PRESETS as readonly string[]).includes(input.range)) range = input.range as DatasetRangePreset; | |
| 277 | − | else if (isObject(input.range) && typeof input.range.from === "string" && typeof input.range.to === "string") | |
| 278 | − | range = { from: input.range.from, to: input.range.to }; | |
| 227 | + | else if (isObject(input.range) && typeof input.range.from === "string" && typeof input.range.to === "string") range = { from: input.range.from, to: input.range.to }; | |
| 279 | 228 | else return { error: "range is 7d, 30d, 90d or { from, to }." }; | |
| 280 | 229 | } | |
| 281 | 230 | const query: DatasetQuery = { | |
| 42 | 42 | { scope: "repo:read", description: "See repositories, their settings, timelines, releases, languages, contributors and security alerts, and search" }, | |
| 43 | 43 | { scope: "repo:create", description: "Create repositories, and nothing that changes or deletes one" }, | |
| 44 | 44 | { scope: "repo:write", description: "Create repositories, create, rename and delete branches, change how pull requests merge and publish releases" }, | |
| 45 | − | { | |
| 46 | − | scope: "repo:admin", | |
| 47 | − | description: "Rename, archive, transfer, delete or change who can see a repository, change its rulesets, and dismiss security alerts", | |
| 48 | − | }, | |
| 45 | + | { scope: "repo:admin", description: "Rename, archive, transfer, delete or change who can see a repository, change its rulesets, and dismiss security alerts" }, | |
| 49 | 46 | { scope: "code:read", description: "Clone and fetch private repositories with git" }, | |
| 50 | 47 | { scope: "code:write", description: "Push commits with git" }, | |
| 51 | − | { | |
| 52 | − | scope: "security:read", | |
| 53 | − | description: "See secret scanning, code scanning and vulnerability alerts, custom patterns, the dependency graph and SBOM, and security settings", | |
| 54 | − | }, | |
| 55 | − | { | |
| 56 | − | scope: "security:write", | |
| 57 | − | description: "Dismiss and reopen alerts, bypass push protection, review bypass requests, manage custom patterns, upload SARIF and change security settings", | |
| 58 | − | }, | |
| 48 | + | { scope: "security:read", description: "See secret scanning, code scanning and vulnerability alerts, custom patterns, the dependency graph and SBOM, and security settings" }, | |
| 49 | + | { scope: "security:write", description: "Dismiss and reopen alerts, bypass push protection, review bypass requests, manage custom patterns, upload SARIF and change security settings" }, | |
| 59 | 50 | { scope: "packages:read", description: "Pull container images and install private packages" }, | |
| 60 | 51 | { scope: "packages:write", description: "Push container images and publish packages" }, | |
| 61 | 52 | { scope: "packages:delete", description: "Delete and restore packages and their versions" }, | |
| ⋯ | |||
| 70 | 61 | { scope: "checks:write", description: "Report statuses and check runs on commits, and ask for checks to run again" }, | |
| 71 | 62 | { scope: "deployments:read", description: "See deployments, their statuses and environments" }, | |
| 72 | 63 | { scope: "deployments:write", description: "Report deployments and their statuses, from any CI" }, | |
| 73 | − | { | |
| 74 | − | scope: "observability:read", | |
| 75 | − | description: "See projects' requests, logs, traces, errors and metrics, and their observability settings, ingest tokens and exports", | |
| 76 | − | }, | |
| 64 | + | { scope: "observability:read", description: "See projects' requests, logs, traces, errors and metrics, and their observability settings, ingest tokens and exports" }, | |
| 77 | 65 | { scope: "observability:write", description: "Resolve and ignore errors, and change projects' observability settings, ingest tokens and exports" }, | |
| 78 | 66 | { scope: "account:read", description: "Read your email addresses, invites, invitations, pinned projects and stars" }, | |
| 79 | 67 | { scope: "account:write", description: "Change your email addresses, make invites, answer invitations, pin projects and star repositories" }, | |
| ⋯ | |||
| 82 | 70 | { scope: "chat:read", description: "Read the conversations you are in: channels, direct messages, threads and reactions, live" }, | |
| 83 | 71 | { scope: "chat:write", description: "Send, edit and delete your messages, react, mark conversations read, and answer cards in chat" }, | |
| 84 | 72 | { scope: "workspace:read", description: "Read workspace settings, invites, integrations, AI providers, teams and rulesets" }, | |
| 85 | − | { | |
| 86 | − | scope: "workspace:admin", | |
| 87 | − | description: | |
| 88 | − | "Create and delete workspaces, invite members, connect integrations, add AI providers and choose what Ask answers with, create, change and delete teams, and change the workspace's rulesets", | |
| 89 | − | }, | |
| 73 | + | { scope: "workspace:admin", description: "Create and delete workspaces, invite members, connect integrations, add AI providers and choose what Ask answers with, create, change and delete teams, and change the workspace's rulesets" }, | |
| 90 | 74 | { scope: "billing:read", description: "See a workspace's usage, budget and invoices" }, | |
| 91 | 75 | { scope: "billing:write", description: "Change a workspace's budget" }, | |
| 92 | 76 | { scope: "access:read", description: "See who has access to repositories" }, | |
| ⋯ | |||
| 109 | 93 | * operation needs them. When one ships, its rows move to the end of | |
| 110 | 94 | * `SCOPES` and `SCOPE_RESOURCES`. Empty now: Artifacts shipped last. | |
| 111 | 95 | */ | |
| 112 | − | export const UPCOMING_SCOPES: readonly { scope: Scope; description: string }[] = [] as const; | |
| 96 | + | export const UPCOMING_SCOPES: readonly { scope: Scope; description: string }[] = [ | |
| 97 | + | ] as const; | |
| 113 | 98 | ||
| 114 | 99 | /** | |
| 115 | 100 | * Scopes of what g1t no longer has (Rust: `Resource::retired`): `agents` | |
| ⋯ | |||
| 158 | 143 | ]; | |
| 159 | 144 | ||
| 160 | 145 | /** Resources not offered yet, as `UPCOMING_SCOPES`: settings never show them. */ | |
| 161 | − | export const UPCOMING_RESOURCES: { resource: ScopeResource; label: string; group: ResourceGroup }[] = []; | |
| 146 | + | export const UPCOMING_RESOURCES: { resource: ScopeResource; label: string; group: ResourceGroup }[] = [ | |
| 147 | + | ]; | |
| 162 | 148 | ||
| 163 | 149 | /** Resources of what g1t no longer has, as `RETIRED_SCOPES`: settings never show them. */ | |
| 164 | 150 | export const RETIRED_RESOURCES: { resource: ScopeResource; label: string; group: ResourceGroup }[] = [ | |
| ⋯ | |||
| 193 | 179 | ||
| 194 | 180 | /** Whether holding `held` gives `needed`: the same resource, at its level or lower. */ | |
| 195 | 181 | export function scopeIncludes(held: Scope, needed: Scope): boolean { | |
| 196 | − | return scopeResource(held) === scopeResource(needed) && LEVEL_ORDER[scopeLevel(held)] >= LEVEL_ORDER[scopeLevel(needed)]; | |
| 182 | + | return ( | |
| 183 | + | scopeResource(held) === scopeResource(needed) && | |
| 184 | + | LEVEL_ORDER[scopeLevel(held)] >= LEVEL_ORDER[scopeLevel(needed)] | |
| 185 | + | ); | |
| 197 | 186 | } | |
| 198 | 187 | ||
| 199 | 188 | /** | |
| ⋯ | |||
| 263 | 252 | /** Starting points for choosing scopes. `*` is full access. No preset gives chat: an application gets it only by asking for it. */ | |
| 264 | 253 | export const PRESET_SCOPES = { | |
| 265 | 254 | read_only: [ | |
| 266 | − | "repo:read", | |
| 267 | − | "code:read", | |
| 268 | − | "security:read", | |
| 269 | − | "packages:read", | |
| 270 | − | "work:read", | |
| 271 | − | "pull_requests:read", | |
| 272 | − | "workflows:read", | |
| 273 | − | "checks:read", | |
| 274 | − | "deployments:read", | |
| 275 | − | "observability:read", | |
| 276 | − | "account:read", | |
| 277 | − | "notifications:read", | |
| 278 | − | "workspace:read", | |
| 279 | − | "billing:read", | |
| 280 | − | "access:read", | |
| 281 | − | "webhooks:read", | |
| 282 | − | "secrets:read", | |
| 283 | − | "runners:read", | |
| 284 | − | "artifacts:read", | |
| 255 | + | "repo:read", "code:read", "security:read", "packages:read", "work:read", "pull_requests:read", "workflows:read", "checks:read", "deployments:read", "observability:read", "account:read", "notifications:read", "workspace:read", "billing:read", "access:read", "webhooks:read", "secrets:read", "runners:read", "artifacts:read", | |
| 285 | 256 | ] as const, | |
| 286 | 257 | agent: [ | |
| 287 | − | "repo:read", | |
| 288 | − | "repo:create", | |
| 289 | − | "code:read", | |
| 290 | − | "code:write", | |
| 291 | − | "security:read", | |
| 292 | − | "packages:read", | |
| 293 | − | "work:read", | |
| 294 | − | "work:write", | |
| 295 | − | "pull_requests:read", | |
| 296 | − | "pull_requests:write", | |
| 297 | − | "workflows:read", | |
| 298 | − | "checks:read", | |
| 299 | − | "deployments:read", | |
| 300 | − | "observability:read", | |
| 301 | − | "account:read", | |
| 302 | − | "notifications:read", | |
| 303 | − | "notifications:write", | |
| 304 | − | "workspace:read", | |
| 305 | − | "billing:read", | |
| 306 | − | "access:read", | |
| 307 | − | "webhooks:read", | |
| 308 | − | "secrets:read", | |
| 309 | − | "artifacts:read", | |
| 258 | + | "repo:read", "repo:create", "code:read", "code:write", "security:read", "packages:read", "work:read", "work:write", "pull_requests:read", "pull_requests:write", "workflows:read", "checks:read", "deployments:read", "observability:read", "account:read", "notifications:read", "notifications:write", "workspace:read", "billing:read", "access:read", "webhooks:read", "secrets:read", "artifacts:read", | |
| 310 | 259 | ] as const, | |
| 311 | 260 | ci: [ | |
| 312 | − | "repo:read", | |
| 313 | − | "code:read", | |
| 314 | − | "code:write", | |
| 315 | − | "packages:read", | |
| 316 | − | "packages:write", | |
| 317 | − | "workflows:read", | |
| 318 | − | "workflows:write", | |
| 319 | − | "checks:read", | |
| 320 | − | "checks:write", | |
| 321 | − | "deployments:read", | |
| 322 | − | "deployments:write", | |
| 261 | + | "repo:read", "code:read", "code:write", "packages:read", "packages:write", "workflows:read", "workflows:write", "checks:read", "checks:write", "deployments:read", "deployments:write", | |
| 262 | + | ] as const, | |
| 263 | + | full: [ | |
| 264 | + | "*", | |
| 323 | 265 | ] as const, | |
| 324 | − | full: ["*"] as const, | |
| 325 | 266 | }; | |
| 326 | 267 | ||
| 327 | 268 | export const PRESETS: { id: PresetId; label: string; description: string }[] = [ | |
Comments
Sign in to comment.