Skip to content
164 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.

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.1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { DirectoryPerson, DirectoryTeam, PeopleDirectory } from "@g1t/contracts";
5
6import {
7 type PeopleAgent,
8 agentIdsOn,
9 budgetFromText,
10 codeAccessWords,
11 directoryEntries,
12 managerChoices,
13 orgChart,
14 ownsFromText,
15 teamBlock,
16 teamsOfAgent,
17} from "./people.ts";
18
19const person = (username: string, extra: Partial<DirectoryPerson> = {}): DirectoryPerson => ({
20 user_id: `usr_${username}`,
21 username,
22 name: null,
23 avatar: null,
24 bio: null,
25 location: null,
26 pronouns: null,
27 timezone: null,
28 role: "member",
29 title: null,
30 manager: null,
31 owns: [],
32 joined_at: "2026-10-01T00:00:00Z",
33 ...extra,
34});
35
36const team = (slug: string, name: string, extra: Partial<DirectoryTeam> = {}): DirectoryTeam => ({
37 slug,
38 name,
39 description: null,
40 visibility: "visible",
41 parent: null,
42 lead: null,
43 channel: null,
44 budget_micros: null,
45 people: [],
46 agent_ids: [],
47 repos_count: 0,
48 ...extra,
49});
50
51const agent = (id: string, handle: string, extra: Partial<PeopleAgent> = {}): PeopleAgent => ({
52 id,
53 handle,
54 display_name: handle[0]!.toUpperCase() + handle.slice(1),
55 avatar: null,
56 avatar_seed: handle,
57 title: "",
58 role: "",
59 team: null,
60 department: "",
61 status: "idle",
62 responsibilities: [],
63 builtin: false,
64 spent_month_micros: 0,
65 ...extra,
66});
67
68const directory: PeopleDirectory = {
69 people: [
70 person("chase", { name: "Chase Pierce", title: "Founder", role: "owner" }),
71 person("sofia", { name: "Sofia Reyes", title: "Head of Sales", manager: "chase", owns: ["the forecast"] }),
72 person("jordan", { name: "Jordan Lee", title: "Account Executive", manager: "sofia", owns: ["Halcyon", "Bluebird"] }),
73 person("kai", { name: "Kai Nakamura", title: "Product Designer", manager: "chase" }),
74 ],
75 teams: [
76 team("sales", "Sales", {
77 lead: { kind: "user", username: "sofia", name: "Sofia Reyes", avatar: null },
78 people: [
79 { username: "sofia", role: "maintainer" },
80 { username: "jordan", role: "member" },
81 ],
82 agent_ids: ["agt_david"],
83 repos_count: 0,
84 }),
85 team("design", "Design", { people: [{ username: "kai", role: "maintainer" }], repos_count: 2 }),
86 team("night-shift", "Night shift", { lead: { kind: "agent", agent_id: "agt_atlas" }, agent_ids: ["agt_atlas"] }),
87 ],
88 base_permission: "read",
89 can_manage: true,
90};
91
92const agents = [
93 agent("agt_david", "david", { title: "CRM keeper", team: "sales" }),
94 agent("agt_atlas", "atlas", { title: "Night watch" }),
95 agent("agt_sentinel", "sentinel", { title: "Error watch", team: "night-shift", responsibilities: ["Watches errors"] }),
96];
97
98test("an agent is on the teams it was added to and its home team", () => {
99 assert.deepEqual(agentIdsOn(directory.teams[2]!, agents), ["agt_atlas", "agt_sentinel"]);
100 assert.deepEqual(
101 teamsOfAgent(directory.teams, agents[2]!).map((t) => t.slug),
102 ["night-shift"],
103 );
104});
105
106test("the directory finds people and agents in one search", () => {
107 const names = (query: string, kind: "everyone" | "people" | "agents" = "everyone") =>
108 directoryEntries(directory, agents, query, kind).map((e) => (e.kind === "person" ? e.person.username : `@${e.agent.handle}`));
109 assert.deepEqual(names("sales"), ["sofia", "jordan", "@david"]);
110 assert.deepEqual(names("halcyon"), ["jordan"]);
111 assert.deepEqual(names("errors"), ["@sentinel"]);
112 assert.deepEqual(names("", "agents"), ["@david", "@atlas", "@sentinel"]);
113 assert.deepEqual(names("night"), ["@atlas", "@sentinel"]);
114 assert.equal(names("nobody here").length, 0);
115});
116
117test("the org chart follows reporting lines, with each team's agents beside its lead", () => {
118 const chart = orgChart(directory, agents);
119 assert.deepEqual(chart.roots.map((n) => n.person.username), ["chase"]);
120 const chase = chart.roots[0]!;
121 assert.deepEqual(chase.reports.map((n) => n.person.username), ["sofia", "kai"]);
122 const sofia = chase.reports[0]!;
123 assert.deepEqual(sofia.agents.map((a) => a.handle), ["david"]);
124 assert.deepEqual(sofia.reports.map((n) => n.person.username), ["jordan"]);
125 // A team an agent leads sits apart, with its agents.
126 assert.deepEqual(chart.unled.map((u) => [u.team.slug, u.agents.map((a) => a.handle)]), [["night-shift", ["atlas", "sentinel"]]]);
127});
128
129test("no one goes missing from the org chart, even in a loop", () => {
130 const looped: PeopleDirectory = { ...directory, people: [person("a", { manager: "b" }), person("b", { manager: "a" })] };
131 const chart = orgChart(looped, []);
132 const all = (nodes: typeof chart.roots): string[] => nodes.flatMap((n) => [n.person.username, ...all(n.reports)]);
133 assert.deepEqual(all(chart.roots).sort(), ["a", "b"]);
134});
135
136test("someone can report to anyone but themselves and the people under them", () => {
137 assert.deepEqual(managerChoices(directory.people, "sofia").map((p) => p.username), ["chase", "kai"]);
138 assert.deepEqual(managerChoices(directory.people, "jordan").map((p) => p.username), ["chase", "sofia", "kai"]);
139});
140
141test("forms read plainly", () => {
142 assert.deepEqual(ownsFromText("storefront\n the release process ,, billing"), ["storefront", "the release process", "billing"]);
143 assert.equal(budgetFromText(""), 0);
144 assert.equal(budgetFromText("$150"), 150_000_000);
145 assert.equal(budgetFromText("1,250.50"), 1_250_500_000);
146 assert.equal(budgetFromText("lots"), null);
147 assert.equal(budgetFromText("-5"), null);
148});
149
150test("access to Code says where it comes from", () => {
151 assert.equal(codeAccessWords({ role: "owner" }, "read", []).summary, "Admin on every repository, as an owner");
152 const kai = codeAccessWords({ role: "member" }, "read", [directory.teams[1]!]);
153 assert.equal(kai.summary, "Read on every repository, the workspace's base permission");
154 assert.deepEqual(kai.through, ["Roles on 2 repositories through Design"]);
155 assert.equal(codeAccessWords({ role: "member" }, "none", []).summary, "Only repositories they're given a role on");
156});
157
158test("a team's part of what an agent is told", () => {
159 const told = "## Your teams\n\nIntro.\n\n### Sales\n\nLed by Sofia.\n- @sofia\n\n### Support\n\n- @dev";
160 assert.equal(teamBlock(told, "Sales"), "### Sales\n\nLed by Sofia.\n- @sofia");
161 assert.equal(teamBlock(told, "Support"), "### Support\n\n- @dev");
162 assert.equal(teamBlock(told, "Design"), null);
163 assert.equal(teamBlock(null, "Sales"), null);
164});