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.

g1t.sh
174 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.

The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import {
5 type ChecklistFacts,
6 agentWasAssigned,
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb977 checklistPlan,
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor8 dismiss,
9 dismissKey,
10 hasInstructions,
11 isDismissed,
12 productionChecklist,
13 progress,
A project is an app or a library: libraries show their package and how to ship a release, not production14 releaseChecklist,
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb9715 startChecklist,
The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor16} from "./checklist.ts";
17
18const fresh: ChecklistFacts = {
19 base: "/acme/web",
20 hasCode: false,
21 deploysEnabled: false,
22 productionDeployed: false,
23 domains: 0,
24 previewOpened: false,
25 instructions: false,
26 agentAssigned: false,
27};
28
29test("a new project has everything to do, in order", () => {
30 const items = productionChecklist(fresh);
31 assert.deepEqual(
32 items.map((item) => item.key),
33 ["code", "deploy", "domain", "preview", "instructions", "agent"],
34 );
35 assert.deepEqual(progress(items), { done: 0, total: 6, complete: false });
36});
37
38test("each step is done from its own fact", () => {
39 const items = productionChecklist({ ...fresh, hasCode: true, productionDeployed: true, domains: 2 });
40 assert.deepEqual(progress(items), { done: 3, total: 6, complete: false });
41 const all = productionChecklist({
42 ...fresh,
43 hasCode: true,
44 productionDeployed: true,
45 domains: 1,
46 previewOpened: true,
47 instructions: true,
48 agentAssigned: true,
49 });
50 assert.equal(progress(all).complete, true);
51});
52
53test("unknown facts count as not done", () => {
54 const items = productionChecklist({ ...fresh, domains: null, instructions: null });
55 assert.equal(items.find((item) => item.key === "domain")?.done, false);
56 assert.equal(items.find((item) => item.key === "instructions")?.done, false);
57});
58
59test("each step links to where it is done", () => {
60 const off = productionChecklist(fresh);
61 assert.equal(off.find((item) => item.key === "deploy")?.to, "/acme/web/settings/deployments");
62 const on = productionChecklist({ ...fresh, deploysEnabled: true });
63 assert.equal(on.find((item) => item.key === "deploy")?.to, "/acme/web/deployments");
64 assert.equal(on.find((item) => item.key === "domain")?.to, "/acme/web/settings/domains");
65 assert.equal(on.find((item) => item.key === "agent")?.to, "/acme/web/issues/new");
66});
67
68test("instructions are AGENTS.md or CLAUDE.md at the root", () => {
69 assert.equal(hasInstructions(["README.md", "AGENTS.md"]), true);
70 assert.equal(hasInstructions(["claude.md"]), true);
71 assert.equal(hasInstructions(["README.md", "AGENTS.mdx", "docs"]), false);
72});
73
74test("g1t counts as assigned from a run, a pull request or an issue", () => {
75 const none = { runAgents: ["claude-code"], pullAgents: ["claude-code"], issues: [{ assignees: ["ana"], agent: null }] };
76 assert.equal(agentWasAssigned(none), false);
77 assert.equal(agentWasAssigned({ ...none, runAgents: ["g1t"] }), true);
78 assert.equal(agentWasAssigned({ ...none, pullAgents: ["g1t"] }), true);
79 assert.equal(agentWasAssigned({ ...none, issues: [{ assignees: ["G1T"], agent: null }] }), true);
80 assert.equal(agentWasAssigned({ ...none, issues: [{ assignees: [], agent: "g1t" }] }), true);
81});
82
83test("dismissing is remembered per project, and storage that throws is ignored", () => {
84 const map = new Map<string, string>();
85 const store = { getItem: (key: string) => map.get(key) ?? null, setItem: (key: string, value: string) => void map.set(key, value) };
86 assert.equal(isDismissed(() => store, "/acme/web"), false);
87 assert.equal(dismiss(() => store, "/Acme/Web"), true);
88 assert.equal(isDismissed(() => store, "/acme/web"), true);
89 assert.equal(isDismissed(() => store, "/acme/api"), false);
90 assert.equal(dismissKey("/Acme/Web"), "g1t:checklist-dismissed:/acme/web");
91 const blocked = {
92 getItem: () => {
93 throw new Error("blocked");
94 },
95 setItem: () => {
96 throw new Error("blocked");
97 },
98 };
99 assert.equal(isDismissed(() => blocked, "/acme/web"), false);
100 assert.equal(dismiss(() => blocked, "/acme/web"), false);
101});
A project is an app or a library: libraries show their package and how to ship a release, not production102
103test("a library's checklist ships a release instead of deploying", () => {
104 const facts = {
105 base: "/flagon-io/php-log",
106 hasCode: true,
107 instructions: false,
108 agentAssigned: false,
109 hasWorkflow: false,
110 released: true,
111 releaseTo: "/flagon-io/-/packages/composer/psr/log",
112 };
113 const items = releaseChecklist(facts);
114 assert.deepEqual(
115 items.map((item) => item.key),
116 ["code", "checks", "release", "instructions", "agent"],
117 );
118 assert.deepEqual(progress(items), { done: 2, total: 5, complete: false });
119 assert.equal(items.find((item) => item.key === "checks")?.to, "/flagon-io/php-log/actions");
120 assert.equal(items.find((item) => item.key === "release")?.to, "/flagon-io/-/packages/composer/psr/log");
121 assert.ok(items.every((item) => !/deploy|production|domain|preview/i.test(item.title)));
122 // An unknown workflow list counts as not done.
123 assert.equal(releaseChecklist({ ...facts, hasWorkflow: null }).find((item) => item.key === "checks")?.done, false);
124});
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97125
126const start = {
127 base: "/flagon-io/g1t",
128 hasCode: true,
129 instructions: true,
130 agentAssigned: false,
131 hasWorkflow: true,
132 productionUrl: null,
133 hasLinks: false,
134 hasDocsLink: false,
135};
136
137test("only what g1t deploys gets production's steps", () => {
138 assert.deepEqual(checklistPlan({ kind: "app", runs: "g1t" }), { plan: "production", title: "Get to production" });
139 assert.deepEqual(checklistPlan({ kind: "docs", runs: "g1t" }).plan, "production");
140 assert.deepEqual(checklistPlan({ kind: "app", runs: "elsewhere" }), { plan: "elsewhere", title: "Get started" });
141 assert.equal(checklistPlan({ kind: "app", runs: null }).plan, "unknown");
142 assert.deepEqual(checklistPlan({ kind: "tool", runs: null }), { plan: "release", title: "Ship a release" });
143 assert.equal(checklistPlan({ kind: "library", runs: null }).plan, "release");
144 assert.equal(checklistPlan({ kind: "docs", runs: "elsewhere" }).plan, "docs");
145 assert.equal(checklistPlan({ kind: "other", runs: null }).plan, "other");
146});
147
148test("an app deployed elsewhere is never asked to deploy on g1t", () => {
149 const items = startChecklist("elsewhere", start);
150 assert.deepEqual(
151 items.map((item) => item.key),
152 ["code", "production", "checks", "instructions", "agent"],
153 );
154 assert.ok(items.every((item) => !/deploy to|turn on|domain|preview/i.test(`${item.title} ${item.detail}`)));
155 assert.equal(items.find((item) => item.key === "production")?.done, false);
156 assert.equal(startChecklist("elsewhere", { ...start, productionUrl: "https://g1t.sh" }).find((item) => item.key === "production")?.done, true);
157 // Every step can be done.
158 const all = startChecklist("elsewhere", { ...start, productionUrl: "https://g1t.sh", agentAssigned: true });
159 assert.equal(progress(all).complete, true);
160});
161
162test("an app nobody has placed asks where it runs; docs and other ask for links", () => {
163 assert.deepEqual(
164 startChecklist("unknown", start).map((item) => item.key),
165 ["code", "where", "checks", "instructions", "agent"],
166 );
167 assert.equal(startChecklist("unknown", start).find((item) => item.key === "where")?.to, "/flagon-io/g1t/settings#kind");
168 const docs = startChecklist("docs", { ...start, hasDocsLink: true });
169 assert.deepEqual(docs.map((item) => item.key), ["code", "links", "instructions", "agent"]);
170 assert.equal(docs.find((item) => item.key === "links")?.done, true);
171 const other = startChecklist("other", start);
172 assert.equal(other.find((item) => item.key === "links")?.done, false);
173 assert.equal(startChecklist("other", { ...start, hasLinks: true, agentAssigned: true }).every((item) => item.done), true);
174});

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