@gitterm/sdk 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,8 +12,8 @@ bun add @gitterm/sdk
12
12
  npm install @gitterm/sdk
13
13
  ```
14
14
 
15
- Requires Node 22.12+ or Bun. Create an API token in the dashboard under
16
- **Settings → Account → API tokens**, or with `gitterm login`.
15
+ Requires Node 22.12+ or Bun. Create an API token under **API tokens** in the dashboard, or with
16
+ `gitterm login`.
17
17
 
18
18
  ## Quick start
19
19
 
@@ -23,12 +23,10 @@ Create a workspace, run a prompt, and get the final result:
23
23
  import { createGittermClient } from "@gitterm/sdk";
24
24
 
25
25
  const client = createGittermClient({ token: process.env.GITTERM_API_TOKEN });
26
- const [github] = await client.integrations.connections.list({ integration: "github" });
27
- if (!github) throw new Error("Connect GitHub in the Gitterm dashboard first");
28
26
 
29
27
  const { workspace } = await client.workspaces.create({
30
28
  repo: "https://github.com/acme/product",
31
- connections: [github.id],
29
+ connections: ["github"], // the GitHub connection that covers acme
32
30
  autoTerminateAfterMs: 2 * 60 * 60 * 1000,
33
31
  });
34
32
 
@@ -37,6 +35,8 @@ try {
37
35
  workspace,
38
36
  idempotencyKey: "review-pr-42",
39
37
  prompt: "Review PR #42 and fix the failing tests.",
38
+ // Optional files for the agent, e.g. a screenshot of the failure.
39
+ attachments: [{ name: "failure.png", mime: "image/png", data: base64Png }],
40
40
  });
41
41
  const result = await client.runs.result(run);
42
42
  console.log(result.finalText);
@@ -46,19 +46,24 @@ try {
46
46
  ```
47
47
 
48
48
  Every integration you can attach, personal or admin-provided, is a **connection** with one shape.
49
- Attach any number by id (at most one per integration):
49
+ Reference each one the way you remember it:
50
50
 
51
51
  ```ts
52
- const connections = await client.integrations.connections.list();
53
- const github = connections.find((c) => c.integration === "github");
54
- const google = connections.find((c) => c.integration === "google");
55
-
56
52
  await client.workspaces.create({
57
53
  repo: "https://github.com/acme/product",
58
- connections: [github!.id, google!.id],
54
+ connections: [
55
+ "github", // integration key: the GitHub connection that covers acme, or the shared one
56
+ "Linear", // a connection name, as shown under Integrations (case-insensitive)
57
+ "3f7d0c2e-…", // or an id from connections.list()
58
+ ],
59
59
  });
60
60
  ```
61
61
 
62
+ An integration key works when it is unambiguous: `github` picks by the repository's owner;
63
+ `google`, `mcp`, and `executor` need exactly one connection of that kind. Names are not unique, so
64
+ a name shared by two connections is rejected with both ids; use the id or rename one. At most one
65
+ GitHub and one Google connection can be attached; MCP and Executor connections are unlimited.
66
+
62
67
  GitHub tokens and Google workload credentials are issued inside the workspace; the SDK caller does
63
68
  not receive or forward them.
64
69
 
@@ -166,6 +171,7 @@ client.credentials.listProviders();
166
171
  client.integrations.catalog(); // integrations the admin enabled: key, category, personal/shared
167
172
  client.integrations.connections.list(filter?); // what you can attach; personal + shared, one shape
168
173
  client.integrations.connections.get(id);
174
+ client.integrations.connections.resolve(references, { repo }); // what ids/keys/names attach
169
175
  client.integrations.connections.create(input); // integrations:write; may return a browser step
170
176
  client.integrations.connections.remove(id);
171
177
  client.integrations.connections.waitFor({ integration, since }); // after a `pending` create
@@ -298,6 +304,11 @@ running `gh auth login`:
298
304
  - Without repository credentials or an integration, GitTerm leaves CLI authentication
299
305
  to the environment or the CLI's existing configuration.
300
306
 
