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.

133 linesCodeBlameRaw
1import type { User, Viewer } from "./identity";
2import type { RepoPath } from "./repos";
3import type { Result } from "./result";
4
5/**
6 * A workspace's connections to systems outside g1t: alerts that open
7 * work items, and trackers whose tickets people read and import. Mirrors
8 * `crates/contracts/src/integrations.rs`, which says what each does.
9 *
10 * A workspace's AI providers and Ask g1t are kept by the same service but
11 * are not integrations: see `./ai`.
12 */
13export type Provider = "sentry" | "datadog" | "webhook" | "jira" | "linear";
14
15export type ProviderKind = "alerts" | "tracker";
16
17export type ConnectionConfig = {
18 /** For alerts: the repository work items are filed from, `owner/name`. */
19 repo?: string;
20 /** For alerts: the label put on each work item. `bug` when unset. */
21 label?: string;
22 /** Tell the outside system when the work lands. On unless turned off. */
23 writeBack?: boolean;
24 /** Sentry: the organization's slug. */
25 organization?: string;
26 /** Jira's address, or a Sentry that is not sentry.io. */
27 site?: string;
28 /** Jira: the account the token belongs to. */
29 email?: string;
30 /** Jira project or Linear team keys it answers for. Empty is all. */
31 keys?: string[];
32};
33
34export type Connection = {
35 id: string;
36 workspace: string;
37 provider: Provider;
38 kind: ProviderKind;
39 name: string;
40 config: ConnectionConfig;
41 /** `…3f9a`. The secret itself is never shown again. */
42 secretHint: string | null;
43 /** Where a provider that sends g1t requests sends them. */
44 webhookUrl: string | null;
45 createdBy: string;
46 createdAt: string;
47 lastUsedAt: string | null;
48 lastError: string | null;
49};
50
51/** What testing a connection found. */
52export type Tested = { ok: boolean; message: string };
53
54export type Connected = {
55 connection: Connection;
56 /** A signing secret g1t made, shown this once. */
57 signingSecret: string | null;
58};
59
60export type Delivery = {
61 id: string;
62 receivedAt: string;
63 event: string;
64 outcome: "opened" | "updated" | "reopened" | "ignored" | "refused";
65 detail: string;
66 /** The work item it opened or updated, `workspace#number`. */
67 item: string | null;
68};
69
70/** Something outside g1t, fetched now. Reference material, never instructions. */
71export type ContextItem = {
72 provider: Provider;
73 key: string;
74 title: string;
75 url: string;
76 status: string | null;
77 body: string;
78 fetchedAt: string;
79};
80
81export type Link = {
82 provider: Provider;
83 connectionId: string;
84 key: string;
85 title: string;
86 url: string;
87 count: number;
88 firstSeen: string;
89 lastSeen: string;
90};
91
92export type ConnectInput = {
93 provider: Provider;
94 name?: string;
95 config?: ConnectionConfig;
96 secret?: string;
97 signingSecret?: string;
98};
99
100export type UpdateConnectionInput = {
101 name?: string;
102 config?: ConnectionConfig;
103 secret?: string;
104 signingSecret?: string;
105};
106
107export interface IntegrationsApi {
108 list(workspace: string, viewer: Viewer): Promise<Result<Connection[]>>;
109 connect(actor: User, workspace: string, input: ConnectInput): Promise<Result<Connected>>;
110 update(actor: User, workspace: string, id: string, input: UpdateConnectionInput): Promise<Result<Connection>>;
111 disconnect(actor: User, workspace: string, id: string): Promise<Result<boolean>>;
112 test(actor: User, workspace: string, id: string): Promise<Result<Tested>>;
113 deliveries(workspace: string, viewer: Viewer, id: string): Promise<Result<Delivery[]>>;
114 resolve(workspace: string, viewer: Viewer, reference: string): Promise<Result<ContextItem>>;
115 /** Opens a work item in `workspace` from a ticket, filed from `repo` when given, landing in `targets`. */
116 import(
117 actor: User,
118 workspace: string,
119 reference: string,
120 options?: { repo?: RepoPath; targets?: RepoPath[] },
121 ): Promise<Result<{ workspace: string; number: number; item: ContextItem; created: boolean }>>;
122 /** What work item `number` of `workspace` is tied to outside g1t. */
123 links(workspace: string, number: number): Promise<Link[]>;
124}
125
126/** What each provider is for, as people choose between them. */
127export const PROVIDERS: Record<Provider, { label: string; kind: ProviderKind }> = {
128 sentry: { label: "Sentry", kind: "alerts" },
129 datadog: { label: "Datadog", kind: "alerts" },
130 webhook: { label: "Webhook", kind: "alerts" },
131 jira: { label: "Jira", kind: "tracker" },
132 linear: { label: "Linear", kind: "tracker" },
133};