Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

Commit

Contracts: workspace_signals, what a workspace's work says over the last weeks

Home's daily signal and the Workspace overview read it: per repository, weekly merges, agent merges, rework, draft and first-review times and stalled changes; daily activity; unreviewed pull requests and the work items waiting on them; pull requests with their work items, milestones and owners; and who has merged where. Part of #157

G1t-Session:
ses_01m57128wre9bvvj1y4z4b8dk0
syntaqxcommitted Parente59e4c9Browse files
4 files+232−00/4 viewed
+3−0
1919 mod insights;
2020 pub use insights::*;
2121
22+mod signals;
23+pub use signals::*;
24+
2225 mod coordination;
2326 pub use coordination::*;
2427
+158−0
1+//! What a workspace's work says over the last weeks: the reads behind
2+//! Home's daily signal and the Workspace overview. Each row is one
3+//! repository's, so a caller that asks in batches adds them up.
4+//!
5+//! A pull request is an agent's when g1t's agent opened it, it was opened
6+//! as an agent's, or a harness session is tied to it (by a link, by saying
7+//! so when it started, or by pushing its branch). Whose it is (`owner`) is
8+//! the person it was requested by, else its author: the one who
9+//! understood it.
10+use crate::Viewer;
11+use serde::{Deserialize, Serialize};
12+
13+#[derive(Deserialize, Serialize)]
14+#[serde(rename_all = "camelCase")]
15+pub struct WorkspaceSignalsArgs {
16+ /// The workspace the repositories belong to: its work items and milestones.
17+ pub workspace: String,
18+ /// Up to 100 repositories; the ones the viewer cannot read are left out.
19+ pub repo_ids: Vec<String>,
20+ pub viewer: Viewer,
21+ /// The last UTC day covered, `YYYY-MM-DD`: the last week ends with it.
22+ pub until: String,
23+ /// How many weeks of seven UTC days end with `until`: 1 through 13.
24+ pub weeks: u32,
25+ /// How many UTC days end with `until` for `days`: 1 through 28.
26+ pub days: u32,
27+ /// The first UTC day `pulls` reaches back to, `YYYY-MM-DD`: at most 400 days before `until`.
28+ pub since: String,
29+}
30+
31+/// One repository's week, starting on UTC day `start`. Weeks with nothing
32+/// in them are left out.
33+#[derive(Clone, Default, Deserialize, Serialize)]
34+#[serde(default, rename_all(serialize = "camelCase"))]
35+pub struct SignalWeek {
36+ pub repo_id: String,
37+ pub start: String,
38+ pub merged: u32,
39+ /// Of `merged`, an agent's.
40+ pub agent_merged: u32,
41+ /// Of `agent_merged`, the ones a person asked for changes on before they merged.
42+ pub agent_reworked: u32,
43+ /// Agent pull requests opened in the week whose session started first,
44+ /// and the seconds from each session's start to its pull request opening.
45+ pub agent_drafted: u32,
46+ pub agent_draft_seconds: f64,
47+ /// First reviews given in the week (a person's approval or request for
48+ /// changes, as Insights counts them), and the seconds each waited.
49+ pub reviewed: u32,
50+ pub review_seconds: f64,
51+ /// Pull requests open when the week ended (now, for the current week)
52+ /// that had been open over seven days by then.
53+ pub stalled: u32,
54+}
55+
56+/// One repository's UTC day. Days with nothing in them are left out.
57+#[derive(Clone, Default, Deserialize, Serialize)]
58+#[serde(default, rename_all(serialize = "camelCase"))]
59+pub struct SignalDay {
60+ pub repo_id: String,
61+ pub day: String,
62+ pub opened: u32,
63+ pub merged: u32,
64+ /// Of `merged`, an agent's.
65+ pub agent_merged: u32,
66+ /// A person's requests for changes.
67+ pub reworked: u32,
68+ /// Reviews and comments by people other than the pull request's owner.
69+ pub reviews: u32,
70+ /// Harness sessions started.
71+ pub sessions: u32,
72+}
73+
74+/// An open pull request no one has reviewed yet, oldest first.
75+#[derive(Clone, Default, Deserialize, Serialize)]
76+#[serde(default, rename_all(serialize = "camelCase"))]
77+pub struct WaitingPull {
78+ pub repo_id: String,
79+ pub number: u32,
80+ pub title: String,
81+ pub created_at: String,
82+ pub agent: bool,
83+ /// For an agent's: seconds from its first session's start to opening.
84+ pub draft_seconds: Option<f64>,
85+ /// The work item it is for, and the open work items blocked by that one.
86+ pub item: Option<u32>,
87+ pub blocks: Vec<u32>,
88+}
89+
90+/// A pull request opened or merged since `since`.
91+#[derive(Clone, Default, Deserialize, Serialize)]
92+#[serde(default, rename_all(serialize = "camelCase"))]
93+pub struct SignalPull {
94+ pub repo_id: String,
95+ pub number: u32,
96+ pub title: String,
97+ /// draft, open, merged or closed.
98+ pub status: String,
99+ pub agent: bool,
100+ pub owner_id: String,
101+ pub owner_name: String,
102+ pub created_at: String,
103+ pub merged_at: Option<String>,
104+ /// The work item it is for, and that item's milestone.
105+ pub item: Option<u32>,
106+ pub milestone: Option<u32>,
107+}
108+
109+/// One person's merged pull requests in one repository, over its whole history.
110+#[derive(Clone, Default, Deserialize, Serialize)]
111+#[serde(default, rename_all(serialize = "camelCase"))]
112+pub struct SignalAuthor {
113+ pub repo_id: String,
114+ pub owner_id: String,
115+ pub owner_name: String,
116+ pub first_merged_at: String,
117+ pub last_merged_at: String,
118+ pub merged: u32,
119+ /// Of `merged`, the ones in the 90 days ending with `until`.
120+ pub recent: u32,
121+}
122+
123+/// A work item `pulls` or `waiting` names.
124+#[derive(Clone, Default, Deserialize, Serialize)]
125+#[serde(default, rename_all(serialize = "camelCase"))]
126+pub struct SignalItem {
127+ pub number: u32,
128+ pub title: String,
129+ pub state: String,
130+ pub milestone: Option<u32>,
131+}
132+
133+/// One of the workspace's milestones.
134+#[derive(Clone, Default, Deserialize, Serialize)]
135+#[serde(default, rename_all(serialize = "camelCase"))]
136+pub struct SignalMilestone {
137+ pub number: u32,
138+ pub title: String,
139+ pub state: String,
140+ pub due_on: Option<String>,
141+ pub created_at: String,
142+ pub closed_at: Option<String>,
143+}
144+
145+#[derive(Default, Serialize)]
146+#[serde(rename_all = "camelCase")]
147+pub struct WorkspaceSignals {
148+ pub weeks: Vec<SignalWeek>,
149+ pub days: Vec<SignalDay>,
150+ /// At most 50.
151+ pub waiting: Vec<WaitingPull>,
152+ /// At most 3,000, newest first; `pulls_capped` when there were more.
153+ pub pulls: Vec<SignalPull>,
154+ pub pulls_capped: bool,
155+ pub authors: Vec<SignalAuthor>,
156+ pub items: Vec<SignalItem>,
157+ pub milestones: Vec<SignalMilestone>,
158+}
+1−0
564564 openPull: (actor, repo, input) => call("open_pull", { actor, repo, ...input }),
565565 listPulls: (repo, viewer, state, filter = {}) => call("list_pulls", { repo, viewer, state, ...filter }),
566566 deliveryInsights: (repoIds, viewer, from, until) => call("delivery_insights", { repoIds, viewer, from, until }),
567+ workspaceSignals: (args, viewer) => call("workspace_signals", { ...args, viewer }),
567568 pullsForRepos: (repoIds, viewer, limit) => call("pulls_for_repos", { repoIds, viewer, limit }),
568569 // Its own fields arrive in snake_case: read into camelCase here.
569570 getPull: (repo, number, viewer) =>
+70−0
10851085 */
10861086 deliveryInsights(repoIds: string[], viewer: Viewer, from: string, until: string): Promise<DeliveryInsights>;
10871087 /**
1088+ * What up to 100 of a workspace's repositories' work says over the last
1089+ * weeks, for Home's daily signal and the Workspace overview: each row is
1090+ * one repository's, so batches add up. Repositories the viewer cannot
1091+ * read are left out.
1092+ */
1093+ workspaceSignals(args: WorkspaceSignalsArgs, viewer: Viewer): Promise<WorkspaceSignals>;
1094+ /**
10881095 * The newest `limit` open and closed pull requests of each repository,
10891096 * in one call. Repositories the viewer cannot read, and forks, are left
10901097 * out: ask those with `listPulls`.
18331840 export type DeliveryMetrics = { repoId: string; opened: number; merged: number; active: number; unreviewed: number; checking: number; failed: number; queued: number; leadSeconds: number; reviewSeconds: number; reviewed: number };
18341841 /** `checksUnavailable`: g1t Actions could not be read, so `checking` and `failed` are not known. */
18351842 export type DeliveryInsights = { projects: DeliveryMetrics[]; days: { day: string; merged: number }[]; checksUnavailable: boolean };
1843+
1844+/**
1845+ * What a workspace's work says over the last weeks (crates/contracts
1846+ * work/signals.rs). A pull request is an agent's when g1t's agent opened
1847+ * it, it was opened as an agent's, or a harness session is tied to it; its
1848+ * owner is the person who asked for it, else its author.
1849+ */
1850+export type WorkspaceSignalsArgs = {
1851+ workspace: string;
1852+ repoIds: string[];
1853+ /** The last UTC day covered, `YYYY-MM-DD`. */
1854+ until: string;
1855+ /** Weeks of seven UTC days ending with `until`: 1 through 13. */
1856+ weeks: number;
1857+ /** UTC days ending with `until` for `days`: 1 through 28. */
1858+ days: number;
1859+ /** The first UTC day `pulls` reaches back to: at most 400 days before `until`. */
1860+ since: string;
1861+};
1862+/** One repository's week from UTC day `start`; empty weeks are left out. `stalled`: open when the week ended (now, for this week), and open over seven days by then. */
1863+export type SignalWeek = {
1864+ repoId: string;
1865+ start: string;
1866+ merged: number;
1867+ agentMerged: number;
1868+ /** Of `agentMerged`, the ones a person asked for changes on first. */
1869+ agentReworked: number;
1870+ agentDrafted: number;
1871+ agentDraftSeconds: number;
1872+ reviewed: number;
1873+ reviewSeconds: number;
1874+ stalled: number;
1875+};
1876+export type SignalDay = { repoId: string; day: string; opened: number; merged: number; agentMerged: number; reworked: number; reviews: number; sessions: number };
1877+/** An open pull request no one has reviewed, oldest first; `blocks`: the open work items waiting on its work item. */
1878+export type WaitingPull = { repoId: string; number: number; title: string; createdAt: string; agent: boolean; draftSeconds: number | null; item: number | null; blocks: number[] };
1879+export type SignalPull = {
1880+ repoId: string;
1881+ number: number;
1882+ title: string;
1883+ status: "draft" | "open" | "merged" | "closed";
1884+ agent: boolean;
1885+ ownerId: string;
1886+ ownerName: string;
1887+ createdAt: string;
1888+ mergedAt: string | null;
1889+ item: number | null;
1890+ milestone: number | null;
1891+};
1892+/** One person's merged pull requests in one repository over its history; `recent`: in the 90 days ending with `until`. */
1893+export type SignalAuthor = { repoId: string; ownerId: string; ownerName: string; firstMergedAt: string; lastMergedAt: string; merged: number; recent: number };
1894+export type SignalItem = { number: number; title: string; state: string; milestone: number | null };
1895+export type SignalMilestone = { number: number; title: string; state: string; dueOn: string | null; createdAt: string; closedAt: string | null };
1896+export type WorkspaceSignals = {
1897+ weeks: SignalWeek[];
1898+ days: SignalDay[];
1899+ waiting: WaitingPull[];
1900+ pulls: SignalPull[];
1901+ pullsCapped: boolean;
1902+ authors: SignalAuthor[];
1903+ items: SignalItem[];
1904+ milestones: SignalMilestone[];
1905+};

Comments

Sign in to comment.