@gitterm/bot 0.0.0-stage → 0.1.1
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 +83 -2
- package/dist/bot.d.ts +6 -0
- package/dist/download.d.ts +7 -0
- package/dist/env.d.ts +21 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1567 -0
- package/dist/markdown.d.ts +7 -0
- package/dist/preflight.d.ts +17 -0
- package/dist/prompt.d.ts +26 -0
- package/dist/saved.d.ts +10 -0
- package/dist/state.d.ts +44 -0
- package/dist/status.d.ts +30 -0
- package/dist/types.d.ts +215 -0
- package/dist/workspaces.d.ts +63 -0
- package/package.json +43 -4
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Markdown tables as monospaced code blocks, for chats that do not render tables. */
|
|
2
|
+
export declare function tablesToCode(markdown: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* Split text into chunks of at most `limit` characters, preferring line breaks. A code block
|
|
5
|
+
* cut in two is closed at the end of one chunk and reopened at the start of the next.
|
|
6
|
+
*/
|
|
7
|
+
export declare function splitMessage(text: string, limit: number): string[];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type GittermClient } from "@gitterm/sdk";
|
|
2
|
+
import type { BotLogger, ModelChoice, WorkspaceOverrides } from "./types.js";
|
|
3
|
+
import { type Repo } from "./workspaces.js";
|
|
4
|
+
export declare const BOT_TOKEN_SCOPES: readonly ["identity:read", "workspace:read", "workspace:write", "run:read", "run:write", "integrations:read"];
|
|
5
|
+
/**
|
|
6
|
+
* Everything a first mention would need, checked before the bot connects, so a misconfigured
|
|
7
|
+
* bot fails at startup with what to fix instead of in a Slack thread later. Problems that only
|
|
8
|
+
* matter for some requests (a public repository without GitHub access) are warnings.
|
|
9
|
+
*/
|
|
10
|
+
export declare function checkSetup(input: {
|
|
11
|
+
gitterm: GittermClient;
|
|
12
|
+
repos: Repo[];
|
|
13
|
+
connections: string[];
|
|
14
|
+
model: ModelChoice | undefined;
|
|
15
|
+
overrides: WorkspaceOverrides | undefined;
|
|
16
|
+
log: BotLogger;
|
|
17
|
+
}): Promise<void>;
|
package/dist/prompt.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AgentQuestion } from "@gitterm/sdk";
|
|
2
|
+
import type { ChatFile, ChatMessage, HistoryMessage } from "./types.js";
|
|
3
|
+
export declare const isForwardableImage: (file: ChatFile) => boolean;
|
|
4
|
+
export type BuiltPrompt = {
|
|
5
|
+
text: string;
|
|
6
|
+
images: ChatFile[];
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* The run prompt: who is asking, the thread messages this session has not seen (as quoted
|
|
10
|
+
* context), and the request. Images are attached once, with the message that first shows them.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildPrompt(input: {
|
|
13
|
+
platform: string;
|
|
14
|
+
message: ChatMessage;
|
|
15
|
+
history: HistoryMessage[];
|
|
16
|
+
continued: boolean;
|
|
17
|
+
}): BuiltPrompt;
|
|
18
|
+
/**
|
|
19
|
+
* A typed reply as option labels: a number (`2`), numbers for multi-select (`1, 3`), or an
|
|
20
|
+
* exact label; otherwise the free-text answer when the question allows one. Null when the
|
|
21
|
+
* reply cannot answer the question.
|
|
22
|
+
*/
|
|
23
|
+
export declare function interpretTypedAnswer(question: AgentQuestion, text: string): string[] | null;
|
|
24
|
+
/** `yes`/`allow`, `always`, or `no`/`deny` typed in reply to a permission prompt. */
|
|
25
|
+
export declare function interpretPermissionReply(text: string): "once" | "always" | "reject" | null;
|
|
26
|
+
export declare function agentInstructions(platform: string, extra: string | undefined): string;
|
package/dist/saved.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type SavedBot } from "@gitterm/sdk";
|
|
2
|
+
import type { BotLogger, BotOptions } from "./types.js";
|
|
3
|
+
type Options = Omit<BotOptions, "adapter">;
|
|
4
|
+
/**
|
|
5
|
+
* Adds the settings saved for this bot in the GitTerm dashboard (Bots), found by its API token.
|
|
6
|
+
* Routing can be overridden locally; saved authorization is an upper bound. Without saved settings,
|
|
7
|
+
* for example a token that isn't a bot's, the options come back unchanged.
|
|
8
|
+
*/
|
|
9
|
+
export declare function withSavedConfig(options: Options, platform: SavedBot["platform"], log?: BotLogger): Promise<Options>;
|
|
10
|
+
export {};
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ChatThread, ChatUser } from "./types.js";
|
|
2
|
+
/** The run a thread continues from and the last chat message it has seen. */
|
|
3
|
+
export type ThreadSession = {
|
|
4
|
+
/** The repository the thread works on, chosen by its first message. */
|
|
5
|
+
repo: string;
|
|
6
|
+
workspaceId: string;
|
|
7
|
+
runId: string;
|
|
8
|
+
lastMessageId: string;
|
|
9
|
+
updatedAt: number;
|
|
10
|
+
};
|
|
11
|
+
/** A request being worked on, so a restarted bot can pick its run up again. */
|
|
12
|
+
export type InFlightRequest = {
|
|
13
|
+
/** Prevent recovery into a different platform installation after reconfiguration. */
|
|
14
|
+
scope?: string;
|
|
15
|
+
thread: ChatThread;
|
|
16
|
+
/** The status message; absent when the platform showed a native indicator instead. */
|
|
17
|
+
statusId?: string;
|
|
18
|
+
requester: ChatUser;
|
|
19
|
+
repo: string;
|
|
20
|
+
/** The sandbox (space and repository) it works in, so a restart can still guard reset. */
|
|
21
|
+
sandbox?: string;
|
|
22
|
+
/** When the server cancels the run (ms since epoch). */
|
|
23
|
+
deadline?: number;
|
|
24
|
+
/** Reply messages already posted, so a retried delivery doesn't repeat them. */
|
|
25
|
+
deliveredParts?: number;
|
|
26
|
+
/** Set once the run exists; before that a restart can only report the request as lost. */
|
|
27
|
+
run?: {
|
|
28
|
+
workspaceId: string;
|
|
29
|
+
id: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export type StateStore = {
|
|
33
|
+
session(threadKey: string): ThreadSession | undefined;
|
|
34
|
+
setSession(threadKey: string, session: Omit<ThreadSession, "updatedAt">): Promise<void>;
|
|
35
|
+
inFlight(): Record<string, InFlightRequest>;
|
|
36
|
+
setInFlight(threadKey: string, request: InFlightRequest | undefined): Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Holds GitTerm workspace/run ids only, never tokens, written atomically with mode 0600.
|
|
40
|
+
* It is a cache: losing it costs thread continuity, not sandboxes, which are found by metadata.
|
|
41
|
+
*/
|
|
42
|
+
export declare function openStateStore(file: string): Promise<StateStore>;
|
|
43
|
+
/** Run operations with the same key one after another. */
|
|
44
|
+
export declare function createLocks(): <T>(key: string, operation: () => Promise<T>) => Promise<T>;
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ChatAdapter, ChatThread } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* One state of a request, worded for a status message and for a native indicator, which the
|
|
4
|
+
* platform shows after the bot's name ("Acme Agent is working on it…"). An empty indicator
|
|
5
|
+
* hides it, e.g. while a prompt waits for a person.
|
|
6
|
+
*/
|
|
7
|
+
export type StatusText = {
|
|
8
|
+
message: string;
|
|
9
|
+
indicator: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const WORKING: StatusText;
|
|
12
|
+
export declare const WAITING_FOR_APPROVAL: StatusText;
|
|
13
|
+
export declare const WAITING_FOR_ANSWER: StatusText;
|
|
14
|
+
export declare const minutes: (ms: number) => number;
|
|
15
|
+
export type StatusLine = {
|
|
16
|
+
/** The status message, when the platform shows no native indicator. */
|
|
17
|
+
readonly messageId: string | undefined;
|
|
18
|
+
set(status: StatusText): void;
|
|
19
|
+
/** Replace the status with a final line, e.g. an error. */
|
|
20
|
+
finish(text: string): Promise<void>;
|
|
21
|
+
/** The answer was posted; take the status away. */
|
|
22
|
+
remove(): Promise<void>;
|
|
23
|
+
stop(): void;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* The single status of a request: the platform's native indicator when it has one, otherwise
|
|
27
|
+
* a message that is edited as the request progresses. `messageId` resumes a status message
|
|
28
|
+
* left by a previous process.
|
|
29
|
+
*/
|
|
30
|
+
export declare function openStatusLine(adapter: ChatAdapter, thread: ChatThread, messageId?: string): Promise<StatusLine>;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import type { AgentPermissionRequest, AgentQuestion, GittermClient, GittermClientOptions, WorkspaceCreateInput } from "@gitterm/sdk";
|
|
2
|
+
/** A conversation: the channel and the thread inside it. Every thread is one agent session. */
|
|
3
|
+
export type ChatThread = {
|
|
4
|
+
channel: string;
|
|
5
|
+
thread: string;
|
|
6
|
+
};
|
|
7
|
+
export type ChatUser = {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
/**
|
|
11
|
+
* Not a full member of the workspace (Slack guests and people from other organisations in
|
|
12
|
+
* shared channels). Guests cannot use the bot unless `allowGuests` is set.
|
|
13
|
+
*/
|
|
14
|
+
guest?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/** A file posted in the chat. Only images are forwarded to the agent; the rest are named. */
|
|
17
|
+
export type ChatFile = {
|
|
18
|
+
id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
mime: string;
|
|
21
|
+
size: number;
|
|
22
|
+
/** Base64 content. Called only for files the bot forwards. */
|
|
23
|
+
download(signal?: AbortSignal): Promise<string>;
|
|
24
|
+
};
|
|
25
|
+
export type ChatMessage = {
|
|
26
|
+
/** Platform message id (Slack `ts`, Discord snowflake). */
|
|
27
|
+
id: string;
|
|
28
|
+
thread: ChatThread;
|
|
29
|
+
author: ChatUser;
|
|
30
|
+
/** Text with the bot's own mention removed. */
|
|
31
|
+
text: string;
|
|
32
|
+
files: ChatFile[];
|
|
33
|
+
/** The bot was mentioned. Other thread replies only answer an open question. */
|
|
34
|
+
mentioned: boolean;
|
|
35
|
+
/** The thread existed before this message, so it may hold earlier context. */
|
|
36
|
+
inThread: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* A one-to-one conversation with the bot. It gets its own sandbox, so the agent there can't
|
|
39
|
+
* see the sessions other people run in channels.
|
|
40
|
+
*/
|
|
41
|
+
direct?: boolean;
|
|
42
|
+
/** Tenant boundary (e.g. a Discord guild). */
|
|
43
|
+
tenant?: string;
|
|
44
|
+
};
|
|
45
|
+
/** A message read back from a thread to give a new or continued session its context. */
|
|
46
|
+
export type HistoryMessage = {
|
|
47
|
+
id: string;
|
|
48
|
+
author: ChatUser;
|
|
49
|
+
/** Written by this bot (status lines, earlier answers) or another bot. */
|
|
50
|
+
fromBot: boolean;
|
|
51
|
+
text: string;
|
|
52
|
+
files: ChatFile[];
|
|
53
|
+
};
|
|
54
|
+
/** Something the agent is blocked on, shown in the thread with buttons. */
|
|
55
|
+
export type ChatPrompt = {
|
|
56
|
+
id: string;
|
|
57
|
+
kind: "question";
|
|
58
|
+
question: AgentQuestion;
|
|
59
|
+
/** Position among the questions the agent asked together; they are shown one at a time. */
|
|
60
|
+
index: number;
|
|
61
|
+
total: number;
|
|
62
|
+
requester: ChatUser;
|
|
63
|
+
} | {
|
|
64
|
+
id: string;
|
|
65
|
+
kind: "permission";
|
|
66
|
+
request: AgentPermissionRequest;
|
|
67
|
+
requester: ChatUser;
|
|
68
|
+
};
|
|
69
|
+
export type ChatAnswer = {
|
|
70
|
+
kind: "question";
|
|
71
|
+
labels: string[];
|
|
72
|
+
} | {
|
|
73
|
+
kind: "permission";
|
|
74
|
+
response: "once" | "always" | "reject";
|
|
75
|
+
};
|
|
76
|
+
/** What the engine gives an adapter to report chat activity. */
|
|
77
|
+
export type ChatEvents = {
|
|
78
|
+
message(message: ChatMessage): void;
|
|
79
|
+
/**
|
|
80
|
+
* Button, menu, or dialog answer. `stale` when the prompt is no longer open, `forbidden` when
|
|
81
|
+
* this person may not use the bot; adapters tell the clicker privately.
|
|
82
|
+
*/
|
|
83
|
+
answer(promptId: string, answer: ChatAnswer, by: ChatUser): "answered" | "stale" | "forbidden";
|
|
84
|
+
/** The open prompt, e.g. to build a free-text dialog for it; undefined once settled. */
|
|
85
|
+
prompt(promptId: string): ChatPrompt | undefined;
|
|
86
|
+
/** Authorization check for controls that modify pending answers without submitting them. */
|
|
87
|
+
canAnswer?(promptId: string, by: ChatUser): boolean;
|
|
88
|
+
/** Whether the bot works in this channel, so adapters do not open threads elsewhere. */
|
|
89
|
+
accepts(channel: string): boolean;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* The chat platform half of a bot. `@gitterm/slack-bot` and `@gitterm/discord-bot` implement it;
|
|
93
|
+
* implement it yourself to put the same agent behind another chat platform.
|
|
94
|
+
*/
|
|
95
|
+
export interface ChatAdapter {
|
|
96
|
+
/** e.g. "slack"; tags the bot's workspaces and appears in prompts. */
|
|
97
|
+
readonly platform: string;
|
|
98
|
+
/** Human-readable platform name for prompts and instructions, e.g. "Slack". */
|
|
99
|
+
readonly displayName: string;
|
|
100
|
+
/**
|
|
101
|
+
* Connect and start reporting events. Resolves with the id of the installation (Slack team,
|
|
102
|
+
* Discord application) so two installations never share a sandbox.
|
|
103
|
+
*/
|
|
104
|
+
start(events: ChatEvents): Promise<{
|
|
105
|
+
scope: string;
|
|
106
|
+
}>;
|
|
107
|
+
stop(): Promise<void>;
|
|
108
|
+
/** The thread's messages oldest first; only those after `after` when it is given. */
|
|
109
|
+
history(thread: ChatThread, after: string | undefined): Promise<HistoryMessage[]>;
|
|
110
|
+
/** Post a short plain status line; resolves with its message id. */
|
|
111
|
+
post(thread: ChatThread, text: string): Promise<string>;
|
|
112
|
+
edit(thread: ChatThread, messageId: string, text: string): Promise<void>;
|
|
113
|
+
remove(thread: ChatThread, messageId: string): Promise<void>;
|
|
114
|
+
/** The agent's answer as Markdown; the adapter converts and splits it for the platform. */
|
|
115
|
+
reply(thread: ChatThread, markdown: string, footer: string, delivery?: {
|
|
116
|
+
sent: number;
|
|
117
|
+
recordSent(sent: number): Promise<void>;
|
|
118
|
+
}): Promise<void>;
|
|
119
|
+
/** Show a prompt with controls that call `ChatEvents.answer`; resolves with its message id. */
|
|
120
|
+
ask(thread: ChatThread, prompt: ChatPrompt): Promise<string>;
|
|
121
|
+
/** Replace the prompt's controls with its outcome once it is answered or abandoned. */
|
|
122
|
+
settle(thread: ChatThread, messageId: string, prompt: ChatPrompt, outcome: string): Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Show the platform's native "working" indicator in the thread (e.g. "Acme Agent is working
|
|
125
|
+
* on it…"); an empty status hides it. Resolve false when the platform refuses, and the engine
|
|
126
|
+
* keeps a status message instead. Optional.
|
|
127
|
+
*/
|
|
128
|
+
indicate?(thread: ChatThread, status: string): Promise<boolean>;
|
|
129
|
+
/**
|
|
130
|
+
* React to a request's message: `seen` when accepted (e.g. 👀, so people know it waits its
|
|
131
|
+
* turn), then `done` (✅) or `failed` (❌). Optional.
|
|
132
|
+
*/
|
|
133
|
+
mark?(message: ChatMessage, state: "seen" | "done" | "failed"): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
/** A repository, optionally with a branch: `https://github.com/acme/app` or `…/app#develop`. */
|
|
136
|
+
export type RepoTarget = string | {
|
|
137
|
+
url: string;
|
|
138
|
+
branch?: string;
|
|
139
|
+
};
|
|
140
|
+
export type ModelChoice = {
|
|
141
|
+
/** OpenCode `provider/model`, e.g. `anthropic/claude-sonnet-5-5`. */
|
|
142
|
+
id: string;
|
|
143
|
+
/** Label of a saved dashboard credential. Default: the provider's default credential. */
|
|
144
|
+
credential?: string;
|
|
145
|
+
/** An API key for this bot only; injected into the sandbox, never saved in the dashboard. */
|
|
146
|
+
apiKey?: string;
|
|
147
|
+
};
|
|
148
|
+
/** Workspace settings the bot does not decide itself. */
|
|
149
|
+
export type WorkspaceOverrides = Omit<WorkspaceCreateInput, "repo" | "branch" | "metadata" | "name" | "agent" | "connections">;
|
|
150
|
+
export type BotLogger = Pick<Console, "info" | "warn" | "error">;
|
|
151
|
+
export type BotOptions = {
|
|
152
|
+
/** Stable deployment identity. Saved configurations supply the immutable bot id. */
|
|
153
|
+
botId?: string;
|
|
154
|
+
/** Authorization boundary independent of repository routing. */
|
|
155
|
+
allowedChannels?: string[];
|
|
156
|
+
/** Sharing across channels is opt-in and only appropriate for equally trusted participants. */
|
|
157
|
+
shareChannels?: boolean;
|
|
158
|
+
/** Direct-conversation sandbox lifetime. Default 7 days; resets start a new lifetime. */
|
|
159
|
+
directRetentionMs?: number;
|
|
160
|
+
/** Separate permission approvers. Defaults to the requester only. */
|
|
161
|
+
approvers?: string[];
|
|
162
|
+
/** Persistent OpenCode approvals affect future work; disabled unless explicitly enabled. */
|
|
163
|
+
allowAlways?: boolean;
|
|
164
|
+
/** Maximum accepted requests, including queued work. Default 20. */
|
|
165
|
+
maxPendingRequests?: number;
|
|
166
|
+
/** Maximum accepted requests per platform user. Default 3. */
|
|
167
|
+
maxPendingPerUser?: number;
|
|
168
|
+
adapter: ChatAdapter;
|
|
169
|
+
/** A client, or options for one. Defaults to `GITTERM_API_TOKEN` / `GITTERM_SERVER_URL`. */
|
|
170
|
+
gitterm?: GittermClient | GittermClientOptions;
|
|
171
|
+
/** Repository for every channel without its own entry in `channels`. */
|
|
172
|
+
repo?: RepoTarget;
|
|
173
|
+
/** Per-channel repositories. Without `repo` or `repos`, the bot only works in these channels. */
|
|
174
|
+
channels?: Record<string, RepoTarget>;
|
|
175
|
+
/**
|
|
176
|
+
* More repositories people can pick by naming them in a thread's first message, e.g.
|
|
177
|
+
* "@bot in acme/api, why is login slow?". A channel without a repository asks which one.
|
|
178
|
+
*/
|
|
179
|
+
repos?: RepoTarget[];
|
|
180
|
+
/**
|
|
181
|
+
* Tools to attach to new sandboxes besides GitHub: connection names as shown under
|
|
182
|
+
* Integrations (`"Linear"`), integration keys (`"executor"`), or ids. GitHub access for the
|
|
183
|
+
* repository is attached automatically.
|
|
184
|
+
*/
|
|
185
|
+
connections?: string[];
|
|
186
|
+
/** Environment variables for new sandboxes, e.g. test credentials. Never logged. */
|
|
187
|
+
env?: Record<string, string>;
|
|
188
|
+
/** Shell commands run in the checkout before the agent starts in a new sandbox. */
|
|
189
|
+
setup?: string[];
|
|
190
|
+
/** Platform user ids allowed to use the bot. Default: everyone in channels it can see. */
|
|
191
|
+
allowedUsers?: string[];
|
|
192
|
+
/** Let guests and people from other organisations use the bot. Default false. */
|
|
193
|
+
allowGuests?: boolean;
|
|
194
|
+
/**
|
|
195
|
+
* The model for every run, as OpenCode `provider/model`. Only that provider's credential
|
|
196
|
+
* reaches new sandboxes: its dashboard default, the saved credential labelled `credential`, or
|
|
197
|
+
* an inline `apiKey`. Without a model, sandboxes inherit no saved credentials.
|
|
198
|
+
*/
|
|
199
|
+
model?: string | ModelChoice;
|
|
200
|
+
/** What the agent should know and how to behave, after the bot's own rules. New sandboxes. */
|
|
201
|
+
instructions?: string;
|
|
202
|
+
/** Provider, image, setup, OpenCode config, and other workspace settings for new sandboxes. */
|
|
203
|
+
workspace?: WorkspaceOverrides;
|
|
204
|
+
/** Thread sessions and in-flight requests. Default `.gitterm-bot/<platform>.json`. */
|
|
205
|
+
stateFile?: string;
|
|
206
|
+
/** Total time for one request, including time spent waiting for answers. Default 60 min. */
|
|
207
|
+
runTimeoutMs?: number;
|
|
208
|
+
/** How long a question or permission prompt waits for an answer. Default 30 min. */
|
|
209
|
+
inputTimeoutMs?: number;
|
|
210
|
+
logger?: BotLogger;
|
|
211
|
+
};
|
|
212
|
+
export type Bot = {
|
|
213
|
+
start(): Promise<void>;
|
|
214
|
+
stop(): Promise<void>;
|
|
215
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { GittermClient, ModelCredential, Workspace, WorkspaceModelsInput } from "@gitterm/sdk";
|
|
2
|
+
import type { StatusText } from "./status.js";
|
|
3
|
+
import type { BotLogger, ModelChoice, RepoTarget, WorkspaceOverrides } from "./types.js";
|
|
4
|
+
export type Repo = {
|
|
5
|
+
url: string;
|
|
6
|
+
branch: string | undefined;
|
|
7
|
+
};
|
|
8
|
+
/** Accepts `url`, `url#branch`, or `{ url, branch }`. */
|
|
9
|
+
export declare function parseRepo(target: RepoTarget): Repo;
|
|
10
|
+
export declare const repoKey: (repo: Repo) => string;
|
|
11
|
+
/** `acme/app` for display; the URL itself for anything that is not a recognisable host path. */
|
|
12
|
+
export declare function repoLabel(repo: Repo): string;
|
|
13
|
+
/**
|
|
14
|
+
* Credentials for exactly the chosen model's provider, so a sandbox shared by a whole channel
|
|
15
|
+
* holds one model key instead of every account on the dashboard. A provider without a saved
|
|
16
|
+
* credential (free or ambient-auth models) gets none; a run that needs one then fails with the
|
|
17
|
+
* provider's authentication error, and startup warns about it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function modelsFor(model: ModelChoice, saved: ModelCredential[]): WorkspaceModelsInput;
|
|
20
|
+
/**
|
|
21
|
+
* `["github"]` when GitTerm has a GitHub connection covering the repository (the server picks
|
|
22
|
+
* it), otherwise nothing: a public repository still clones, and startup already warned.
|
|
23
|
+
*/
|
|
24
|
+
export declare function githubFor(gitterm: GittermClient, repo: Repo): Promise<string[]>;
|
|
25
|
+
/** Channels share one sandbox per repository. */
|
|
26
|
+
export declare const SHARED_SPACE = "shared";
|
|
27
|
+
/** Where a message's sandbox lives: its own per direct conversation, else the shared one. */
|
|
28
|
+
export declare const spaceOf: (message: {
|
|
29
|
+
direct?: boolean;
|
|
30
|
+
tenant?: string;
|
|
31
|
+
thread: {
|
|
32
|
+
channel: string;
|
|
33
|
+
};
|
|
34
|
+
}, shareChannels?: boolean) => string;
|
|
35
|
+
/** Sandboxes are per repository and space (shared channels, or one direct conversation). */
|
|
36
|
+
export type WorkspaceManager = {
|
|
37
|
+
/** The sandbox, found by its tags or created, and running. */
|
|
38
|
+
ensure(repo: Repo, progress: (status: StatusText) => void, space?: string): Promise<Workspace>;
|
|
39
|
+
/** The sandbox, if there is one, without waking it. */
|
|
40
|
+
find(repo: Repo, space?: string): Promise<Workspace | null>;
|
|
41
|
+
/** Terminate the sandbox; the next request creates a fresh one. */
|
|
42
|
+
reset(repo: Repo, space?: string): Promise<boolean>;
|
|
43
|
+
};
|
|
44
|
+
export declare function createWorkspaceManager(input: {
|
|
45
|
+
gitterm: GittermClient;
|
|
46
|
+
platform: string;
|
|
47
|
+
scope: string;
|
|
48
|
+
botId?: string;
|
|
49
|
+
directRetentionMs?: number;
|
|
50
|
+
identityPolicy?: {
|
|
51
|
+
allowedUsers?: string[];
|
|
52
|
+
allowGuests?: boolean;
|
|
53
|
+
allowedChannels?: string[];
|
|
54
|
+
shareChannels?: boolean;
|
|
55
|
+
};
|
|
56
|
+
connections: string[];
|
|
57
|
+
env: Record<string, string>;
|
|
58
|
+
setup: string[];
|
|
59
|
+
model: ModelChoice | undefined;
|
|
60
|
+
instructions: string;
|
|
61
|
+
overrides: WorkspaceOverrides | undefined;
|
|
62
|
+
log: BotLogger;
|
|
63
|
+
}): WorkspaceManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gitterm/bot",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Chat-platform-agnostic engine for GitTerm agent bots: one sandbox per repository, one agent session per thread",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agent",
|
|
7
|
+
"bot",
|
|
8
|
+
"gitterm",
|
|
9
|
+
"opencode"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://gitterm.dev",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Opeyemi Oginni",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"default": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"publishConfig": {
|
|
28
|
+
"access": "public"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "rm -rf dist && bun build src/index.ts --outdir dist --target node --format esm --packages external && tsc -p tsconfig.build.json",
|
|
32
|
+
"prepublishOnly": "bun run check-types && bun run build",
|
|
33
|
+
"check-types": "tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@gitterm/sdk": "^0.10.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/bun": "^1.2.6",
|
|
40
|
+
"typescript": "^5.8.2"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=22.12.0"
|
|
44
|
+
}
|
|
45
|
+
}
|