Skip to content
134 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");
The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404.123 assert.equal(teamCounts({ members_count: 2, repos_count: 1, child_teams_count: 0 }), "2 members · 1 repository");
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar124});
Merge branch 'worktree-agent-ad7c6d88d93adc817'125
126test("who may create teams follows the workspace's setting", async () => {
127 // From the contracts' source: the Teams page and the + menu decide with it.
128 const { mayCreateTeams } = await import("../../../../packages/contracts/src/teams.ts");
129 assert.equal(mayCreateTeams(undefined, "member"), true);
130 assert.equal(mayCreateTeams("members", "member"), true);
131 assert.equal(mayCreateTeams("owners", "member"), false);
132 assert.equal(mayCreateTeams("owners", "owner"), true);
133 assert.equal(mayCreateTeams("members", null), false);
134});

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