@gitterm/sdk 0.0.8 → 0.1.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 +109 -0
- package/dist/direct/ascii.d.ts +2 -0
- package/dist/direct/client.d.ts +58 -0
- package/dist/direct/daytona.d.ts +2 -0
- package/dist/direct/e2b.d.ts +2 -0
- package/dist/direct/exedev.d.ts +2 -0
- package/dist/direct/index.d.ts +8 -0
- package/dist/direct/index.js +1802 -0
- package/dist/direct/provisioning.d.ts +34 -0
- package/dist/direct/railway.d.ts +2 -0
- package/dist/direct/types.d.ts +285 -0
- package/dist/direct/vercel.d.ts +2 -0
- package/dist/types.d.ts +2 -0
- package/package.json +15 -4
package/README.md
CHANGED
|
@@ -4,6 +4,115 @@ TypeScript SDK for the [GitTerm](https://gitterm.dev) API. Used by the `gitterm`
|
|
|
4
4
|
the OpenCode plugin, and any integration that needs to manage GitTerm workspaces with
|
|
5
5
|
a user API token.
|
|
6
6
|
|
|
7
|
+
## Direct provider mode
|
|
8
|
+
|
|
9
|
+
Direct mode runs an agent using your cloud-provider account without a Gitterm server. It intentionally omits managed billing, proxying, policy, durable run history, and automatic cleanup; your application owns workspace state and lifecycle.
|
|
10
|
+
|
|
11
|
+
All built-in compute providers use the same provisioning plan and workspace/run API:
|
|
12
|
+
|
|
13
|
+
| Provider | Direct prerequisite | Persistent pause | Keep-alive |
|
|
14
|
+
| -------- | --------------------------------------------------------------------------------------- | ---------------- | ---------- |
|
|
15
|
+
| E2B | OpenCode-compatible template | Yes | Yes |
|
|
16
|
+
| Daytona | Public Gitterm OpenCode server image by default | Yes | Yes |
|
|
17
|
+
| Vercel | Vercel Sandbox project | Yes | Yes |
|
|
18
|
+
| Ascii | Box API key | Yes | Yes |
|
|
19
|
+
| exe.dev | Token with `new,ls,ssh,share,ssh-key,pause,resume,rm`; public OpenCode image by default | Yes | No |
|
|
20
|
+
| Railway | Project/environment and public service domains | With a volume | No |
|
|
21
|
+
|
|
22
|
+
AWS remains available through `createGittermClient()` and the Gitterm control plane; it is intentionally not exposed in direct mode.
|
|
23
|
+
|
|
24
|
+
Cloudflare remains available through the Gitterm control plane. Direct Cloudflare support is deferred until the OpenCode v2 Workerd runtime is stable.
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { createDirectGittermClient } from "@gitterm/sdk/direct";
|
|
28
|
+
|
|
29
|
+
const direct = createDirectGittermClient({
|
|
30
|
+
provider: {
|
|
31
|
+
type: "e2b",
|
|
32
|
+
apiKey: process.env.E2B_API_KEY!,
|
|
33
|
+
size: "standard",
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
let workspace = await direct.workspaces.create({
|
|
38
|
+
repo: "https://github.com/acme/project",
|
|
39
|
+
lifecycle: "ephemeral",
|
|
40
|
+
modelCredentials: [{ providerName: "anthropic", apiKey: process.env.ANTHROPIC_API_KEY! }],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
try {
|
|
44
|
+
const run = await direct.runs.create({ workspace, prompt: "Review the open pull request" });
|
|
45
|
+
const completed = await direct.runs.wait(run, workspace);
|
|
46
|
+
console.log(completed.finalText);
|
|
47
|
+
} finally {
|
|
48
|
+
workspace = await direct.workspaces.terminate(workspace);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`DirectWorkspace` is JSON-serializable. Persist it together with the returned `sessionId` to resume provider lifecycle and OpenCode conversation context after an application restart. The serialized workspace contains the OpenCode password and may contain provider routing tokens, so encrypt it as credential material. Custom providers can implement `DirectProviderAdapter`; use `client.provider.capabilities` rather than hard-coding lifecycle assumptions.
|
|
53
|
+
|
|
54
|
+
Every adapter receives the same normalized plan: repository/ref and optional Git credentials, agent files, model credentials, environment, setup commands, serve command, and port. Provider-specific configuration only describes how to allocate and expose compute.
|
|
55
|
+
|
|
56
|
+
### Provider authentication
|
|
57
|
+
|
|
58
|
+
Direct workspaces can start OpenCode provider authentication without shell access. Discover the provider's methods and select a headless or device-code OAuth method when OpenCode is running remotely:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const openai = await direct.auth.get(workspace, "openai");
|
|
62
|
+
const method = openai.methods.find(
|
|
63
|
+
(item) => item.type === "oauth" && item.id === "chatgpt-headless",
|
|
64
|
+
);
|
|
65
|
+
if (!method || method.type !== "oauth") throw new Error("OpenAI device OAuth is unavailable");
|
|
66
|
+
|
|
67
|
+
const attempt = await direct.auth.connectOAuth({
|
|
68
|
+
workspace,
|
|
69
|
+
integrationId: "openai",
|
|
70
|
+
methodId: method.id,
|
|
71
|
+
label: "Slack bot",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Present these through your application UI.
|
|
75
|
+
console.log(attempt.url, attempt.instructions);
|
|
76
|
+
|
|
77
|
+
if (attempt.mode === "auto") {
|
|
78
|
+
await direct.auth.wait(attempt, workspace);
|
|
79
|
+
} else {
|
|
80
|
+
await direct.auth.complete(attempt, workspace, await getCodeFromUser());
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
OAuth started this way is stored and refreshed by OpenCode inside the workspace. Reusing a persistent workspace avoids repeated authentication; terminating an ephemeral workspace also destroys its credential store. OpenCode does not export OAuth tokens from this flow.
|
|
85
|
+
|
|
86
|
+
Applications that own OAuth separately can keep the token bundle in encrypted storage and inject it into every new workspace instead:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
const credential = await credentialStore.get(slackInstallationId);
|
|
90
|
+
const workspace = await direct.workspaces.create({
|
|
91
|
+
lifecycle: "ephemeral",
|
|
92
|
+
modelCredentials: [
|
|
93
|
+
{
|
|
94
|
+
type: "oauth",
|
|
95
|
+
providerName: "openai",
|
|
96
|
+
refreshToken: credential.refreshToken,
|
|
97
|
+
accessToken: credential.accessToken,
|
|
98
|
+
expiresAt: credential.expiresAt,
|
|
99
|
+
accountId: credential.accountId,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Credentials can also be added or rotated on an existing runtime.
|
|
105
|
+
await direct.auth.setCredential(workspace, {
|
|
106
|
+
type: "oauth",
|
|
107
|
+
providerName: "openai",
|
|
108
|
+
refreshToken: credential.refreshToken,
|
|
109
|
+
accessToken: credential.accessToken,
|
|
110
|
+
expiresAt: credential.expiresAt,
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
In this mode the application owns encryption, tenant scoping, refresh, and persistence. OpenCode may refresh its workspace-local copy; the direct SDK does not copy rotated tokens back into application storage. Use the Gitterm control plane when those credential-management responsibilities should be managed centrally.
|
|
115
|
+
|
|
7
116
|
## Install
|
|
8
117
|
|
|
9
118
|
```sh
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { DirectProviderAdapter, DirectProviderConfig, DirectAuthAttempt, DirectAuthAttemptStatus, DirectAuthIntegration, DirectAuthWaitOptions, DirectModelCredential, DirectRun, DirectRunCreateInput, DirectRunMessage, DirectRunWaitOptions, DirectWorkspace, DirectWorkspaceCreateInput } from "./types.js";
|
|
2
|
+
export type DirectGittermClientOptions = {
|
|
3
|
+
provider: DirectProviderAdapter | DirectProviderConfig;
|
|
4
|
+
};
|
|
5
|
+
export declare function createDirectGittermClient(options: DirectGittermClientOptions): {
|
|
6
|
+
provider: {
|
|
7
|
+
name: string;
|
|
8
|
+
capabilities: import("./types.js").DirectProviderCapabilities;
|
|
9
|
+
};
|
|
10
|
+
auth: {
|
|
11
|
+
setCredential(workspace: DirectWorkspace, credential: DirectModelCredential): Promise<void>;
|
|
12
|
+
list(workspace: DirectWorkspace): Promise<DirectAuthIntegration[]>;
|
|
13
|
+
get(workspace: DirectWorkspace, integrationId: string): Promise<DirectAuthIntegration>;
|
|
14
|
+
connectKey(input: {
|
|
15
|
+
workspace: DirectWorkspace;
|
|
16
|
+
integrationId: string;
|
|
17
|
+
key: string;
|
|
18
|
+
label?: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
connectOAuth(input: {
|
|
21
|
+
workspace: DirectWorkspace;
|
|
22
|
+
integrationId: string;
|
|
23
|
+
methodId: string;
|
|
24
|
+
inputs?: Record<string, string>;
|
|
25
|
+
label?: string;
|
|
26
|
+
}): Promise<DirectAuthAttempt>;
|
|
27
|
+
status(attempt: DirectAuthAttempt, workspace: DirectWorkspace): Promise<DirectAuthAttemptStatus>;
|
|
28
|
+
complete(attempt: DirectAuthAttempt, workspace: DirectWorkspace, code: string): Promise<void>;
|
|
29
|
+
wait(attempt: DirectAuthAttempt, workspace: DirectWorkspace, wait?: DirectAuthWaitOptions): Promise<DirectAuthAttemptStatus>;
|
|
30
|
+
cancel(attempt: DirectAuthAttempt, workspace: DirectWorkspace): Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
workspaces: {
|
|
33
|
+
create(input?: DirectWorkspaceCreateInput): Promise<DirectWorkspace>;
|
|
34
|
+
status(workspace: DirectWorkspace): Promise<DirectWorkspace>;
|
|
35
|
+
pause(workspace: DirectWorkspace): Promise<DirectWorkspace>;
|
|
36
|
+
resume(workspace: DirectWorkspace): Promise<DirectWorkspace>;
|
|
37
|
+
terminate(workspace: DirectWorkspace): Promise<DirectWorkspace>;
|
|
38
|
+
keepAlive(workspace: DirectWorkspace, timeoutMs: number): Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
runs: {
|
|
41
|
+
create(input: DirectRunCreateInput): Promise<DirectRun>;
|
|
42
|
+
get: (run: DirectRun, workspace: DirectWorkspace) => Promise<{
|
|
43
|
+
status: "running" | "completed" | "failed" | "cancelled" | "retrying";
|
|
44
|
+
error: string | null;
|
|
45
|
+
finalText: string | null;
|
|
46
|
+
id: string;
|
|
47
|
+
workspaceId: string;
|
|
48
|
+
sessionId: string;
|
|
49
|
+
messageId: string;
|
|
50
|
+
title: string;
|
|
51
|
+
submittedAt: string;
|
|
52
|
+
}>;
|
|
53
|
+
wait(run: DirectRun, workspace: DirectWorkspace, wait?: DirectRunWaitOptions): Promise<DirectRun>;
|
|
54
|
+
messages(run: DirectRun, workspace: DirectWorkspace): Promise<DirectRunMessage[]>;
|
|
55
|
+
cancel(run: DirectRun, workspace: DirectWorkspace): Promise<boolean>;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export type DirectGittermClient = ReturnType<typeof createDirectGittermClient>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createDirectGittermClient, type DirectGittermClient, type DirectGittermClientOptions, } from "./client.js";
|
|
2
|
+
export { createE2BDirectProvider } from "./e2b.js";
|
|
3
|
+
export { createAsciiDirectProvider } from "./ascii.js";
|
|
4
|
+
export { createDaytonaDirectProvider } from "./daytona.js";
|
|
5
|
+
export { createExeDevDirectProvider } from "./exedev.js";
|
|
6
|
+
export { createRailwayDirectProvider } from "./railway.js";
|
|
7
|
+
export { createVercelDirectProvider } from "./vercel.js";
|
|
8
|
+
export type { AsciiDirectProviderConfig, DirectAuthAttempt, DirectAuthAttemptStatus, DirectAuthIntegration, DirectAuthMethod, DirectAuthPrompt, DirectAuthWaitOptions, DirectApiModelCredential, DaytonaDirectProviderConfig, DirectModelCredential, DirectOAuthModelCredential, DirectProviderAdapter, DirectProviderCapabilities, DirectProviderConfig, DirectProviderWorkspaceInput, DirectRun, DirectRunCreateInput, DirectRunMessage, DirectRunWaitOptions, DirectWorkspace, DirectWorkspaceCreateInput, DirectWorkspaceLifecycle, DirectWorkspaceRuntime, E2BDirectProviderConfig, ExeDevDirectProviderConfig, RailwayDirectProviderConfig, VercelDirectProviderConfig, } from "./types.js";
|