@band-ai/sdk 0.1.6 → 0.2.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 +372 -0
- package/dist/{ClaudeSDKAdapter-CRq4R-WB.d.cts → ClaudeSDKAdapter-BY4zEbCl.d.cts} +14 -10
- package/dist/{ClaudeSDKAdapter-BHOkjN3X.d.ts → ClaudeSDKAdapter-Cna5P1dR.d.ts} +14 -10
- package/dist/{acp-server-B1Da7L6u.d.ts → acp-server-CiUqN3G3.d.ts} +2 -2
- package/dist/{acp-server-BdRz9_UN.d.cts → acp-server-Dlj7D563.d.cts} +2 -2
- package/dist/adapters.cjs +734 -279
- package/dist/adapters.d.cts +21 -19
- package/dist/adapters.d.ts +21 -19
- package/dist/adapters.js +65 -44
- package/dist/backends-D-dBdDm-.d.ts +27 -0
- package/dist/backends-ZLxmQrTZ.d.cts +27 -0
- package/dist/{chunk-MSL6CWHY.js → chunk-4IAXZBXX.js} +77 -37
- package/dist/{chunk-SG4WLD2H.js → chunk-EAI2M3WM.js} +38 -94
- package/dist/{chunk-YR3BOQNW.js → chunk-JY75VSQK.js} +7 -7
- package/dist/{chunk-INA6YZTZ.js → chunk-LBWKISBS.js} +51 -31
- package/dist/{chunk-I5EZG52P.js → chunk-N2QTUMGO.js} +532 -327
- package/dist/{chunk-RHVH2GZR.js → chunk-NMZLX7TP.js} +110 -56
- package/dist/{chunk-EDPKUUJL.js → chunk-NT7TBFX2.js} +9 -1
- package/dist/{chunk-GVEQ3RAH.js → chunk-RV76SKFT.js} +169 -54
- package/dist/{chunk-W5NDZSYE.js → chunk-TLBCKDQO.js} +23 -23
- package/dist/chunk-US226AS4.js +130 -0
- package/dist/{chunk-IZPV6QS6.js → chunk-WL2HNJZ6.js} +38 -11
- package/dist/chunk-WLCM2OXG.js +181 -0
- package/dist/config.cjs +40 -13
- package/dist/config.d.cts +7 -1
- package/dist/config.d.ts +7 -1
- package/dist/config.js +2 -2
- package/dist/converters.cjs +491 -35
- package/dist/converters.d.cts +5 -5
- package/dist/converters.d.ts +5 -5
- package/dist/converters.js +4 -3
- package/dist/core.cjs +53 -10
- package/dist/core.d.cts +10 -9
- package/dist/core.d.ts +10 -9
- package/dist/core.js +8 -4
- package/dist/disconnectReason-IuADl6TH.d.cts +34 -0
- package/dist/disconnectReason-IuADl6TH.d.ts +34 -0
- package/dist/{dtos-DUpbIu8k.d.ts → dtos-B8KU_q4d.d.cts} +26 -6
- package/dist/{dtos-DUpbIu8k.d.cts → dtos-B8KU_q4d.d.ts} +26 -6
- package/dist/index.cjs +1510 -735
- package/dist/index.d.cts +18 -16
- package/dist/index.d.ts +18 -16
- package/dist/index.js +21 -13
- package/dist/linear.cjs +1044 -112
- package/dist/linear.d.cts +146 -16
- package/dist/linear.d.ts +146 -16
- package/dist/linear.js +1031 -110
- package/dist/mcp-claude.cjs +338 -66
- package/dist/mcp-claude.d.cts +3 -3
- package/dist/mcp-claude.d.ts +3 -3
- package/dist/mcp-claude.js +215 -16
- package/dist/mcp.cjs +414 -105
- package/dist/mcp.d.cts +29 -16
- package/dist/mcp.d.ts +29 -16
- package/dist/mcp.js +14 -14
- package/dist/{opencode-BBcDchcN.d.cts → opencode-2YdscIc1.d.cts} +5 -5
- package/dist/{opencode-DthQQUsZ.d.ts → opencode-Bld62x5t.d.ts} +5 -5
- package/dist/{pagination-CcDkVFxK.d.ts → pagination-BgEx-HeL.d.ts} +2 -2
- package/dist/{pagination-BPiys10t.d.cts → pagination-DqdkQArT.d.cts} +2 -2
- package/dist/{protocols-DrhzOH6K.d.ts → protocols-Bwwcql0h.d.ts} +1 -1
- package/dist/{protocols-CInhtFpA.d.cts → protocols-Bz1rxcUg.d.cts} +1 -1
- package/dist/rest.cjs +41 -97
- package/dist/rest.d.cts +7 -7
- package/dist/rest.d.ts +7 -7
- package/dist/rest.js +2 -2
- package/dist/runtime.cjs +998 -620
- package/dist/runtime.d.cts +22 -29
- package/dist/runtime.d.ts +22 -29
- package/dist/runtime.js +19 -67
- package/dist/{schemas-BpEBkq5V.d.cts → schemas-BotL3ZLH.d.cts} +51 -56
- package/dist/{schemas-vos1AaBc.d.ts → schemas-DBsC4J1g.d.ts} +51 -56
- package/dist/{sdk-CwTAxhwI.d.cts → sdk-BTciSLRQ.d.cts} +35 -5
- package/dist/{sdk-CcnQ5OUC.d.ts → sdk-qKJtMma_.d.ts} +35 -5
- package/dist/{simpleAdapter-9OE_p6QW.d.ts → simpleAdapter--wznuoOw.d.ts} +1 -1
- package/dist/{simpleAdapter-DqhvjsGr.d.cts → simpleAdapter-BpT4XbZC.d.cts} +1 -1
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/{types-7jVzOeOP.d.ts → types-BTN_ZETM.d.ts} +2 -2
- package/dist/{types-CxII3XkA.d.ts → types-BgYFd_Yw.d.cts} +5 -5
- package/dist/{types-CSHFipIc.d.cts → types-BivGO7I9.d.ts} +5 -5
- package/dist/{types-CovcHpYf.d.cts → types-D958TC71.d.cts} +2 -2
- package/package.json +25 -23
- package/dist/backends-CzDbiQar.d.ts +0 -20
- package/dist/backends-SVMT-7l4.d.cts +0 -20
- package/dist/chunk-SFVKOEQH.js +0 -103
package/dist/linear.d.cts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { LinearClient, LinearDocument } from '@linear/sdk';
|
|
2
|
-
import { R as RestApi } from './types-
|
|
3
|
-
import { AgentSessionEventWebhookPayload } from '@linear/sdk/webhooks';
|
|
2
|
+
import { R as RestApi } from './types-BgYFd_Yw.cjs';
|
|
3
|
+
import { AppUserNotificationWebhookPayloadWithNotification, AgentSessionEventWebhookPayload, AppUserTeamAccessChangedWebhookPayload, OAuthAppWebhookPayload } from '@linear/sdk/webhooks';
|
|
4
4
|
import { L as Logger } from './logger-CABQOnlR.cjs';
|
|
5
5
|
import { C as CustomToolDef } from './customTools-BzF0IISO.cjs';
|
|
6
6
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
7
|
-
import './dtos-
|
|
7
|
+
import './dtos-B8KU_q4d.cjs';
|
|
8
8
|
import 'zod';
|
|
9
9
|
|
|
10
|
+
interface CandidateRepositoryInput {
|
|
11
|
+
hostname: string;
|
|
12
|
+
repositoryFullName: string;
|
|
13
|
+
}
|
|
14
|
+
interface RepositorySuggestion {
|
|
15
|
+
repositoryFullName: string;
|
|
16
|
+
hostname?: string | null;
|
|
17
|
+
confidence: number;
|
|
18
|
+
}
|
|
10
19
|
/**
|
|
11
20
|
* Subset of `LinearClient` covering only the activity-reporting methods.
|
|
12
21
|
*/
|
|
@@ -14,7 +23,9 @@ interface LinearActivityClient {
|
|
|
14
23
|
createAgentActivity(input: {
|
|
15
24
|
agentSessionId: string;
|
|
16
25
|
content: Record<string, unknown>;
|
|
26
|
+
ephemeral?: boolean;
|
|
17
27
|
}): Promise<unknown>;
|
|
28
|
+
updateAgentSession?: (id: string, input: Record<string, unknown>) => Promise<unknown>;
|
|
18
29
|
updateIssue?: (issueId: string, input: Record<string, unknown>) => Promise<unknown>;
|
|
19
30
|
createComment?: (input: {
|
|
20
31
|
issueId: string;
|
|
@@ -22,22 +33,81 @@ interface LinearActivityClient {
|
|
|
22
33
|
}) => Promise<unknown>;
|
|
23
34
|
issue?: (issueId: string) => Promise<unknown>;
|
|
24
35
|
workflowStates?: (variables?: Record<string, unknown>) => Promise<unknown>;
|
|
36
|
+
issueRepositorySuggestions?: (candidateRepositories: CandidateRepositoryInput[], issueId: string, variables?: {
|
|
37
|
+
agentSessionId?: string | null;
|
|
38
|
+
}) => Promise<unknown>;
|
|
39
|
+
agentSessionUpdateExternalUrl?: (id: string, input: Record<string, unknown>) => Promise<unknown>;
|
|
40
|
+
/** Create an agent session on an existing Linear issue (proactive initiation). */
|
|
41
|
+
agentSessionCreateOnIssue?: (input: {
|
|
42
|
+
issueId: string;
|
|
43
|
+
externalLink?: string;
|
|
44
|
+
}) => Promise<unknown>;
|
|
45
|
+
/** Create an agent session on a specific comment thread (proactive initiation). */
|
|
46
|
+
agentSessionCreateOnComment?: (input: {
|
|
47
|
+
commentId: string;
|
|
48
|
+
externalLink?: string;
|
|
49
|
+
}) => Promise<unknown>;
|
|
50
|
+
/** Create a new Linear issue from scratch. */
|
|
51
|
+
createIssue?: (input: {
|
|
52
|
+
teamId: string;
|
|
53
|
+
title: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
priority?: number;
|
|
56
|
+
assigneeId?: string;
|
|
57
|
+
stateId?: string;
|
|
58
|
+
labelIds?: string[];
|
|
59
|
+
}) => Promise<unknown>;
|
|
25
60
|
}
|
|
26
61
|
interface PlanStep {
|
|
27
62
|
title: string;
|
|
28
63
|
status: "pending" | "in_progress" | "completed" | "failed";
|
|
29
64
|
}
|
|
30
|
-
|
|
31
|
-
|
|
65
|
+
interface SelectOption {
|
|
66
|
+
label: string;
|
|
67
|
+
value: string;
|
|
68
|
+
}
|
|
69
|
+
/** Longest body string allowed in an elicitation activity. */
|
|
70
|
+
declare const ELICITATION_BODY_MAX_LENGTH = 10000;
|
|
71
|
+
/** Longest label or value string allowed in a select option. */
|
|
72
|
+
declare const SELECT_OPTION_MAX_LENGTH = 200;
|
|
73
|
+
/** Longest provider name string allowed in an auth elicitation. */
|
|
74
|
+
declare const PROVIDER_MAX_LENGTH = 100;
|
|
75
|
+
declare function postThought(client: LinearActivityClient, sessionId: string, body: string, options?: {
|
|
76
|
+
ephemeral?: boolean;
|
|
77
|
+
}): Promise<void>;
|
|
78
|
+
declare function postError(client: LinearActivityClient, sessionId: string, body: string, options?: {
|
|
79
|
+
ephemeral?: boolean;
|
|
80
|
+
}): Promise<void>;
|
|
32
81
|
declare function postResponse(client: LinearActivityClient, sessionId: string, body: string): Promise<void>;
|
|
33
82
|
declare function postElicitation(client: LinearActivityClient, sessionId: string, body: string): Promise<void>;
|
|
34
|
-
declare function
|
|
83
|
+
declare function postSelectElicitation(client: LinearActivityClient, sessionId: string, body: string, options: SelectOption[]): Promise<void>;
|
|
84
|
+
declare function postAuthElicitation(client: LinearActivityClient, sessionId: string, body: string, url: string, provider?: string): Promise<void>;
|
|
85
|
+
declare function postAction(client: LinearActivityClient, sessionId: string, body: string, options?: {
|
|
86
|
+
ephemeral?: boolean;
|
|
87
|
+
}): Promise<void>;
|
|
35
88
|
declare function updatePlan(client: LinearActivityClient, sessionId: string, steps: PlanStep[]): Promise<void>;
|
|
36
89
|
|
|
90
|
+
interface HandleAppUserNotificationInput {
|
|
91
|
+
payload: AppUserNotificationWebhookPayloadWithNotification;
|
|
92
|
+
deps: LinearBandBridgeDeps;
|
|
93
|
+
logger: Logger;
|
|
94
|
+
/** The Linear app-user id from the webhook envelope; used to skip self-notifications. */
|
|
95
|
+
appUserId?: string;
|
|
96
|
+
}
|
|
97
|
+
declare function handleAppUserNotification(input: HandleAppUserNotificationInput): Promise<void>;
|
|
98
|
+
|
|
37
99
|
type RoomStrategy = "issue" | "session";
|
|
38
100
|
type WritebackMode = "final_only" | "activity_stream";
|
|
39
101
|
type SessionStatus = "active" | "waiting" | "completed" | "canceled" | "errored";
|
|
40
|
-
|
|
102
|
+
/** Default interval (ms) between stale-session keepalive checks. */
|
|
103
|
+
declare const STALE_SESSION_CHECK_INTERVAL_MS: number;
|
|
104
|
+
/**
|
|
105
|
+
* Maximum age (ms) of the last Linear activity before a session is considered
|
|
106
|
+
* at risk of going stale. Linear marks sessions stale after 30 minutes of
|
|
107
|
+
* inactivity; we send a keepalive well before that threshold.
|
|
108
|
+
*/
|
|
109
|
+
declare const STALE_SESSION_THRESHOLD_MS: number;
|
|
110
|
+
interface LinearBandBridgeConfig {
|
|
41
111
|
linearAccessToken: string;
|
|
42
112
|
linearWebhookSecret: string;
|
|
43
113
|
roomStrategy?: RoomStrategy;
|
|
@@ -46,20 +116,23 @@ interface LinearThenvoiBridgeConfig {
|
|
|
46
116
|
planningAgentHandles?: string[];
|
|
47
117
|
implementationAgentHandles?: string[];
|
|
48
118
|
recoveredRoomRetryBaseDelayMs?: number;
|
|
119
|
+
bandAppBaseUrl?: string;
|
|
49
120
|
}
|
|
50
121
|
interface SessionRoomRecord {
|
|
51
122
|
linearSessionId: string;
|
|
52
123
|
linearIssueId: string | null;
|
|
53
|
-
|
|
124
|
+
bandRoomId: string;
|
|
54
125
|
status: SessionStatus;
|
|
55
126
|
lastEventKey?: string | null;
|
|
127
|
+
/** ISO-8601 timestamp of the last activity sent to Linear for this session. */
|
|
128
|
+
lastLinearActivityAt?: string | null;
|
|
56
129
|
createdAt: string;
|
|
57
130
|
updatedAt: string;
|
|
58
131
|
}
|
|
59
132
|
interface PendingBootstrapRequest {
|
|
60
133
|
eventKey: string;
|
|
61
134
|
linearSessionId: string;
|
|
62
|
-
|
|
135
|
+
bandRoomId: string;
|
|
63
136
|
expectedContent: string;
|
|
64
137
|
messageType: string;
|
|
65
138
|
senderId?: string | null;
|
|
@@ -76,18 +149,20 @@ interface SessionRoomStore {
|
|
|
76
149
|
enqueueBootstrapRequest(request: PendingBootstrapRequest): Promise<void>;
|
|
77
150
|
listPendingBootstrapRequests(limit?: number): Promise<PendingBootstrapRequest[]>;
|
|
78
151
|
markBootstrapRequestProcessed(eventKey: string): Promise<void>;
|
|
152
|
+
/** List sessions with active or waiting status (used by stale-session keepalive). */
|
|
153
|
+
listActiveSessions?(): Promise<SessionRoomRecord[]>;
|
|
79
154
|
close?(): Promise<void>;
|
|
80
155
|
}
|
|
81
|
-
interface
|
|
82
|
-
|
|
156
|
+
interface LinearBandBridgeDeps {
|
|
157
|
+
bandRest: RestApi;
|
|
83
158
|
linearClient: LinearClient;
|
|
84
159
|
store: SessionRoomStore;
|
|
85
160
|
logger?: Logger;
|
|
86
161
|
}
|
|
87
162
|
interface HandleAgentSessionEventInput {
|
|
88
163
|
payload: AgentSessionEventWebhookPayload;
|
|
89
|
-
config:
|
|
90
|
-
deps:
|
|
164
|
+
config: LinearBandBridgeConfig;
|
|
165
|
+
deps: LinearBandBridgeDeps;
|
|
91
166
|
}
|
|
92
167
|
|
|
93
168
|
type LinearSessionStatus = SessionStatus;
|
|
@@ -120,6 +195,55 @@ declare function completeLinearSession(input: {
|
|
|
120
195
|
lastEventKey?: string | null;
|
|
121
196
|
}): Promise<void>;
|
|
122
197
|
|
|
198
|
+
interface StaleSessionGuardOptions {
|
|
199
|
+
store: SessionRoomStore;
|
|
200
|
+
linearClient: LinearActivityClient;
|
|
201
|
+
logger?: Logger;
|
|
202
|
+
/** Interval (ms) between keepalive checks. Defaults to 20 minutes. */
|
|
203
|
+
checkIntervalMs?: number;
|
|
204
|
+
/** Max age (ms) of last activity before sending a keepalive. Defaults to 25 minutes. */
|
|
205
|
+
staleThresholdMs?: number;
|
|
206
|
+
/** Message sent as a keepalive thought. */
|
|
207
|
+
keepAliveMessage?: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Periodically checks active Linear sessions and sends a keepalive activity
|
|
211
|
+
* to prevent Linear from marking them as stale (30-minute inactivity timeout).
|
|
212
|
+
*/
|
|
213
|
+
declare class StaleSessionGuard {
|
|
214
|
+
private readonly store;
|
|
215
|
+
private readonly linearClient;
|
|
216
|
+
private readonly logger;
|
|
217
|
+
private readonly checkIntervalMs;
|
|
218
|
+
private readonly staleThresholdMs;
|
|
219
|
+
private readonly keepAliveMessage;
|
|
220
|
+
private timer;
|
|
221
|
+
constructor(options: StaleSessionGuardOptions);
|
|
222
|
+
/** Start the periodic keepalive check. Safe to call multiple times. */
|
|
223
|
+
start(): void;
|
|
224
|
+
/** Stop the periodic keepalive check. */
|
|
225
|
+
stop(): void;
|
|
226
|
+
/** Run a single keepalive check. Exposed for testing and manual invocation. */
|
|
227
|
+
tick(): Promise<number>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Returns `true` when the session's last Linear activity is older than
|
|
231
|
+
* `thresholdMs`, meaning it risks being marked stale by Linear.
|
|
232
|
+
*/
|
|
233
|
+
declare function isSessionStale(session: SessionRoomRecord, nowMs: number, thresholdMs: number): boolean;
|
|
234
|
+
/**
|
|
235
|
+
* Checks whether a session may have gone stale and sends a recovery activity
|
|
236
|
+
* before the main update. Call this before posting significant activities to
|
|
237
|
+
* a session that may have been idle for a long time.
|
|
238
|
+
*/
|
|
239
|
+
declare function sendRecoveryActivityIfStale(input: {
|
|
240
|
+
session: SessionRoomRecord;
|
|
241
|
+
linearClient: LinearActivityClient;
|
|
242
|
+
store: SessionRoomStore;
|
|
243
|
+
logger: Logger;
|
|
244
|
+
staleThresholdMs?: number;
|
|
245
|
+
}): Promise<boolean>;
|
|
246
|
+
|
|
123
247
|
declare function isLinearApiKey(token: string): boolean;
|
|
124
248
|
declare function createLinearClient(token: string): LinearClient;
|
|
125
249
|
declare function buildLinearAuthorizationHeader(token: string): string;
|
|
@@ -133,6 +257,7 @@ interface CreateLinearToolsOptions {
|
|
|
133
257
|
client: LinearActivityClient;
|
|
134
258
|
store?: SessionRoomStore;
|
|
135
259
|
enableElicitation?: boolean;
|
|
260
|
+
logger?: Logger;
|
|
136
261
|
}
|
|
137
262
|
/**
|
|
138
263
|
* Create Linear activity tools usable by any adapter via `customTools`.
|
|
@@ -149,10 +274,15 @@ interface LinearBridgeDispatcher {
|
|
|
149
274
|
isQueued?(eventKey: string): boolean;
|
|
150
275
|
waitForIdle?(): Promise<void>;
|
|
151
276
|
}
|
|
277
|
+
interface PermissionChangeCallbacks {
|
|
278
|
+
onTeamAccessChanged?: (payload: AppUserTeamAccessChangedWebhookPayload) => void | Promise<void>;
|
|
279
|
+
onOAuthAppRevoked?: (payload: OAuthAppWebhookPayload) => void | Promise<void>;
|
|
280
|
+
}
|
|
152
281
|
interface CreateLinearWebhookHandlerOptions {
|
|
153
|
-
config:
|
|
154
|
-
deps:
|
|
282
|
+
config: LinearBandBridgeConfig;
|
|
283
|
+
deps: LinearBandBridgeDeps;
|
|
155
284
|
dispatcher?: LinearBridgeDispatcher;
|
|
285
|
+
permissionCallbacks?: PermissionChangeCallbacks;
|
|
156
286
|
}
|
|
157
287
|
declare function createInlineLinearBridgeDispatcher(options?: {
|
|
158
288
|
logger?: Logger;
|
|
@@ -164,4 +294,4 @@ declare function createLinearWebhookHandler(options: CreateLinearWebhookHandlerO
|
|
|
164
294
|
|
|
165
295
|
declare const DEFAULT_STATUS_MAPPING: Record<SessionStatus, LinearSessionStatus>;
|
|
166
296
|
|
|
167
|
-
export { type CreateLinearWebhookHandlerOptions, DEFAULT_STATUS_MAPPING, type HandleAgentSessionEventInput, type LinearActivityClient, type LinearBridgeDispatchJob, type LinearBridgeDispatcher, type LinearBridgeRuntime, type LinearSessionStatus, type
|
|
297
|
+
export { type CandidateRepositoryInput, type CreateLinearWebhookHandlerOptions, DEFAULT_STATUS_MAPPING, ELICITATION_BODY_MAX_LENGTH, type HandleAgentSessionEventInput, type HandleAppUserNotificationInput, type LinearActivityClient, type LinearBandBridgeConfig, type LinearBandBridgeDeps, type LinearBridgeDispatchJob, type LinearBridgeDispatcher, type LinearBridgeRuntime, type LinearSessionStatus, PROVIDER_MAX_LENGTH, type PendingBootstrapRequest, type PermissionChangeCallbacks, type PlanStep, type RepositorySuggestion, type RoomStrategy, SELECT_OPTION_MAX_LENGTH, STALE_SESSION_CHECK_INTERVAL_MS, STALE_SESSION_THRESHOLD_MS, type SelectOption, type SessionRoomRecord, type SessionRoomStore, type SessionStatus, StaleSessionGuard, type StaleSessionGuardOptions, type WritebackMode, buildLinearAuthorizationHeader, completeLinearSession, createInProcessLinearBridgeDispatcher, createInlineLinearBridgeDispatcher, createLinearBridgeRuntime, createLinearClient, createLinearTools, createLinearWebhookHandler, createSqliteSessionRoomStore, dedupeHandles, handleAgentSessionEvent, handleAppUserNotification, isLinearApiKey, isSessionStale, postAction, postAuthElicitation, postElicitation, postError, postResponse, postSelectElicitation, postThought, sendRecoveryActivityIfStale, stripHandlePrefix, updatePlan };
|
package/dist/linear.d.ts
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { LinearClient, LinearDocument } from '@linear/sdk';
|
|
2
|
-
import { R as RestApi } from './types-
|
|
3
|
-
import { AgentSessionEventWebhookPayload } from '@linear/sdk/webhooks';
|
|
2
|
+
import { R as RestApi } from './types-BivGO7I9.js';
|
|
3
|
+
import { AppUserNotificationWebhookPayloadWithNotification, AgentSessionEventWebhookPayload, AppUserTeamAccessChangedWebhookPayload, OAuthAppWebhookPayload } from '@linear/sdk/webhooks';
|
|
4
4
|
import { L as Logger } from './logger-CABQOnlR.js';
|
|
5
5
|
import { C as CustomToolDef } from './customTools-BzF0IISO.js';
|
|
6
6
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
7
|
-
import './dtos-
|
|
7
|
+
import './dtos-B8KU_q4d.js';
|
|
8
8
|
import 'zod';
|
|
9
9
|
|
|
10
|
+
interface CandidateRepositoryInput {
|
|
11
|
+
hostname: string;
|
|
12
|
+
repositoryFullName: string;
|
|
13
|
+
}
|
|
14
|
+
interface RepositorySuggestion {
|
|
15
|
+
repositoryFullName: string;
|
|
16
|
+
hostname?: string | null;
|
|
17
|
+
confidence: number;
|
|
18
|
+
}
|
|
10
19
|
/**
|
|
11
20
|
* Subset of `LinearClient` covering only the activity-reporting methods.
|
|
12
21
|
*/
|
|
@@ -14,7 +23,9 @@ interface LinearActivityClient {
|
|
|
14
23
|
createAgentActivity(input: {
|
|
15
24
|
agentSessionId: string;
|
|
16
25
|
content: Record<string, unknown>;
|
|
26
|
+
ephemeral?: boolean;
|
|
17
27
|
}): Promise<unknown>;
|
|
28
|
+
updateAgentSession?: (id: string, input: Record<string, unknown>) => Promise<unknown>;
|
|
18
29
|
updateIssue?: (issueId: string, input: Record<string, unknown>) => Promise<unknown>;
|
|
19
30
|
createComment?: (input: {
|
|
20
31
|
issueId: string;
|
|
@@ -22,22 +33,81 @@ interface LinearActivityClient {
|
|
|
22
33
|
}) => Promise<unknown>;
|
|
23
34
|
issue?: (issueId: string) => Promise<unknown>;
|
|
24
35
|
workflowStates?: (variables?: Record<string, unknown>) => Promise<unknown>;
|
|
36
|
+
issueRepositorySuggestions?: (candidateRepositories: CandidateRepositoryInput[], issueId: string, variables?: {
|
|
37
|
+
agentSessionId?: string | null;
|
|
38
|
+
}) => Promise<unknown>;
|
|
39
|
+
agentSessionUpdateExternalUrl?: (id: string, input: Record<string, unknown>) => Promise<unknown>;
|
|
40
|
+
/** Create an agent session on an existing Linear issue (proactive initiation). */
|
|
41
|
+
agentSessionCreateOnIssue?: (input: {
|
|
42
|
+
issueId: string;
|
|
43
|
+
externalLink?: string;
|
|
44
|
+
}) => Promise<unknown>;
|
|
45
|
+
/** Create an agent session on a specific comment thread (proactive initiation). */
|
|
46
|
+
agentSessionCreateOnComment?: (input: {
|
|
47
|
+
commentId: string;
|
|
48
|
+
externalLink?: string;
|
|
49
|
+
}) => Promise<unknown>;
|
|
50
|
+
/** Create a new Linear issue from scratch. */
|
|
51
|
+
createIssue?: (input: {
|
|
52
|
+
teamId: string;
|
|
53
|
+
title: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
priority?: number;
|
|
56
|
+
assigneeId?: string;
|
|
57
|
+
stateId?: string;
|
|
58
|
+
labelIds?: string[];
|
|
59
|
+
}) => Promise<unknown>;
|
|
25
60
|
}
|
|
26
61
|
interface PlanStep {
|
|
27
62
|
title: string;
|
|
28
63
|
status: "pending" | "in_progress" | "completed" | "failed";
|
|
29
64
|
}
|
|
30
|
-
|
|
31
|
-
|
|
65
|
+
interface SelectOption {
|
|
66
|
+
label: string;
|
|
67
|
+
value: string;
|
|
68
|
+
}
|
|
69
|
+
/** Longest body string allowed in an elicitation activity. */
|
|
70
|
+
declare const ELICITATION_BODY_MAX_LENGTH = 10000;
|
|
71
|
+
/** Longest label or value string allowed in a select option. */
|
|
72
|
+
declare const SELECT_OPTION_MAX_LENGTH = 200;
|
|
73
|
+
/** Longest provider name string allowed in an auth elicitation. */
|
|
74
|
+
declare const PROVIDER_MAX_LENGTH = 100;
|
|
75
|
+
declare function postThought(client: LinearActivityClient, sessionId: string, body: string, options?: {
|
|
76
|
+
ephemeral?: boolean;
|
|
77
|
+
}): Promise<void>;
|
|
78
|
+
declare function postError(client: LinearActivityClient, sessionId: string, body: string, options?: {
|
|
79
|
+
ephemeral?: boolean;
|
|
80
|
+
}): Promise<void>;
|
|
32
81
|
declare function postResponse(client: LinearActivityClient, sessionId: string, body: string): Promise<void>;
|
|
33
82
|
declare function postElicitation(client: LinearActivityClient, sessionId: string, body: string): Promise<void>;
|
|
34
|
-
declare function
|
|
83
|
+
declare function postSelectElicitation(client: LinearActivityClient, sessionId: string, body: string, options: SelectOption[]): Promise<void>;
|
|
84
|
+
declare function postAuthElicitation(client: LinearActivityClient, sessionId: string, body: string, url: string, provider?: string): Promise<void>;
|
|
85
|
+
declare function postAction(client: LinearActivityClient, sessionId: string, body: string, options?: {
|
|
86
|
+
ephemeral?: boolean;
|
|
87
|
+
}): Promise<void>;
|
|
35
88
|
declare function updatePlan(client: LinearActivityClient, sessionId: string, steps: PlanStep[]): Promise<void>;
|
|
36
89
|
|
|
90
|
+
interface HandleAppUserNotificationInput {
|
|
91
|
+
payload: AppUserNotificationWebhookPayloadWithNotification;
|
|
92
|
+
deps: LinearBandBridgeDeps;
|
|
93
|
+
logger: Logger;
|
|
94
|
+
/** The Linear app-user id from the webhook envelope; used to skip self-notifications. */
|
|
95
|
+
appUserId?: string;
|
|
96
|
+
}
|
|
97
|
+
declare function handleAppUserNotification(input: HandleAppUserNotificationInput): Promise<void>;
|
|
98
|
+
|
|
37
99
|
type RoomStrategy = "issue" | "session";
|
|
38
100
|
type WritebackMode = "final_only" | "activity_stream";
|
|
39
101
|
type SessionStatus = "active" | "waiting" | "completed" | "canceled" | "errored";
|
|
40
|
-
|
|
102
|
+
/** Default interval (ms) between stale-session keepalive checks. */
|
|
103
|
+
declare const STALE_SESSION_CHECK_INTERVAL_MS: number;
|
|
104
|
+
/**
|
|
105
|
+
* Maximum age (ms) of the last Linear activity before a session is considered
|
|
106
|
+
* at risk of going stale. Linear marks sessions stale after 30 minutes of
|
|
107
|
+
* inactivity; we send a keepalive well before that threshold.
|
|
108
|
+
*/
|
|
109
|
+
declare const STALE_SESSION_THRESHOLD_MS: number;
|
|
110
|
+
interface LinearBandBridgeConfig {
|
|
41
111
|
linearAccessToken: string;
|
|
42
112
|
linearWebhookSecret: string;
|
|
43
113
|
roomStrategy?: RoomStrategy;
|
|
@@ -46,20 +116,23 @@ interface LinearThenvoiBridgeConfig {
|
|
|
46
116
|
planningAgentHandles?: string[];
|
|
47
117
|
implementationAgentHandles?: string[];
|
|
48
118
|
recoveredRoomRetryBaseDelayMs?: number;
|
|
119
|
+
bandAppBaseUrl?: string;
|
|
49
120
|
}
|
|
50
121
|
interface SessionRoomRecord {
|
|
51
122
|
linearSessionId: string;
|
|
52
123
|
linearIssueId: string | null;
|
|
53
|
-
|
|
124
|
+
bandRoomId: string;
|
|
54
125
|
status: SessionStatus;
|
|
55
126
|
lastEventKey?: string | null;
|
|
127
|
+
/** ISO-8601 timestamp of the last activity sent to Linear for this session. */
|
|
128
|
+
lastLinearActivityAt?: string | null;
|
|
56
129
|
createdAt: string;
|
|
57
130
|
updatedAt: string;
|
|
58
131
|
}
|
|
59
132
|
interface PendingBootstrapRequest {
|
|
60
133
|
eventKey: string;
|
|
61
134
|
linearSessionId: string;
|
|
62
|
-
|
|
135
|
+
bandRoomId: string;
|
|
63
136
|
expectedContent: string;
|
|
64
137
|
messageType: string;
|
|
65
138
|
senderId?: string | null;
|
|
@@ -76,18 +149,20 @@ interface SessionRoomStore {
|
|
|
76
149
|
enqueueBootstrapRequest(request: PendingBootstrapRequest): Promise<void>;
|
|
77
150
|
listPendingBootstrapRequests(limit?: number): Promise<PendingBootstrapRequest[]>;
|
|
78
151
|
markBootstrapRequestProcessed(eventKey: string): Promise<void>;
|
|
152
|
+
/** List sessions with active or waiting status (used by stale-session keepalive). */
|
|
153
|
+
listActiveSessions?(): Promise<SessionRoomRecord[]>;
|
|
79
154
|
close?(): Promise<void>;
|
|
80
155
|
}
|
|
81
|
-
interface
|
|
82
|
-
|
|
156
|
+
interface LinearBandBridgeDeps {
|
|
157
|
+
bandRest: RestApi;
|
|
83
158
|
linearClient: LinearClient;
|
|
84
159
|
store: SessionRoomStore;
|
|
85
160
|
logger?: Logger;
|
|
86
161
|
}
|
|
87
162
|
interface HandleAgentSessionEventInput {
|
|
88
163
|
payload: AgentSessionEventWebhookPayload;
|
|
89
|
-
config:
|
|
90
|
-
deps:
|
|
164
|
+
config: LinearBandBridgeConfig;
|
|
165
|
+
deps: LinearBandBridgeDeps;
|
|
91
166
|
}
|
|
92
167
|
|
|
93
168
|
type LinearSessionStatus = SessionStatus;
|
|
@@ -120,6 +195,55 @@ declare function completeLinearSession(input: {
|
|
|
120
195
|
lastEventKey?: string | null;
|
|
121
196
|
}): Promise<void>;
|
|
122
197
|
|
|
198
|
+
interface StaleSessionGuardOptions {
|
|
199
|
+
store: SessionRoomStore;
|
|
200
|
+
linearClient: LinearActivityClient;
|
|
201
|
+
logger?: Logger;
|
|
202
|
+
/** Interval (ms) between keepalive checks. Defaults to 20 minutes. */
|
|
203
|
+
checkIntervalMs?: number;
|
|
204
|
+
/** Max age (ms) of last activity before sending a keepalive. Defaults to 25 minutes. */
|
|
205
|
+
staleThresholdMs?: number;
|
|
206
|
+
/** Message sent as a keepalive thought. */
|
|
207
|
+
keepAliveMessage?: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Periodically checks active Linear sessions and sends a keepalive activity
|
|
211
|
+
* to prevent Linear from marking them as stale (30-minute inactivity timeout).
|
|
212
|
+
*/
|
|
213
|
+
declare class StaleSessionGuard {
|
|
214
|
+
private readonly store;
|
|
215
|
+
private readonly linearClient;
|
|
216
|
+
private readonly logger;
|
|
217
|
+
private readonly checkIntervalMs;
|
|
218
|
+
private readonly staleThresholdMs;
|
|
219
|
+
private readonly keepAliveMessage;
|
|
220
|
+
private timer;
|
|
221
|
+
constructor(options: StaleSessionGuardOptions);
|
|
222
|
+
/** Start the periodic keepalive check. Safe to call multiple times. */
|
|
223
|
+
start(): void;
|
|
224
|
+
/** Stop the periodic keepalive check. */
|
|
225
|
+
stop(): void;
|
|
226
|
+
/** Run a single keepalive check. Exposed for testing and manual invocation. */
|
|
227
|
+
tick(): Promise<number>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Returns `true` when the session's last Linear activity is older than
|
|
231
|
+
* `thresholdMs`, meaning it risks being marked stale by Linear.
|
|
232
|
+
*/
|
|
233
|
+
declare function isSessionStale(session: SessionRoomRecord, nowMs: number, thresholdMs: number): boolean;
|
|
234
|
+
/**
|
|
235
|
+
* Checks whether a session may have gone stale and sends a recovery activity
|
|
236
|
+
* before the main update. Call this before posting significant activities to
|
|
237
|
+
* a session that may have been idle for a long time.
|
|
238
|
+
*/
|
|
239
|
+
declare function sendRecoveryActivityIfStale(input: {
|
|
240
|
+
session: SessionRoomRecord;
|
|
241
|
+
linearClient: LinearActivityClient;
|
|
242
|
+
store: SessionRoomStore;
|
|
243
|
+
logger: Logger;
|
|
244
|
+
staleThresholdMs?: number;
|
|
245
|
+
}): Promise<boolean>;
|
|
246
|
+
|
|
123
247
|
declare function isLinearApiKey(token: string): boolean;
|
|
124
248
|
declare function createLinearClient(token: string): LinearClient;
|
|
125
249
|
declare function buildLinearAuthorizationHeader(token: string): string;
|
|
@@ -133,6 +257,7 @@ interface CreateLinearToolsOptions {
|
|
|
133
257
|
client: LinearActivityClient;
|
|
134
258
|
store?: SessionRoomStore;
|
|
135
259
|
enableElicitation?: boolean;
|
|
260
|
+
logger?: Logger;
|
|
136
261
|
}
|
|
137
262
|
/**
|
|
138
263
|
* Create Linear activity tools usable by any adapter via `customTools`.
|
|
@@ -149,10 +274,15 @@ interface LinearBridgeDispatcher {
|
|
|
149
274
|
isQueued?(eventKey: string): boolean;
|
|
150
275
|
waitForIdle?(): Promise<void>;
|
|
151
276
|
}
|
|
277
|
+
interface PermissionChangeCallbacks {
|
|
278
|
+
onTeamAccessChanged?: (payload: AppUserTeamAccessChangedWebhookPayload) => void | Promise<void>;
|
|
279
|
+
onOAuthAppRevoked?: (payload: OAuthAppWebhookPayload) => void | Promise<void>;
|
|
280
|
+
}
|
|
152
281
|
interface CreateLinearWebhookHandlerOptions {
|
|
153
|
-
config:
|
|
154
|
-
deps:
|
|
282
|
+
config: LinearBandBridgeConfig;
|
|
283
|
+
deps: LinearBandBridgeDeps;
|
|
155
284
|
dispatcher?: LinearBridgeDispatcher;
|
|
285
|
+
permissionCallbacks?: PermissionChangeCallbacks;
|
|
156
286
|
}
|
|
157
287
|
declare function createInlineLinearBridgeDispatcher(options?: {
|
|
158
288
|
logger?: Logger;
|
|
@@ -164,4 +294,4 @@ declare function createLinearWebhookHandler(options: CreateLinearWebhookHandlerO
|
|
|
164
294
|
|
|
165
295
|
declare const DEFAULT_STATUS_MAPPING: Record<SessionStatus, LinearSessionStatus>;
|
|
166
296
|
|
|
167
|
-
export { type CreateLinearWebhookHandlerOptions, DEFAULT_STATUS_MAPPING, type HandleAgentSessionEventInput, type LinearActivityClient, type LinearBridgeDispatchJob, type LinearBridgeDispatcher, type LinearBridgeRuntime, type LinearSessionStatus, type
|
|
297
|
+
export { type CandidateRepositoryInput, type CreateLinearWebhookHandlerOptions, DEFAULT_STATUS_MAPPING, ELICITATION_BODY_MAX_LENGTH, type HandleAgentSessionEventInput, type HandleAppUserNotificationInput, type LinearActivityClient, type LinearBandBridgeConfig, type LinearBandBridgeDeps, type LinearBridgeDispatchJob, type LinearBridgeDispatcher, type LinearBridgeRuntime, type LinearSessionStatus, PROVIDER_MAX_LENGTH, type PendingBootstrapRequest, type PermissionChangeCallbacks, type PlanStep, type RepositorySuggestion, type RoomStrategy, SELECT_OPTION_MAX_LENGTH, STALE_SESSION_CHECK_INTERVAL_MS, STALE_SESSION_THRESHOLD_MS, type SelectOption, type SessionRoomRecord, type SessionRoomStore, type SessionStatus, StaleSessionGuard, type StaleSessionGuardOptions, type WritebackMode, buildLinearAuthorizationHeader, completeLinearSession, createInProcessLinearBridgeDispatcher, createInlineLinearBridgeDispatcher, createLinearBridgeRuntime, createLinearClient, createLinearTools, createLinearWebhookHandler, createSqliteSessionRoomStore, dedupeHandles, handleAgentSessionEvent, handleAppUserNotification, isLinearApiKey, isSessionStale, postAction, postAuthElicitation, postElicitation, postError, postResponse, postSelectElicitation, postThought, sendRecoveryActivityIfStale, stripHandlePrefix, updatePlan };
|