Skip to content
73 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 Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { FIRST_PARTY_EXTENSIONS, type ExtensionManifest, checkManifest, dataDisclosure, extensionFrameUrl, parseListing, versionOfTag } from "./marketplace.ts";
5import { isScope } from "./scopes.ts";
6
7const published: ExtensionManifest = {
8 ...FIRST_PARTY_EXTENSIONS[0]!,
9 id: "standup",
10 status: "available",
11 source: { repo: "flagon-io/standup", tag: "v1.2.0" },
12 version: "1.2.0",
13};
14
15test("g1t's own extensions are listed as coming, with manifests publishing would accept", () => {
16 const ids = new Set<string>();
17 for (const extension of FIRST_PARTY_EXTENSIONS) {
18 assert.ok(!ids.has(extension.id), extension.id);
19 ids.add(extension.id);
20 assert.equal(extension.status, "soon", `${extension.id} isn't published yet`);
21 assert.equal(extension.source, null);
22 assert.equal(extension.pricing, null);
23 assert.equal(extension.publisher.tier, "official");
24 const checked = checkManifest(extension, isScope);
25 assert.ok(checked.ok, `${extension.id}: ${checked.ok ? "" : checked.message}`);
26 }
27});
28
29test("publishing checks a manifest strictly", () => {
30 assert.ok(checkManifest(published, isScope).ok);
31 const refused = (changes: Partial<ExtensionManifest> | Record<string, unknown>, why: RegExp) => {
32 const checked = checkManifest({ ...published, ...changes }, isScope);
33 assert.equal(checked.ok, false, JSON.stringify(changes));
34 if (!checked.ok) assert.match(checked.message, why);
35 };
36 refused({ id: "Bad Id" }, /id/);
37 refused({ scopes: ["everything:admin"] }, /scope/);
38 refused({ source: null }, /source/);
39 refused({ domains: ["not a host"] }, /domains/);
40 refused({ runtime: "connected", domains: [] }, /declares the domains/);
41 refused({ publisher: { name: "anyone", tier: "community" } }, /Community extensions run on their publisher's servers/);
42 refused({ pricing: { monthly: 5 } }, /free/);
43 refused({ permissions: [] }, /permissions/);
44 refused({ ui: { entry: "index.html" } }, /ui.entry/);
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.45 refused({ bridges: " " }, /bridges/);
46 refused({ adds: { pages: [], agent_roles: [], tools: [], notifications: [] } }, /cards/);
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.47 // A community extension that runs on its own servers, declaring them, is fine.
48 assert.ok(checkManifest({ ...published, runtime: "connected", publisher: { name: "anyone", tier: "community" }, domains: ["api.example.com"] }, isScope).ok);
49});
50
51test("the install screen says where data goes", () => {
52 assert.equal(dataDisclosure({ domains: [] }), "Its data stays in g1t.");
53 assert.equal(dataDisclosure({ domains: ["api.acme.dev", "eu.acme.dev"] }), "Data leaves g1t to api.acme.dev, eu.acme.dev.");
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.54 assert.equal(dataDisclosure({ domains: [], bridges: "the CRM you connect" }), "Data leaves g1t to the CRM you connect.");
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.55});
56
57test("an extension's page loads from the user-content origin, by version", () => {
58 assert.equal(extensionFrameUrl(published, "https://g1tusercontent.com/"), "https://g1tusercontent.com/x/standup/1.2.0/index.html");
59 assert.equal(extensionFrameUrl({ ...published, ui: null }, "https://g1tusercontent.com"), null);
60 assert.equal(extensionFrameUrl(FIRST_PARTY_EXTENSIONS[0]!, "https://g1tusercontent.com"), null, "nothing published, nothing to load");
61});
62
63test("a tag publishes a version", () => {
64 assert.equal(versionOfTag("v1.4.0"), "1.4.0");
65 assert.equal(versionOfTag("2.0.0-beta.1"), "2.0.0-beta.1");
66 assert.equal(versionOfTag("latest"), null);
67});
68
69test("listings are referenced by kind and id", () => {
70 assert.deepEqual(parseListing("extension:on-call"), { kind: "extension", id: "on-call" });
71 assert.equal(parseListing("app:on-call"), null);
The Marketplace adds what g1t doesn't do and connects what you already use: extensions (Mail, Support, CRM, Recruiting, On-call, and bridges to a helpdesk, CRM or ERP you run, all Soon), starter kits, and integrations connected by the workspace or by each person; agents aren't installed there. Agent templates live in Agents, as starting points you configure, at Agents → Templates, and the Marketplace's old agent addresses lead there. The marketplace and agents guides say how.72 assert.equal(parseListing("agent:engineering"), null, "agents start from templates in Agents, not the Marketplace");
The Marketplace is where a workspace finds what to add, reached from Apps: the agent catalog of roles with who already does each job and Add to workspace; every integration with whether it's connected; g1t's own extensions, listed as Soon; and requests, where members ask and owners add or turn down, each told by a notification. Underneath, an extension is a manifest (publisher and tier, source and version from a tag, scopes, the domains its data goes to, its page on g1tusercontent.com, no price) and an install pins its version with an off switch, a budget and the audit log. Apps lists only what was added from the Marketplace, with pins; g1t's own pages stay in their sidebars, and AI Gateway joins Workspace's. The marketplace guide says how.73});