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.
| Project settings say who created the project, by name | 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; | |
| 3 | ||
| 4 | import { | |
| 5 | parseAllowances, | |
| 6 | parseCredit, | |
| 7 | parseDecision, | |
| 8 | parseEmail, | |
| 9 | parseGoodwill, | |
| 10 | parsePayment, | |
| 11 | parseSales, | |
| 12 | parseSalesNote, | |
| 13 | parseSlugList, | |
| 14 | parseTerms, | |
| 15 | } from "./forms.ts"; | |
| 16 | ||
| 17 | const NOW = new Date("2026-10-04T12:00:00Z"); | |
| 18 | ||
| 19 | function form(entries: Record<string, string>): FormData { | |
| 20 | const data = new FormData(); | |
| 21 | for (const [name, value] of Object.entries(entries)) data.set(name, value); | |
| 22 | return data; | |
| 23 | } | |
| 24 | ||
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 25 | test("a 100% discount keeps its budget and an end date, and names who set it", () => { |
| 26 | const result = parseTerms(form({ preset: "100", note: "g1t's own", ceiling: "500", until: "2026-12-31", discount: "40" }), "owner@g1t.sh", NOW); | |
| Project settings say who created the project, by name | 27 | assert.deepEqual(result, { |
| 28 | ok: true, | |
| 29 | value: { | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 30 | kind: "custom", |
| 31 | discountPercent: 100, | |
| Project settings say who created the project, by name | 32 | ceilingMicros: 500_000_000, |
| 33 | note: "g1t's own", | |
| 34 | until: "2026-12-31T23:59:59Z", | |
| 35 | setBy: "owner@g1t.sh", | |
| 36 | setAt: NOW.toISOString(), | |
| 37 | }, | |
| 38 | }); | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 39 | // A form from before discounts, saying comped, is a 100% discount. |
| 40 | const old = parseTerms(form({ kind: "comped", note: "g1t's own" }), "a", NOW); | |
| 41 | assert.ok(old.ok && old.value.kind === "custom" && old.value.discountPercent === 100); | |
| Project settings say who created the project, by name | 42 | }); |
| 43 | ||
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 44 | test("a discount is a preset or a custom whole percent", () => { |
| 45 | const custom = parseTerms(form({ preset: "custom", discount: "30", note: "Design partner" }), "a", NOW); | |
| 46 | assert.ok(custom.ok && custom.value.discountPercent === 30 && custom.value.kind === "custom"); | |
| 47 | const half = parseTerms(form({ preset: "50", discount: "30", note: "x" }), "a", NOW); | |
| 48 | assert.ok(half.ok && half.value.discountPercent === 50); | |
| 49 | // A limit alone is custom terms too. | |
| 50 | const limit = parseTerms(form({ preset: "0", ceiling: "250", note: "x" }), "a", NOW); | |
| 51 | assert.ok(limit.ok && limit.value.kind === "custom" && limit.value.discountPercent === 0); | |
| 52 | }); | |
| 53 | ||
| 54 | test("no discount and no limit is standard, which clears the end date", () => { | |
| 55 | const result = parseTerms(form({ preset: "0", note: "back to normal", until: "2027-01-01" }), "a@g1t.sh", NOW); | |
| Project settings say who created the project, by name | 56 | assert.ok(result.ok); |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 57 | assert.equal(result.value.kind, "standard"); |
| Project settings say who created the project, by name | 58 | assert.equal(result.value.ceilingMicros, null); |
| 59 | assert.equal(result.value.until, null); | |
| 60 | }); | |
| 61 | ||
| 62 | test("terms are refused without a note, with a bad discount, or ending in the past", () => { | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 63 | assert.equal(parseTerms(form({ preset: "100", note: "" }), "a", NOW).ok, false); |
| 64 | assert.equal(parseTerms(form({ preset: "custom", note: "x", discount: "101" }), "a", NOW).ok, false); | |
| 65 | assert.equal(parseTerms(form({ preset: "custom", note: "x" }), "a", NOW).ok, false); | |
| 66 | assert.equal(parseTerms(form({ preset: "custom", note: "x", discount: "20", until: "2026-10-01" }), "a", NOW).ok, false); | |
| 67 | assert.equal(parseTerms(form({ preset: "custom", note: "x", discount: "20", until: "2026-02-30" }), "a", NOW).ok, false); | |
| 68 | assert.equal(parseTerms(form({ preset: "75", note: "x" }), "a", NOW).ok, true); | |
| 69 | assert.equal(parseTerms(form({ preset: "free", note: "x" }), "a", NOW).ok, false); | |
| Project settings say who created the project, by name | 70 | }); |
| 71 | ||
| 72 | test("workspace lists take commas, spaces and lines, once each", () => { | |
| 73 | assert.deepEqual(parseSlugList("acme, Acme-labs\nbeta beta"), { ok: true, value: ["acme", "acme-labs", "beta"] }); | |
| 74 | assert.equal(parseSlugList("acme, bad--slug").ok, false); | |
| 75 | assert.equal(parseSlugList("../etc").ok, false); | |
| 76 | }); | |
| 77 | ||
| 78 | test("invoice emails are one address", () => { | |
| 79 | assert.deepEqual(parseEmail(" Billing@Acme.com "), { ok: true, value: "billing@acme.com" }); | |
| 80 | assert.equal(parseEmail("a@b").ok, false); | |
| 81 | assert.equal(parseEmail("a@b.com, c@d.com").ok, false); | |
| 82 | assert.equal(parseEmail("a@@b.com").ok, false); | |
| 83 | assert.equal(parseEmail("").ok, false); | |
| 84 | }); | |
| 85 | ||
| 86 | test("credits are positive and capped", () => { | |
| 87 | assert.deepEqual(parseCredit("25.50"), { ok: true, value: 25_500_000 }); | |
| 88 | assert.equal(parseCredit("0").ok, false); | |
| 89 | assert.equal(parseCredit("10000.01").ok, false); | |
| 90 | }); | |
| 91 | ||
| 92 | test("a sales record: a stage, an owner's email or nobody, a next step and its day", () => { | |
| 93 | assert.deepEqual(parseSales(form({ stage: "contacted", owner: " Me@G1t.sh ", nextStep: "Call about\n terms", nextAt: "2026-10-09" })), { | |
| 94 | ok: true, | |
| 95 | value: { stage: "contacted", owner: "me@g1t.sh", nextStep: "Call about terms", nextAt: "2026-10-09" }, | |
| 96 | }); | |
| 97 | assert.deepEqual(parseSales(form({ stage: "none", owner: "", nextStep: "", nextAt: "" })), { | |
| 98 | ok: true, | |
| 99 | value: { stage: "none", owner: null, nextStep: null, nextAt: null }, | |
| 100 | }); | |
| 101 | assert.equal(parseSales(form({ stage: "closed" })).ok, false); | |
| 102 | assert.equal(parseSales(form({ stage: "lead", owner: "not an email" })).ok, false); | |
| 103 | assert.equal(parseSales(form({ stage: "lead", nextStep: "x".repeat(201) })).ok, false); | |
| 104 | assert.equal(parseSales(form({ stage: "lead", nextStep: "Call", nextAt: "2026-02-30" })).ok, false); | |
| 105 | assert.equal(parseSales(form({ stage: "lead", nextStep: "Call", nextAt: "next week" })).ok, false); | |
| 106 | // A date needs a step to go with it. | |
| 107 | assert.equal(parseSales(form({ stage: "lead", nextAt: "2026-10-09" })).ok, false); | |
| 108 | }); | |
| 109 | ||
| 110 | test("a sales note is required, and not endless", () => { | |
| 111 | assert.deepEqual(parseSalesNote("Spoke to Ana; wants an enterprise quote."), { ok: true, value: "Spoke to Ana; wants an enterprise quote." }); | |
| 112 | assert.equal(parseSalesNote("").ok, false); | |
| 113 | assert.equal(parseSalesNote("x".repeat(2001)).ok, false); | |
| 114 | }); | |
| 115 | ||
| 116 | ||
| 117 | test("allowances: the plan without its price, pool shares, and staff's overrides", () => { | |
| 118 | assert.deepEqual(parseAllowances(form({})), { | |
| 119 | ok: true, | |
| 120 | value: { | |
| 121 | plan: false, | |
| 122 | ossRepoMicros: null, | |
| 123 | trialMicros: null, | |
| 124 | maxConcurrentAgents: null, | |
| 125 | runCapMicros: null, | |
| 126 | issueCapMicros: null, | |
| 127 | auditRetentionDays: null, | |
| 128 | hold: null, | |
| 129 | }, | |
| 130 | }); | |
| 131 | assert.deepEqual( | |
| 132 | parseAllowances(form({ plan: "on", oss: "5", trial: "2.50", agents: "20", runCap: "25", issueCap: "500", auditDays: "365", hold: " Card disputed;\nwaiting on the bank " })), | |
| 133 | { | |
| 134 | ok: true, | |
| 135 | value: { | |
| 136 | plan: true, | |
| 137 | ossRepoMicros: 5_000_000, | |
| 138 | trialMicros: 2_500_000, | |
| 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. | 139 | // Retired with g1t's own agents: always cleared, whatever an old form sends. |
| 140 | maxConcurrentAgents: null, | |
| 141 | runCapMicros: null, | |
| 142 | issueCapMicros: null, | |
| Project settings say who created the project, by name | 143 | auditRetentionDays: 365, |
| 144 | hold: "Card disputed; waiting on the bank", | |
| 145 | }, | |
| 146 | }, | |
| 147 | ); | |
| 148 | assert.equal(parseAllowances(form({ oss: "lots" })).ok, false); | |
| 149 | assert.equal(parseAllowances(form({ trial: "5000" })).ok, false); | |
| 150 | // Audit log days: shorter or longer than the plan's, up to 400. | |
| 151 | assert.equal((parseAllowances(form({ auditDays: "3" })) as { value: { auditRetentionDays: number } }).value.auditRetentionDays, 3); | |
| 152 | assert.equal((parseAllowances(form({ auditDays: "400" })) as { value: { auditRetentionDays: number } }).value.auditRetentionDays, 400); | |
| 153 | assert.equal(parseAllowances(form({ auditDays: "0" })).ok, false); | |
| 154 | assert.equal(parseAllowances(form({ auditDays: "401" })).ok, false); | |
| 155 | assert.equal(parseAllowances(form({ auditDays: "30.5" })).ok, false); | |
| 156 | assert.equal(parseAllowances(form({ auditDays: "a year" })).ok, false); | |
| 157 | assert.equal(parseAllowances(form({ hold: "x".repeat(201) })).ok, false); | |
| 158 | }); | |
| 159 | ||
| 160 | test("a bank transfer: an amount, its reference, a note, and the slug typed out", () => { | |
| 161 | const ok = { amount: "1,500", reference: " TRX 0042 ", note: "Invoice INV-7, by wire", confirmation: "acme" }; | |
| 162 | assert.deepEqual(parsePayment(form(ok), "acme"), { ok: true, value: { amountMicros: 1_500_000_000, reference: "TRX 0042", note: "Invoice INV-7, by wire" } }); | |
| 163 | assert.equal(parsePayment(form({ ...ok, amount: "0" }), "acme").ok, false); | |
| 164 | assert.equal(parsePayment(form({ ...ok, amount: "100000.01" }), "acme").ok, false); | |
| 165 | assert.equal(parsePayment(form({ ...ok, reference: "" }), "acme").ok, false); | |
| 166 | assert.equal(parsePayment(form({ ...ok, note: "" }), "acme").ok, false); | |
| 167 | assert.equal(parsePayment(form({ ...ok, confirmation: "Acme" }), "acme").ok, false); | |
| 168 | }); | |
| 169 | ||
| 170 | test("a decision: approve as asked or at another amount; decline needs a note", () => { | |
| 171 | assert.deepEqual(parseDecision(form({ id: "lr_1", decision: "approve" })), { | |
| 172 | ok: true, | |
| 173 | value: { id: "lr_1", decision: "approve", amountMicros: null, note: "" }, | |
| 174 | }); | |
| 175 | assert.deepEqual(parseDecision(form({ id: "lr_1", decision: "approve", amount: "750", note: "Half now." })), { | |
| 176 | ok: true, | |
| 177 | value: { id: "lr_1", decision: "approve", amountMicros: 750_000_000, note: "Half now." }, | |
| 178 | }); | |
| 179 | assert.equal(parseDecision(form({ id: "lr_1", decision: "approve", amount: "0.50" })).ok, false); | |
| 180 | assert.equal(parseDecision(form({ id: "lr_1", decision: "approve", amount: "1000000.01" })).ok, false); | |
| 181 | assert.equal(parseDecision(form({ id: "lr_1", decision: "decline" })).ok, false); | |
| 182 | assert.deepEqual(parseDecision(form({ id: "lr_1", decision: "decline", note: "After a month of payments.", amount: "5" })), { | |
| 183 | ok: true, | |
| 184 | value: { id: "lr_1", decision: "decline", amountMicros: null, note: "After a month of payments." }, | |
| 185 | }); | |
| 186 | assert.equal(parseDecision(form({ id: "../x", decision: "approve" })).ok, false); | |
| 187 | assert.equal(parseDecision(form({ id: "lr_1", decision: "maybe" })).ok, false); | |
| 188 | }); | |
| 189 | ||
| 190 | test("goodwill: no amount is the one-click credit; a reason when one is needed; a day not in the future", () => { | |
| 191 | const never = () => false; | |
| 192 | const always = () => true; | |
| 193 | assert.deepEqual(parseGoodwill(form({}), never, NOW), { ok: true, value: { amountMicros: null, reason: "", day: null } }); | |
| 194 | assert.deepEqual(parseGoodwill(form({ amount: "60", reason: "Looping agent on #12, owner caught it late.", day: "2026-10-03" }), always, NOW), { | |
| 195 | ok: true, | |
| 196 | value: { amountMicros: 60_000_000, reason: "Looping agent on #12, owner caught it late.", day: "2026-10-03" }, | |
| 197 | }); | |
| 198 | assert.equal(parseGoodwill(form({ amount: "60", reason: "oops" }), always, NOW).ok, false); | |
| 199 | assert.equal(parseGoodwill(form({ amount: "0" }), never, NOW).ok, false); | |
| 200 | assert.equal(parseGoodwill(form({ amount: "10000.01" }), never, NOW).ok, false); | |
| 201 | assert.equal(parseGoodwill(form({ day: "2026-10-05" }), never, NOW).ok, false); | |
| 202 | assert.equal(parseGoodwill(form({ day: "2026-02-30" }), never, NOW).ok, false); | |
| 203 | // The check is given the amount typed, or null for the one-click credit. | |
| 204 | const seen: (number | null)[] = []; | |
| 205 | parseGoodwill(form({ amount: "12.50" }), (amount) => (seen.push(amount), false), NOW); | |
| 206 | parseGoodwill(form({}), (amount) => (seen.push(amount), false), NOW); | |
| 207 | assert.deepEqual(seen, [12_500_000, null]); | |
| 208 | }); |
This file's history is long; its oldest lines are credited to the oldest commit read.