307
+ Commit attribution is separate from these push credentials. By default the workspace owner
308
+ is the author (their GitHub noreply address when GitHub is linked) and GitTerm is the
309
+ committer: the GitHub App's bot account when the deployment uses an app. **Settings →
310
+ Account → Commit attribution** makes the owner both instead, for new workspaces.
311
+
301
312
  GitTerm supplies `GH_TOKEN` only to the invoked CLI process, so there is no stale
302
313
  installation token exported into the agent's long-running environment. Explicit
303
314
  `GH_TOKEN` or `GITHUB_TOKEN` environment variables override this CLI authentication;
@@ -480,8 +491,10 @@ await client.workspaces.create({
480
491
 
481
492
  `provider` is a discriminated union, so TypeScript only offers `region` for providers
482
493
  where GitTerm supports caller-selected placement. Machine keys are configured by admins
483
- and returned by `client.catalog.workspaceOptions()`; raw CPU, memory, credentials, and
484
- provider account configuration are never supplied by SDK callers.
494
+ and returned by `client.catalog.workspaceOptions()` with their `vcpus` and `memoryGb`;
495
+ raw CPU, memory, credentials, and provider account configuration are never supplied by SDK
496
+ callers. The catalog lists only the sizes you may use: an admin can pin a provider to its
497
+ default size, and on managed GitTerm the Free plan gets each provider's smallest size.
485
498
 
486
499
  This makes release automation a normal workspace task: create an OpenCode workspace,
487
500
  run UI review or browser capture tools in the sandbox, upload the resulting media, update
@@ -500,7 +513,7 @@ A workspace has one of four statuses:
500
513
  | `terminated` | Gone for good. |
501
514
 
502
515
  Whether `create()` returns `running` or `pending` depends on the provider. Sandbox providers
503
- (E2B, Daytona, Vercel, Ascii, exe.dev, Cloudflare) settle immediately and return `running`.
516
+ (E2B, Daytona, Vercel, boat, exe.dev, Cloudflare) settle immediately and return `running`.
504
517
  Railway settles by webhook and returns `pending` until its deployment reports success, usually
505
518
  within a minute. Code that only ever ran against a sandbox provider will see `pending` for the
506
519
  first time when it moves to Railway.
@@ -724,7 +737,7 @@ const { workspace } = await client.workspaces.create({
724
737
 
725
738
  const run = await client.runs.create({
726
739
  workspace,
727
- model: "anthropic/claude-sonnet-4-20250514",
740
+ model: "anthropic/claude-sonnet-5-5",
728
741
  prompt: "Record before/after videos of the changes in PR #42",
729
742
  });
730
743
  ```
@@ -838,7 +851,7 @@ await saveConfig({
838
851
  ```
839
852
 
840
853
  Device-code logins produce the same revocable `gt_...` API token as the dashboard;
841
- they appear in **Settings → Account → API tokens** and can be revoked there.
854
+ they appear under **API tokens** in the dashboard and can be revoked there.
842
855
 
843
856
  ## Direct provider mode
844
857
 
@@ -851,7 +864,7 @@ All built-in compute providers use the same provisioning plan and workspace/run
851
864
  | E2B | OpenCode-compatible template | Yes | Yes |
852
865
  | Daytona | Public Gitterm OpenCode server image by default | Yes | Yes |
853
866
  | Vercel | Vercel Sandbox project | Yes | Yes |
854
- | Ascii | Box API key | Yes | Yes |
867
+ | boat | boat API key (provider type `ascii`) | Yes | Yes |
855
868
  | exe.dev | Lifecycle token, or an existing VM with `ls,ssh,share,ssh-key` | Yes | No |
856
869
  | Railway | Project/environment and public service domains | With a volume | No |
857
870
 
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AgentType, AgentRun, AgentRunCreateInput, AgentRunListOptions, AgentRunListResult, AgentRunMessage, AgentRunReply, AuthStatus, CloudProvider, RunRef, RunWaitOptions, RunWatchOptions, WaitOptions, Workspace, WorkspaceCreateInput, WorkspaceCreateResult, WorkspaceEnsureRunningResult, WorkspaceListOptions, WorkspaceListResult, WorkspaceRef, WorkspaceRestartResult, WorkspaceRuntimeAccess, WorkspacePauseResult, WorkspaceTerminateResult, WorkspaceCatalog, WorkspaceSetupStatus, ModelCredential, ModelProviderInfo, Integration, IntegrationKey, Connection, ConnectionKind, CreateConnectionInput, CreateConnectionResult, GitHubRepository, GitHubBranch, GoogleSetup } from "./types.js";
1
+ import type { AgentType, AgentRun, AgentRunCreateInput, AgentRunListOptions, AgentRunListResult, AgentRunMessage, AgentRunReply, AuthStatus, CloudProvider, RunRef, RunWaitOptions, RunWatchOptions, WaitOptions, Workspace, WorkspaceCreateInput, WorkspaceCreateResult, WorkspaceEnsureRunningResult, WorkspaceListOptions, WorkspaceListResult, WorkspaceRef, WorkspaceRestartResult, WorkspaceRuntimeAccess, WorkspacePauseResult, WorkspaceTerminateResult, WorkspaceCatalog, WorkspaceSetupStatus, ModelCredential, ModelProviderInfo, Integration, IntegrationKey, Connection, SavedBot, ConnectionKind, CreateConnectionInput, CreateConnectionResult, GitHubRepository, GitHubBranch, GoogleSetup, McpConnectionTestResult, UpdateMcpConnectionInput } from "./types.js";
2
2
  import type { AgentRunEvent, AgentRunResult, RunResultOptions, WorkspaceModelAccess } from "./types.js";
3
3
  export type GittermClientOptions = {
4
4
  serverUrl?: string;
@@ -69,6 +69,17 @@ export type GittermClient = {
69
69
  list(): Promise<ModelCredential[]>;
70
70
  listProviders(): Promise<ModelProviderInfo[]>;
71
71
  };
72
+ bots: {
73
+ /** Claims (or renews) the right to run this saved bot; one process at a time. */
74
+ acquireLease(leaseId: string): Promise<{
75
+ success: true;
76
+ }>;
77
+ releaseLease(leaseId: string): Promise<{
78
+ success: true;
79
+ }>;
80
+ /** The settings saved for this client's token in the dashboard; null if it isn't a bot's. */
81
+ self(): Promise<SavedBot | null>;
82
+ };
72
83
  integrations: {
73
84
  /** Integrations the admin has enabled for this deployment. */
74
85
  catalog(): Promise<Integration[]>;
@@ -79,6 +90,14 @@ export type GittermClient = {
79
90
  kind?: ConnectionKind;
80
91
  }): Promise<Connection[]>;
81
92
  get(id: string): Promise<Connection>;
93
+ /**
94
+ * The connections `workspaces.create({ connections })` would attach for these references
95
+ * (ids, integration keys, or names), without creating anything. Rejects with the same
96
+ * message creation would, e.g. for an ambiguous name. Pass `repo` to resolve `"github"`.
97
+ */
98
+ resolve(references: string[], options?: {
99
+ repo?: string;
100
+ }): Promise<Connection[]>;
82
101
  /** Requires the `integrations:write` scope. */
83
102
  create(input: CreateConnectionInput): Promise<CreateConnectionResult>;
84
103
  /** Removes a personal connection. Shared connections are managed by the admin. */
@@ -92,6 +111,7 @@ export type GittermClient = {
92
111
  since?: Date | string;
93
112
  timeoutMs?: number;
94
113
  intervalMs?: number;
114
+ connectionId?: string;
95
115
  }): Promise<Connection>;
96
116
  };
97
117
  github: {
@@ -103,6 +123,10 @@ export type GittermClient = {
103
123
  /** Issuer and attribute mapping to configure the Google provider before connecting. */
104
124
  setup(): Promise<GoogleSetup>;
105
125
  };
126
+ mcp: {
127
+ test(id: string): Promise<McpConnectionTestResult>;
128
+ update(input: UpdateMcpConnectionInput): Promise<Connection>;
129
+ };
106
130
  };
107
131
  };
108
132
  export declare function createGittermClient(options?: GittermClientOptions): GittermClient;
@@ -1827,7 +1827,12 @@ function createV2Runtime(target) {
1827
1827
  },
1828
1828
  async prompt(input) {
1829
1829
  await switchSessionOptions(input.sessionId, input.agent, input.model);
1830
- await call(client.session.prompt({ sessionID: input.sessionId, id: input.messageId, text: input.prompt }, options()));
1830
+ await call(client.session.prompt({
1831
+ sessionID: input.sessionId,
1832
+ id: input.messageId,
1833
+ text: input.prompt,
1834
+ files: input.files
1835
+ }, options()));
1831
1836
  },
1832
1837
  async abort(sessionID) {
1833
1838
  await call(client.session.interrupt({ sessionID }, options()));
@@ -3336,7 +3341,7 @@ function createAsciiDirectProvider(config) {
3336
3341
  async function deleteBox(boxId) {
3337
3342
  const response = await fetch(`https://ascii.dev/api/box/v1/boxes/${boxId}`, {
3338
3343
  method: "DELETE",
3339
- headers: { Authorization: `Bearer ${config.apiKey}` }
3344
+ headers: { Authorization: `Bearer ${config.apiKey}`, "X-Ascii-Confirm-Delete": boxId }
3340
3345
  });
3341
3346
  if (!response.ok && response.status !== 404) {
3342
3347
  throw new Error(`Ascii Box deletion failed (${response.status})`);
package/dist/index.d.ts CHANGED
@@ -6,4 +6,4 @@ export type { DeviceCodeInfo, LoginWithDeviceCodeOptions } from "./device-login.
6
6
  export { AgentRunError, GittermError, WorkspaceLifecycleError } from "./errors.js";
7
7
  export { createGittermWorkspaceClient, getWorkspaceEnvironment, type GittermWorkspaceClient, type WorkspaceClientOptions, type WorkspaceEnvironment, type WorkspacePort, type WorkspacePortVisibility, type WorkspaceSelf, } from "./workspace-client.js";
8
8
  export type { CredentialErrorCode, GittermErrorCode, WorkspaceLifecycleErrorCode, } from "./errors.js";
9
- export type { AgentPermissionRequest, AgentQuestion, AgentQuestionOption, AgentQuestionRequest, AgentRun, AgentRunCreateInput, AgentRunInputRequest, AgentRunMessage, AgentRunMessagePart, AgentRunReply, AgentRunStatus, AgentRunEvent, AgentRunResult, AgentRunReplyPermission, AgentRunReplyQuestion, RunResultOptions, RunRef, RunWaitOptions, RunWatchOptions, AgentType, AgentKey, AuthStatus, BuiltInAgentKey, CloudProvider, ProviderKey, Workspace, WorkspaceCreateInput, WorkspaceCreateResult, WorkspaceCatalog, WorkspaceEnsureRunningResult, WorkspaceHostingType, WorkspaceListOptions, WorkspaceListResult, WorkspaceRestartResult, WorkspaceRuntimeAccess, WorkspaceStatus, WorkspaceSetupStatus, ModelCredential, ModelProviderInfo, ModelCredentialSource, WorkspaceModelsInput, WorkspaceModelAccess, WorkspacePauseResult, WorkspaceTerminateResult, WorkspaceProviderSelection, Integration, IntegrationKey, IntegrationCategory, Connection, ConnectionKind, ConnectionStatus, ConnectionDetails, GitHubConnectionDetails, GoogleConnectionDetails, CreateConnectionInput, CreateConnectionResult, GitHubRepository, GitHubBranch, GoogleSetup, } from "./types.js";
9
+ export type { AgentPermissionRequest, AgentQuestion, AgentQuestionOption, AgentQuestionRequest, AgentRun, AgentRunAttachment, AgentRunCreateInput, AgentRunInputRequest, AgentRunMessage, AgentRunMessagePart, AgentRunReply, AgentRunStatus, AgentRunEvent, AgentRunResult, AgentRunReplyPermission, AgentRunReplyQuestion, RunResultOptions, RunRef, RunWaitOptions, RunWatchOptions, AgentType, AgentKey, AuthStatus, BuiltInAgentKey, CloudProvider, ProviderKey, Workspace, WorkspaceCreateInput, WorkspaceCreateResult, WorkspaceCatalog, WorkspaceEnsureRunningResult, WorkspaceHostingType, WorkspaceListOptions, WorkspaceListResult, WorkspaceRestartResult, WorkspaceRuntimeAccess, WorkspaceStatus, WorkspaceSetupStatus, ModelCredential, ModelProviderInfo, ModelCredentialSource, WorkspaceModelsInput, WorkspaceModelAccess, WorkspacePauseResult, WorkspaceTerminateResult, WorkspaceProviderSelection, Integration, IntegrationKey, IntegrationCategory, Connection, SavedBot, ConnectionKind, ConnectionStatus, ConnectionDetails, GitHubConnectionDetails, GoogleConnectionDetails, McpConnectionDetails, McpAuthentication, CreateMcpConnectionInput, UpdateMcpConnectionInput, McpConnectionTestResult, CreateConnectionInput, CreateConnectionResult, GitHubRepository, GitHubBranch, GoogleSetup, } from "./types.js";
package/dist/index.js CHANGED
@@ -288,7 +288,12 @@ function runHelpers(operations) {
288
288
 
289
289
  // src/client.ts
290
290
  function toConnection(connection) {
291
- return { ...connection, connectedAt: toIso(connection.connectedAt) };
291
+ const details = connection.details;
292
+ return {
293
+ ...connection,
294
+ connectedAt: toIso(connection.connectedAt),
295
+ details: "lastCheckedAt" in details ? { ...details, lastCheckedAt: toIso(details.lastCheckedAt) } : details
296
+ };
292
297
  }
293
298
  function envValue(name) {
294
299
  const value = typeof process !== "undefined" ? process.env[name] : undefined;
@@ -698,14 +703,27 @@ ${log}` : ""}`);
698
703
  return result.map(toConnection);
699
704
  }),
700
705
  get: (id) => run(async () => toConnection(await trpc.integrations.connections.get.query({ id }))),
706
+ resolve: (references, options) => run(async () => {
707
+ const result = await trpc.integrations.connections.resolve.query({
708
+ references,
709
+ ...options?.repo ? { repo: options.repo } : {}
710
+ });
711
+ return result.map(toConnection);
712
+ }),
701
713
  create: (input) => run(async () => {
702
714
  const result = await trpc.integrations.connections.create.mutate(input);
703
- return result.status === "connected" ? { ...result, connection: toConnection(result.connection) } : result;
715
+ return result.status !== "pending" ? { ...result, connection: toConnection(result.connection) } : result;
704
716
  }),
705
717
  remove: (id) => run(async () => {
706
718
  await trpc.integrations.connections.remove.mutate({ id });
707
719
  }),
708
- waitFor: ({ integration, since, timeoutMs = 5 * 60000, intervalMs = 3000 }) => run(async () => {
720
+ waitFor: ({
721
+ integration,
722
+ since,
723
+ connectionId,
724
+ timeoutMs = 5 * 60000,
725
+ intervalMs = 3000
726
+ }) => run(async () => {
709
727
  const sinceMs = since ? new Date(since).getTime() : 0;
710
728
  const deadline = Date.now() + timeoutMs;
711
729
  while (Date.now() < deadline) {
@@ -713,7 +731,7 @@ ${log}` : ""}`);
713
731
  integration,
714
732
  kind: "personal"
715
733
  });
716
- const match = result.map(toConnection).filter((c) => c.status === "connected" && new Date(c.connectedAt).getTime() >= sinceMs).sort((a, b) => b.connectedAt.localeCompare(a.connectedAt))[0];
734
+ const match = result.map(toConnection).filter((c) => c.status === "connected" && (connectionId ? c.id === connectionId : new Date(c.connectedAt).getTime() >= sinceMs)).sort((a, b) => b.connectedAt.localeCompare(a.connectedAt))[0];
717
735
  if (match)
718
736
  return match;
719
737
  await new Promise((resolve) => setTimeout(resolve, intervalMs));
@@ -727,8 +745,20 @@ ${log}` : ""}`);
727
745
  },
728
746
  google: {
729
747
  setup: () => run(async () => trpc.integrations.google.setup.query())
748
+ },
749
+ mcp: {
750
+ test: (id) => run(async () => {
751
+ const result = await trpc.integrations.mcp.test.mutate({ id });
752
+ return { ...result, connection: toConnection(result.connection) };
753
+ }),
754
+ update: (input) => run(async () => toConnection(await trpc.integrations.mcp.update.mutate(input)))
730
755
  }
731
756
  },
757
+ bots: {
758
+ acquireLease: (leaseId) => run(() => trpc.bots.acquireLease.mutate({ leaseId })),
759
+ releaseLease: (leaseId) => run(() => trpc.bots.releaseLease.mutate({ leaseId })),
760
+ self: () => run(async () => trpc.bots.self.query())
761
+ },
732
762
  credentials: {
733
763
  list: () => run(async () => {
734
764
  const result = await trpc.modelCredentials.listMyCredentials.query();
package/dist/types.d.ts CHANGED
@@ -106,50 +106,12 @@ export type ProviderKey = "railway" | "aws" | "e2b" | "daytona" | "cloudflare" |
106
106
  type ProviderSelectionBase = {
107
107
  /** Select a specific provider installation. Usually omitted. */
108
108
  providerId?: string;
109
- /** An admin-defined profile or flexible resources within the provider's allowed limits. */
109
+ /** An admin-defined machine size, by key. */
110
110
  machine?: {
111
111
  type: "profile";
112
112
  key: string;
113
113
  };
114
114
  };
115
- type FlexibleMachine<T> = {
116
- type: "profile";
117
- key: string;
118
- } | {
119
- type: "custom";
120
- resources: T;
121
- };
122
- type AwsResources = {
123
- cpu?: number;
124
- memory?: number;
125
- ephemeralStorageGiB?: number;
126
- architecture?: "X86_64" | "ARM64";
127
- };
128
- type DaytonaResources = {
129
- resources?: {
130
- cpu?: number;
131
- memory?: number;
132
- disk?: number;
133
- };
134
- editorResources?: {
135
- cpu?: number;
136
- memory?: number;
137
- disk?: number;
138
- };
139
- };
140
- type VercelResources = {
141
- vcpus?: number;
142
- };
143
- type ExeDevResources = {
144
- cpu?: number;
145
- memory?: string;
146
- disk?: string;
147
- };
148
- /** E2B fixes CPU/RAM per template, so resources select a template build. */
149
- type E2bResources = {
150
- templateId?: string;
151
- sshTemplateId?: string;
152
- };
153
115
  export type WorkspaceProviderSelection = {
154
116
  type: "railway";
155
117
  providerId?: string;
@@ -158,26 +120,8 @@ export type WorkspaceProviderSelection = {
158
120
  type: "aws";
159
121
  region?: string;
160
122
  accessProfile?: string;
161
- } & Omit<ProviderSelectionBase, "machine"> & {
162
- machine?: FlexibleMachine<AwsResources>;
163
- }) | ({
164
- type: "daytona";
165
- } & Omit<ProviderSelectionBase, "machine"> & {
166
- machine?: FlexibleMachine<DaytonaResources>;
167
- }) | ({
168
- type: "vercel";
169
- } & Omit<ProviderSelectionBase, "machine"> & {
170
- machine?: FlexibleMachine<VercelResources>;
171
- }) | ({
172
- type: "exedev";
173
- } & Omit<ProviderSelectionBase, "machine"> & {
174
- machine?: FlexibleMachine<ExeDevResources>;
175
- }) | ({
176
- type: "e2b";
177
- } & Omit<ProviderSelectionBase, "machine"> & {
178
- machine?: FlexibleMachine<E2bResources>;
179
- }) | ({
180
- type: "ascii";
123
+ } & ProviderSelectionBase) | ({
124
+ type: "daytona" | "vercel" | "exedev" | "e2b" | "ascii";
181
125
  } & ProviderSelectionBase) | {
182
126
  type: "cloudflare";
183
127
  providerId?: string;
@@ -185,6 +129,7 @@ export type WorkspaceProviderSelection = {
185
129
  export type BuiltInAgentKey = "opencode-ttyd" | "opencode" | "t3code";
186
130
  export type AgentKey = BuiltInAgentKey | (string & {});
187
131
  export type WorkspaceCreateInput = {
132
+ provisioningProfile?: "personal" | "bot";
188
133
  idempotencyKey?: string;
189
134
  name?: string;
190
135
  /**
@@ -225,13 +170,21 @@ export type WorkspaceCreateInput = {
225
170
  token: string;
226
171
  };
227
172
  /**
228
- * Connection ids to attach, from `client.integrations.connections.list()`. At most one per
229
- * integration. A GitHub connection renews Git/gh credentials automatically; a Google connection
230
- * injects keyless ADC/gcloud auth. Cannot be combined with `repositoryCredentials` for GitHub.
173
+ * Connections to attach. Each is a connection id from `client.integrations.connections.list()`,
174
+ * an integration key, or a connection name (case-insensitive; ambiguous names are rejected).
175
+ * `"github"` attaches the connection that covers the repository's owner, or the deployment's
176
+ * shared one. At most one GitHub and one Google connection; any number of MCP/Executor ones.
177
+ * A GitHub connection renews Git/gh credentials automatically; a Google connection injects
178
+ * keyless ADC/gcloud auth. Cannot be combined with `repositoryCredentials` for GitHub.
231
179
  */
232
180
  connections?: string[];
233
181
  /** Defaults from the selected provider. */
234
182
  persistent?: boolean;
183
+ /**
184
+ * Keep the workspace running while idle instead of pausing it. On managed
185
+ * GitTerm this needs a paid plan, and spending limits still pause it.
186
+ */
187
+ alwaysOn?: boolean;
235
188
  workspaceProfile?: "standard" | "ssh-enabled";
236
189
  /** Omit to use dashboard defaults. An explicit block inherits nothing unless requested. */
237
190
  models?: WorkspaceModelsInput;
@@ -283,7 +236,7 @@ export type Integration = {
283
236
  allowShared: boolean;
284
237
  };
285
238
  export type ConnectionKind = "personal" | "shared";
286
- export type ConnectionStatus = "connected" | "suspended";
239
+ export type ConnectionStatus = "connected" | "suspended" | "untested" | "needs_auth" | "error";
287
240
  export type GitHubConnectionDetails = {
288
241
  integration: "github";
289
242
  mode: "app" | "pat";
@@ -305,7 +258,42 @@ export type GoogleConnectionDetails = {
305
258
  attributeMapping: Record<string, string>;
306
259
  };
307
260
  };
308
- export type ConnectionDetails = GitHubConnectionDetails | GoogleConnectionDetails;
261
+ export type McpConnectionDetails = {
262
+ revision?: number;
263
+ integration: "mcp" | "executor";
264
+ url: string;
265
+ authType: "none" | "headers";
266
+ codemode: boolean;
267
+ toolCount: number | null;
268
+ serverInfo: {
269
+ name: string;
270
+ version: string;
271
+ } | null;
272
+ lastCheckedAt: string | null;
273
+ };
274
+ export type McpAuthentication = {
275
+ type: "none";
276
+ } | {
277
+ type: "headers";
278
+ headers: Record<string, string>;
279
+ };
280
+ export type CreateMcpConnectionInput = {
281
+ integration: "mcp" | "executor";
282
+ name: string;
283
+ url: string;
284
+ authentication: McpAuthentication;
285
+ codemode?: boolean;
286
+ };
287
+ export type UpdateMcpConnectionInput = Omit<CreateMcpConnectionInput, "integration" | "authentication"> & {
288
+ id: string;
289
+ authentication?: McpAuthentication;
290
+ };
291
+ export type McpConnectionTestResult = {
292
+ status: "connected" | "needs_auth" | "error";
293
+ message: string;
294
+ connection: Connection;
295
+ };
296
+ export type ConnectionDetails = GitHubConnectionDetails | GoogleConnectionDetails | McpConnectionDetails;
309
297
  /**
310
298
  * Something you can attach to a workspace via `connections: [id]`. Personal connections are
311
299
  * owned by you; shared ones are provided by the admin and have stable ids like `github:shared`.
@@ -328,15 +316,16 @@ export type CreateConnectionInput = {
328
316
  serviceAccountEmail: string;
329
317
  } | {
330
318
  integration: "github";
331
- };
319
+ } | CreateMcpConnectionInput;
332
320
  export type CreateConnectionResult = {
333
- status: "connected";
321
+ status: "connected" | "saved";
334
322
  connection: Connection;
335
323
  /** Commands you still need to run outside GitTerm, e.g. the Google IAM binding. */
336
324
  nextSteps: Array<{
337
325
  label: string;
338
326
  command: string;
339
327
  }>;
328
+ message?: string;
340
329
  } | {
341
330
  /** Finish in a browser at `authorizeUrl`, then `connections.waitFor()` the new connection. */
342
331
  status: "pending";
@@ -440,6 +429,8 @@ export type AgentRunReply = {
440
429
  reject: true;
441
430
  };
442
431
  export type AgentRun = {
432
+ /** A runtime snapshot was read successfully, even if it contained no final text. */
433
+ outputAvailable?: boolean;
443
434
  id: string;
444
435
  workspaceId: string;
445
436
  title: string;
@@ -479,7 +470,17 @@ export type AgentRunListResult = {
479
470
  hasMore: boolean;
480
471
  };
481
472
  };
473
+ export type AgentRunAttachment = {
474
+ /** Shown to the agent so the prompt can refer to the file by name. */
475
+ name?: string;
476
+ /** e.g. `image/png`. */
477
+ mime: string;
478
+ /** Base64-encoded content. */
479
+ data: string;
480
+ };
482
481
  export type AgentRunCreateInput = {
482
+ /** Absolute execution deadline enforced by the server, even if the client disconnects. */
483
+ deadlineAt?: string;
483
484
  workspace: WorkspaceRef;
484
485
  /**
485
486
  * Stable key used to return the same run when a request is retried.
@@ -488,6 +489,11 @@ export type AgentRunCreateInput = {
488
489
  */
489
490
  idempotencyKey?: string;
490
491
  prompt: string;
492
+ /**
493
+ * Files the agent receives together with the prompt, e.g. screenshots for a vision model.
494
+ * At most 10 per run and 20 MB of base64 in total.
495
+ */
496
+ attachments?: AgentRunAttachment[];
491
497
  title?: string;
492
498
  agent?: string;
493
499
  /** OpenCode model in provider/model format. */
@@ -717,11 +723,18 @@ export type WorkspaceCatalog = {
717
723
  description: string;
718
724
  roleArn: string;
719
725
  }>;
726
+ /** Where the provider runs workspaces (e.g. "EU", "US"); null when not set. */
727
+ location: string | null;
728
+ /** Sizes you may pick on this provider; `isDefault` is used when none is requested. */
720
729
  machines: Array<{
721
730
  id: string;
722
731
  key: string;
723
732
  name: string;
724
733
  description: string | null;
734
+ vcpus: number | null;
735
+ memoryGb: number | null;
736
+ /** Hourly price in millionths of a dollar on managed GitTerm; null when unpriced. */
737
+ priceMicrosPerHour: number | null;
725
738
  isDefault: boolean;
726
739
  }>;
727
740
  agentKeys: string[];
@@ -735,4 +748,30 @@ export type WorkspaceCatalog = {
735
748
  workspaceApiAccess: boolean;
736
749
  }>;
737
750
  };
751
+ /** A chat bot's settings, saved in the dashboard (Bots). Secrets stay in the bot's .env. */
752
+ export type SavedBot = {
753
+ id: string;
754
+ name: string;
755
+ platform: "slack" | "discord";
756
+ /** Repository URL, with `#branch` when one is picked. */
757
+ repo: string;
758
+ /** OpenCode `provider/model`. */
759
+ model: string;
760
+ /** Saved credential label; null uses the provider's default credential. */
761
+ credential: string | null;
762
+ /** Tool connection references besides GitHub. */
763
+ connections: string[];
764
+ /** Compute provider key; null uses your default. */
765
+ provider: string | null;
766
+ /** "token": the bot brings its own GITTERM_BOT_GITHUB_TOKEN. */
767
+ githubAccess: "connection" | "token";
768
+ /** Channel ids it answers in; empty answers in every channel it's in. */
769
+ channels: string[];
770
+ /** User ids allowed to use it; empty allows everyone in the channel. */
771
+ allowedUsers: string[];
772
+ allowGuests: boolean;
773
+ instructions: string | null;
774
+ /** A command run in the checkout before the agent starts in a new sandbox. */
775
+ setup: string | null;
776
+ };
738
777
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitterm/sdk",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "files": [
5
5
  "dist"
6
6
  ],