import type { SessionAuthContext } from "#channel/types.js"; import type { HandleMessageStreamEvent } from "#protocol/message.js"; import { createLinearAgentActivity, listLinearAgentSessionActivities, updateLinearAgentSession, type LinearApiOptions } from "#public/channels/linear/api.js"; import type { LinearChannelCredentials } from "#public/channels/linear/auth.js"; import { type LinearAgentSessionEvent, type LinearAgentSessionRef, type LinearDataWebhookEvent, type LinearDelivery } from "#public/channels/linear/inbound.js"; import type { SessionContext } from "#public/definitions/callback-context.js"; import { type Channel, type ChannelSessionOps } from "#public/definitions/defineChannel.js"; import type { JsonObject } from "#shared/json.js"; type EventData = Extract extends { data: infer D; } ? D : undefined; /** JSON-serializable state for one Linear Agent Session conversation. */ export interface LinearChannelState { readonly agentSessionId: string | null; readonly agentSessionUrl?: string | null; readonly commentId?: string | null; readonly issueId?: string | null; readonly issueIdentifier?: string | null; readonly issueTitle?: string | null; readonly issueUrl?: string | null; readonly organizationId?: string | null; /** * Buffered text from a `message.completed` event whose `finishReason` * was `"tool-calls"`. The default `actions.requested` handler uses this * as the next ephemeral progress activity, matching Slack's typing status. */ pendingToolCallMessage?: string | null; readonly sourceCommentId?: string | null; } /** Per-session instrumentation snapshot for Linear runtime telemetry. */ export interface LinearInstrumentationMetadata extends Record { readonly agentSessionId: string | null; readonly commentId: string | null; readonly issueId: string | null; readonly issueIdentifier: string | null; readonly organizationId: string | null; } /** Target accepted by `receive(linear, { target })` for proactive Linear sessions. */ export type LinearReceiveTarget = { readonly agentSessionId: string; readonly initialActivity?: string; } | { readonly externalLink?: string; readonly externalUrls?: readonly { readonly label: string; readonly url: string; }[]; readonly initialActivity?: string; readonly issueId: string; } | { readonly commentId: string; readonly externalLink?: string; readonly externalUrls?: readonly { readonly label: string; readonly url: string; }[]; readonly initialActivity?: string; }; /** Pre-dispatch Linear context passed to inbound hooks. */ export interface LinearSessionContext { readonly delivery: LinearDelivery; readonly linear: LinearHandle; readonly session: LinearAgentSessionRef; } /** Channel-owned Linear context rebuilt from persisted channel state. */ export interface LinearChannelContext { readonly linear: LinearHandle; state: LinearChannelState; } /** Event-handler Linear context, including session operations. */ export interface LinearEventContext extends LinearChannelContext, ChannelSessionOps { } /** Low-level Linear handle exposed to hooks and event handlers. */ export interface LinearHandle { readonly agentSessionId: string; createActivity(content: Parameters[0]["activity"]["content"], options?: { readonly ephemeral?: boolean; readonly signal?: Parameters[0]["activity"]["signal"]; readonly signalMetadata?: JsonObject; }): Promise<{ readonly id: string; readonly success: boolean; }>; listActivities(options?: { readonly last?: number; }): Promise>>; updateSession(update: Parameters[0]["update"]): Promise<{ readonly success: boolean; }>; } type LinearEventHandler = (data: EventData, channel: LinearEventContext, ctx: SessionContext) => void | Promise; type LinearSessionFailedHandler = (data: EventData<"session.failed">, channel: LinearEventContext) => void | Promise; /** Event handlers supported by `linearChannel({ events })`. */ export interface LinearChannelEvents { readonly "turn.started"?: LinearEventHandler<"turn.started">; readonly "actions.requested"?: LinearEventHandler<"actions.requested">; readonly "action.result"?: LinearEventHandler<"action.result">; readonly "message.completed"?: LinearEventHandler<"message.completed">; readonly "message.appended"?: LinearEventHandler<"message.appended">; readonly "input.requested"?: LinearEventHandler<"input.requested">; readonly "turn.failed"?: LinearEventHandler<"turn.failed">; readonly "turn.completed"?: LinearEventHandler<"turn.completed">; readonly "session.failed"?: LinearSessionFailedHandler; readonly "session.completed"?: LinearEventHandler<"session.completed">; readonly "session.waiting"?: LinearEventHandler<"session.waiting">; readonly "authorization.required"?: LinearEventHandler<"authorization.required">; readonly "authorization.completed"?: LinearEventHandler<"authorization.completed">; } /** * Result of an inbound Linear hook. Return `null` to acknowledge without * dispatching; return `{ auth }` to dispatch. Optional `context` strings are * added as `role: "user"` messages before the dispatched turn. */ export type LinearInboundResult = { readonly auth: SessionAuthContext | null; readonly context?: readonly string[]; } | null; /** Sync or async {@link LinearInboundResult}. */ export type LinearInboundResultOrPromise = LinearInboundResult | Promise; /** Configuration for {@link linearChannel}. */ export interface LinearChannelConfig { readonly api?: LinearApiOptions; readonly credentials?: LinearChannelCredentials; readonly events?: LinearChannelEvents; readonly route?: string; /** Inbound Agent Session hook. Defaults to dispatching `created` and `prompted` events. */ onAgentSession?(ctx: LinearSessionContext, event: LinearAgentSessionEvent): LinearInboundResultOrPromise; /** Optional hook for generic Linear data webhooks sent to the same route. */ onDataWebhook?(event: LinearDataWebhookEvent): void | Promise; } /** Concrete return type of {@link linearChannel}. */ export interface LinearChannel extends Channel { } /** Linear channel factory for Linear Agent Session webhooks and Agent Activities. */ export declare function linearChannel(config?: LinearChannelConfig): LinearChannel; export {};