Skip to content
135 linesCodeBlameRaw

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.

Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { ReviewAssignment } from "@g1t/contracts";
5
6import {
7 filterTeams,
8 newTeamFromForm,
9 parentChoices,
10 reviewAssignmentFromForm,
11 splitTeams,
12 teamChangesFromForm,
13 teamCounts,
14 teamPath,
15} from "./teams.ts";
16
17const team = (slug: string, extra: Record<string, unknown> = {}) => ({
18 slug,
19 name: slug[0].toUpperCase() + slug.slice(1),
20 description: null as string | null,
21 visibility: "visible" as "visible" | "secret",
22 parent: null as { slug: string; name: string } | null,
23 viewer_role: null as "member" | "maintainer" | null,
24 ...extra,
25});
26
27const form = (fields: Record<string, string | string[]>) => {
28 const data = new FormData();
29 for (const [key, value] of Object.entries(fields)) {
30 for (const one of Array.isArray(value) ? value : [value]) data.append(key, one);
31 }
32 return data;
33};
34
35const DEFAULTS: ReviewAssignment = {
36 enabled: false,
37 algorithm: "round_robin",
38 count: 1,
39 skip_busy: false,
40 busy_at: 5,
41 include_child_teams: false,
42 excluded: [],
43 notify_team: false,
44};
45
46test("team pages live under the workspace's teams", () => {
47 assert.equal(teamPath("acme", "backend"), "/acme/-/teams/backend");
48 assert.equal(teamPath("acme", "backend", "settings"), "/acme/-/teams/backend/settings");
49});
50
51test("teams are found by every word of the search", () => {
52 const teams = [team("backend", { description: "APIs and data" }), team("web"), team("platform", { description: "Shared backend tools" })];
53 assert.deepEqual(filterTeams(teams, "").map((t) => t.slug), ["backend", "web", "platform"]);
54 assert.deepEqual(filterTeams(teams, "BACKEND").map((t) => t.slug), ["backend", "platform"]);
55 assert.deepEqual(filterTeams(teams, "backend tools").map((t) => t.slug), ["platform"]);
56 assert.deepEqual(filterTeams(teams, "nothing"), []);
57});
58
59test("your teams come first", () => {
60 const { mine, others } = splitTeams([team("a"), team("b", { viewer_role: "member" }), team("c", { viewer_role: "maintainer" })]);
61 assert.deepEqual(mine.map((t) => t.slug), ["b", "c"]);
62 assert.deepEqual(others.map((t) => t.slug), ["a"]);
63});
64
65test("a team can go under any visible team but itself and those below it", () => {
66 const teams = [
67 team("eng"),
68 team("backend", { parent: { slug: "eng", name: "Eng" } }),
69 team("api", { parent: { slug: "backend", name: "Backend" } }),
70 team("web", { parent: { slug: "eng", name: "Eng" } }),
71 team("secret", { visibility: "secret" }),
72 ];
73 assert.deepEqual(parentChoices(teams, "backend").map((t) => t.slug), ["eng", "web"]);
74 assert.deepEqual(parentChoices(teams, "eng").map((t) => t.slug), []);
75 assert.deepEqual(parentChoices(teams, null).map((t) => t.slug), ["eng", "backend", "api", "web"]);
76});
77
78test("a new team reads its form", () => {
79 assert.deepEqual(newTeamFromForm(form({ name: " Backend ", slug: "", description: "", visibility: "secret", parent: "", members: "@ana, bo cy" })), {
80 name: "Backend",
81 slug: null,
82 description: null,
83 visibility: "secret",
84 parent: null,
85 members: ["ana", "bo", "cy"],
86 });
87 assert.equal(newTeamFromForm(form({ name: "x", visibility: "weird" })).visibility, "visible");
88});
89
90test("settings change only what their form has", () => {
91 assert.deepEqual(teamChangesFromForm(form({ name: "Web", description: " UI " })), { name: "Web", description: "UI" });
92 assert.deepEqual(teamChangesFromForm(form({ parent: "" })), { parent: "" });
93 assert.deepEqual(teamChangesFromForm(form({ "notify-shown": "1" })), { notify: false });
94 assert.deepEqual(teamChangesFromForm(form({ "notify-shown": "1", notify: "on" })), { notify: true });
95 assert.deepEqual(teamChangesFromForm(form({ visibility: "secret" })), { visibility: "secret" });
96});
97
98test("review assignment is read within bounds", () => {
99 const read = reviewAssignmentFromForm(
100 form({ enabled: "on", algorithm: "load_balance", count: "40", skip_busy: "on", busy_at: "0", excluded: "@Ana, bo ana" }),
101 DEFAULTS,
102 );
103 assert.deepEqual(read, {
104 enabled: true,
105 algorithm: "load_balance",
106 count: 10,
107 skip_busy: true,
108 busy_at: 1,
109 include_child_teams: false,
110 excluded: ["ana", "bo"],
111 notify_team: false,
112 });
113 // Off, and nonsense kept as it was.
114 const off = reviewAssignmentFromForm(form({ algorithm: "random", count: "many" }), { ...DEFAULTS, count: 3 });
115 assert.equal(off.enabled, false);
116 assert.equal(off.algorithm, "round_robin");
117 assert.equal(off.count, 3);
118});
119
120test("counts leave out what is none", () => {
121 assert.equal(teamCounts({ members_count: 1, repos_count: 0, child_teams_count: 2 }), "1 member · 2 child teams");
122 assert.equal(teamCounts({ members_count: 0, repos_count: 0, child_teams_count: 0 }), "No members yet");
People and teams are front and centre: one directory of people and agents with presence, local time, titles, teams and what each owns; profiles with manager and reports and the agents they work with; an org chart with each team's agents beside the person who leads it; and teams of any mix, with a lead, a channel, a budget agents keep to and the agents on them. Every agent is told its teams each turn (who leads, who owns what, who's around and who to page), and the team page shows exactly what. Member management is Members and invites; the people and teams guide says how.123 assert.equal(teamCounts({ members_count: 2, repos_count: 1, child_teams_count: 0 }, 1), "2 members · 1 agent · 1 repository");
124 assert.equal(teamCounts({ members_count: 0, repos_count: 0, child_teams_count: 0 }, 3), "3 agents");
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar125});
Merge branch 'worktree-agent-ad7c6d88d93adc817'126
127test("who may create teams follows the workspace's setting", async () => {
128 // From the contracts' source: the Teams page and the + menu decide with it.
129 const { mayCreateTeams } = await import("../../../../packages/contracts/src/teams.ts");
130 assert.equal(mayCreateTeams(undefined, "member"), true);
131 assert.equal(mayCreateTeams("members", "member"), true);
132 assert.equal(mayCreateTeams("owners", "member"), false);
133 assert.equal(mayCreateTeams("owners", "owner"), true);
134 assert.equal(mayCreateTeams("members", null), false);
135});

This file's history is long; its oldest lines are credited to the oldest commit read.