@opentag/slack 0.2.0 → 0.3.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/dist/dispatcher-events.d.ts +5 -0
- package/dist/dispatcher-events.d.ts.map +1 -1
- package/dist/events.d.ts +98 -1
- package/dist/events.d.ts.map +1 -1
- package/dist/index.js +1255 -197
- package/dist/index.js.map +1 -1
- package/dist/ingress.d.ts +10 -0
- package/dist/ingress.d.ts.map +1 -1
- package/dist/normalize.d.ts +1 -0
- package/dist/normalize.d.ts.map +1 -1
- package/dist/render.d.ts +57 -4
- package/dist/render.d.ts.map +1 -1
- package/dist/socket-mode.d.ts +5 -2
- package/dist/socket-mode.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/events.ts","../src/normalize.ts","../src/ingress.ts","../src/dispatcher-events.ts","../src/render.ts","../src/socket-mode.ts"],"sourcesContent":["import { parseThreadActionCommand, type OpenTagEvent } from \"@opentag/core\";\nimport { encodeSlackThreadKey, normalizeSlackAppMention, stripSlackAppMention, type SlackChannelBinding } from \"./normalize.js\";\n\nexport type SlackThreadActionInput = {\n id: string;\n rawText: string;\n actor: {\n provider: \"slack\";\n providerUserId: string;\n handle: string;\n organizationId: string;\n };\n callback: {\n provider: \"slack\";\n uri: string;\n threadKey: string;\n };\n metadata: Record<string, unknown>;\n};\n\nexport type SlackEventEnvelope = {\n token?: string;\n type: \"url_verification\" | \"event_callback\";\n challenge?: string;\n team_id?: string;\n api_app_id?: string;\n event?: {\n type: string;\n user?: string;\n text?: string;\n ts?: string;\n thread_ts?: string;\n channel?: string;\n subtype?: string;\n bot_id?: string;\n };\n event_id?: string;\n event_time?: number;\n authorizations?: Array<{ user_id?: string }>;\n};\n\nexport type SlackAppRuntimeConfig = {\n agentId: string;\n appId?: string;\n callbackUri?: string;\n};\n\nexport type SlackEventProcessorInput = {\n resolveChannelBinding(input: { teamId: string; channelId: string }): Promise<SlackChannelBinding | null>;\n createRun(event: OpenTagEvent): Promise<{ runId: string }>;\n submitThreadAction?(action: SlackThreadActionInput): Promise<unknown>;\n now(): string;\n};\n\nexport type SlackEventProcessorStatus = 200 | 400;\n\nexport type SlackEventProcessorResult =\n | {\n kind: \"json\";\n status: SlackEventProcessorStatus;\n body: Record<string, unknown>;\n }\n | {\n kind: \"text\";\n status: SlackEventProcessorStatus;\n body: string;\n };\n\nfunction json(body: Record<string, unknown>, status: SlackEventProcessorStatus = 200): SlackEventProcessorResult {\n return { kind: \"json\", status, body };\n}\n\nfunction text(body: string, status: SlackEventProcessorStatus = 200): SlackEventProcessorResult {\n return { kind: \"text\", status, body };\n}\n\nexport function createSlackEventProcessor(input: SlackEventProcessorInput) {\n return {\n async process(payload: SlackEventEnvelope, slackApp: SlackAppRuntimeConfig): Promise<SlackEventProcessorResult> {\n if (payload.type === \"url_verification\") {\n return text(payload.challenge ?? \"\");\n }\n if (payload.type !== \"event_callback\" || !payload.event || ![\"app_mention\", \"message\"].includes(payload.event.type)) {\n return json({ ok: true });\n }\n if (payload.event.type === \"message\" && (payload.event.subtype || payload.event.bot_id)) {\n return json({ ok: true });\n }\n if (!payload.team_id || !payload.event.channel || !payload.event.user || !payload.event.text || !payload.event.ts || !payload.event_id) {\n return json({ error: \"invalid_event_payload\" }, 400);\n }\n\n const rawThreadActionText =\n payload.event.type === \"app_mention\"\n ? stripSlackAppMention(payload.event.text, payload.authorizations?.[0]?.user_id)\n : payload.event.text.trim();\n if (payload.event.type === \"message\" && (!rawThreadActionText || !parseThreadActionCommand(rawThreadActionText))) {\n return json({ ok: true });\n }\n\n const binding = await input.resolveChannelBinding({\n teamId: payload.team_id,\n channelId: payload.event.channel\n });\n if (!binding) {\n return json({ ok: true, ignored: \"unbound_channel\" });\n }\n\n if (rawThreadActionText && parseThreadActionCommand(rawThreadActionText) && input.submitThreadAction) {\n await input.submitThreadAction({\n id: `approval_slack_${payload.event_id}`,\n rawText: rawThreadActionText,\n actor: {\n provider: \"slack\",\n providerUserId: payload.event.user,\n handle: payload.event.user,\n organizationId: payload.team_id\n },\n callback: {\n provider: \"slack\",\n uri: slackApp.callbackUri ?? \"https://slack.com/api/chat.postMessage\",\n threadKey: encodeSlackThreadKey({\n teamId: payload.team_id,\n channelId: payload.event.channel,\n threadTs: payload.event.thread_ts ?? payload.event.ts\n })\n },\n metadata: {\n teamId: payload.team_id,\n channelId: payload.event.channel,\n messageTs: payload.event.ts,\n ...(payload.api_app_id ? { slackAppId: payload.api_app_id } : {}),\n ...(payload.authorizations?.[0]?.user_id ? { slackBotUserId: payload.authorizations[0].user_id } : {}),\n repoProvider: binding.repoProvider ?? \"github\",\n owner: binding.owner,\n repo: binding.repo\n }\n });\n return json({ ok: true });\n }\n\n if (payload.event.type !== \"app_mention\") {\n return json({ ok: true });\n }\n\n const event = normalizeSlackAppMention({\n teamId: payload.team_id,\n channelId: payload.event.channel,\n userId: payload.event.user,\n text: payload.event.text,\n ts: payload.event.ts,\n eventId: payload.event_id,\n eventTime: payload.event_time ?? Math.floor(Date.parse(input.now()) / 1000),\n agentId: slackApp.agentId,\n binding,\n ...(payload.api_app_id ? { appId: payload.api_app_id } : {}),\n ...(payload.event.thread_ts ? { threadTs: payload.event.thread_ts } : {}),\n ...(payload.authorizations?.[0]?.user_id ? { botUserId: payload.authorizations[0].user_id } : {}),\n ...(slackApp.callbackUri ? { callbackUri: slackApp.callbackUri } : {})\n });\n if (!event) {\n return json({ ok: true, ignored: \"empty_command\" });\n }\n\n await input.createRun(event);\n return json({ ok: true });\n }\n };\n}\n","import { commandFromRawText, type ContextPointer, type OpenTagCommand, type OpenTagEvent, type PermissionGrant } from \"@opentag/core\";\n\nexport type SlackChannelBinding = {\n teamId: string;\n channelId: string;\n repoProvider?: string;\n owner: string;\n repo: string;\n};\n\nexport type SlackAppMentionInput = {\n teamId: string;\n channelId: string;\n userId: string;\n text: string;\n ts: string;\n threadTs?: string;\n eventId: string;\n eventTime: number;\n appId?: string;\n agentId?: string;\n botUserId?: string;\n callbackUri?: string;\n binding: SlackChannelBinding;\n};\n\nexport function stripSlackAppMention(text: string, botUserId?: string): string | null {\n const patterns = botUserId\n ? [new RegExp(`^<@${botUserId}>\\\\s*`, \"i\"), /^<@[^>]+>\\s*/]\n : [/^<@[^>]+>\\s*/];\n\n for (const pattern of patterns) {\n const stripped = text.replace(pattern, \"\").trim();\n if (stripped !== text.trim()) {\n return stripped.length > 0 ? stripped : null;\n }\n }\n\n return null;\n}\n\nexport function encodeSlackThreadKey(input: { teamId: string; channelId: string; threadTs: string }): string {\n return `${input.teamId}|${input.channelId}|${input.threadTs}`;\n}\n\nexport function parseSlackThreadKey(threadKey: string): { teamId: string; channelId: string; threadTs: string } {\n const [teamId, channelId, threadTs] = threadKey.split(\"|\");\n if (!teamId || !channelId || !threadTs) {\n throw new Error(`Invalid Slack thread key: ${threadKey}`);\n }\n return { teamId, channelId, threadTs };\n}\n\nfunction permissionsForIntent(intent: OpenTagCommand[\"intent\"]): PermissionGrant[] {\n const permissions: PermissionGrant[] = [\n {\n scope: \"chat:postMessage\",\n reason: \"reply in the originating Slack thread\"\n },\n {\n scope: \"runner:local\",\n reason: \"execute the run on a paired local daemon\"\n }\n ];\n\n if (intent === \"fix\" || intent === \"run\") {\n permissions.push(\n {\n scope: \"repo:read\",\n reason: \"inspect the repository in the paired local checkout\"\n },\n {\n scope: \"repo:write\",\n reason: \"commit code changes on an isolated run branch\"\n },\n {\n scope: \"pr:create\",\n reason: \"open a pull request for completed code changes\"\n }\n );\n }\n\n return permissions;\n}\n\nfunction contextPointersForCommand(command: OpenTagCommand): ContextPointer[] {\n const context: ContextPointer[] = [];\n\n for (const reference of command.parsed?.references ?? []) {\n if (reference.kind === \"url\") {\n context.push({\n kind: \"url\",\n uri: reference.uri,\n visibility: \"organization\",\n title: reference.title ?? \"Command URL reference\"\n });\n continue;\n }\n\n if (reference.kind === \"file\" || reference.kind === \"path\") {\n context.push({\n kind: \"file\",\n uri: reference.uri,\n ...(reference.line ? { line: reference.line } : {}),\n ...(reference.startLine ? { startLine: reference.startLine } : {}),\n ...(reference.endLine ? { endLine: reference.endLine } : {}),\n visibility: \"organization\",\n title: referenceTitle(reference)\n });\n }\n }\n\n return context;\n}\n\nfunction referenceTitle(reference: NonNullable<OpenTagCommand[\"parsed\"]>[\"references\"][number]): string {\n return reference.title ?? \"Command file reference\";\n}\n\nfunction commandMetadata(command: OpenTagCommand): Record<string, unknown> {\n if (!command.parsed) return {};\n return {\n commandParser: command.parsed.version,\n commandDiagnostics: command.parsed.diagnostics,\n ...(command.parsed.approval ? { approval: command.parsed.approval } : {}),\n ...(command.parsed.network ? { network: command.parsed.network } : {})\n };\n}\n\nexport function normalizeSlackAppMention(input: SlackAppMentionInput): OpenTagEvent | null {\n const rawText = stripSlackAppMention(input.text, input.botUserId);\n if (!rawText) return null;\n\n const command = commandFromRawText(rawText);\n const replyThreadTs = input.threadTs ?? input.ts;\n const agentId = input.agentId ?? \"opentag\";\n\n return {\n id: `evt_slack_app_mention_${input.eventId}`,\n source: \"slack\",\n sourceEventId: input.eventId,\n receivedAt: new Date(input.eventTime * 1000).toISOString(),\n actor: {\n provider: \"slack\",\n providerUserId: input.userId,\n handle: input.userId,\n organizationId: input.teamId\n },\n target: {\n mention: input.botUserId ? `<@${input.botUserId}>` : \"<@app>\",\n agentId,\n ...(command.parsed?.executorHint ? { executorHint: command.parsed.executorHint } : {})\n },\n command,\n context: [\n {\n provider: \"slack\",\n kind: \"message\",\n uri: `slack://team/${input.teamId}/channel/${input.channelId}/message/${input.ts}`,\n visibility: \"organization\",\n title: \"Slack message\"\n },\n {\n kind: \"text\",\n uri: input.text,\n visibility: \"organization\",\n title: \"Slack message text\"\n },\n ...contextPointersForCommand(command)\n ],\n permissions: permissionsForIntent(command.intent),\n callback: {\n provider: \"slack\",\n uri: input.callbackUri ?? \"https://slack.com/api/chat.postMessage\",\n threadKey: encodeSlackThreadKey({\n teamId: input.teamId,\n channelId: input.channelId,\n threadTs: replyThreadTs\n })\n },\n metadata: {\n teamId: input.teamId,\n channelId: input.channelId,\n messageTs: input.ts,\n ...(input.appId ? { slackAppId: input.appId } : {}),\n ...(input.botUserId ? { slackBotUserId: input.botUserId } : {}),\n ...commandMetadata(command),\n repoProvider: input.binding.repoProvider ?? \"github\",\n owner: input.binding.owner,\n repo: input.binding.repo\n }\n };\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { serve } from \"@hono/node-server\";\nimport { Hono } from \"hono\";\nimport { createSlackDispatcherEventProcessorInput } from \"./dispatcher-events.js\";\nimport { createSlackEventProcessor, type SlackAppRuntimeConfig, type SlackEventEnvelope, type SlackEventProcessorInput } from \"./events.js\";\n\nexport type SlackEventsAppInput = {\n slackApps: Array<\n SlackAppRuntimeConfig & {\n signingSecret: string;\n }\n >;\n clock?: () => number;\n} & SlackEventProcessorInput;\n\nexport type SlackEventsApiIngressConfig = {\n signingSecret: string;\n dispatcherUrl: string;\n dispatcherToken?: string;\n port?: number;\n agentId?: string;\n appId?: string;\n callbackUri?: string;\n};\n\nexport type SlackIngressConfig = SlackEventsApiIngressConfig;\n\nexport type SlackIngressHandle = {\n url: string;\n server: ReturnType<typeof serve>;\n close(): Promise<void>;\n};\n\nexport function computeSlackSignature(input: {\n signingSecret: string;\n timestamp: string;\n rawBody: string;\n}): string {\n const base = `v0:${input.timestamp}:${input.rawBody}`;\n const digest = createHmac(\"sha256\", input.signingSecret).update(base).digest(\"hex\");\n return `v0=${digest}`;\n}\n\nexport function verifySlackSignature(input: {\n signingSecret: string;\n timestamp: string;\n rawBody: string;\n signature: string;\n}): boolean {\n const expected = computeSlackSignature(input);\n const expectedBuffer = Buffer.from(expected);\n const actualBuffer = Buffer.from(input.signature);\n return expectedBuffer.length === actualBuffer.length && timingSafeEqual(expectedBuffer, actualBuffer);\n}\n\nexport function verifySlackTimestamp(input: { timestamp: string; nowMs: number; toleranceSeconds?: number }): boolean {\n const timestampSeconds = Number(input.timestamp);\n if (!Number.isFinite(timestampSeconds)) return false;\n const toleranceSeconds = input.toleranceSeconds ?? 300;\n const ageSeconds = Math.abs(Math.floor(input.nowMs / 1000) - timestampSeconds);\n return ageSeconds <= toleranceSeconds;\n}\n\nexport function createSlackEventsApp(input: SlackEventsAppInput) {\n const app = new Hono();\n const processor = createSlackEventProcessor(input);\n\n function parseSlackPayload(rawBody: string): SlackEventEnvelope | null {\n try {\n return JSON.parse(rawBody) as SlackEventEnvelope;\n } catch {\n return null;\n }\n }\n\n function resolveSlackApp(inputValue: {\n apiAppId?: string;\n rawBody: string;\n signature: string;\n timestamp: string;\n }) {\n const candidates = inputValue.apiAppId\n ? input.slackApps.filter((candidate) => !candidate.appId || candidate.appId === inputValue.apiAppId)\n : input.slackApps;\n if (candidates.length === 0) {\n return { error: \"unknown_slack_app\" as const };\n }\n const slackApp = candidates.find((candidate) =>\n verifySlackSignature({\n signingSecret: candidate.signingSecret,\n timestamp: inputValue.timestamp,\n rawBody: inputValue.rawBody,\n signature: inputValue.signature\n })\n );\n return slackApp ? { slackApp } : { error: \"invalid_signature\" as const };\n }\n\n app.post(\"/slack/events\", async (c) => {\n const timestamp = c.req.header(\"x-slack-request-timestamp\");\n const signature = c.req.header(\"x-slack-signature\");\n if (!timestamp || !signature) {\n return c.json({ error: \"missing_signature_headers\" }, 401);\n }\n if (!verifySlackTimestamp({ timestamp, nowMs: input.clock?.() ?? Date.now() })) {\n return c.json({ error: \"stale_signature_timestamp\" }, 401);\n }\n const rawBody = await c.req.text();\n const payload = parseSlackPayload(rawBody);\n if (!payload) {\n return c.json({ error: \"invalid_json\" }, 400);\n }\n const resolvedSlackApp = resolveSlackApp({\n rawBody,\n signature,\n timestamp,\n ...(payload.api_app_id ? { apiAppId: payload.api_app_id } : {})\n });\n if (\"error\" in resolvedSlackApp) {\n return c.json({ error: resolvedSlackApp.error }, 401);\n }\n const result = await processor.process(payload, resolvedSlackApp.slackApp);\n if (result.kind === \"text\") {\n return c.text(result.body, result.status);\n }\n return c.json(result.body, result.status);\n });\n\n return app;\n}\n\nexport function startSlackIngress(config: SlackEventsApiIngressConfig): SlackIngressHandle {\n const port = config.port ?? 3040;\n const server = serve({\n fetch: createSlackEventsApp({\n slackApps: [\n {\n signingSecret: config.signingSecret,\n agentId: config.agentId ?? \"opentag\",\n ...(config.appId ? { appId: config.appId } : {}),\n ...(config.callbackUri ? { callbackUri: config.callbackUri } : {})\n }\n ],\n ...createSlackDispatcherEventProcessorInput(config)\n }).fetch,\n port\n });\n\n return {\n url: `http://localhost:${port}`,\n server,\n close() {\n return new Promise((resolve, reject) => {\n server.close((error?: Error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { createOpenTagClient } from \"@opentag/client\";\nimport type { SlackEventProcessorInput } from \"./events.js\";\n\nexport type SlackDispatcherEventConfig = {\n dispatcherUrl: string;\n dispatcherToken?: string;\n};\n\nexport function createSlackDispatcherEventProcessorInput(config: SlackDispatcherEventConfig): SlackEventProcessorInput {\n const dispatcherClient = createOpenTagClient({\n dispatcherUrl: config.dispatcherUrl,\n ...(config.dispatcherToken ? { pairingToken: config.dispatcherToken } : {})\n });\n\n return {\n async resolveChannelBinding(input) {\n try {\n const { binding } = await dispatcherClient.getChannelBinding({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId\n });\n return {\n teamId: binding.accountId,\n channelId: binding.conversationId,\n repoProvider: binding.repoProvider,\n owner: binding.owner,\n repo: binding.repo\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"channel_binding_not_found\")) {\n return null;\n }\n throw error;\n }\n },\n async createRun(event) {\n const runId = `run_${randomUUID()}`;\n const created = await dispatcherClient.createRun({ runId, event });\n return created.outcome === \"run_created\" ? { runId: created.run.id } : { runId };\n },\n async submitThreadAction(action) {\n await dispatcherClient.submitThreadAction(action);\n },\n now: () => new Date().toISOString()\n };\n}\n","import { suggestedActionCandidatesFromResult, type OpenTagRunResult } from \"@opentag/core\";\n\nexport type SlackTextBlock = {\n type: \"section\";\n text: {\n type: \"mrkdwn\";\n text: string;\n };\n};\n\nexport type SlackDividerBlock = {\n type: \"divider\";\n};\n\nexport type SlackBlock = SlackTextBlock | SlackDividerBlock;\n\nexport type SlackMessagePayload = {\n channel: string;\n text: string;\n thread_ts?: string;\n ts?: string;\n blocks?: SlackBlock[];\n};\n\nfunction escapeSlackText(text: string): string {\n return text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nexport function markdownToSlackMrkdwn(text: string): string {\n const links: string[] = [];\n const withoutLinks = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_match, label: string, url: string) => {\n const token = `\\u0000SLACK_LINK_${links.length}\\u0000`;\n links.push(`<${url}|${escapeSlackText(label)}>`);\n return token;\n });\n const converted = escapeSlackText(withoutLinks)\n .replace(/\\*\\*(.+?)\\*\\*/g, \"*$1*\")\n .replace(/__(.+?)__/g, \"*$1*\");\n return links.reduce((output, link, index) => output.replace(`\\u0000SLACK_LINK_${index}\\u0000`, link), converted);\n}\n\nexport function renderSlackAcknowledgement(runId: string): string {\n return `I picked this up: \\`${runId}\\``;\n}\n\nfunction nextActionSummary(result: OpenTagRunResult): string | undefined {\n if (!result.nextAction) return undefined;\n if (typeof result.nextAction === \"string\") return result.nextAction;\n return result.nextAction.summary;\n}\n\nfunction stringParam(params: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = params?.[key];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction stringArrayParam(params: Record<string, unknown> | undefined, key: string): string[] {\n const value = params?.[key];\n if (!Array.isArray(value)) return [];\n return value.filter((item): item is string => typeof item === \"string\" && item.length > 0);\n}\n\nfunction renderVerificationParams(params: Record<string, unknown> | undefined): string[] {\n const value = params?.[\"verification\"];\n if (!Array.isArray(value)) return [];\n return value\n .map((item) => {\n if (!item || typeof item !== \"object\" || Array.isArray(item)) return undefined;\n const command = (item as Record<string, unknown>)[\"command\"];\n const outcome = (item as Record<string, unknown>)[\"outcome\"];\n return typeof command === \"string\" && typeof outcome === \"string\" ? ` - \\`${command}\\`: ${outcome}` : undefined;\n })\n .filter((line): line is string => Boolean(line));\n}\n\nfunction renderSuggestedActionDetails(params: Record<string, unknown> | undefined, action: string): string[] {\n if (action !== \"create_pull_request\") return [];\n const lines: string[] = [];\n const title = stringParam(params, \"title\");\n const head = stringParam(params, \"head\") ?? stringParam(params, \"branch\");\n const base = stringParam(params, \"base\") ?? stringParam(params, \"baseBranch\");\n const changedFiles = stringArrayParam(params, \"changedFiles\");\n const risks = stringArrayParam(params, \"risks\");\n const verification = renderVerificationParams(params);\n if (title) lines.push(` Title: ${markdownToSlackMrkdwn(title)}`);\n if (head || base) lines.push(` Branch: \\`${head ?? \"unknown\"}\\` -> \\`${base ?? \"main\"}\\``);\n if (changedFiles.length > 0) lines.push(` Changed files: ${changedFiles.map((file) => `\\`${file}\\``).join(\", \")}`);\n if (risks.length > 0) {\n lines.push(\" Risks:\");\n for (const risk of risks) {\n lines.push(` - ${markdownToSlackMrkdwn(risk)}`);\n }\n }\n if (verification.length > 0) {\n lines.push(\" Verification:\");\n lines.push(...verification);\n }\n return lines;\n}\n\nfunction renderSuggestedActionsMarkdown(result: OpenTagRunResult): string[] {\n const candidates = suggestedActionCandidatesFromResult(result);\n if (candidates.length === 0) return [];\n\n const lines = [\"*Suggested actions*\"];\n for (const candidate of candidates) {\n lines.push(\n \"\",\n `${candidate.index}. *${markdownToSlackMrkdwn(candidate.intent.summary)}*`,\n ` Intent: \\`${candidate.intent.action}\\` (\\`${candidate.intent.domain}\\`)`,\n ` Proposal: \\`${candidate.proposalId}\\``,\n ` Intent ID: \\`${candidate.intent.intentId}\\``\n );\n lines.push(...renderSuggestedActionDetails(candidate.intent.params, candidate.intent.action));\n if (candidate.proposalPreconditions?.length) {\n lines.push(\" Preconditions:\");\n for (const precondition of candidate.proposalPreconditions) {\n lines.push(` - ${markdownToSlackMrkdwn(precondition)}`);\n }\n }\n }\n\n lines.push(\n \"\",\n \"Reply with:\",\n \"- `approve 1` to record approval\",\n \"- `apply 1` or `apply all` to apply supported actions\",\n \"- `continue 1` to continue with a follow-up run\",\n \"- `reject 1` to reject an action\"\n );\n return lines;\n}\n\nexport function renderSlackFinalResult(result: OpenTagRunResult): string {\n const lines = [`Finished with *${result.conclusion}*.`, \"\", markdownToSlackMrkdwn(result.summary)];\n\n if (result.verification?.length) {\n lines.push(\"\", \"*Verification*\");\n for (const check of result.verification) {\n lines.push(`- \\`${check.command}\\`: ${check.outcome}`);\n }\n }\n\n const nextAction = nextActionSummary(result);\n if (nextAction) {\n lines.push(\"\", `*Next action*: ${markdownToSlackMrkdwn(nextAction)}`);\n }\n\n const suggestedActions = renderSuggestedActionsMarkdown(result);\n if (suggestedActions.length > 0) {\n lines.push(\"\", ...suggestedActions);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function createSlackFinalResultBlocks(result: OpenTagRunResult): SlackBlock[] {\n const blocks: SlackBlock[] = [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*Finished with ${result.conclusion}.*\\n${markdownToSlackMrkdwn(result.summary)}`\n }\n }\n ];\n\n if (result.verification?.length) {\n blocks.push({ type: \"divider\" });\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: markdownToSlackMrkdwn([\"*Verification*\", ...result.verification.map((check) => `- \\`${check.command}\\`: ${check.outcome}`)].join(\"\\n\"))\n }\n });\n }\n\n const nextAction = nextActionSummary(result);\n if (nextAction) {\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*Next action*: ${markdownToSlackMrkdwn(nextAction)}`\n }\n });\n }\n\n const suggestedActions = renderSuggestedActionsMarkdown(result);\n if (suggestedActions.length > 0) {\n blocks.push({ type: \"divider\" });\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: suggestedActions.join(\"\\n\")\n }\n });\n }\n\n return blocks;\n}\n\nexport function createSlackPostMessagePayload(input: { channelId: string; text: string; threadTs: string; blocks?: SlackBlock[] }): SlackMessagePayload {\n return {\n channel: input.channelId,\n text: markdownToSlackMrkdwn(input.text),\n thread_ts: input.threadTs,\n ...(input.blocks?.length ? { blocks: input.blocks } : {})\n };\n}\n\nexport function createSlackUpdateMessagePayload(input: { channelId: string; text: string; messageTs: string; blocks?: SlackBlock[] }): SlackMessagePayload {\n return {\n channel: input.channelId,\n text: markdownToSlackMrkdwn(input.text),\n ts: input.messageTs,\n ...(input.blocks?.length ? { blocks: input.blocks } : {})\n };\n}\n","import WebSocket, { type RawData } from \"ws\";\nimport { createSlackDispatcherEventProcessorInput, type SlackDispatcherEventConfig } from \"./dispatcher-events.js\";\nimport { createSlackEventProcessor, type SlackAppRuntimeConfig, type SlackEventEnvelope, type SlackEventProcessorInput } from \"./events.js\";\n\nconst SLACK_CONNECTIONS_OPEN_URL = \"https://slack.com/api/apps.connections.open\";\nconst DEFAULT_RECONNECT_DELAY_MS = 1_000;\n\nexport type SlackSocketModeEnvelope = {\n type?: string;\n envelope_id?: string;\n payload?: SlackEventEnvelope;\n accepts_response_payload?: boolean;\n};\n\nexport type SlackSocketModeAppInput = {\n appToken: string;\n slackApp: SlackAppRuntimeConfig;\n} & SlackEventProcessorInput;\n\nexport type SlackSocketModeIngressConfig = SlackDispatcherEventConfig & {\n appToken: string;\n agentId?: string;\n appId?: string;\n callbackUri?: string;\n};\n\nexport type SlackSocketModeIngressHandle = {\n startPromise: Promise<void>;\n close(): Promise<void>;\n};\n\nexport type SlackSocketModeDependencies = {\n fetchImpl?: typeof fetch;\n createWebSocket?(url: string): WebSocket;\n reconnectDelayMs?: number;\n log?(message: string): void;\n logError?(message: string, error?: unknown): void;\n};\n\ntype SlackConnectionsOpenResponse = {\n ok?: boolean;\n url?: string;\n error?: string;\n needed?: string;\n provided?: string;\n};\n\nfunction rawDataToString(data: RawData): string {\n if (typeof data === \"string\") return data;\n if (Buffer.isBuffer(data)) return data.toString(\"utf8\");\n if (Array.isArray(data)) return Buffer.concat(data).toString(\"utf8\");\n if (data instanceof ArrayBuffer) return Buffer.from(data).toString(\"utf8\");\n return Buffer.from(data).toString(\"utf8\");\n}\n\nasync function openSlackSocketUrl(input: { appToken: string; fetchImpl: typeof fetch }): Promise<string> {\n const response = await input.fetchImpl(SLACK_CONNECTIONS_OPEN_URL, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${input.appToken}`\n }\n });\n const body = (await response.json().catch(() => ({}))) as SlackConnectionsOpenResponse;\n if (!response.ok || !body.ok || !body.url) {\n const reason = body.error ?? `http_${response.status}`;\n throw new Error(`Slack Socket Mode connection failed: ${reason}`);\n }\n return body.url;\n}\n\nfunction parseSocketEnvelope(data: RawData): SlackSocketModeEnvelope | null {\n try {\n return JSON.parse(rawDataToString(data)) as SlackSocketModeEnvelope;\n } catch {\n return null;\n }\n}\n\nasync function handleSocketMessage(input: {\n data: RawData;\n socket: WebSocket;\n processor: ReturnType<typeof createSlackEventProcessor>;\n slackApp: SlackAppRuntimeConfig;\n logError(message: string, error?: unknown): void;\n}): Promise<void> {\n const envelope = parseSocketEnvelope(input.data);\n if (!envelope?.envelope_id) {\n input.logError(\"[slack] ignored Socket Mode envelope without envelope_id\");\n return;\n }\n\n input.socket.send(JSON.stringify({ envelope_id: envelope.envelope_id }));\n\n if (envelope.type !== \"events_api\" || !envelope.payload) {\n return;\n }\n if (input.slackApp.appId && envelope.payload.api_app_id && envelope.payload.api_app_id !== input.slackApp.appId) {\n return;\n }\n\n await input.processor.process(envelope.payload, input.slackApp);\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function startSlackSocketModeApp(\n input: SlackSocketModeAppInput,\n dependencies: SlackSocketModeDependencies = {}\n): SlackSocketModeIngressHandle {\n const fetchImpl = dependencies.fetchImpl ?? fetch;\n const createWebSocket = dependencies.createWebSocket ?? ((url: string) => new WebSocket(url));\n const reconnectDelayMs = dependencies.reconnectDelayMs ?? DEFAULT_RECONNECT_DELAY_MS;\n const log = dependencies.log ?? ((message: string) => console.log(message));\n const logError = dependencies.logError ?? ((message: string, error?: unknown) => (error ? console.error(message, error) : console.error(message)));\n const processor = createSlackEventProcessor(input);\n let closed = false;\n let activeSocket: WebSocket | undefined;\n\n async function runOneConnection(socketUrl: string): Promise<void> {\n await new Promise<void>((resolve) => {\n const socket = createWebSocket(socketUrl);\n activeSocket = socket;\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n if (activeSocket === socket) activeSocket = undefined;\n resolve();\n };\n\n socket.once(\"open\", () => {\n log(\"[slack] Socket Mode connected\");\n });\n socket.on(\"message\", (data) => {\n void handleSocketMessage({\n data,\n socket,\n processor,\n slackApp: input.slackApp,\n logError\n }).catch((error: unknown) => {\n logError(\"[slack] failed to handle Socket Mode event:\", error);\n });\n });\n socket.once(\"close\", finish);\n socket.once(\"error\", (error) => {\n if (!closed) {\n logError(\"[slack] Socket Mode connection error:\", error);\n }\n socket.close();\n finish();\n });\n });\n }\n\n const startPromise = (async () => {\n while (!closed) {\n const socketUrl = await openSlackSocketUrl({ appToken: input.appToken, fetchImpl });\n await runOneConnection(socketUrl);\n if (!closed) {\n await wait(reconnectDelayMs);\n }\n }\n })();\n\n return {\n startPromise,\n async close() {\n closed = true;\n activeSocket?.close();\n await startPromise.catch(() => undefined);\n }\n };\n}\n\nexport function startSlackSocketModeIngress(\n config: SlackSocketModeIngressConfig,\n dependencies: SlackSocketModeDependencies = {}\n): SlackSocketModeIngressHandle {\n return startSlackSocketModeApp(\n {\n appToken: config.appToken,\n slackApp: {\n agentId: config.agentId ?? \"opentag\",\n ...(config.appId ? { appId: config.appId } : {}),\n ...(config.callbackUri ? { callbackUri: config.callbackUri } : {})\n },\n ...createSlackDispatcherEventProcessorInput(config)\n },\n dependencies\n );\n}\n"],"mappings":"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","names":["text","text"]}
|
|
1
|
+
{"version":3,"sources":["../src/events.ts","../src/normalize.ts","../src/render.ts","../src/ingress.ts","../src/dispatcher-events.ts","../src/socket-mode.ts"],"sourcesContent":["import {\n createDoctorSummaryPresentation,\n createSourceThreadStatusPresentation,\n parseProjectTargetRef,\n parseThreadActionCommand,\n renderOpenTagPresentationPlainText,\n type OpenTagDoctorSummaryPresentation,\n type OpenTagEvent,\n type OpenTagSourceThreadStatusPresentation\n} from \"@opentag/core\";\nimport { encodeSlackThreadKey, normalizeSlackAppMention, stripSlackAppMention, type SlackChannelBinding } from \"./normalize.js\";\nimport {\n createSlackDoctorSummaryBlocks,\n createSlackSourceThreadStatusBlocks,\n parseSlackSuggestedActionButtonValue,\n type SlackBlock\n} from \"./render.js\";\n\nexport type SlackThreadActionInput = {\n id: string;\n rawText: string;\n actor: {\n provider: \"slack\";\n providerUserId: string;\n handle: string;\n organizationId: string;\n };\n callback: {\n provider: \"slack\";\n uri: string;\n threadKey: string;\n };\n metadata: Record<string, unknown>;\n};\n\nexport type SlackEventEnvelope = {\n token?: string;\n type: \"url_verification\" | \"event_callback\";\n challenge?: string;\n team_id?: string;\n api_app_id?: string;\n event?: {\n type: string;\n user?: string;\n text?: string;\n ts?: string;\n thread_ts?: string;\n channel?: string;\n subtype?: string;\n bot_id?: string;\n };\n event_id?: string;\n event_time?: number;\n authorizations?: Array<{ user_id?: string }>;\n};\n\nexport type SlackInteractiveBlockAction = {\n type?: string;\n action_id?: string;\n block_id?: string;\n value?: string;\n action_ts?: string;\n};\n\nexport type SlackInteractivePayload = {\n type: \"block_actions\";\n api_app_id?: string;\n team?: { id?: string; domain?: string };\n user?: { id?: string; username?: string; name?: string };\n channel?: { id?: string; name?: string };\n message?: { ts?: string; thread_ts?: string };\n container?: { type?: string; channel_id?: string; message_ts?: string; thread_ts?: string };\n trigger_id?: string;\n actions?: SlackInteractiveBlockAction[];\n};\n\nexport type SlackIngressPayload = SlackEventEnvelope | SlackInteractivePayload;\n\nexport type SlackIngressVerification = {\n signatureVerified?: boolean;\n};\n\nexport type SlackAppRuntimeConfig = {\n agentId: string;\n appId?: string;\n callbackUri?: string;\n};\n\nexport type SlackSelfServiceReply = {\n text: string;\n blocks?: SlackBlock[];\n};\n\nexport type SlackSelfServiceContext = {\n teamId: string;\n channelId: string;\n threadTs: string;\n userId: string;\n binding: SlackChannelBinding | null;\n};\n\nexport type SlackBindingManagementContext = {\n action: \"bind\" | \"unbind\";\n teamId: string;\n channelId: string;\n threadTs: string;\n userId: string;\n eventId: string;\n appId?: string;\n};\n\nexport type SlackStopRunResult =\n | { outcome: \"cancelled\"; runId: string }\n | { outcome: \"already_terminal\"; runId: string }\n | { outcome: \"not_found\"; runId?: string };\n\nexport type SlackEventProcessorInput = {\n resolveChannelBinding(input: { teamId: string; channelId: string }): Promise<SlackChannelBinding | null>;\n createRun(event: OpenTagEvent): Promise<{ runId: string }>;\n submitThreadAction?(action: SlackThreadActionInput): Promise<unknown>;\n bindChannel?(input: { teamId: string; channelId: string; repoProvider: string; owner: string; repo: string }): Promise<void>;\n unbindChannel?(input: { teamId: string; channelId: string }): Promise<void>;\n reply?(input: { channelId: string; threadTs: string; text: string; blocks?: SlackBlock[] }): Promise<void>;\n status?(input: SlackSelfServiceContext): Promise<SlackSelfServiceReply | string>;\n doctor?(input: SlackSelfServiceContext): Promise<SlackSelfServiceReply | string>;\n stopRun?(input: { teamId: string; channelId: string; runId?: string; requestedBy: string }): Promise<SlackStopRunResult>;\n canManageBinding?(input: SlackBindingManagementContext): Promise<boolean> | boolean;\n now(): string;\n};\n\nexport type SlackEventProcessorStatus = 200 | 400;\n\nexport type SlackEventProcessorResult =\n | {\n kind: \"json\";\n status: SlackEventProcessorStatus;\n body: Record<string, unknown>;\n }\n | {\n kind: \"text\";\n status: SlackEventProcessorStatus;\n body: string;\n };\n\nfunction json(body: Record<string, unknown>, status: SlackEventProcessorStatus = 200): SlackEventProcessorResult {\n return { kind: \"json\", status, body };\n}\n\nfunction text(body: string, status: SlackEventProcessorStatus = 200): SlackEventProcessorResult {\n return { kind: \"text\", status, body };\n}\n\nconst HELP_TEXT = [\n \"OpenTag commands:\",\n \"- @mention the app with `/bind <owner>/<repo>` or `/bind <provider>:<owner>/<repo>` to connect this Slack channel to a Project Target.\",\n \"- @mention the app with `/status` to see the Project Target, active run, queued follow-ups, and next safe action.\",\n \"- @mention the app with `/doctor` to see a redacted readiness summary for this Slack channel.\",\n \"- @mention the app with `/stop [run_id]` to request cancellation for the active channel run or a specific run; OpenTag will not treat stop as successful completion.\",\n \"- @mention the app with `/unbind confirm` to disconnect this Slack channel from its Project Target; this does not delete local checkout config.\",\n \"- Reply in a source thread with `apply 1`, `approve 1`, `reject 1`, or `continue 1` when OpenTag posts source-thread actions.\",\n \"Project Targets never use absolute local paths. Keep local checkout paths in runner config and allowlists.\"\n].join(\"\\n\");\nconst BIND_USAGE =\n \"Usage: @mention the app with `/bind <owner>/<repo>` — e.g. `/bind amplifthq/opentag` or `/bind github:amplifthq/opentag`. Project Targets never use absolute local paths.\";\nconst UNBIND_USAGE =\n \"Usage: @mention the app with `/unbind confirm` to disconnect this Slack channel from its Project Target. This does not remove local checkout config, repository bindings, or allowlists.\";\nconst UNBOUND_HINT =\n \"This Slack channel is not connected to a Project Target. @mention the app with `/bind <owner>/<repo>` before starting runs, or update local OpenTag channel bindings.\";\nconst STOP_UNAVAILABLE_TEXT = [\n \"Run cancellation from this Slack ingress is not configured.\",\n \"OpenTag will not treat a stop request as a successful completion. Use `opentag status --run <run_id>` for audit detail, or `opentag service stop` if you need to stop the local background service.\"\n].join(\"\\n\");\nconst BINDING_AUTH_DENIED_TEXT =\n \"Only an authorized Slack binding manager can change this channel's Project Target. Ask an admin to run the command or update local OpenTag channel bindings.\";\n\nfunction normalizeSelfServiceReply(reply: SlackSelfServiceReply | string): SlackSelfServiceReply {\n return typeof reply === \"string\" ? { text: reply } : reply;\n}\n\nfunction parseSelfServiceCommand(command: string | null): \"help\" | \"status\" | \"doctor\" | null {\n const trimmed = command?.trim();\n if (!trimmed) return null;\n if (/^\\/help(\\s|$)/.test(trimmed)) return \"help\";\n if (/^\\/status(\\s|$)/.test(trimmed)) return \"status\";\n if (/^\\/doctor(\\s|$)/.test(trimmed)) return \"doctor\";\n return null;\n}\n\nfunction parseStopCommand(command: string | null): { runId?: string } | null {\n const match = command?.trim().match(/^\\/stop(?:\\s+(\\S+))?\\s*$/);\n if (!match) return null;\n return match[1] ? { runId: match[1] } : {};\n}\n\nfunction parseBindCommand(\n command: string | null\n): { ok: true; repoProvider: string; owner: string; repo: string } | { ok: false } | null {\n const trimmed = command?.trim();\n if (!trimmed || !/^\\/bind(\\s|$)/.test(trimmed)) return null;\n const match = trimmed.match(/^\\/bind\\s+(\\S+)\\s*$/);\n if (!match) return { ok: false };\n try {\n const ref = parseProjectTargetRef(match[1] as string);\n return { ok: true, repoProvider: ref.provider, owner: ref.owner, repo: ref.repo };\n } catch {\n return { ok: false };\n }\n}\n\nfunction parseUnbindCommand(command: string | null): { ok: true } | { ok: false } | null {\n const trimmed = command?.trim();\n if (!trimmed || !/^\\/unbind(\\s|$)/.test(trimmed)) return null;\n return /^\\/unbind\\s+confirm\\s*$/.test(trimmed) ? { ok: true } : { ok: false };\n}\n\nasync function canManageSlackBinding(\n input: SlackEventProcessorInput,\n context: SlackBindingManagementContext\n): Promise<boolean> {\n if (input.canManageBinding) return input.canManageBinding(context);\n return false;\n}\n\nfunction formatStopResultText(result: SlackStopRunResult): string {\n if (result.outcome === \"cancelled\") {\n return [\n `Cancellation requested for run ${result.runId}.`,\n \"- OpenTag will not treat this stop request as a successful completion.\",\n \"- The local executor may need a moment to observe the cancellation; further nonessential completion writes are suppressed.\"\n ].join(\"\\n\");\n }\n if (result.outcome === \"already_terminal\") {\n return `Run ${result.runId} is already finished. OpenTag will not change its final result.`;\n }\n return result.runId\n ? `Run ${result.runId} was not found or is no longer cancelable.`\n : \"No active run was found for this Slack channel and Project Target.\";\n}\n\nfunction formatProjectTarget(binding: SlackChannelBinding): string {\n return `${binding.repoProvider ?? \"github\"}:${binding.owner}/${binding.repo}`;\n}\n\nfunction statusPresentation(input: SlackSelfServiceContext): OpenTagSourceThreadStatusPresentation {\n if (!input.binding) {\n return createSourceThreadStatusPresentation({\n title: \"OpenTag status:\",\n sourceContainer: `slack:${input.teamId}/${input.channelId}`,\n bindingState: \"unbound\",\n nextAction: \"bind this Slack channel to a Project Target before starting runs.\",\n detailHint: \"active run and queued follow-up status are unavailable until this channel is bound.\"\n });\n }\n return createSourceThreadStatusPresentation({\n title: \"OpenTag status:\",\n sourceContainer: `slack:${input.teamId}/${input.channelId}`,\n projectTarget: formatProjectTarget(input.binding),\n bindingState: \"bound\",\n nextAction: \"mention the app with a task, send a follow-up in the source thread, or use `opentag status --run <run_id>` locally.\",\n stopHint: \"cancellation is explicit and is not reported as successful completion; timeout policy is recorded in audit/status.\",\n detailHint: \"at most one run is active per Project Target + source thread; same-thread requests queue behind it.\"\n });\n}\n\nfunction statusReply(input: SlackSelfServiceContext): SlackSelfServiceReply {\n const presentation = statusPresentation(input);\n return {\n text: renderOpenTagPresentationPlainText(presentation),\n blocks: createSlackSourceThreadStatusBlocks(presentation)\n };\n}\n\nfunction doctorPresentation(input: SlackSelfServiceContext): OpenTagDoctorSummaryPresentation {\n return createDoctorSummaryPresentation({\n title: \"OpenTag doctor (redacted):\",\n checks: [\n { status: \"ok\", name: \"Source container\", message: `slack:${input.teamId}/${input.channelId}` },\n {\n status: input.binding ? \"ok\" : \"warn\",\n name: \"Project Target\",\n message: input.binding ? formatProjectTarget(input.binding) : \"not bound\"\n },\n { status: \"ok\", name: \"Secrets\", message: \"redacted. Use env/file/keychain SecretRef config and never paste tokens into Slack.\" },\n {\n status: \"warn\",\n name: \"Runtime readiness\",\n message: \"check `opentag service status` locally; launchd running is not the same as connector ready.\"\n },\n { status: \"ok\", name: \"Source-thread output\", message: \"concise final replies by default; detailed process stays in audit/status.\" }\n ]\n });\n}\n\nfunction doctorReply(input: SlackSelfServiceContext): SlackSelfServiceReply {\n const presentation = doctorPresentation(input);\n return {\n text: renderOpenTagPresentationPlainText(presentation),\n blocks: createSlackDoctorSummaryBlocks(presentation)\n };\n}\n\nexport function createSlackEventProcessor(input: SlackEventProcessorInput) {\n async function processBlockActions(payload: SlackInteractivePayload, slackApp: SlackAppRuntimeConfig): Promise<SlackEventProcessorResult> {\n const action = payload.actions?.find((candidate) => {\n if (candidate.action_id?.startsWith(\"opentag:\")) return true;\n return typeof candidate.value === \"string\" && parseSlackSuggestedActionButtonValue(candidate.value) !== null;\n });\n if (!action) {\n return json({ ok: true });\n }\n\n const parsedValue = typeof action.value === \"string\" ? parseSlackSuggestedActionButtonValue(action.value) : null;\n const rawText =\n parsedValue?.command ??\n (typeof action.value === \"string\" && parseThreadActionCommand(action.value) ? action.value.trim() : undefined);\n if (!rawText || !parseThreadActionCommand(rawText)) {\n return json({ error: \"invalid_interactive_action\" }, 400);\n }\n if (!input.submitThreadAction) {\n return json({ ok: true });\n }\n\n const teamId = payload.team?.id;\n const userId = payload.user?.id;\n const channelId = payload.channel?.id ?? payload.container?.channel_id;\n const messageTs = payload.message?.ts ?? payload.container?.message_ts;\n const threadTs = payload.message?.thread_ts ?? payload.container?.thread_ts ?? messageTs;\n if (!teamId || !userId || !channelId || !messageTs || !threadTs) {\n return json({ error: \"invalid_interactive_payload\" }, 400);\n }\n\n const binding = await input.resolveChannelBinding({\n teamId,\n channelId\n });\n if (!binding) {\n return json({ ok: true, ignored: \"unbound_channel\" });\n }\n\n await input.submitThreadAction({\n id: `approval_slack_block_${payload.trigger_id ?? `${action.action_id ?? \"action\"}_${action.action_ts ?? messageTs}`}`,\n rawText,\n actor: {\n provider: \"slack\",\n providerUserId: userId,\n handle: payload.user?.username ?? payload.user?.name ?? userId,\n organizationId: teamId\n },\n callback: {\n provider: \"slack\",\n uri: slackApp.callbackUri ?? \"https://slack.com/api/chat.postMessage\",\n threadKey: encodeSlackThreadKey({\n teamId,\n channelId,\n threadTs\n })\n },\n metadata: {\n source: \"slack_button\",\n teamId,\n channelId,\n messageTs,\n ...(payload.api_app_id ? { slackAppId: payload.api_app_id } : {}),\n ...(action.action_id ? { actionId: action.action_id } : {}),\n ...(action.block_id ? { blockId: action.block_id } : {}),\n ...(action.action_ts ? { actionTs: action.action_ts } : {}),\n ...(parsedValue ? { proposalId: parsedValue.proposalId, intentId: parsedValue.intentId } : {}),\n repoProvider: binding.repoProvider ?? \"github\",\n owner: binding.owner,\n repo: binding.repo\n }\n });\n return json({ ok: true });\n }\n\n return {\n async process(\n payload: SlackIngressPayload,\n slackApp: SlackAppRuntimeConfig,\n verification: SlackIngressVerification = {}\n ): Promise<SlackEventProcessorResult> {\n if (payload.type === \"block_actions\") {\n return processBlockActions(payload, slackApp);\n }\n if (payload.type === \"url_verification\") {\n return text(payload.challenge ?? \"\");\n }\n if (payload.type !== \"event_callback\" || !payload.event || ![\"app_mention\", \"message\"].includes(payload.event.type)) {\n return json({ ok: true });\n }\n if (payload.event.type === \"message\" && (payload.event.subtype || payload.event.bot_id)) {\n return json({ ok: true });\n }\n if (!payload.team_id || !payload.event.channel || !payload.event.user || !payload.event.text || !payload.event.ts || !payload.event_id) {\n return json({ error: \"invalid_event_payload\" }, 400);\n }\n\n const rawThreadActionText =\n payload.event.type === \"app_mention\"\n ? stripSlackAppMention(payload.event.text, payload.authorizations?.[0]?.user_id)\n : payload.event.text.trim();\n const bindRequest = payload.event.type === \"app_mention\" ? parseBindCommand(rawThreadActionText) : null;\n if (bindRequest) {\n const threadTs = payload.event.thread_ts ?? payload.event.ts;\n if (!input.reply) {\n return json({ ok: true, ignored: \"self_service_reply_unavailable\", command: \"bind\" });\n }\n if (!input.bindChannel) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: \"Slack channel binding from source threads is not configured. Re-run `opentag setup` or update local OpenTag channel bindings.\"\n });\n return json({ ok: true, selfService: \"bind\", unavailable: true });\n }\n if (!bindRequest.ok) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: BIND_USAGE\n });\n return json({ ok: true, selfService: \"bind\", usage: true });\n }\n const authorized = await canManageSlackBinding(input, {\n action: \"bind\",\n teamId: payload.team_id,\n channelId: payload.event.channel,\n threadTs,\n userId: payload.event.user,\n eventId: payload.event_id,\n ...(payload.api_app_id ? { appId: payload.api_app_id } : {})\n });\n if (!authorized) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: BINDING_AUTH_DENIED_TEXT\n });\n return json({ ok: true, selfService: \"bind\", unauthorized: true });\n }\n await input.bindChannel({\n teamId: payload.team_id,\n channelId: payload.event.channel,\n repoProvider: bindRequest.repoProvider,\n owner: bindRequest.owner,\n repo: bindRequest.repo\n });\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: `Connected this Slack channel to Project Target ${bindRequest.repoProvider}:${bindRequest.owner}/${bindRequest.repo}. @mention the app with a task to start a run.`\n });\n return json({ ok: true, selfService: \"bind\" });\n }\n const unbindRequest = payload.event.type === \"app_mention\" ? parseUnbindCommand(rawThreadActionText) : null;\n if (unbindRequest) {\n const threadTs = payload.event.thread_ts ?? payload.event.ts;\n if (!input.reply) {\n return json({ ok: true, ignored: \"self_service_reply_unavailable\", command: \"unbind\" });\n }\n if (!input.unbindChannel) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: \"Slack channel unbinding is not enabled in this build. Re-run `opentag setup` or update local OpenTag channel bindings.\"\n });\n return json({ ok: true, selfService: \"unbind\", unavailable: true });\n }\n if (!unbindRequest.ok) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: UNBIND_USAGE\n });\n return json({ ok: true, selfService: \"unbind\", usage: true });\n }\n const authorized = await canManageSlackBinding(input, {\n action: \"unbind\",\n teamId: payload.team_id,\n channelId: payload.event.channel,\n threadTs,\n userId: payload.event.user,\n eventId: payload.event_id,\n ...(payload.api_app_id ? { appId: payload.api_app_id } : {})\n });\n if (!authorized) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: BINDING_AUTH_DENIED_TEXT\n });\n return json({ ok: true, selfService: \"unbind\", unauthorized: true });\n }\n const binding = await input.resolveChannelBinding({\n teamId: payload.team_id,\n channelId: payload.event.channel\n });\n if (!binding) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: UNBOUND_HINT\n });\n return json({ ok: true, selfService: \"unbind\", ignored: \"unbound_channel\" });\n }\n await input.unbindChannel({\n teamId: payload.team_id,\n channelId: payload.event.channel\n });\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: `Disconnected this Slack channel from Project Target ${formatProjectTarget(binding)}. Re-run \\`opentag setup\\` or update local OpenTag channel bindings to connect a new target.`\n });\n return json({ ok: true, selfService: \"unbind\" });\n }\n const stopRequest = payload.event.type === \"app_mention\" ? parseStopCommand(rawThreadActionText) : null;\n if (stopRequest) {\n const threadTs = payload.event.thread_ts ?? payload.event.ts;\n if (!input.stopRun) {\n if (input.reply) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: STOP_UNAVAILABLE_TEXT\n });\n }\n return json({ ok: true, selfService: \"stop\", unavailable: true });\n }\n const result = await input.stopRun({\n teamId: payload.team_id,\n channelId: payload.event.channel,\n ...(stopRequest.runId ? { runId: stopRequest.runId } : {}),\n requestedBy: `slack:${payload.event.user}`\n });\n if (input.reply) {\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: formatStopResultText(result)\n });\n }\n return json({ ok: true, selfService: \"stop\", outcome: result.outcome, ...(result.runId ? { runId: result.runId } : {}) });\n }\n const selfServiceCommand = payload.event.type === \"app_mention\" ? parseSelfServiceCommand(rawThreadActionText) : null;\n if (selfServiceCommand) {\n const binding =\n selfServiceCommand === \"help\"\n ? null\n : await input.resolveChannelBinding({\n teamId: payload.team_id,\n channelId: payload.event.channel\n });\n const threadTs = payload.event.thread_ts ?? payload.event.ts;\n if (!input.reply) {\n return json({ ok: true, ignored: \"self_service_reply_unavailable\", command: selfServiceCommand });\n }\n const context: SlackSelfServiceContext = {\n teamId: payload.team_id,\n channelId: payload.event.channel,\n threadTs,\n userId: payload.event.user,\n binding\n };\n const reply =\n selfServiceCommand === \"help\"\n ? { text: HELP_TEXT }\n : normalizeSelfServiceReply(\n selfServiceCommand === \"status\"\n ? input.status\n ? await input.status(context)\n : statusReply(context)\n : input.doctor\n ? await input.doctor(context)\n : doctorReply(context)\n );\n await input.reply({\n channelId: payload.event.channel,\n threadTs,\n text: reply.text,\n ...(reply.blocks?.length ? { blocks: reply.blocks } : {})\n });\n return json({ ok: true, selfService: selfServiceCommand });\n }\n if (payload.event.type === \"message\" && (!rawThreadActionText || !parseThreadActionCommand(rawThreadActionText))) {\n return json({ ok: true });\n }\n\n const binding = await input.resolveChannelBinding({\n teamId: payload.team_id,\n channelId: payload.event.channel\n });\n if (!binding) {\n return json({ ok: true, ignored: \"unbound_channel\" });\n }\n\n if (rawThreadActionText && parseThreadActionCommand(rawThreadActionText) && input.submitThreadAction) {\n await input.submitThreadAction({\n id: `approval_slack_${payload.event_id}`,\n rawText: rawThreadActionText,\n actor: {\n provider: \"slack\",\n providerUserId: payload.event.user,\n handle: payload.event.user,\n organizationId: payload.team_id\n },\n callback: {\n provider: \"slack\",\n uri: slackApp.callbackUri ?? \"https://slack.com/api/chat.postMessage\",\n threadKey: encodeSlackThreadKey({\n teamId: payload.team_id,\n channelId: payload.event.channel,\n threadTs: payload.event.thread_ts ?? payload.event.ts\n })\n },\n metadata: {\n teamId: payload.team_id,\n channelId: payload.event.channel,\n messageTs: payload.event.ts,\n sourceDeliveryId: payload.event_id,\n slackEventId: payload.event_id,\n ...(payload.api_app_id ? { slackAppId: payload.api_app_id } : {}),\n ...(payload.authorizations?.[0]?.user_id ? { slackBotUserId: payload.authorizations[0].user_id } : {}),\n ...(typeof verification.signatureVerified === \"boolean\"\n ? { webhookSignatureVerified: verification.signatureVerified, signatureState: verification.signatureVerified ? \"verified\" : \"unverified\" }\n : {}),\n repoProvider: binding.repoProvider ?? \"github\",\n owner: binding.owner,\n repo: binding.repo\n }\n });\n return json({ ok: true });\n }\n\n if (payload.event.type !== \"app_mention\") {\n return json({ ok: true });\n }\n\n const event = normalizeSlackAppMention({\n teamId: payload.team_id,\n channelId: payload.event.channel,\n userId: payload.event.user,\n text: payload.event.text,\n ts: payload.event.ts,\n eventId: payload.event_id,\n eventTime: payload.event_time ?? Math.floor(Date.parse(input.now()) / 1000),\n agentId: slackApp.agentId,\n binding,\n ...(payload.api_app_id ? { appId: payload.api_app_id } : {}),\n ...(payload.event.thread_ts ? { threadTs: payload.event.thread_ts } : {}),\n ...(payload.authorizations?.[0]?.user_id ? { botUserId: payload.authorizations[0].user_id } : {}),\n ...(slackApp.callbackUri ? { callbackUri: slackApp.callbackUri } : {}),\n ...(typeof verification.signatureVerified === \"boolean\" ? { signatureVerified: verification.signatureVerified } : {})\n });\n if (!event) {\n return json({ ok: true, ignored: \"empty_command\" });\n }\n\n await input.createRun(event);\n return json({ ok: true });\n }\n };\n}\n","import { commandFromRawText, type ContextPointer, type OpenTagCommand, type OpenTagEvent, type PermissionGrant } from \"@opentag/core\";\n\nexport type SlackChannelBinding = {\n teamId: string;\n channelId: string;\n repoProvider?: string;\n owner: string;\n repo: string;\n};\n\nexport type SlackAppMentionInput = {\n teamId: string;\n channelId: string;\n userId: string;\n text: string;\n ts: string;\n threadTs?: string;\n eventId: string;\n eventTime: number;\n appId?: string;\n agentId?: string;\n botUserId?: string;\n callbackUri?: string;\n signatureVerified?: boolean;\n binding: SlackChannelBinding;\n};\n\n// Matches a run of one or more leading user mentions (e.g. a teammate mention\n// placed before the bot mention) along with the whitespace separating them.\nconst LEADING_MENTION_RUN = /^(?:<@[^>]+>\\s*)+/;\n// Matches a single mention token, used to confirm the bot itself appears in the\n// leading run so we only treat the message as an at-mention of the bot.\nconst MENTION_TOKEN = /<@([^>]+)>/g;\n\nexport function stripSlackAppMention(text: string, botUserId?: string): string | null {\n const run = text.match(LEADING_MENTION_RUN);\n if (!run) return null;\n\n // Only strip the *leading* run of mentions; mentions later in the message\n // (e.g. \"<@bot> ping <@teammate> now\") must be preserved as command text.\n const leadingRun = run[0];\n\n if (botUserId) {\n // Require that the bot is mentioned somewhere in the leading run before we\n // accept this as a command directed at the bot. This lets a teammate\n // mention precede the bot mention without breaking routing.\n const mentionedIds = leadingRun.match(MENTION_TOKEN) ?? [];\n const botIsMentioned = mentionedIds.some((token) => {\n // Slack mentions may carry a display-name/label suffix, e.g.\n // \"<@U12345|alice>\". Strip the label so we compare against the bare\n // user ID rather than \"U12345|alice\".\n const id = token.slice(2, -1).split(\"|\")[0] ?? \"\";\n return id.toLowerCase() === botUserId.toLowerCase();\n });\n if (!botIsMentioned) return null;\n }\n\n const stripped = text.slice(leadingRun.length).trim();\n return stripped.length > 0 ? stripped : null;\n}\n\nexport function encodeSlackThreadKey(input: { teamId: string; channelId: string; threadTs: string }): string {\n return `${input.teamId}|${input.channelId}|${input.threadTs}`;\n}\n\nexport function parseSlackThreadKey(threadKey: string): { teamId: string; channelId: string; threadTs: string } {\n const [teamId, channelId, threadTs] = threadKey.split(\"|\");\n if (!teamId || !channelId || !threadTs) {\n throw new Error(`Invalid Slack thread key: ${threadKey}`);\n }\n return { teamId, channelId, threadTs };\n}\n\nconst UNKNOWN_WRITE_VERB_PATTERN = /\\b(add|append|apply|change|commit|create|delete|edit|fix|modify|open\\s+a?\\s*pr|pull\\s+request|remove|update|write)\\b/i;\nconst REPO_WRITE_TARGET_PATTERN =\n /\\b(repo|repository|code|file|files|branch|commit|diff|patch|readme|pr|pull\\s+request|package\\.json|pnpm|npm|test|build)\\b|(?:^|\\s)[./\\w-]+\\.(?:cjs|css|gitignore|go|html|js|json|jsx|lock|md|mjs|py|rb|rs|sh|toml|ts|tsx|txt|yaml|yml)\\b|(?:^|[\\s`'\"(])(?:[./\\w-]+\\/)?(?:Dockerfile|Makefile|Procfile|Rakefile|Gemfile|Brewfile|Justfile|Taskfile|\\.dockerignore|\\.env(?:\\.[\\w-]+)?|\\.gitignore|\\.npmrc)(?=$|[\\s`'\",.):])/i;\n\nfunction commandLooksRepoWriteCapable(command: OpenTagCommand): boolean {\n return UNKNOWN_WRITE_VERB_PATTERN.test(command.rawText) && REPO_WRITE_TARGET_PATTERN.test(command.rawText);\n}\n\nfunction permissionsForCommand(command: OpenTagCommand): PermissionGrant[] {\n const permissions: PermissionGrant[] = [\n {\n scope: \"chat:postMessage\",\n reason: \"reply in the originating Slack thread\"\n },\n {\n scope: \"reactions:write\",\n reason: \"mark the originating Slack message as received without posting a thread reply\"\n },\n {\n scope: \"runner:local\",\n reason: \"execute the run on a paired local daemon\"\n }\n ];\n\n if (command.intent === \"fix\" || command.intent === \"run\" || (command.intent === \"unknown\" && commandLooksRepoWriteCapable(command))) {\n permissions.push(\n {\n scope: \"repo:read\",\n reason: \"inspect the repository in the paired local checkout\"\n },\n {\n scope: \"repo:write\",\n reason: \"commit code changes on an isolated run branch\"\n },\n {\n scope: \"pr:create\",\n reason: \"open a pull request for completed code changes\"\n }\n );\n }\n\n return permissions;\n}\n\nfunction contextPointersForCommand(command: OpenTagCommand): ContextPointer[] {\n const context: ContextPointer[] = [];\n\n for (const reference of command.parsed?.references ?? []) {\n if (reference.kind === \"url\") {\n context.push({\n kind: \"url\",\n uri: reference.uri,\n visibility: \"organization\",\n title: reference.title ?? \"Command URL reference\"\n });\n continue;\n }\n\n if (reference.kind === \"file\" || reference.kind === \"path\") {\n context.push({\n kind: \"file\",\n uri: reference.uri,\n ...(reference.line ? { line: reference.line } : {}),\n ...(reference.startLine ? { startLine: reference.startLine } : {}),\n ...(reference.endLine ? { endLine: reference.endLine } : {}),\n visibility: \"organization\",\n title: referenceTitle(reference)\n });\n }\n }\n\n return context;\n}\n\nfunction referenceTitle(reference: NonNullable<OpenTagCommand[\"parsed\"]>[\"references\"][number]): string {\n return reference.title ?? \"Command file reference\";\n}\n\nfunction commandMetadata(command: OpenTagCommand): Record<string, unknown> {\n if (!command.parsed) return {};\n return {\n commandParser: command.parsed.version,\n commandDiagnostics: command.parsed.diagnostics,\n ...(command.parsed.approval ? { approval: command.parsed.approval } : {}),\n ...(command.parsed.network ? { network: command.parsed.network } : {})\n };\n}\n\nexport function normalizeSlackAppMention(input: SlackAppMentionInput): OpenTagEvent | null {\n const rawText = stripSlackAppMention(input.text, input.botUserId);\n if (!rawText) return null;\n\n const command = commandFromRawText(rawText);\n const replyThreadTs = input.threadTs ?? input.ts;\n const agentId = input.agentId ?? \"opentag\";\n\n return {\n id: `evt_slack_app_mention_${input.eventId}`,\n source: \"slack\",\n sourceEventId: input.eventId,\n receivedAt: new Date(input.eventTime * 1000).toISOString(),\n actor: {\n provider: \"slack\",\n providerUserId: input.userId,\n handle: input.userId,\n organizationId: input.teamId\n },\n target: {\n mention: input.botUserId ? `<@${input.botUserId}>` : \"<@app>\",\n agentId,\n ...(command.parsed?.executorHint ? { executorHint: command.parsed.executorHint } : {})\n },\n command,\n context: [\n {\n provider: \"slack\",\n kind: \"message\",\n uri: `slack://team/${input.teamId}/channel/${input.channelId}/message/${input.ts}`,\n visibility: \"organization\",\n title: \"Slack message\"\n },\n {\n kind: \"text\",\n uri: input.text,\n visibility: \"organization\",\n title: \"Slack message text\"\n },\n ...contextPointersForCommand(command)\n ],\n permissions: permissionsForCommand(command),\n callback: {\n provider: \"slack\",\n uri: input.callbackUri ?? \"https://slack.com/api/chat.postMessage\",\n threadKey: encodeSlackThreadKey({\n teamId: input.teamId,\n channelId: input.channelId,\n threadTs: replyThreadTs\n })\n },\n metadata: {\n teamId: input.teamId,\n channelId: input.channelId,\n messageTs: input.ts,\n sourceDeliveryId: input.eventId,\n slackEventId: input.eventId,\n ...(input.appId ? { slackAppId: input.appId } : {}),\n ...(input.botUserId ? { slackBotUserId: input.botUserId } : {}),\n ...(typeof input.signatureVerified === \"boolean\"\n ? { webhookSignatureVerified: input.signatureVerified, signatureState: input.signatureVerified ? \"verified\" : \"unverified\" }\n : {}),\n ...commandMetadata(command),\n repoProvider: input.binding.repoProvider ?? \"github\",\n owner: input.binding.owner,\n repo: input.binding.repo\n }\n };\n}\n","import {\n type ActionReceiptContext,\n type ActionReceiptDecision,\n type OpenTagActionReceiptPresentation,\n type OpenTagDoctorSummaryPresentation,\n type OpenTagFinalSummaryPresentation,\n type OpenTagPresentationAction,\n type OpenTagSourceThreadStatusPresentation,\n createFinalSummaryPresentation,\n type OpenTagRunResult\n} from \"@opentag/core\";\n\nexport type SlackTextBlock = {\n type: \"section\";\n text: {\n type: \"mrkdwn\";\n text: string;\n };\n};\n\nexport type SlackDividerBlock = {\n type: \"divider\";\n};\n\nexport type SlackContextBlock = {\n type: \"context\";\n elements: Array<{\n type: \"mrkdwn\";\n text: string;\n }>;\n};\n\nexport type SlackButtonElement = {\n type: \"button\";\n text: {\n type: \"plain_text\";\n text: string;\n emoji?: boolean;\n };\n action_id: string;\n value: string;\n style?: \"primary\" | \"danger\";\n};\n\nexport type SlackActionsBlock = {\n type: \"actions\";\n block_id?: string;\n elements: SlackButtonElement[];\n};\n\nexport type SlackBlock = SlackTextBlock | SlackDividerBlock | SlackContextBlock | SlackActionsBlock;\n\nexport type SlackSuggestedActionButtonValue = {\n version: 1;\n command: string;\n proposalId: string;\n intentId: string;\n};\n\nexport type SlackMessagePayload = {\n channel: string;\n text: string;\n thread_ts?: string;\n ts?: string;\n blocks?: SlackBlock[];\n};\n\nexport type SlackReactionPayload = {\n channel: string;\n timestamp: string;\n name: string;\n};\n\nexport type SlackSourceReceiptState = \"received\" | \"running\";\n\nconst MAX_SLACK_SUGGESTED_ACTION_CANDIDATES = 20;\n\nexport type SlackRenderOptions = {\n receiptContext?: ActionReceiptContext;\n auditRunId?: string;\n};\n\nexport function buildSlackSuggestedActionButtonValue(input: SlackSuggestedActionButtonValue): string {\n return JSON.stringify(input);\n}\n\nexport function parseSlackSuggestedActionButtonValue(value: string): SlackSuggestedActionButtonValue | null {\n try {\n const parsed = JSON.parse(value) as Partial<SlackSuggestedActionButtonValue>;\n if (\n parsed.version !== 1 ||\n typeof parsed.command !== \"string\" ||\n parsed.command.trim().length === 0 ||\n typeof parsed.proposalId !== \"string\" ||\n parsed.proposalId.length === 0 ||\n typeof parsed.intentId !== \"string\" ||\n parsed.intentId.length === 0\n ) {\n return null;\n }\n return {\n version: 1,\n command: parsed.command.trim(),\n proposalId: parsed.proposalId,\n intentId: parsed.intentId\n };\n } catch {\n return null;\n }\n}\n\nfunction escapeSlackText(text: string): string {\n return text.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nexport function markdownToSlackMrkdwn(text: string): string {\n const links: string[] = [];\n const withoutLinks = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, (_match, label: string, url: string) => {\n const token = `\\u0000SLACK_LINK_${links.length}\\u0000`;\n links.push(`<${url}|${escapeSlackText(label)}>`);\n return token;\n });\n const converted = escapeSlackText(withoutLinks)\n .replace(/\\*\\*(.+?)\\*\\*/g, \"*$1*\")\n .replace(/__(.+?)__/g, \"*$1*\");\n return links.reduce((output, link, index) => output.replace(`\\u0000SLACK_LINK_${index}\\u0000`, link), converted);\n}\n\nfunction markdownToSlackActionDetail(text: string): string {\n return markdownToSlackMrkdwn(text).replace(/->/g, \"->\");\n}\n\nexport function renderSlackAcknowledgement(runId: string): string {\n void runId;\n return \"Working on it.\";\n}\n\nexport function slackSourceReceiptReactionName(state: SlackSourceReceiptState): string {\n if (state === \"received\") return \"eyes\";\n if (state === \"running\") return \"hourglass_flowing_sand\";\n return \"eyes\";\n}\n\nexport function createSlackReactionPayload(input: { channelId: string; messageTs: string; name: string }): SlackReactionPayload {\n return {\n channel: input.channelId,\n timestamp: input.messageTs,\n name: input.name\n };\n}\n\nfunction truncateSlackText(text: string, maxLength: number): string {\n const normalized = text.replace(/\\s+/g, \" \").trim();\n if (normalized.length <= maxLength) return normalized;\n return `${normalized.slice(0, Math.max(0, maxLength - 1)).trimEnd()}…`;\n}\n\nfunction firstMarkdownSection(text: string, heading: string): string | undefined {\n const pattern = new RegExp(`\\\\*\\\\*${heading}:\\\\*\\\\*\\\\s*([\\\\s\\\\S]*?)(?=\\\\n\\\\s*\\\\n\\\\*\\\\*[^*]+:\\\\*\\\\*|\\\\n\\\\s*\\\\n[A-Z][^\\\\n]{0,60}:|$)`, \"i\");\n const match = text.match(pattern);\n return match?.[1]?.trim();\n}\n\nfunction compactSlackSummary(summary: string): string {\n const whatChanged = firstMarkdownSection(summary, \"What changed\");\n const firstParagraph = summary\n .split(/\\n\\s*\\n/)\n .map((part) => part.trim())\n .find(Boolean);\n const selected = whatChanged ?? firstParagraph ?? summary;\n return truncateSlackText(selected.replace(/^\\*\\*[^*]+:\\*\\*\\s*/i, \"\"), 360);\n}\n\nfunction compactNextAction(nextAction: string): string {\n return truncateSlackText(nextAction, 180);\n}\n\nfunction resultForFinalSummaryPresentation(result: OpenTagRunResult): OpenTagRunResult {\n if (!result.suggestedChanges) return result;\n const visibleSuggestedChanges = result.suggestedChanges.filter((snapshot) => snapshot.intents.length > 0);\n if (visibleSuggestedChanges.length === result.suggestedChanges.length) return result;\n const { suggestedChanges: _suggestedChanges, ...withoutSuggestedChanges } = result;\n return visibleSuggestedChanges.length > 0 ? { ...withoutSuggestedChanges, suggestedChanges: visibleSuggestedChanges } : withoutSuggestedChanges;\n}\n\nfunction slackSection(text: string): SlackTextBlock {\n return {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text\n }\n };\n}\n\nfunction slackContext(text: string): SlackContextBlock {\n return {\n type: \"context\",\n elements: [{ type: \"mrkdwn\", text }]\n };\n}\n\nfunction slackCheckStatusLabel(status: OpenTagDoctorSummaryPresentation[\"checks\"][number][\"status\"]): string {\n if (status === \"ok\") return \"OK\";\n if (status === \"warn\") return \"WARN\";\n if (status === \"fail\") return \"FAIL\";\n return \"UNKNOWN\";\n}\n\nfunction slackStatusActiveRun(presentation: OpenTagSourceThreadStatusPresentation): string {\n if (!presentation.activeRun) return \"none\";\n return `${presentation.activeRun.id} (${presentation.activeRun.status})${presentation.activeRun.updatedAt ? `, updated ${presentation.activeRun.updatedAt}` : \"\"}`;\n}\n\nfunction slackStatusQueuedFollowUps(presentation: OpenTagSourceThreadStatusPresentation): string {\n const total = presentation.queuedFollowUpsTotal ?? presentation.queuedFollowUps.length;\n if (total === 0) return \"none\";\n const visible = presentation.queuedFollowUps.map((followUp) => {\n const status = followUp.status ? ` (${followUp.status})` : \"\";\n const command = followUp.command ? `: ${markdownToSlackMrkdwn(truncateSlackText(followUp.command, 120))}` : \"\";\n return `${followUp.id}${status}${command}`;\n });\n const remaining = Math.max(total - visible.length, 0);\n return `${total}${visible.length ? ` (${visible.join(\", \")}${remaining > 0 ? `, +${remaining} more` : \"\"})` : \"\"}`;\n}\n\nfunction renderPresentationActionLines(action: OpenTagPresentationAction): string[] {\n const lines = [`${action.index}. *${markdownToSlackMrkdwn(action.title)}*`];\n lines.push(`Target: ${markdownToSlackMrkdwn(action.targetLabel)}`);\n if (action.setupReason) {\n lines.push(`Status: ${markdownToSlackMrkdwn(action.setupReason)}`);\n }\n if (action.details?.length) {\n lines.push(...action.details.map(markdownToSlackActionDetail));\n }\n return lines;\n}\n\ntype SlackActionReceiptGroup = {\n state: OpenTagPresentationAction[\"state\"];\n title: string;\n actions: OpenTagPresentationAction[];\n};\n\nconst ACTION_RECEIPT_GROUP_ORDER: Array<OpenTagPresentationAction[\"state\"]> = [\n \"ready_to_apply\",\n \"needs_setup\",\n \"needs_approval\",\n \"unsupported\"\n];\n\nfunction actionReceiptGroupTitle(state: OpenTagPresentationAction[\"state\"]): string {\n if (state === \"ready_to_apply\") return \"Ready to apply\";\n if (state === \"needs_setup\") return \"Needs setup\";\n if (state === \"unsupported\") return \"Needs attention\";\n return \"Needs approval\";\n}\n\nfunction actionReceiptGroups(actions: OpenTagPresentationAction[]): SlackActionReceiptGroup[] {\n return ACTION_RECEIPT_GROUP_ORDER.flatMap((state) => {\n const groupedActions = actions.filter((action) => action.state === state);\n return groupedActions.length > 0\n ? [\n {\n state,\n title: actionReceiptGroupTitle(state),\n actions: groupedActions\n }\n ]\n : [];\n });\n}\n\nfunction renderActionReceiptMarkdownLines(input: { title: string; actions: OpenTagPresentationAction[] }): string[] {\n if (input.actions.length === 0) return [];\n\n const visibleActions = input.actions.slice(0, MAX_SLACK_SUGGESTED_ACTION_CANDIDATES);\n const groups = actionReceiptGroups(visibleActions);\n const showGroupHeadings = groups.length > 1;\n const lines = [`*${input.title}*`, \"\", \"Choose an action in this thread. Details stay in the OpenTag audit log.\"];\n for (const group of groups) {\n if (showGroupHeadings) {\n lines.push(\"\", `*${group.title}*`);\n }\n for (const action of group.actions) {\n lines.push(\"\", ...renderPresentationActionLines(action));\n }\n }\n\n const remainingCount = input.actions.length - visibleActions.length;\n if (remainingCount > 0) {\n lines.push(\"\", `Showing first ${visibleActions.length} of ${input.actions.length} actions. Reply with an action number for the rest.`);\n }\n lines.push(\"\", \"Use the buttons below, or reply with the matching command.\");\n return lines;\n}\n\nfunction renderSuggestedActionsMarkdown(presentation: OpenTagFinalSummaryPresentation): string[] {\n const actions = presentation.actions ?? [];\n if (actions.length === 0 || !presentation.actionReceiptTitle) return [];\n return renderActionReceiptMarkdownLines({ title: presentation.actionReceiptTitle, actions });\n}\n\nfunction createSuggestedActionButton(action: OpenTagPresentationAction & { proposalId: string; intentId: string }, decision: ActionReceiptDecision): SlackButtonElement {\n const index = action.index;\n const labels: Record<ActionReceiptDecision, string> = {\n apply: `Apply ${index}`,\n approve: \"Approve only\",\n continue: \"Continue\",\n reject: \"Reject\"\n };\n return {\n type: \"button\",\n text: { type: \"plain_text\", text: labels[decision], emoji: true },\n action_id: `opentag:${decision}:${index}`,\n value: buildSlackSuggestedActionButtonValue({\n version: 1,\n command: `${decision} ${index}`,\n proposalId: action.proposalId,\n intentId: action.intentId\n }),\n ...(decision === \"apply\" ? { style: \"primary\" as const } : {}),\n ...(decision === \"reject\" ? { style: \"danger\" as const } : {})\n };\n}\n\nfunction actionHasInteractiveIdentity(action: OpenTagPresentationAction): action is OpenTagPresentationAction & { proposalId: string; intentId: string } {\n return Boolean(action.proposalId && action.intentId);\n}\n\nfunction createSuggestedActionButtons(action: OpenTagPresentationAction): SlackButtonElement[] {\n if (!actionHasInteractiveIdentity(action)) return [];\n return action.visibleDecisions.map((decision) => createSuggestedActionButton(action, decision));\n}\n\nfunction createSlackActionReceiptBlockSet(input: {\n title: string;\n actions: OpenTagPresentationAction[];\n auditRunId?: string;\n includeDivider?: boolean;\n}): SlackBlock[] {\n const blocks: SlackBlock[] = [];\n if (input.includeDivider) blocks.push({ type: \"divider\" });\n blocks.push(\n slackSection(`*${markdownToSlackMrkdwn(input.title)}*\\n\\nChoose an action in this thread. Details stay in the OpenTag audit log.`)\n );\n\n const visibleActions = input.actions.slice(0, MAX_SLACK_SUGGESTED_ACTION_CANDIDATES);\n const groups = actionReceiptGroups(visibleActions);\n const showGroupHeadings = groups.length > 1;\n for (const group of groups) {\n if (showGroupHeadings) {\n blocks.push(slackSection(`*${markdownToSlackMrkdwn(group.title)}*`));\n }\n for (const action of group.actions) {\n blocks.push(slackSection(renderPresentationActionLines(action).join(\"\\n\")));\n const buttons = createSuggestedActionButtons(action);\n if (buttons.length === 0) continue;\n blocks.push({\n type: \"actions\",\n block_id: `opentag_actions_${action.index}`,\n elements: buttons\n });\n }\n }\n\n const remainingCount = input.actions.length - visibleActions.length;\n if (remainingCount > 0) {\n blocks.push(slackSection(`Showing first ${visibleActions.length} of ${input.actions.length} actions. Reply with an action number for the rest.`));\n }\n\n if (input.auditRunId) {\n blocks.push(slackContext(markdownToSlackMrkdwn(`Audit: \\`opentag status --run ${input.auditRunId}\\``)));\n }\n\n return blocks;\n}\n\nexport function renderSlackActionReceiptPresentation(presentation: OpenTagActionReceiptPresentation): string {\n const lines = renderActionReceiptMarkdownLines({ title: presentation.title, actions: presentation.actions });\n if (presentation.auditRunId) {\n lines.push(\"\", markdownToSlackMrkdwn(`Audit: \\`opentag status --run ${presentation.auditRunId}\\``));\n }\n return lines.join(\"\\n\");\n}\n\nexport function createSlackActionReceiptBlocks(presentation: OpenTagActionReceiptPresentation): SlackBlock[] {\n return createSlackActionReceiptBlockSet({\n title: presentation.title,\n actions: presentation.actions,\n ...(presentation.auditRunId ? { auditRunId: presentation.auditRunId } : {})\n });\n}\n\nexport function renderSlackFinalResult(result: OpenTagRunResult, options: SlackRenderOptions = {}): string {\n return renderSlackFinalSummaryPresentation(\n createFinalSummaryPresentation({\n result: resultForFinalSummaryPresentation(result),\n ...(options.receiptContext ? { receiptContext: options.receiptContext } : {}),\n ...(options.auditRunId ? { auditRunId: options.auditRunId } : {})\n })\n );\n}\n\nexport function renderSlackFinalSummaryPresentation(presentation: OpenTagFinalSummaryPresentation): string {\n const lines = [`*Finished: ${presentation.outcome}.*`, markdownToSlackMrkdwn(compactSlackSummary(presentation.summary))];\n\n if (presentation.verification?.length) {\n lines.push(\n `Verified: ${presentation.verification\n .slice(0, 3)\n .map((check) => `\\`${markdownToSlackMrkdwn(check.command)}\\` ${markdownToSlackMrkdwn(check.outcome)}`)\n .join(\", \")}`\n );\n }\n\n const suggestedActions = renderSuggestedActionsMarkdown(presentation);\n if (presentation.nextActions?.length && suggestedActions.length === 0) {\n lines.push(`Next: ${markdownToSlackMrkdwn(compactNextAction(presentation.nextActions[0] ?? \"\"))}`);\n }\n if (suggestedActions.length > 0) {\n lines.push(\"\", ...suggestedActions);\n }\n if (presentation.auditRunId) {\n lines.push(\"\", markdownToSlackMrkdwn(`Audit: \\`opentag status --run ${presentation.auditRunId}\\``));\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function createSlackFinalResultBlocks(result: OpenTagRunResult, options: SlackRenderOptions = {}): SlackBlock[] {\n return createSlackFinalSummaryBlocks(\n createFinalSummaryPresentation({\n result: resultForFinalSummaryPresentation(result),\n ...(options.receiptContext ? { receiptContext: options.receiptContext } : {}),\n ...(options.auditRunId ? { auditRunId: options.auditRunId } : {})\n })\n );\n}\n\nexport function createSlackFinalSummaryBlocks(presentation: OpenTagFinalSummaryPresentation): SlackBlock[] {\n const blocks: SlackBlock[] = [\n {\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `*Finished: ${presentation.outcome}.*\\n${markdownToSlackMrkdwn(compactSlackSummary(presentation.summary))}`\n }\n }\n ];\n\n if (presentation.verification?.length) {\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `Verified: ${markdownToSlackMrkdwn(\n presentation.verification\n .slice(0, 3)\n .map((check) => `\\`${check.command}\\` ${check.outcome}`)\n .join(\", \")\n )}`\n }\n });\n }\n\n const actions = presentation.actions ?? [];\n if (presentation.nextActions?.length && actions.length === 0) {\n blocks.push({\n type: \"section\",\n text: {\n type: \"mrkdwn\",\n text: `Next: ${markdownToSlackMrkdwn(compactNextAction(presentation.nextActions[0] ?? \"\"))}`\n }\n });\n }\n\n if (actions.length > 0 && presentation.actionReceiptTitle) {\n blocks.push(...createSlackActionReceiptBlockSet({ title: presentation.actionReceiptTitle, actions, includeDivider: true }));\n }\n\n if (presentation.auditRunId) {\n blocks.push({\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: markdownToSlackMrkdwn(`Audit: \\`opentag status --run ${presentation.auditRunId}\\``)\n }\n ]\n });\n }\n\n return blocks;\n}\n\nexport function createSlackDoctorSummaryBlocks(presentation: OpenTagDoctorSummaryPresentation): SlackBlock[] {\n const blocks: SlackBlock[] = [slackSection(`*${markdownToSlackMrkdwn(presentation.title)}*`)];\n if (presentation.checks.length === 0) {\n blocks.push(slackContext(\"No readiness checks were reported.\"));\n return blocks;\n }\n\n for (const check of presentation.checks.slice(0, 10)) {\n blocks.push(\n slackSection(\n `*${slackCheckStatusLabel(check.status)} ${markdownToSlackMrkdwn(check.name)}*${check.message ? `\\n${markdownToSlackMrkdwn(check.message)}` : \"\"}`\n )\n );\n }\n if (presentation.checks.length > 10) {\n blocks.push(slackContext(`Showing first 10 of ${presentation.checks.length} readiness checks. Use \\`opentag doctor\\` locally for full detail.`));\n }\n return blocks;\n}\n\nexport function createSlackSourceThreadStatusBlocks(presentation: OpenTagSourceThreadStatusPresentation): SlackBlock[] {\n const blocks: SlackBlock[] = [\n slackSection(`*${markdownToSlackMrkdwn(presentation.title)}*`),\n slackContext(\n [\n presentation.sourceContainer ? `Source: \\`${presentation.sourceContainer}\\`` : undefined,\n `Project Target: \\`${presentation.projectTarget ?? \"not bound\"}\\``\n ]\n .filter((line): line is string => Boolean(line))\n .join(\" | \")\n ),\n slackSection(\n [\n `*Active run:* ${markdownToSlackMrkdwn(slackStatusActiveRun(presentation))}`,\n presentation.currentCommand ? `*Command:* ${markdownToSlackMrkdwn(presentation.currentCommand)}` : undefined,\n `*Queued follow-ups:* ${markdownToSlackMrkdwn(slackStatusQueuedFollowUps(presentation))}`,\n `*Next action:* ${markdownToSlackMrkdwn(presentation.nextAction)}`\n ]\n .filter((line): line is string => Boolean(line))\n .join(\"\\n\")\n )\n ];\n\n if (presentation.stopHint || presentation.detailHint) {\n blocks.push(\n slackContext(\n [\n presentation.stopHint ? `Stop/timeout: ${presentation.stopHint}` : undefined,\n presentation.detailHint ? `Details: ${presentation.detailHint}` : undefined\n ]\n .filter((line): line is string => Boolean(line))\n .map(markdownToSlackMrkdwn)\n .join(\" | \")\n )\n );\n }\n return blocks;\n}\n\nexport function createSlackPostMessagePayload(input: { channelId: string; text: string; threadTs: string; blocks?: SlackBlock[] }): SlackMessagePayload {\n return {\n channel: input.channelId,\n text: markdownToSlackMrkdwn(input.text),\n thread_ts: input.threadTs,\n ...(input.blocks?.length ? { blocks: input.blocks } : {})\n };\n}\n\nexport function createSlackUpdateMessagePayload(input: { channelId: string; text: string; messageTs: string; blocks?: SlackBlock[] }): SlackMessagePayload {\n return {\n channel: input.channelId,\n text: markdownToSlackMrkdwn(input.text),\n ts: input.messageTs,\n ...(input.blocks?.length ? { blocks: input.blocks } : {})\n };\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { serve } from \"@hono/node-server\";\nimport { createOpenTagClient } from \"@opentag/client\";\nimport { DEFAULT_MAX_REQUEST_BODY_BYTES, RequestBodyTooLargeError, readRequestTextWithLimit } from \"@opentag/core\";\nimport { Hono } from \"hono\";\nimport { createSlackDispatcherEventProcessorInput } from \"./dispatcher-events.js\";\nimport { createSlackEventProcessor, type SlackAppRuntimeConfig, type SlackEventProcessorInput, type SlackIngressPayload } from \"./events.js\";\n\nexport type SlackEventsAppInput = {\n slackApps: Array<\n SlackAppRuntimeConfig & {\n signingSecret: string;\n }\n >;\n clock?: () => number;\n recordControlPlaneEvent?(event: {\n type: string;\n severity?: \"info\" | \"warn\" | \"error\";\n subject?: string;\n payload?: Record<string, unknown>;\n }): Promise<void>;\n maxRequestBodyBytes?: number;\n} & SlackEventProcessorInput;\n\nexport type SlackEventsApiIngressConfig = {\n signingSecret: string;\n dispatcherUrl: string;\n dispatcherToken?: string;\n botToken?: string;\n port?: number;\n agentId?: string;\n appId?: string;\n callbackUri?: string;\n runTimeoutMs?: number;\n maxRequestBodyBytes?: number;\n};\n\nexport type SlackIngressConfig = SlackEventsApiIngressConfig;\n\nexport type SlackIngressHandle = {\n url: string;\n server: ReturnType<typeof serve>;\n close(): Promise<void>;\n};\n\nexport function computeSlackSignature(input: {\n signingSecret: string;\n timestamp: string;\n rawBody: string;\n}): string {\n const base = `v0:${input.timestamp}:${input.rawBody}`;\n const digest = createHmac(\"sha256\", input.signingSecret).update(base).digest(\"hex\");\n return `v0=${digest}`;\n}\n\nexport function verifySlackSignature(input: {\n signingSecret: string;\n timestamp: string;\n rawBody: string;\n signature: string;\n}): boolean {\n const expected = computeSlackSignature(input);\n const expectedBuffer = Buffer.from(expected);\n const actualBuffer = Buffer.from(input.signature);\n return expectedBuffer.length === actualBuffer.length && timingSafeEqual(expectedBuffer, actualBuffer);\n}\n\nexport function verifySlackTimestamp(input: { timestamp: string; nowMs: number; toleranceSeconds?: number }): boolean {\n const timestampSeconds = Number(input.timestamp);\n if (!Number.isFinite(timestampSeconds)) return false;\n const toleranceSeconds = input.toleranceSeconds ?? 300;\n const ageSeconds = Math.abs(Math.floor(input.nowMs / 1000) - timestampSeconds);\n return ageSeconds <= toleranceSeconds;\n}\n\nasync function recordSlackSignatureFailure(input: {\n recordControlPlaneEvent?: SlackEventsAppInput[\"recordControlPlaneEvent\"];\n reason: \"missing_signature_headers\" | \"stale_signature_timestamp\" | \"invalid_signature\" | \"unknown_slack_app\";\n hasSignature: boolean;\n hasTimestamp: boolean;\n apiAppId?: string;\n}): Promise<void> {\n try {\n await input.recordControlPlaneEvent?.({\n type: \"security.signature_failed\",\n severity: \"warn\",\n subject: \"slack:POST /slack/events\",\n payload: {\n provider: \"slack\",\n endpoint: \"POST /slack/events\",\n reason: input.reason,\n hasSignature: input.hasSignature,\n hasTimestamp: input.hasTimestamp,\n ...(input.apiAppId ? { apiAppId: input.apiAppId } : {})\n }\n });\n } catch {\n // Signature rejection should not turn into a 5xx if audit reporting is unavailable.\n }\n}\n\nasync function recordSlackRequestBodyRejected(input: {\n recordControlPlaneEvent?: SlackEventsAppInput[\"recordControlPlaneEvent\"];\n reason: \"request_body_too_large\" | \"invalid_json_body\" | \"invalid_request_body\";\n maxBytes?: number;\n contentLength: string | null;\n apiAppId?: string;\n}): Promise<void> {\n try {\n await input.recordControlPlaneEvent?.({\n type: \"security.request_body_rejected\",\n severity: \"warn\",\n subject: \"slack:POST /slack/events\",\n payload: {\n provider: \"slack\",\n endpoint: \"POST /slack/events\",\n reason: input.reason,\n ...(input.maxBytes !== undefined ? { maxBytes: input.maxBytes } : {}),\n contentLength: input.contentLength,\n ...(input.apiAppId ? { apiAppId: input.apiAppId } : {})\n }\n });\n } catch {\n // Oversized-payload rejection should still fail closed if audit reporting is unavailable.\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction hasOptionalStringProperties(value: Record<string, unknown>, keys: string[]): boolean {\n return keys.every((key) => value[key] === undefined || typeof value[key] === \"string\");\n}\n\nfunction isSlackEventEnvelope(value: Record<string, unknown>): boolean {\n if (value.type !== \"url_verification\" && value.type !== \"event_callback\") return false;\n if (!hasOptionalStringProperties(value, [\"token\", \"challenge\", \"team_id\", \"api_app_id\", \"event_id\"])) return false;\n if (value.event_time !== undefined && typeof value.event_time !== \"number\") return false;\n if (value.authorizations !== undefined) {\n if (!Array.isArray(value.authorizations)) return false;\n if (\n !value.authorizations.every(\n (authorization) =>\n isRecord(authorization) && (authorization.user_id === undefined || typeof authorization.user_id === \"string\")\n )\n ) {\n return false;\n }\n }\n if (value.event !== undefined) {\n if (!isRecord(value.event) || typeof value.event.type !== \"string\") return false;\n if (!hasOptionalStringProperties(value.event, [\"user\", \"text\", \"ts\", \"thread_ts\", \"channel\", \"subtype\", \"bot_id\"])) {\n return false;\n }\n }\n return true;\n}\n\nfunction isSlackInteractivePayload(value: Record<string, unknown>): boolean {\n if (value.type !== \"block_actions\") return false;\n if (!hasOptionalStringProperties(value, [\"api_app_id\", \"trigger_id\"])) return false;\n if (value.team !== undefined && (!isRecord(value.team) || !hasOptionalStringProperties(value.team, [\"id\", \"domain\"]))) return false;\n if (value.user !== undefined && (!isRecord(value.user) || !hasOptionalStringProperties(value.user, [\"id\", \"username\", \"name\"]))) return false;\n if (value.channel !== undefined && (!isRecord(value.channel) || !hasOptionalStringProperties(value.channel, [\"id\", \"name\"]))) return false;\n if (value.message !== undefined && (!isRecord(value.message) || !hasOptionalStringProperties(value.message, [\"ts\", \"thread_ts\"]))) return false;\n if (\n value.container !== undefined &&\n (!isRecord(value.container) ||\n !hasOptionalStringProperties(value.container, [\"type\", \"channel_id\", \"message_ts\", \"thread_ts\"]))\n ) {\n return false;\n }\n if (value.actions !== undefined) {\n if (!Array.isArray(value.actions)) return false;\n return value.actions.every(\n (action) =>\n isRecord(action) &&\n hasOptionalStringProperties(action, [\"type\", \"action_id\", \"block_id\", \"value\", \"action_ts\"])\n );\n }\n return true;\n}\n\nfunction isSlackIngressPayload(value: unknown): value is SlackIngressPayload {\n if (!isRecord(value) || typeof value.type !== \"string\") return false;\n return isSlackEventEnvelope(value) || isSlackInteractivePayload(value);\n}\n\nexport function createSlackEventsApp(input: SlackEventsAppInput) {\n const app = new Hono();\n const processor = createSlackEventProcessor(input);\n const maxRequestBodyBytes = input.maxRequestBodyBytes ?? DEFAULT_MAX_REQUEST_BODY_BYTES;\n\n function parseSlackPayload(rawBody: string, contentType?: string): unknown | null {\n try {\n if (contentType?.includes(\"application/x-www-form-urlencoded\") || rawBody.startsWith(\"payload=\")) {\n const interactivePayload = new URLSearchParams(rawBody).get(\"payload\");\n if (!interactivePayload) return null;\n return JSON.parse(interactivePayload) as SlackIngressPayload;\n }\n return JSON.parse(rawBody) as SlackIngressPayload;\n } catch {\n return null;\n }\n }\n\n function resolveSlackApp(inputValue: {\n apiAppId?: string;\n rawBody: string;\n signature: string;\n timestamp: string;\n }) {\n const candidates = inputValue.apiAppId\n ? input.slackApps.filter((candidate) => !candidate.appId || candidate.appId === inputValue.apiAppId)\n : input.slackApps;\n if (candidates.length === 0) {\n return { error: \"unknown_slack_app\" as const };\n }\n const slackApp = candidates.find((candidate) =>\n verifySlackSignature({\n signingSecret: candidate.signingSecret,\n timestamp: inputValue.timestamp,\n rawBody: inputValue.rawBody,\n signature: inputValue.signature\n })\n );\n return slackApp ? { slackApp } : { error: \"invalid_signature\" as const };\n }\n\n app.post(\"/slack/events\", async (c) => {\n const timestamp = c.req.header(\"x-slack-request-timestamp\");\n const signature = c.req.header(\"x-slack-signature\");\n if (!timestamp || !signature) {\n await recordSlackSignatureFailure({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n reason: \"missing_signature_headers\",\n hasSignature: Boolean(signature),\n hasTimestamp: Boolean(timestamp)\n });\n return c.json({ error: \"missing_signature_headers\" }, 401);\n }\n if (!verifySlackTimestamp({ timestamp, nowMs: input.clock?.() ?? Date.now() })) {\n await recordSlackSignatureFailure({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n reason: \"stale_signature_timestamp\",\n hasSignature: true,\n hasTimestamp: true\n });\n return c.json({ error: \"stale_signature_timestamp\" }, 401);\n }\n let rawBody: string;\n try {\n rawBody = await readRequestTextWithLimit(c.req.raw, { maxBytes: maxRequestBodyBytes });\n } catch (error) {\n if (error instanceof RequestBodyTooLargeError) {\n await recordSlackRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n reason: \"request_body_too_large\",\n maxBytes: error.maxBytes,\n contentLength: c.req.raw.headers.get(\"content-length\")\n });\n return c.json({ error: \"request_body_too_large\", maxBytes: error.maxBytes }, 413);\n }\n throw error;\n }\n const payload = parseSlackPayload(rawBody, c.req.header(\"content-type\"));\n if (!payload) {\n await recordSlackRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n reason: \"invalid_json_body\",\n contentLength: c.req.raw.headers.get(\"content-length\")\n });\n return c.json({ error: \"invalid_json\" }, 400);\n }\n if (!isSlackIngressPayload(payload)) {\n await recordSlackRequestBodyRejected({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n reason: \"invalid_request_body\",\n contentLength: c.req.raw.headers.get(\"content-length\"),\n ...(isRecord(payload) && typeof payload.api_app_id === \"string\" ? { apiAppId: payload.api_app_id } : {})\n });\n return c.json({ error: \"invalid_request_body\" }, 400);\n }\n const resolvedSlackApp = resolveSlackApp({\n rawBody,\n signature,\n timestamp,\n ...(payload.api_app_id ? { apiAppId: payload.api_app_id } : {})\n });\n if (\"error\" in resolvedSlackApp) {\n await recordSlackSignatureFailure({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n reason: resolvedSlackApp.error,\n hasSignature: true,\n hasTimestamp: true,\n ...(payload.api_app_id ? { apiAppId: payload.api_app_id } : {})\n });\n return c.json({ error: resolvedSlackApp.error }, 401);\n }\n const result = await processor.process(payload, resolvedSlackApp.slackApp, { signatureVerified: true });\n if (result.kind === \"text\") {\n return c.text(result.body, result.status);\n }\n return c.json(result.body, result.status);\n });\n\n return app;\n}\n\nexport function startSlackIngress(config: SlackEventsApiIngressConfig): SlackIngressHandle {\n const port = config.port ?? 3040;\n const dispatcherClient = createOpenTagClient({\n dispatcherUrl: config.dispatcherUrl,\n ...(config.dispatcherToken ? { pairingToken: config.dispatcherToken } : {})\n });\n const server = serve({\n fetch: createSlackEventsApp({\n slackApps: [\n {\n signingSecret: config.signingSecret,\n agentId: config.agentId ?? \"opentag\",\n ...(config.appId ? { appId: config.appId } : {}),\n ...(config.callbackUri ? { callbackUri: config.callbackUri } : {})\n }\n ],\n ...(config.maxRequestBodyBytes ? { maxRequestBodyBytes: config.maxRequestBodyBytes } : {}),\n async recordControlPlaneEvent(event) {\n await dispatcherClient.recordControlPlaneEvent(event);\n },\n ...createSlackDispatcherEventProcessorInput(config)\n }).fetch,\n port\n });\n\n return {\n url: `http://localhost:${port}`,\n server,\n close() {\n return new Promise((resolve, reject) => {\n server.close((error?: Error) => {\n if (error) {\n reject(error);\n return;\n }\n resolve();\n });\n });\n }\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { createOpenTagClient, type ChannelRuntimeStatus } from \"@opentag/client\";\nimport { createDoctorSummaryPresentation, createSourceThreadStatusPresentation, renderOpenTagPresentationPlainText } from \"@opentag/core\";\nimport type { SlackEventProcessorInput, SlackSelfServiceReply, SlackStopRunResult } from \"./events.js\";\nimport { createSlackDoctorSummaryBlocks, createSlackPostMessagePayload, createSlackSourceThreadStatusBlocks } from \"./render.js\";\n\nexport type SlackDispatcherEventConfig = {\n dispatcherUrl: string;\n dispatcherToken?: string;\n botToken?: string;\n callbackUri?: string;\n bindingAdminUserIds?: string[];\n runTimeoutMs?: number;\n fetchImpl?: typeof fetch;\n};\n\nfunction formatProjectTarget(input: { repoProvider?: string; owner: string; repo: string }): string {\n return `${input.repoProvider ?? \"github\"}:${input.owner}/${input.repo}`;\n}\n\nfunction queuedFollowUpsSummary(status: ChannelRuntimeStatus): string {\n if (status.queuedFollowUps.length === 0) return \"none.\";\n const visible = status.queuedFollowUps.slice(0, 3).map((followUp) => followUp.id);\n const suffix = status.queuedFollowUps.length > visible.length ? `, +${status.queuedFollowUps.length - visible.length} more` : \"\";\n return `${status.queuedFollowUps.length} (${visible.join(\", \")}${suffix}).`;\n}\n\nfunction formatDurationMs(ms: number): string {\n if (ms % 60_000 === 0) return `${ms / 60_000} minute(s)`;\n if (ms % 1_000 === 0) return `${ms / 1_000} second(s)`;\n return `${ms}ms`;\n}\n\nfunction runTimeoutPolicy(input: { runTimeoutMs?: number; status?: ChannelRuntimeStatus }): string {\n const hardTimeoutMs = input.status?.runTimeoutPolicy?.hardTimeoutMs ?? input.runTimeoutMs;\n return hardTimeoutMs ? `hard timeout after ${formatDurationMs(hardTimeoutMs)}` : \"disabled\";\n}\n\nfunction slackRuntimeStatusReply(status: ChannelRuntimeStatus, input: { runTimeoutMs?: number } = {}): SlackSelfServiceReply {\n const presentation = createSourceThreadStatusPresentation({\n title: \"OpenTag status:\",\n sourceContainer: `${status.binding.provider}:${status.binding.accountId}/${status.binding.conversationId}`,\n projectTarget: formatProjectTarget(status.binding),\n bindingState: \"bound\",\n ...(status.activeRun\n ? {\n activeRun: {\n id: status.activeRun.id,\n status: status.activeRun.status,\n updatedAt: status.activeRun.updatedAt\n }\n }\n : {}),\n ...(status.activeEvent?.command.rawText ? { currentCommand: status.activeEvent.command.rawText } : {}),\n queuedFollowUps: status.queuedFollowUps.slice(0, 3).map((followUp) => ({\n id: followUp.id,\n status: followUp.status,\n command: followUp.event.command.rawText\n })),\n queuedFollowUpsTotal: status.queuedFollowUps.length,\n nextAction: status.activeRun\n ? \"wait for the final reply, send a follow-up to queue more context, or use `opentag status --run <run_id>` locally.\"\n : \"@mention the app with a task to start a run.\",\n stopHint: `cancellation is explicit and is not reported as successful completion; timeout policy: ${runTimeoutPolicy({ ...input, status })}.`,\n detailHint: \"use `opentag status --run <run_id>` locally for audit events and executor detail.\"\n });\n return {\n text: renderOpenTagPresentationPlainText(presentation),\n blocks: createSlackSourceThreadStatusBlocks(presentation)\n };\n}\n\nfunction slackRuntimeDoctorReply(input: { teamId: string; channelId: string; status: ChannelRuntimeStatus; runTimeoutMs?: number }): SlackSelfServiceReply {\n const presentation = createDoctorSummaryPresentation({\n title: \"OpenTag doctor (redacted):\",\n checks: [\n { status: \"ok\", name: \"Source container\", message: `slack:${input.teamId}/${input.channelId}` },\n { status: \"ok\", name: \"Project Target\", message: formatProjectTarget(input.status.binding) },\n { status: \"ok\", name: \"Dispatcher\", message: \"reachable for this source container.\" },\n {\n status: \"ok\",\n name: \"Active run\",\n message: input.status.activeRun\n ? `${input.status.activeRun.id} (${input.status.activeRun.status}), updated ${input.status.activeRun.updatedAt}.`\n : \"none.\"\n },\n { status: \"ok\", name: \"Queued follow-ups\", message: queuedFollowUpsSummary(input.status) },\n { status: \"ok\", name: \"Timeout policy\", message: runTimeoutPolicy({ ...input, status: input.status }) },\n {\n status: \"ok\",\n name: \"Runtime readiness\",\n message: \"source-container status is reachable; run `opentag service status` locally to confirm controller, connector, executor, and heartbeat health.\"\n },\n { status: \"ok\", name: \"Secrets\", message: \"redacted. Use env/file/keychain SecretRef config and never paste tokens into Slack.\" }\n ]\n });\n return {\n text: renderOpenTagPresentationPlainText(presentation),\n blocks: createSlackDoctorSummaryBlocks(presentation)\n };\n}\n\nfunction statusUnavailable(input: { binding?: { repoProvider?: string; owner: string; repo: string }; error: unknown }): string {\n const message = input.error instanceof Error ? input.error.message : String(input.error);\n return [\n \"OpenTag status:\",\n input.binding ? `Project Target: ${formatProjectTarget(input.binding)}` : \"Project Target: not bound.\",\n \"Runtime status: unavailable from dispatcher.\",\n `Reason: ${message}`,\n \"Next action: check `opentag service status` and `opentag status` locally.\"\n ].join(\"\\n\");\n}\n\nfunction doctorUnavailable(input: { teamId: string; channelId: string; binding?: { repoProvider?: string; owner: string; repo: string }; error: unknown }): string {\n const message = input.error instanceof Error ? input.error.message : String(input.error);\n return [\n \"OpenTag doctor (redacted):\",\n `Source container: slack:${input.teamId}/${input.channelId}`,\n input.binding ? `Project Target: ${formatProjectTarget(input.binding)}` : \"Project Target: not bound.\",\n \"Dispatcher: source-container status unavailable.\",\n `Reason: ${message}`,\n \"Runtime readiness: run `opentag service status` and `opentag status --channel slack:<team>/<channel>` locally.\",\n \"Secrets: redacted; do not share local config or app tokens in Slack.\"\n ].join(\"\\n\");\n}\n\nfunction mapStopError(input: { error: unknown; runId?: string }): SlackStopRunResult | null {\n const message = input.error instanceof Error ? input.error.message : String(input.error);\n if (message.includes(\"run_already_terminal\")) {\n return { outcome: \"already_terminal\", runId: input.runId ?? \"active run\" };\n }\n if (message.includes(\"run_not_found\") || message.includes(\"active_run_not_found\") || message.includes(\"channel_binding_not_found\")) {\n return input.runId ? { outcome: \"not_found\", runId: input.runId } : { outcome: \"not_found\" };\n }\n return null;\n}\n\nexport function createSlackDispatcherEventProcessorInput(config: SlackDispatcherEventConfig): SlackEventProcessorInput {\n const fetchImpl = config.fetchImpl ?? fetch;\n const dispatcherClient = createOpenTagClient({\n dispatcherUrl: config.dispatcherUrl,\n ...(config.dispatcherToken ? { pairingToken: config.dispatcherToken } : {}),\n fetchImpl\n });\n\n const processorInput: SlackEventProcessorInput = {\n async resolveChannelBinding(input) {\n try {\n const { binding } = await dispatcherClient.getChannelBinding({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId\n });\n return {\n teamId: binding.accountId,\n channelId: binding.conversationId,\n repoProvider: binding.repoProvider,\n owner: binding.owner,\n repo: binding.repo\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"channel_binding_not_found\")) {\n return null;\n }\n throw error;\n }\n },\n async createRun(event) {\n const runId = `run_${randomUUID()}`;\n const created = await dispatcherClient.createRun({ runId, event });\n return created.outcome === \"run_created\" ? { runId: created.run.id } : { runId };\n },\n async bindChannel(input) {\n await dispatcherClient.bindChannel({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId,\n repoProvider: input.repoProvider,\n owner: input.owner,\n repo: input.repo\n });\n },\n async submitThreadAction(action) {\n await dispatcherClient.submitThreadAction(action);\n },\n async unbindChannel(input) {\n await dispatcherClient.unbindChannel({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId\n });\n },\n canManageBinding(input) {\n return Boolean(config.bindingAdminUserIds?.includes(input.userId));\n },\n async stopRun(input) {\n try {\n const result = input.runId\n ? await dispatcherClient.cancelRun({\n runId: input.runId,\n reason: \"Stop requested from Slack.\",\n requestedBy: input.requestedBy\n })\n : await dispatcherClient.cancelActiveChannelRun({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId,\n reason: \"Stop requested from Slack.\",\n requestedBy: input.requestedBy\n });\n return { outcome: \"cancelled\", runId: result.run.id };\n } catch (error) {\n const mapped = mapStopError({ error, ...(input.runId ? { runId: input.runId } : {}) });\n if (mapped) return mapped;\n throw error;\n }\n },\n async status(input) {\n if (!input.binding) return statusUnavailable({ error: \"channel not bound\" });\n try {\n return slackRuntimeStatusReply(\n await dispatcherClient.getChannelRuntimeStatus({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId\n }),\n { ...(config.runTimeoutMs ? { runTimeoutMs: config.runTimeoutMs } : {}) }\n );\n } catch (error) {\n return statusUnavailable({ binding: input.binding, error });\n }\n },\n async doctor(input) {\n if (!input.binding) {\n return doctorUnavailable({ teamId: input.teamId, channelId: input.channelId, error: \"channel not bound\" });\n }\n try {\n return slackRuntimeDoctorReply({\n teamId: input.teamId,\n channelId: input.channelId,\n status: await dispatcherClient.getChannelRuntimeStatus({\n provider: \"slack\",\n accountId: input.teamId,\n conversationId: input.channelId\n }),\n ...(config.runTimeoutMs ? { runTimeoutMs: config.runTimeoutMs } : {})\n });\n } catch (error) {\n return doctorUnavailable({ teamId: input.teamId, channelId: input.channelId, binding: input.binding, error });\n }\n },\n now: () => new Date().toISOString()\n };\n if (config.botToken) {\n processorInput.reply = async (input) => {\n const response = await fetchImpl(config.callbackUri ?? \"https://slack.com/api/chat.postMessage\", {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${config.botToken}`,\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify(\n createSlackPostMessagePayload({\n channelId: input.channelId,\n threadTs: input.threadTs,\n text: input.text,\n ...(input.blocks?.length ? { blocks: input.blocks } : {})\n })\n )\n });\n if (!response.ok) {\n throw new Error(`deliver Slack self-service reply failed: ${response.status} ${await response.text()}`);\n }\n const body = (await response.json().catch(() => ({}))) as { ok?: boolean; error?: string };\n if (body.ok === false) {\n throw new Error(`deliver Slack self-service reply failed: ${body.error ?? \"unknown_error\"}`);\n }\n };\n }\n return processorInput;\n}\n","import WebSocket, { type RawData } from \"ws\";\nimport { createOpenTagClient, type RecordControlPlaneEventInput } from \"@opentag/client\";\nimport { createSlackDispatcherEventProcessorInput, type SlackDispatcherEventConfig } from \"./dispatcher-events.js\";\nimport { createSlackEventProcessor, type SlackAppRuntimeConfig, type SlackEventProcessorInput, type SlackIngressPayload } from \"./events.js\";\n\nconst SLACK_CONNECTIONS_OPEN_URL = \"https://slack.com/api/apps.connections.open\";\nconst DEFAULT_RECONNECT_DELAY_MS = 1_000;\n\n// Slack Web API `error` codes that represent a terminal authentication or\n// configuration problem with the app token. Retrying these is pointless: the\n// request will fail identically forever, spamming logs and risking rate limits\n// or an API ban. Startup must fail loudly so the operator fixes the config,\n// rather than the daemon silently looping. Transient/network errors (e.g.\n// `ratelimited`, HTTP 5xx, fetch failures) are NOT in this set and are retried.\nconst TERMINAL_SLACK_ERROR_CODES = [\n \"invalid_auth\",\n \"not_authed\",\n \"account_inactive\",\n \"token_revoked\",\n \"token_expired\",\n \"not_allowed_token_type\",\n \"no_permission\",\n \"missing_scope\",\n \"ekm_access_denied\"\n] as const;\n\n/**\n * Returns the terminal Slack auth/config error code that must propagate instead\n * of being retried. The Slack error code is embedded in the thrown Error\n * message by {@link openSlackSocketUrl} (e.g. \"...connection failed:\n * invalid_auth\").\n */\nfunction terminalSlackAuthErrorCode(error: unknown): (typeof TERMINAL_SLACK_ERROR_CODES)[number] | null {\n if (!(error instanceof Error)) return null;\n return TERMINAL_SLACK_ERROR_CODES.find((code) => error.message.includes(code)) ?? null;\n}\n\nexport type SlackSocketModeEnvelope = {\n type?: string;\n envelope_id?: string;\n payload?: SlackIngressPayload;\n accepts_response_payload?: boolean;\n};\n\nexport type SlackSocketModeAppInput = {\n appToken: string;\n slackApp: SlackAppRuntimeConfig;\n recordControlPlaneEvent?(event: RecordControlPlaneEventInput): Promise<void>;\n} & SlackEventProcessorInput;\n\nexport type SlackSocketModeIngressConfig = SlackDispatcherEventConfig & {\n appToken: string;\n agentId?: string;\n appId?: string;\n callbackUri?: string;\n botToken?: string;\n};\n\nexport type SlackSocketModeIngressHandle = {\n startPromise: Promise<void>;\n close(): Promise<void>;\n};\n\nexport type SlackSocketModeDependencies = {\n fetchImpl?: typeof fetch;\n createWebSocket?(url: string): WebSocket;\n reconnectDelayMs?: number;\n log?(message: string): void;\n logError?(message: string, error?: unknown): void;\n};\n\ntype SlackConnectionsOpenResponse = {\n ok?: boolean;\n url?: string;\n error?: string;\n needed?: string;\n provided?: string;\n};\n\nfunction rawDataToString(data: RawData): string {\n if (typeof data === \"string\") return data;\n if (Buffer.isBuffer(data)) return data.toString(\"utf8\");\n if (Array.isArray(data)) return Buffer.concat(data).toString(\"utf8\");\n if (data instanceof ArrayBuffer) return Buffer.from(data).toString(\"utf8\");\n return Buffer.from(data).toString(\"utf8\");\n}\n\nasync function openSlackSocketUrl(input: { appToken: string; fetchImpl: typeof fetch }): Promise<string> {\n const response = await input.fetchImpl(SLACK_CONNECTIONS_OPEN_URL, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${input.appToken}`\n }\n });\n const body = (await response.json().catch(() => ({}))) as SlackConnectionsOpenResponse;\n if (!response.ok || !body.ok || !body.url) {\n const reason = body.error ?? `http_${response.status}`;\n throw new Error(`Slack Socket Mode connection failed: ${reason}`);\n }\n return body.url;\n}\n\nfunction parseSocketEnvelope(data: RawData): SlackSocketModeEnvelope | null {\n try {\n return JSON.parse(rawDataToString(data)) as SlackSocketModeEnvelope;\n } catch {\n return null;\n }\n}\n\nasync function handleSocketMessage(input: {\n data: RawData;\n socket: WebSocket;\n processor: ReturnType<typeof createSlackEventProcessor>;\n slackApp: SlackAppRuntimeConfig;\n logError(message: string, error?: unknown): void;\n}): Promise<void> {\n const envelope = parseSocketEnvelope(input.data);\n if (!envelope?.envelope_id) {\n input.logError(\"[slack] ignored Socket Mode envelope without envelope_id\");\n return;\n }\n\n input.socket.send(JSON.stringify({ envelope_id: envelope.envelope_id }));\n\n if (!envelope.payload) {\n return;\n }\n if (input.slackApp.appId && envelope.payload.api_app_id && envelope.payload.api_app_id !== input.slackApp.appId) {\n return;\n }\n if (envelope.type !== \"events_api\" && envelope.payload.type !== \"block_actions\") {\n return;\n }\n\n await input.processor.process(envelope.payload, input.slackApp);\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function recordSlackSocketTokenMisuse(input: {\n recordControlPlaneEvent?: SlackSocketModeAppInput[\"recordControlPlaneEvent\"];\n slackApp: SlackAppRuntimeConfig;\n reason: (typeof TERMINAL_SLACK_ERROR_CODES)[number];\n}): Promise<void> {\n try {\n await input.recordControlPlaneEvent?.({\n type: \"security.token_misuse\",\n severity: \"warn\",\n subject: \"slack:app_token\",\n payload: {\n provider: \"slack\",\n endpoint: \"apps.connections.open\",\n reason: input.reason,\n tokenKind: \"app_token\",\n mode: \"socket_mode\",\n agentId: input.slackApp.agentId,\n ...(input.slackApp.appId ? { appId: input.slackApp.appId } : {})\n }\n });\n } catch {\n // Token misuse reporting is best-effort: startup should still fail with the\n // original Slack auth/config error instead of masking it behind audit I/O.\n }\n}\n\nexport function startSlackSocketModeApp(\n input: SlackSocketModeAppInput,\n dependencies: SlackSocketModeDependencies = {}\n): SlackSocketModeIngressHandle {\n const fetchImpl = dependencies.fetchImpl ?? fetch;\n const createWebSocket = dependencies.createWebSocket ?? ((url: string) => new WebSocket(url));\n const reconnectDelayMs = dependencies.reconnectDelayMs ?? DEFAULT_RECONNECT_DELAY_MS;\n const log = dependencies.log ?? ((message: string) => console.log(message));\n const logError = dependencies.logError ?? ((message: string, error?: unknown) => (error ? console.error(message, error) : console.error(message)));\n const processor = createSlackEventProcessor(input);\n let closed = false;\n let activeSocket: WebSocket | undefined;\n\n async function runOneConnection(socketUrl: string): Promise<void> {\n await new Promise<void>((resolve) => {\n const socket = createWebSocket(socketUrl);\n activeSocket = socket;\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n if (activeSocket === socket) activeSocket = undefined;\n resolve();\n };\n\n socket.once(\"open\", () => {\n log(\"[slack] Socket Mode connected\");\n });\n socket.on(\"message\", (data) => {\n void handleSocketMessage({\n data,\n socket,\n processor,\n slackApp: input.slackApp,\n logError\n }).catch((error: unknown) => {\n logError(\"[slack] failed to handle Socket Mode event:\", error);\n });\n });\n socket.once(\"close\", finish);\n socket.once(\"error\", (error) => {\n if (!closed) {\n logError(\"[slack] Socket Mode connection error:\", error);\n }\n socket.close();\n finish();\n });\n });\n }\n\n const startPromise = (async () => {\n while (!closed) {\n try {\n const socketUrl = await openSlackSocketUrl({ appToken: input.appToken, fetchImpl });\n await runOneConnection(socketUrl);\n } catch (error) {\n // A terminal auth/config error (invalid app token, missing scope, etc.)\n // will never succeed on retry, so we must NOT swallow it: rethrow so\n // startPromise rejects and startup fails loudly instead of looping\n // forever against Slack's API.\n const terminalErrorCode = terminalSlackAuthErrorCode(error);\n if (terminalErrorCode) {\n if (!closed) {\n logError(\"[slack] terminal Socket Mode auth/config error, aborting:\", error);\n await recordSlackSocketTokenMisuse({\n recordControlPlaneEvent: input.recordControlPlaneEvent,\n slackApp: input.slackApp,\n reason: terminalErrorCode\n });\n }\n throw error;\n }\n // A transient apps.connections.open failure (or any error opening the\n // connection) must NOT reject startPromise: the CLI aborts the entire\n // OpenTag daemon when this promise rejects, so one blip in Slack's API\n // would otherwise take down every other ingress and the dispatcher.\n // Log it and fall through to the shared backoff/retry below.\n if (!closed) {\n logError(\"[slack] failed to open Socket Mode connection, retrying:\", error);\n }\n }\n if (!closed) {\n await wait(reconnectDelayMs);\n }\n }\n })();\n\n return {\n startPromise,\n async close() {\n closed = true;\n activeSocket?.close();\n await startPromise.catch(() => undefined);\n }\n };\n}\n\nexport function startSlackSocketModeIngress(\n config: SlackSocketModeIngressConfig,\n dependencies: SlackSocketModeDependencies = {}\n): SlackSocketModeIngressHandle {\n const dispatcherClient = createOpenTagClient({\n dispatcherUrl: config.dispatcherUrl,\n ...(config.dispatcherToken ? { pairingToken: config.dispatcherToken } : {}),\n fetchImpl: config.fetchImpl ?? fetch\n });\n return startSlackSocketModeApp(\n {\n appToken: config.appToken,\n slackApp: {\n agentId: config.agentId ?? \"opentag\",\n ...(config.appId ? { appId: config.appId } : {}),\n ...(config.callbackUri ? { callbackUri: config.callbackUri } : {})\n },\n async recordControlPlaneEvent(event) {\n await dispatcherClient.recordControlPlaneEvent(event);\n },\n ...createSlackDispatcherEventProcessorInput(config)\n },\n dependencies\n );\n}\n"],"mappings":"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","names":["text","text","binding","createOpenTagClient","createDoctorSummaryPresentation","createSourceThreadStatusPresentation","renderOpenTagPresentationPlainText","formatProjectTarget","createSourceThreadStatusPresentation","renderOpenTagPresentationPlainText","createDoctorSummaryPresentation","createOpenTagClient","createOpenTagClient","createOpenTagClient"]}
|
package/dist/ingress.d.ts
CHANGED
|
@@ -6,15 +6,25 @@ export type SlackEventsAppInput = {
|
|
|
6
6
|
signingSecret: string;
|
|
7
7
|
}>;
|
|
8
8
|
clock?: () => number;
|
|
9
|
+
recordControlPlaneEvent?(event: {
|
|
10
|
+
type: string;
|
|
11
|
+
severity?: "info" | "warn" | "error";
|
|
12
|
+
subject?: string;
|
|
13
|
+
payload?: Record<string, unknown>;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
maxRequestBodyBytes?: number;
|
|
9
16
|
} & SlackEventProcessorInput;
|
|
10
17
|
export type SlackEventsApiIngressConfig = {
|
|
11
18
|
signingSecret: string;
|
|
12
19
|
dispatcherUrl: string;
|
|
13
20
|
dispatcherToken?: string;
|
|
21
|
+
botToken?: string;
|
|
14
22
|
port?: number;
|
|
15
23
|
agentId?: string;
|
|
16
24
|
appId?: string;
|
|
17
25
|
callbackUri?: string;
|
|
26
|
+
runTimeoutMs?: number;
|
|
27
|
+
maxRequestBodyBytes?: number;
|
|
18
28
|
};
|
|
19
29
|
export type SlackIngressConfig = SlackEventsApiIngressConfig;
|
|
20
30
|
export type SlackIngressHandle = {
|
package/dist/ingress.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingress.d.ts","sourceRoot":"","sources":["../src/ingress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ingress.d.ts","sourceRoot":"","sources":["../src/ingress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAA6B,KAAK,qBAAqB,EAAE,KAAK,wBAAwB,EAA4B,MAAM,aAAa,CAAC;AAE7I,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,EAAE,KAAK,CACd,qBAAqB,GAAG;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CACF,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;IACrB,uBAAuB,CAAC,CAAC,KAAK,EAAE;QAC9B,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;QACrC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACnC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,GAAG,wBAAwB,CAAC;AAE7B,MAAM,MAAM,2BAA2B,GAAG;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,2BAA2B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;IACjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAIT;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAKV;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAMpH;AAoHD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,8EAuH9D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,2BAA2B,GAAG,kBAAkB,CAwCzF"}
|
package/dist/normalize.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export type SlackAppMentionInput = {
|
|
|
19
19
|
agentId?: string;
|
|
20
20
|
botUserId?: string;
|
|
21
21
|
callbackUri?: string;
|
|
22
|
+
signatureVerified?: boolean;
|
|
22
23
|
binding: SlackChannelBinding;
|
|
23
24
|
};
|
|
24
25
|
export declare function stripSlackAppMention(text: string, botUserId?: string): string | null;
|
package/dist/normalize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,KAAK,YAAY,EAAwB,MAAM,eAAe,CAAC;AAEtI,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,mBAAmB,CAAC;CAC9B,CAAC;
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgE,KAAK,YAAY,EAAwB,MAAM,eAAe,CAAC;AAEtI,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,mBAAmB,CAAC;CAC9B,CAAC;AASF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyBpF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE3G;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAM9G;AA0FD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,oBAAoB,GAAG,YAAY,GAAG,IAAI,CAoEzF"}
|
package/dist/render.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type OpenTagRunResult } from "@opentag/core";
|
|
1
|
+
import { type ActionReceiptContext, type OpenTagActionReceiptPresentation, type OpenTagDoctorSummaryPresentation, type OpenTagFinalSummaryPresentation, type OpenTagSourceThreadStatusPresentation, type OpenTagRunResult } from "@opentag/core";
|
|
2
2
|
export type SlackTextBlock = {
|
|
3
3
|
type: "section";
|
|
4
4
|
text: {
|
|
@@ -9,7 +9,36 @@ export type SlackTextBlock = {
|
|
|
9
9
|
export type SlackDividerBlock = {
|
|
10
10
|
type: "divider";
|
|
11
11
|
};
|
|
12
|
-
export type
|
|
12
|
+
export type SlackContextBlock = {
|
|
13
|
+
type: "context";
|
|
14
|
+
elements: Array<{
|
|
15
|
+
type: "mrkdwn";
|
|
16
|
+
text: string;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
export type SlackButtonElement = {
|
|
20
|
+
type: "button";
|
|
21
|
+
text: {
|
|
22
|
+
type: "plain_text";
|
|
23
|
+
text: string;
|
|
24
|
+
emoji?: boolean;
|
|
25
|
+
};
|
|
26
|
+
action_id: string;
|
|
27
|
+
value: string;
|
|
28
|
+
style?: "primary" | "danger";
|
|
29
|
+
};
|
|
30
|
+
export type SlackActionsBlock = {
|
|
31
|
+
type: "actions";
|
|
32
|
+
block_id?: string;
|
|
33
|
+
elements: SlackButtonElement[];
|
|
34
|
+
};
|
|
35
|
+
export type SlackBlock = SlackTextBlock | SlackDividerBlock | SlackContextBlock | SlackActionsBlock;
|
|
36
|
+
export type SlackSuggestedActionButtonValue = {
|
|
37
|
+
version: 1;
|
|
38
|
+
command: string;
|
|
39
|
+
proposalId: string;
|
|
40
|
+
intentId: string;
|
|
41
|
+
};
|
|
13
42
|
export type SlackMessagePayload = {
|
|
14
43
|
channel: string;
|
|
15
44
|
text: string;
|
|
@@ -17,10 +46,34 @@ export type SlackMessagePayload = {
|
|
|
17
46
|
ts?: string;
|
|
18
47
|
blocks?: SlackBlock[];
|
|
19
48
|
};
|
|
49
|
+
export type SlackReactionPayload = {
|
|
50
|
+
channel: string;
|
|
51
|
+
timestamp: string;
|
|
52
|
+
name: string;
|
|
53
|
+
};
|
|
54
|
+
export type SlackSourceReceiptState = "received" | "running";
|
|
55
|
+
export type SlackRenderOptions = {
|
|
56
|
+
receiptContext?: ActionReceiptContext;
|
|
57
|
+
auditRunId?: string;
|
|
58
|
+
};
|
|
59
|
+
export declare function buildSlackSuggestedActionButtonValue(input: SlackSuggestedActionButtonValue): string;
|
|
60
|
+
export declare function parseSlackSuggestedActionButtonValue(value: string): SlackSuggestedActionButtonValue | null;
|
|
20
61
|
export declare function markdownToSlackMrkdwn(text: string): string;
|
|
21
62
|
export declare function renderSlackAcknowledgement(runId: string): string;
|
|
22
|
-
export declare function
|
|
23
|
-
export declare function
|
|
63
|
+
export declare function slackSourceReceiptReactionName(state: SlackSourceReceiptState): string;
|
|
64
|
+
export declare function createSlackReactionPayload(input: {
|
|
65
|
+
channelId: string;
|
|
66
|
+
messageTs: string;
|
|
67
|
+
name: string;
|
|
68
|
+
}): SlackReactionPayload;
|
|
69
|
+
export declare function renderSlackActionReceiptPresentation(presentation: OpenTagActionReceiptPresentation): string;
|
|
70
|
+
export declare function createSlackActionReceiptBlocks(presentation: OpenTagActionReceiptPresentation): SlackBlock[];
|
|
71
|
+
export declare function renderSlackFinalResult(result: OpenTagRunResult, options?: SlackRenderOptions): string;
|
|
72
|
+
export declare function renderSlackFinalSummaryPresentation(presentation: OpenTagFinalSummaryPresentation): string;
|
|
73
|
+
export declare function createSlackFinalResultBlocks(result: OpenTagRunResult, options?: SlackRenderOptions): SlackBlock[];
|
|
74
|
+
export declare function createSlackFinalSummaryBlocks(presentation: OpenTagFinalSummaryPresentation): SlackBlock[];
|
|
75
|
+
export declare function createSlackDoctorSummaryBlocks(presentation: OpenTagDoctorSummaryPresentation): SlackBlock[];
|
|
76
|
+
export declare function createSlackSourceThreadStatusBlocks(presentation: OpenTagSourceThreadStatusPresentation): SlackBlock[];
|
|
24
77
|
export declare function createSlackPostMessagePayload(input: {
|
|
25
78
|
channelId: string;
|
|
26
79
|
text: string;
|
package/dist/render.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|