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

Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet1import assert from "node:assert/strict";
2import { readFileSync } from "node:fs";
3import { test } from "node:test";
4
5import type { ServiceBinding } from "./clients.ts";
6import { datasetQueryError } from "./datasets.ts";
7import { dashboardGridError, dashboardOpError } from "./folios-dashboard.ts";
8import { DESIGN_MAX_NODES, countDesignSpecs, designOpError } from "./folios-design.ts";
9import { SLIDE_LAYOUTS, SLIDE_LAYOUT_REGIONS, slideFragment, slidesOpError } from "./folios-slides.ts";
10import {
11 FOLIO_KINDS,
12 FOLIO_RPC_METHODS,
13 FOLIO_ROUTE_SEGMENTS,
14 folioAccessChangeError,
15 folioAgentEditError,
16 folioCanHaveChildren,
17 folioIdFrom,
18 folioListQueryError,
19 folioPath,
20 folioSlug,
21 foliosClient,
22 linkedFolioIds,
23 newFolioError,
24 type FolioAccessChange,
25 type NewFolio,
26} from "./folios.ts";
27import type { User } from "./identity.ts";
28
29const fixtures = JSON.parse(readFileSync(new URL("./folios.fixtures.json", import.meta.url), "utf8")) as {
30 new_folio: { input: unknown; error: string | null }[];
31 access_change: { change: unknown; error: string | null }[];
32 agent_edit: { edit: unknown; error: string | null }[];
33 folio_ids: { segment: string; id: string | null }[];
34};
35
36function expect(label: string, actual: string | null, error: string | null) {
37 if (error === null) assert.equal(actual, null, label);
38 else if (error === "*") assert.notEqual(actual, null, `${label} should be refused`);
39 else assert.equal(actual, error, label);
40}
41
42test("agrees with the Rust validators on every shared case", () => {
43 for (const { input, error } of fixtures.new_folio) expect(JSON.stringify(input), newFolioError(input as NewFolio), error);
44 for (const { change, error } of fixtures.access_change) expect(JSON.stringify(change), folioAccessChangeError(change as FolioAccessChange), error);
45 for (const { edit, error } of fixtures.agent_edit) expect(JSON.stringify(edit), folioAgentEditError(edit), error);
46 for (const { segment, id } of fixtures.folio_ids) assert.equal(folioIdFrom(segment), id, segment);
47});
48
49test("addresses are flat, end in the id and survive renames", () => {
50 const id = "fol_01jb2k7x9hfq0b3zj0f5s2m8ra";
51 assert.equal(folioPath("acme", "Q4 roadmap: pricing", id), `/acme/-/artifacts/q4-roadmap-pricing-${id}`);
52 assert.equal(folioSlug("", id), id);
53 assert.equal(folioSlug("Café ✨ notes", id), `cafe-notes-${id}`);
54 assert.equal(folioIdFrom(folioSlug("Anything at all", id)), id);
55 assert.deepEqual(linkedFolioIds(`see /acme/-/artifacts/x-${id} and ${id}`), [id]);
56 for (const segment of FOLIO_ROUTE_SEGMENTS) assert.equal(folioIdFrom(segment), null, segment);
57});
58
59test("only a doc holds other folios", () => {
60 assert.deepEqual(FOLIO_KINDS.filter(folioCanHaveChildren), ["doc"]);
61});
62
63test("list queries are checked", () => {
64 assert.equal(folioListQueryError({ tab: "shared", kinds: ["slides"], limit: 50 }), null);
65 assert.equal(folioListQueryError({ tab: "everything" as "all" }), "tab is all, yours or shared.");
66 assert.equal(folioListQueryError({ tab: "all", limit: 500 }), "limit is between 1 and 100.");
67 assert.equal(folioListQueryError({ tab: "all", kinds: ["sheet" as "doc"] }), "There is no kind of artifact called sheet.");
68});
69
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.70test("the client calls exactly the artifacts service's folio methods", async () => {
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet71 const called: string[] = [];
72 const bodies: Record<string, unknown>[] = [];
73 const binding: ServiceBinding = {
74 fetch: async (input: RequestInfo | URL, init?: RequestInit) => {
75 called.push(String(input).replace("https://service/rpc/", ""));
76 bodies.push(JSON.parse(String(init?.body)));
77 return new Response(JSON.stringify({ ok: true, value: null }), { headers: { "content-type": "application/json" } });
78 },
79 } as ServiceBinding;
80 const client = foliosClient(binding);
81 const viewer = { id: "usr_1" } as User;
82 const ws = "acme";
83 const f = "fol_1";
84 await Promise.all([
85 client.list(ws, viewer, { tab: "all" }),
86 client.sidebar(ws, viewer),
87 client.folio(ws, viewer, f),
The folio client's test calls folio_page too, so it checks every method the docs service answers.88 client.page(ws, viewer, f),
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet89 client.create(ws, viewer, { kind: "doc" }),
90 client.update(ws, viewer, f, { title: "x" }),
91 client.move(ws, viewer, f, { space_id: null, parent_id: null }),
92 client.duplicate(ws, viewer, f),
93 client.trash(ws, viewer, f),
94 client.restore(ws, viewer, f),
95 client.delete(ws, viewer, f),
96 client.trashed(ws, viewer),
Merge branch 'customize' into main: Customize replaces the Marketplace, the Artifacts trash and spaces changes, the Security-free cleanup, with the desktop app's own title bar kept in the shell.97 client.emptyTrash(ws, viewer),
98 client.deleteSpace(ws, viewer, "spc_1"),
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet99 client.favorite(ws, viewer, f, true),
100 client.content(ws, viewer, f),
101 client.edit(ws, viewer, f, { kind: "doc", target: { kind: "append" }, markdown: "x" }),
102 client.access(ws, viewer, f),
103 client.changeAccess(ws, viewer, f, { op: "grant", principal: "user:usr_2", role: "view" }),
104 client.changeAccess(ws, viewer, f, { op: "general", access: "workspace", role: "view" }),
105 client.requestAccess(ws, viewer, f),
106 client.joinSpace(ws, viewer, "spc_1"),
107 client.leaveSpace(ws, viewer, "spc_1"),
108 client.search(ws, viewer, { q: "roadmap" }),
109 client.versions(ws, viewer, f),
110 client.version(ws, viewer, f, "ver_1"),
111 client.restoreVersion(ws, viewer, f, "ver_1"),
112 client.templates(ws, viewer),
113 client.saveTemplate(ws, viewer, { folio_id: f, name: "T" }),
114 client.deleteTemplate(ws, viewer, "tpl_1"),
115 client.export(ws, viewer, f),
116 client.suggestions(ws, viewer, f),
117 client.decideSuggestion(ws, viewer, "sug_1", "accept"),
118 client.proposals(ws, viewer, f),
119 client.decideProposal(ws, viewer, "prp_1", "reject"),
120 client.thread(ws, viewer, f, { op: "resolve", thread_id: "thr_1" }),
121 client.threads(ws, viewer, f),
122 client.queryTile(ws, viewer, f, "t1"),
123 client.queryDataset(ws, viewer, { dataset: "issues", measure: { op: "count" } }),
124 client.queryDatasetForAgent(ws, "agt_1", viewer, { folio_id: f, tile_id: "t1" }),
125 client.foliosForAgent(ws, "agt_1", viewer, { tab: "all" }),
126 client.readForAgent(ws, "agt_1", viewer, f),
127 client.createAsAgent(ws, "agt_1", viewer, { kind: "doc", title: "Notes", where: "private" }),
128 client.editAsAgent(ws, "agt_1", viewer, f, { kind: "slides", ops: [{ op: "delete_slides", slide_ids: ["s1"] }] }),
129 client.shareAsAgent(ws, "agt_1", viewer, f, { user_ids: ["usr_2"], role: "view" }, { kind: "people", user_ids: ["usr_1", "usr_2"] }),
Every agent starts with g1t's foundational skills, playbooks for documents, research, data, code, communication, and files and media, each using only tools the agent already has and saying plainly what isn't possible yet: agents make PDFs, Word documents, spreadsheets, CSV and Markdown files with make_file, kept with a doc in Artifacts and served from g1tusercontent.com; an agent's Skills tab shows what each skill can do and with which tools, and owners turn a skill off per agent; the agent skills guide says how.130 client.attachAsAgent(ws, "agt_1", viewer, f, { name: "q3.pdf", content_type: "application/pdf", data: "JVBERi0=" }),
Artifacts contracts: folios, their four kinds, dashboard datasets, folio events and the artifacts scopes are typed and validated the same in TypeScript and Rust, with nothing using them yet131 client.recallForAgent(ws, "agt_1", viewer, { query: "pricing" }),
132 client.staleForAgent(ws, "agt_1", viewer),
133 client.markCurrent(ws, viewer, f),
134 client.reindex(ws, viewer),
135 ]);
136 assert.deepEqual([...new Set(called)].sort(), [...FOLIO_RPC_METHODS].sort());
137 // Every body names the workspace and the viewer, and keys are snake_case.
138 for (const body of bodies) {
139 assert.equal(body.workspace, ws);
140 assert.ok(body.viewer);
141 for (const key of Object.keys(body)) assert.match(key, /^[a-z_]+$/, key);
142 }
143});
144
145test("slides ops are checked by shape", () => {
146 assert.equal(slidesOpError({ op: "insert_slides", after_slide_id: null, markdown: "---" }), null);
147 assert.equal(slidesOpError({ op: "move_slide", slide_id: "s1", after_slide_id: "s2" }), null);
148 assert.equal(slidesOpError({ op: "set_theme", theme: "night", accent: "#8b7cf6" }), null);
149 assert.equal(slidesOpError({ op: "set_theme", theme: "night", accent: "lavender" }), "accent is a colour like #8b7cf6, or null.");
150 assert.equal(slidesOpError({ op: "replace_slide", markdown: "# x" }), "replace_slide needs slide_id.");
151 assert.equal(slidesOpError({ op: "delete_slides", slide_ids: [] }), "delete_slides needs slide_ids.");
152 assert.equal(slidesOpError({ op: "shuffle" }), "There is no slides op called shuffle.");
153 for (const layout of SLIDE_LAYOUTS) assert.ok(SLIDE_LAYOUT_REGIONS[layout].includes("notes"), layout);
154 assert.equal(slideFragment("s1", "left"), "slide:s1:left");
155});
156
157test("design ops are checked by shape and size", () => {
158 const frame = { type: "frame", name: "Home", layout: "column", gap: 16, children: [{ type: "text", text: "Hello" }, { type: "html", html: "<b>hi</b>" }] };
159 assert.equal(designOpError({ op: "upsert_nodes", nodes: [frame] }), null);
160 assert.deepEqual(countDesignSpecs([frame as never]), { nodes: 3, depth: 2 });
161 assert.equal(designOpError({ op: "upsert_nodes", nodes: [{ type: "rect", children: [{ type: "text" }] }] }), "Only frames and components have children.");
162 assert.equal(designOpError({ op: "upsert_nodes", nodes: [{ type: "text", html: "<b>" }] }), "Only an html node has html.");
163 assert.equal(designOpError({ op: "upsert_nodes", nodes: [{ type: "blob" }] }), "There is no node type called blob.");
164 assert.equal(designOpError({ op: "set_html", node_id: "n1", html: "x".repeat(200 * 1024 + 1) }), "An html node holds at most 200 KB.");
165 assert.equal(designOpError({ op: "set_html", node_id: "n1", html: "é".repeat(100 * 1024) }), null);
166 assert.equal(designOpError({ op: "set_html", node_id: "n1", html: "é".repeat(100 * 1024 + 1) }), "An html node holds at most 200 KB.");
167 const many = Array.from({ length: DESIGN_MAX_NODES + 1 }, () => ({ type: "rect" }));
168 assert.equal(designOpError({ op: "upsert_nodes", nodes: many }), `A design holds at most ${DESIGN_MAX_NODES} nodes.`);
169 assert.equal(designOpError({ op: "move", ids: ["a"], dx: 1, dy: Number.NaN }), "move needs dx and dy.");
170 assert.equal(designOpError({ op: "instance" }), "There is no design op called instance.");
171});
172
173test("dashboard ops check tiles, their queries and the grid", () => {
174 const tile = {
175 id: "t1",
176 type: "line",
177 title: "Merged per week",
178 description: "",
179 query: { dataset: "pull_requests", measure: { op: "count" }, interval: "week", time: "merged_at" },
180 viz: {},
181 grid: { x: 0, y: 0, w: 6, h: 4 },
182 };
183 assert.equal(dashboardOpError({ op: "upsert_tile", tile }, datasetQueryError), null);
184 assert.equal(dashboardOpError({ op: "upsert_tile", tile: { ...tile, query: { ...tile.query, group_by: "secret" } } }, datasetQueryError), "pull_requests can't be grouped by secret.");
185 assert.equal(dashboardOpError({ op: "upsert_tile", tile: { ...tile, type: "markdown", query: null, markdown: "Notes" } }, datasetQueryError), null);
186 assert.equal(dashboardOpError({ op: "upsert_tile", tile: { ...tile, type: "markdown" } }, datasetQueryError), "A text tile has no query.");
187 assert.equal(dashboardOpError({ op: "upsert_tile", tile: { ...tile, grid: { x: 8, y: 0, w: 6, h: 4 } } }, datasetQueryError), "A tile fits in 12 columns.");
188 assert.equal(dashboardOpError({ op: "set_filters", filters: { range: "30d", repos: ["acme/web"] } }, datasetQueryError), null);
189 assert.equal(dashboardOpError({ op: "set_filters", filters: { range: { from: "2026-02-30", to: "2026-03-01" } } }, datasetQueryError), "A range's from and to are dates or RFC 3339 UTC times.");
190 assert.equal(dashboardOpError({ op: "set_layout", tiles: [{ id: "t1", grid: { x: 0, y: 0, w: 0, h: 1 } }] }, datasetQueryError), "grid starts at 0, 0 and is at least 1 by 1.");
191 assert.equal(dashboardGridError({ x: 0, y: 0, w: 12, h: 1 }), null);
192});

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