@openacp/cli 2026.327.2 → 2026.327.5
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/{adapter-LC2QSDAS.js → adapter-JQFQ3JAO.js} +3 -3
- package/dist/{adapter-Y55NXX6I.js → adapter-UORRGHNH.js} +32 -8
- package/dist/adapter-UORRGHNH.js.map +1 -0
- package/dist/{chunk-TRXBJEZ5.js → chunk-32LVIEPW.js} +49 -19
- package/dist/chunk-32LVIEPW.js.map +1 -0
- package/dist/{chunk-UMT7RU77.js → chunk-HRKAXFWR.js} +2 -2
- package/dist/{chunk-36YQ44D7.js → chunk-P2G275VD.js} +2 -2
- package/dist/{chunk-HUWOFP2H.js → chunk-S3ZGPPXY.js} +3 -3
- package/dist/{chunk-LP45RCA4.js → chunk-XWDW3XBE.js} +338 -414
- package/dist/chunk-XWDW3XBE.js.map +1 -0
- package/dist/{chunk-3ASUU6WW.js → chunk-ZNSO2QVC.js} +2 -2
- package/dist/cli.js +60 -40
- package/dist/cli.js.map +1 -1
- package/dist/{config-editor-3IKBPZA7.js → config-editor-7PKW42GZ.js} +2 -2
- package/dist/{core-plugins-ROU4GPLT.js → core-plugins-Y5US6RED.js} +4 -4
- package/dist/index.d.ts +92 -93
- package/dist/index.js +35 -5
- package/dist/index.js.map +1 -1
- package/dist/{main-UVTZ46WP.js → main-3GF3EQTE.js} +8 -8
- package/dist/plugin-installer-QVJP6VKV.js +42 -0
- package/dist/plugin-installer-QVJP6VKV.js.map +1 -0
- package/dist/{setup-EYAFK2WI.js → setup-A7VPW46C.js} +8 -6
- package/dist/setup-A7VPW46C.js.map +1 -0
- package/dist/{slack-37ZWBDUI.js → slack-2XNWBOWH.js} +2 -2
- package/dist/{telegram-2ZCCCZIY.js → telegram-E65IWFBW.js} +2 -2
- package/package.json +1 -1
- package/dist/adapter-Y55NXX6I.js.map +0 -1
- package/dist/chunk-LP45RCA4.js.map +0 -1
- package/dist/chunk-TRXBJEZ5.js.map +0 -1
- package/dist/plugin-installer-GQ2P3Q3E.js +0 -23
- package/dist/plugin-installer-GQ2P3Q3E.js.map +0 -1
- package/dist/setup-EYAFK2WI.js.map +0 -1
- /package/dist/{adapter-LC2QSDAS.js.map → adapter-JQFQ3JAO.js.map} +0 -0
- /package/dist/{chunk-UMT7RU77.js.map → chunk-HRKAXFWR.js.map} +0 -0
- /package/dist/{chunk-36YQ44D7.js.map → chunk-P2G275VD.js.map} +0 -0
- /package/dist/{chunk-HUWOFP2H.js.map → chunk-S3ZGPPXY.js.map} +0 -0
- /package/dist/{chunk-3ASUU6WW.js.map → chunk-ZNSO2QVC.js.map} +0 -0
- /package/dist/{config-editor-3IKBPZA7.js.map → config-editor-7PKW42GZ.js.map} +0 -0
- /package/dist/{core-plugins-ROU4GPLT.js.map → core-plugins-Y5US6RED.js.map} +0 -0
- /package/dist/{main-UVTZ46WP.js.map → main-3GF3EQTE.js.map} +0 -0
- /package/dist/{slack-37ZWBDUI.js.map → slack-2XNWBOWH.js.map} +0 -0
- /package/dist/{telegram-2ZCCCZIY.js.map → telegram-E65IWFBW.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/setup/wizard.ts","../../src/core/setup/types.ts","../../src/core/setup/helpers.ts","../../src/core/setup/setup-agents.ts","../../src/core/setup/setup-workspace.ts","../../src/core/setup/setup-run-mode.ts","../../src/core/setup/setup-integrations.ts","../../src/core/setup/setup-channels.ts"],"sourcesContent":["import * as clack from \"@clack/prompts\";\nimport type { Config, ConfigManager } from \"../config/config.js\";\nimport type { ChannelId } from \"./types.js\";\nimport type { OnboardSection } from \"./types.js\";\nimport { ONBOARD_SECTION_OPTIONS } from \"./types.js\";\nimport { guardCancel, ok, fail, printStartBanner, summarizeConfig } from \"./helpers.js\";\nimport { setupAgents } from \"./setup-agents.js\";\nimport { setupWorkspace } from \"./setup-workspace.js\";\nimport { setupRunMode } from \"./setup-run-mode.js\";\nimport { setupIntegrations } from \"./setup-integrations.js\";\nimport { configureChannels } from \"./setup-channels.js\";\nimport type { SettingsManager } from \"../plugin/settings-manager.js\";\nimport type { PluginRegistry } from \"../plugin/plugin-registry.js\";\n\n// ─── First-run setup ───\n\nexport async function runSetup(\n configManager: ConfigManager,\n opts?: { skipRunMode?: boolean; settingsManager?: SettingsManager; pluginRegistry?: PluginRegistry },\n): Promise<boolean> {\n await printStartBanner();\n clack.intro(\"Let's set up OpenACP\");\n\n const { settingsManager, pluginRegistry } = opts ?? {};\n\n try {\n if (!settingsManager || !pluginRegistry) {\n console.log(fail('Plugin system not initialized. Cannot set up channels.'));\n return false;\n }\n\n // Ask user which channels to set up\n const channelChoices = guardCancel(\n await clack.multiselect({\n message: 'Which channels do you want to set up?',\n options: [\n { value: 'telegram' as const, label: 'Telegram', hint: 'built-in' },\n { value: 'discord' as const, label: 'Discord', hint: 'will install @openacp/adapter-discord' },\n ],\n required: true,\n initialValues: ['telegram' as const],\n }),\n ) as ChannelId[];\n\n // Calculate total steps dynamically: channel(s) + workspace + run mode\n const channelSteps = channelChoices.length;\n const runModeSteps = opts?.skipRunMode ? 0 : 1;\n const totalSteps = channelSteps + 1 + runModeSteps; // + workspace + optional run mode\n\n let currentStep = 0;\n\n const { createInstallContext } = await import('../plugin/install-context.js');\n\n for (const channelId of channelChoices) {\n currentStep++;\n\n if (channelId === 'telegram') {\n const telegramPlugin = (await import('../../plugins/telegram/index.js')).default;\n const ctx = createInstallContext({\n pluginName: telegramPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n await telegramPlugin.install!(ctx);\n pluginRegistry.register(telegramPlugin.name, {\n version: telegramPlugin.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(telegramPlugin.name),\n description: telegramPlugin.description,\n });\n }\n\n if (channelId === 'discord') {\n await installAndSetupDiscord(settingsManager, pluginRegistry);\n }\n }\n\n const { defaultAgent } = await setupAgents();\n\n // Offer Claude CLI integration\n await setupIntegrations();\n\n currentStep++;\n const workspace = await setupWorkspace({ stepNum: currentStep, totalSteps });\n\n let runMode: 'foreground' | 'daemon' = 'foreground';\n let autoStart = false;\n if (!opts?.skipRunMode) {\n currentStep++;\n const result = await setupRunMode({ stepNum: currentStep, totalSteps });\n runMode = result.runMode;\n autoStart = result.autoStart;\n }\n\n const security = {\n allowedUserIds: [] as string[],\n maxConcurrentSessions: 20,\n sessionTimeoutMinutes: 60,\n };\n\n const config: Config = {\n channels: {},\n agents: {},\n defaultAgent,\n workspace,\n security,\n logging: {\n level: \"info\",\n logDir: \"~/.openacp/logs\",\n maxFileSize: \"10m\",\n maxFiles: 7,\n sessionLogRetentionDays: 30,\n },\n runMode,\n autoStart,\n api: {\n port: 21420,\n host: '127.0.0.1',\n },\n sessionStore: { ttlDays: 30 },\n tunnel: {\n enabled: true,\n port: 3100,\n provider: \"cloudflare\",\n options: {},\n maxUserTunnels: 5,\n storeTtlMinutes: 60,\n auth: { enabled: false },\n },\n usage: {\n enabled: true,\n warningThreshold: 0.8,\n currency: \"USD\",\n retentionDays: 90,\n },\n integrations: {},\n speech: {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n },\n };\n\n try {\n await configManager.writeNew(config);\n } catch (writeErr) {\n console.log(\n fail(`Could not save config: ${(writeErr as Error).message}`),\n );\n return false;\n }\n\n // Auto-register remaining built-in plugins in the registry\n if (settingsManager && pluginRegistry) {\n await registerBuiltinPlugins(settingsManager, pluginRegistry);\n await pluginRegistry.save();\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n\n if (!opts?.skipRunMode) {\n console.log(ok(\"Starting OpenACP...\"));\n console.log(\"\");\n }\n\n return true;\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return false;\n }\n throw err;\n }\n}\n\n/**\n * Install @openacp/adapter-discord from npm if needed, then run its install() hook.\n */\nasync function installAndSetupDiscord(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n): Promise<void> {\n const packageName = '@openacp/adapter-discord';\n\n // Try to import first — if not installed, install it\n let discordPlugin: any;\n const pluginsDir = settingsManager.getBasePath();\n try {\n const { importFromDir } = await import('../plugin/plugin-installer.js');\n const mod = await importFromDir(packageName, pluginsDir);\n discordPlugin = mod.default;\n } catch {\n const spinner = clack.spinner();\n spinner.start(`Installing ${packageName}...`);\n try {\n const { installNpmPlugin } = await import('../plugin/plugin-installer.js');\n const mod = await installNpmPlugin(packageName, pluginsDir);\n discordPlugin = mod.default;\n spinner.stop(ok(`${packageName} installed`));\n } catch (installErr) {\n spinner.stop(fail(`Failed to install ${packageName}: ${(installErr as Error).message}`));\n console.log(fail('You can install it later with: openacp plugin add @openacp/adapter-discord'));\n return;\n }\n }\n\n const { createInstallContext } = await import('../plugin/install-context.js');\n const ctx = createInstallContext({\n pluginName: discordPlugin.name,\n settingsManager,\n basePath: settingsManager.getBasePath(),\n });\n\n if (discordPlugin.install) {\n await discordPlugin.install(ctx);\n }\n\n pluginRegistry.register(discordPlugin.name, {\n version: discordPlugin.version,\n source: 'npm',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(discordPlugin.name),\n description: discordPlugin.description,\n });\n}\n\n/**\n * Register all built-in plugins that haven't been registered yet.\n * Called after first-run setup to populate the registry with defaults.\n */\nasync function registerBuiltinPlugins(\n settingsManager: SettingsManager,\n pluginRegistry: PluginRegistry,\n): Promise<void> {\n const builtinPlugins = [\n { name: '@openacp/security', version: '1.0.0', description: 'User access control and session limits' },\n { name: '@openacp/file-service', version: '1.0.0', description: 'File storage and management' },\n { name: '@openacp/context', version: '1.0.0', description: 'Conversation context management' },\n { name: '@openacp/usage', version: '1.0.0', description: 'Token usage tracking and budget enforcement' },\n { name: '@openacp/speech', version: '1.0.0', description: 'Text-to-speech and speech-to-text' },\n { name: '@openacp/notifications', version: '1.0.0', description: 'Cross-session notification routing' },\n { name: '@openacp/tunnel', version: '1.0.0', description: 'Expose local services via tunnel' },\n { name: '@openacp/api-server', version: '1.0.0', description: 'REST API + SSE streaming server' },\n ];\n\n for (const p of builtinPlugins) {\n if (!pluginRegistry.get(p.name)) {\n pluginRegistry.register(p.name, {\n version: p.version,\n source: 'builtin',\n enabled: true,\n settingsPath: settingsManager.getSettingsPath(p.name),\n description: p.description,\n });\n }\n }\n}\n\n// ─── Reconfigure (section-based, for existing config) ───\n\ntype ReconfigureSection = OnboardSection | \"__continue\";\n\nasync function selectSection(hasSelection: boolean): Promise<ReconfigureSection> {\n return guardCancel(\n await clack.select({\n message: \"Select sections to configure\",\n options: [\n ...ONBOARD_SECTION_OPTIONS,\n {\n value: \"__continue\" as const,\n label: \"Continue\",\n hint: hasSelection ? \"Done\" : \"Skip for now\",\n },\n ],\n initialValue: ONBOARD_SECTION_OPTIONS[0].value,\n }),\n ) as ReconfigureSection;\n}\n\nexport async function runReconfigure(configManager: ConfigManager): Promise<void> {\n await printStartBanner();\n clack.intro(\"OpenACP — Reconfigure\");\n\n try {\n await configManager.load();\n let config = configManager.get();\n\n // Show current config summary\n clack.note(summarizeConfig(config), \"Current configuration\");\n\n let ranSection = false;\n\n while (true) {\n const choice = await selectSection(ranSection);\n if (choice === \"__continue\") break;\n ranSection = true;\n\n if (choice === \"channels\") {\n const result = await configureChannels(config);\n if (result.changed) {\n // IMPORTANT: Use writeNew() instead of save() because save() uses deepMerge\n // which cannot delete keys. Channel deletion (delete next.channels.telegram)\n // would be silently ignored by deepMerge. writeNew() overwrites the full config.\n config = { ...config, channels: result.config.channels };\n await configManager.writeNew(config);\n }\n }\n\n if (choice === \"agents\") {\n const { defaultAgent } = await setupAgents();\n await configManager.save({ defaultAgent });\n config = configManager.get();\n }\n\n if (choice === \"workspace\") {\n const { baseDir } = await setupWorkspace({\n existing: config.workspace.baseDir,\n });\n await configManager.save({ workspace: { baseDir } });\n config = configManager.get();\n }\n\n if (choice === \"runMode\") {\n const result = await setupRunMode({\n existing: { runMode: config.runMode, autoStart: config.autoStart },\n });\n await configManager.save({\n runMode: result.runMode,\n autoStart: result.autoStart,\n });\n config = configManager.get();\n }\n\n if (choice === \"integrations\") {\n await setupIntegrations(config);\n }\n }\n\n if (!ranSection) {\n clack.outro(\"No changes made.\");\n return;\n }\n\n clack.outro(`Config saved to ${configManager.getConfigPath()}`);\n } catch (err) {\n if ((err as Error).name === \"ExitPromptError\") {\n clack.cancel(\"Setup cancelled.\");\n return;\n }\n throw err;\n }\n}\n","export type OnboardSection =\n | \"channels\"\n | \"agents\"\n | \"workspace\"\n | \"runMode\"\n | \"integrations\";\n\nexport type ConfiguredChannelAction = \"modify\" | \"disable\" | \"delete\" | \"skip\";\n\nexport type ChannelId = string;\n\nexport type ChannelStatus = {\n id: ChannelId;\n label: string;\n configured: boolean;\n enabled: boolean;\n hint?: string;\n};\n\nexport const ONBOARD_SECTION_OPTIONS: Array<{\n value: OnboardSection;\n label: string;\n hint: string;\n}> = [\n { value: \"channels\", label: \"Channels\", hint: \"Link/update messaging platforms\" },\n { value: \"agents\", label: \"Agents\", hint: \"Install agents, change default\" },\n { value: \"workspace\", label: \"Workspace\", hint: \"Set workspace directory\" },\n { value: \"runMode\", label: \"Run mode\", hint: \"Foreground/daemon, auto-start\" },\n { value: \"integrations\", label: \"Integrations\", hint: \"Claude CLI session transfer\" },\n];\n\nexport const CHANNEL_META: Record<string, { label: string; method: string }> = {\n telegram: { label: \"Telegram\", method: \"Bot API\" },\n discord: { label: \"Discord\", method: \"Bot API\" },\n};\n\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\n\n// --- ANSI colors ---\n\nexport const c = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n cyan: \"\\x1b[36m\",\n white: \"\\x1b[37m\",\n};\n\nexport const ok = (msg: string) =>\n `${c.green}${c.bold}✓${c.reset} ${c.green}${msg}${c.reset}`;\nexport const warn = (msg: string) => `${c.yellow}⚠ ${msg}${c.reset}`;\nexport const fail = (msg: string) => `${c.red}✗ ${msg}${c.reset}`;\nexport const step = (n: number, total: number, title: string) =>\n `\\n${c.cyan}${c.bold}[${n}/${total}]${c.reset} ${c.bold}${title}${c.reset}\\n`;\nexport const dim = (msg: string) => `${c.dim}${msg}${c.reset}`;\n\nexport function guardCancel<T>(value: T | symbol): T {\n if (clack.isCancel(value)) {\n clack.cancel(\"Setup cancelled.\");\n process.exit(0);\n }\n return value as T;\n}\n\n// --- Banner ---\n\nfunction applyGradient(text: string): string {\n const colors = [135, 99, 63, 33, 39, 44, 44];\n const lines = text.split(\"\\n\");\n return lines\n .map((line, i) => {\n const colorIdx = Math.min(i, colors.length - 1);\n return `\\x1b[38;5;${colors[colorIdx]}m${line}\\x1b[0m`;\n })\n .join(\"\\n\");\n}\n\nconst BANNER = `\n ██████╗ ██████╗ ███████╗███╗ ██╗ █████╗ ██████╗██████╗\n ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔══██╗██╔════╝██╔══██╗\n ██║ ██║██████╔╝█████╗ ██╔██╗ ██║███████║██║ ██████╔╝\n ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══██║██║ ██╔═══╝\n ╚██████╔╝██║ ███████╗██║ ╚████║██║ ██║╚██████╗██║\n ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝ ╚═════╝╚═╝\n`;\n\nexport async function printStartBanner(): Promise<void> {\n let version = \"0.0.0\";\n try {\n const { getCurrentVersion } = await import(\"../../cli/version.js\");\n version = getCurrentVersion();\n } catch {\n // ignore\n }\n console.log(applyGradient(BANNER));\n console.log(`${c.dim} AI coding agents, anywhere. v${version}${c.reset}\\n`);\n}\n\n// --- Config summary ---\n\nexport function summarizeConfig(config: Config): string {\n const lines: string[] = [];\n\n // Channels\n const channelStatuses: string[] = [];\n for (const [id, meta] of Object.entries({\n telegram: \"Telegram\",\n discord: \"Discord\",\n })) {\n const ch = config.channels[id] as { enabled?: boolean } | undefined;\n if (ch?.enabled) {\n channelStatuses.push(`${meta} (enabled)`);\n } else if (ch && Object.keys(ch).length > 1) {\n channelStatuses.push(`${meta} (disabled)`);\n } else {\n channelStatuses.push(`${meta} (not configured)`);\n }\n }\n lines.push(`Channels: ${channelStatuses.join(\", \")}`);\n\n // Default agent\n lines.push(`Default agent: ${config.defaultAgent}`);\n\n // Workspace\n lines.push(`Workspace: ${config.workspace.baseDir}`);\n\n // Run mode\n lines.push(`Run mode: ${config.runMode}${config.autoStart ? \" (auto-start)\" : \"\"}`);\n\n return lines.join(\"\\n\");\n}\n","import { execFileSync } from \"node:child_process\";\nimport * as clack from \"@clack/prompts\";\nimport { commandExists } from \"../agents/agent-dependencies.js\";\nimport { guardCancel, ok, warn, c } from \"./helpers.js\";\n\nconst KNOWN_AGENTS: Array<{ name: string; commands: string[] }> = [\n // claude-agent-acp is bundled as a dependency — no detection needed, but\n // kept here so detectAgents() still returns it for display purposes.\n { name: \"claude\", commands: [\"claude-agent-acp\"] },\n { name: \"codex\", commands: [\"codex\"] },\n];\n\nexport async function detectAgents(): Promise<\n Array<{ name: string; command: string }>\n> {\n const found: Array<{ name: string; command: string }> = [];\n for (const agent of KNOWN_AGENTS) {\n // Find all available commands for this agent (PATH + node_modules/.bin)\n const available: string[] = [];\n for (const cmd of agent.commands) {\n if (commandExists(cmd)) {\n available.push(cmd);\n }\n }\n if (available.length > 0) {\n // Prefer claude-agent-acp over claude/claude-code (priority order)\n found.push({ name: agent.name, command: available[0] });\n }\n }\n return found;\n}\n\nexport async function validateAgentCommand(command: string): Promise<boolean> {\n try {\n execFileSync(\"which\", [command], { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function setupAgents(): Promise<{\n defaultAgent: string;\n}> {\n const { AgentCatalog } = await import(\"../agents/agent-catalog.js\");\n const { muteLogger, unmuteLogger } = await import(\"../utils/log.js\");\n\n muteLogger();\n const catalog = new AgentCatalog();\n catalog.load();\n\n const s = clack.spinner();\n s.start(\"Checking available agents...\");\n await catalog.refreshRegistryIfStale();\n\n // Claude is always pre-installed (bundled dependency)\n if (!catalog.getInstalledAgent(\"claude\")) {\n const claudeRegistry = catalog.findRegistryAgent(\"claude-acp\");\n if (claudeRegistry) {\n await catalog.install(\"claude-acp\");\n } else {\n // Fallback: register bundled claude-agent-acp directly\n const { AgentStore } = await import(\"../agents/agent-store.js\");\n const store = new AgentStore();\n store.load();\n store.addAgent(\"claude\", {\n registryId: \"claude-acp\",\n name: \"Claude Agent\",\n version: \"bundled\",\n distribution: \"npx\",\n command: \"npx\",\n args: [\"@zed-industries/claude-agent-acp\"],\n env: {},\n installedAt: new Date().toISOString(),\n binaryPath: null,\n });\n }\n }\n s.stop(ok(\"Claude Agent ready\"));\n unmuteLogger();\n\n const available = catalog.getAvailable();\n const installed = available.filter((a) => a.installed);\n const installable = available.filter((a) => !a.installed && a.available);\n\n // Offer agent selection — show installed agents as pre-checked + installable agents\n if (installed.length > 0 || installable.length > 0) {\n // Deduplicate by key AND name\n const seen = new Set<string>();\n const options: Array<{ label: string; value: string }> = [];\n\n for (const a of installed) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (installed)`,\n value: a.key,\n });\n }\n for (const a of installable) {\n const dedupeKey = `${a.key}::${a.name}`;\n if (seen.has(dedupeKey)) continue;\n seen.add(dedupeKey);\n options.push({\n label: `${a.name} (${a.distribution})`,\n value: a.key,\n });\n }\n\n const installedKeys = installed.map(a => a.key);\n const selected = guardCancel(\n await clack.autocompleteMultiselect({\n message: \"Install additional agents? (type to search, Space to select)\",\n options,\n initialValues: installedKeys,\n required: false,\n }),\n ) as string[];\n\n for (const key of selected) {\n const regAgent = catalog.findRegistryAgent(key);\n if (regAgent) {\n const installSpinner = clack.spinner();\n installSpinner.start(`Installing ${regAgent.name}...`);\n muteLogger();\n const result = await catalog.install(key);\n unmuteLogger();\n if (result.ok) {\n installSpinner.stop(ok(\"done\"));\n } else {\n installSpinner.stop(warn(`skipped: ${result.error}`));\n }\n }\n }\n }\n\n // Choose default agent\n const installedAgents = Object.keys(catalog.getInstalledEntries());\n let defaultAgent = \"claude\";\n\n if (installedAgents.length > 1) {\n defaultAgent = guardCancel(\n await clack.select({\n message: \"Which agent should be the default?\",\n options: installedAgents.map((key) => {\n const agent = catalog.getInstalledAgent(key)!;\n return { label: `${agent.name} (${key})`, value: key };\n }),\n initialValue: \"claude\",\n }),\n ) as string;\n }\n\n console.log(ok(`Default agent: ${c.bold}${defaultAgent}${c.reset}`));\n return { defaultAgent };\n}\n","import * as clack from \"@clack/prompts\";\nimport { guardCancel, step } from \"./helpers.js\";\n\nexport async function setupWorkspace(opts?: {\n existing?: string;\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ baseDir: string }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, \"Workspace\"));\n }\n\n const baseDir = guardCancel(\n await clack.text({\n message: \"Base directory for workspaces:\",\n initialValue: existing ?? \"~/openacp-workspace\",\n validate: (val) =>\n (val ?? \"\").toString().trim().length > 0 ? undefined : \"Path cannot be empty\",\n }),\n ) as string;\n\n return { baseDir: baseDir.trim().replace(/^['\"]|['\"]$/g, \"\") };\n}\n","import * as clack from \"@clack/prompts\";\nimport { expandHome } from \"../config/config.js\";\nimport { guardCancel, ok, warn, dim, step } from \"./helpers.js\";\n\nexport async function setupRunMode(opts?: {\n existing?: { runMode: string; autoStart: boolean };\n stepNum?: number;\n totalSteps?: number;\n}): Promise<{ runMode: 'foreground' | 'daemon'; autoStart: boolean }> {\n const { existing, stepNum, totalSteps } = opts ?? {};\n if (stepNum != null && totalSteps != null) {\n console.log(step(stepNum, totalSteps, 'Run Mode'));\n }\n\n // Don't show daemon option on Windows\n if (process.platform === 'win32') {\n console.log(dim(' (Daemon mode not available on Windows)'));\n return { runMode: 'foreground', autoStart: false };\n }\n\n const initialValue = (existing?.runMode === 'daemon' ? 'daemon' : 'foreground') as 'foreground' | 'daemon';\n\n const mode = guardCancel(\n await clack.select({\n message: 'How would you like to run OpenACP?',\n options: [\n {\n label: 'Background (daemon)',\n value: 'daemon' as const,\n hint: 'Runs silently, auto-starts on boot. Manage with: openacp status | stop | logs',\n },\n {\n label: 'Foreground (terminal)',\n value: 'foreground' as const,\n hint: 'Runs in current terminal session. Start with: openacp',\n },\n ],\n initialValue,\n }),\n );\n\n const wasDaemon = existing?.runMode === 'daemon';\n\n if (mode === 'daemon') {\n const { installAutoStart, isAutoStartSupported } = await import('../../cli/autostart.js');\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n const autoStart = isAutoStartSupported();\n if (autoStart) {\n muteLogger();\n const result = installAutoStart(expandHome('~/.openacp/logs'));\n unmuteLogger();\n if (result.success) {\n console.log(ok('Auto-start on boot enabled'));\n } else {\n console.log(warn(`Auto-start failed: ${result.error}`));\n }\n }\n return { runMode: 'daemon', autoStart };\n }\n\n // Switching from daemon → foreground: stop daemon + uninstall autostart\n if (wasDaemon) {\n const { muteLogger, unmuteLogger } = await import('../utils/log.js');\n muteLogger();\n try {\n const { stopDaemon } = await import('../../cli/daemon.js');\n const result = await stopDaemon();\n unmuteLogger();\n if (result.stopped) {\n console.log(ok(`Daemon stopped (was PID ${result.pid})`));\n }\n } catch {\n unmuteLogger();\n // Daemon may not be running\n }\n muteLogger();\n try {\n const { uninstallAutoStart } = await import('../../cli/autostart.js');\n uninstallAutoStart();\n unmuteLogger();\n } catch {\n unmuteLogger();\n // ignore\n }\n }\n\n return { runMode: 'foreground', autoStart: false };\n}\n","import * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport { guardCancel } from \"./helpers.js\";\n\nexport async function setupIntegrations(config?: Config): Promise<void> {\n const claudeIntegration = (config?.integrations as Record<string, unknown> | undefined)?.claude as { installed?: boolean } | undefined;\n const isInstalled = claudeIntegration?.installed === true;\n\n const installClaude = guardCancel(\n await clack.confirm({\n message: isInstalled\n ? \"Claude CLI integration is installed. Reinstall?\"\n : \"Install session transfer for Claude? (enables /openacp:handoff in your terminal)\",\n initialValue: !isInstalled,\n }),\n );\n\n if (installClaude) {\n try {\n const { getIntegration } = await import(\"../../cli/integrate.js\");\n const integration = getIntegration(\"claude\");\n if (integration) {\n for (const item of integration.items) {\n const result = await item.install();\n for (const log of result.logs) console.log(` ${log}`);\n }\n }\n console.log(\"Claude CLI integration installed.\\n\");\n } catch (err) {\n console.log(`Could not install Claude CLI integration: ${err instanceof Error ? err.message : err}`);\n console.log(\" You can install it later with: openacp integrate claude\\n\");\n }\n }\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport * as clack from \"@clack/prompts\";\nimport type { Config } from \"../config/config.js\";\nimport type { ConfiguredChannelAction, ChannelId, ChannelStatus } from \"./types.js\";\nimport { CHANNEL_META } from \"./types.js\";\nimport { guardCancel, ok, c } from \"./helpers.js\";\n\nexport function getChannelStatuses(config: Config): ChannelStatus[] {\n const statuses: ChannelStatus[] = [];\n\n for (const [id, meta] of Object.entries(CHANNEL_META) as [ChannelId, typeof CHANNEL_META[ChannelId]][]) {\n const ch = config.channels[id] as Record<string, unknown> | undefined;\n const enabled = ch?.enabled === true;\n const configured = !!ch && Object.keys(ch).length > 1;\n\n let hint: string | undefined;\n if (id === \"telegram\" && ch?.botToken && typeof ch.botToken === \"string\" && ch.botToken !== \"YOUR_BOT_TOKEN_HERE\") {\n hint = `Chat ID: ${ch.chatId}`;\n }\n if (id === \"discord\" && ch?.guildId) {\n hint = `Guild: ${ch.guildId}`;\n }\n\n statuses.push({ id, label: meta.label, configured, enabled, hint });\n }\n\n return statuses;\n}\n\nexport function noteChannelStatus(config: Config): void {\n const statuses = getChannelStatuses(config);\n const lines = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n const hintStr = s.hint ? ` — ${s.hint}` : \"\";\n return ` ${s.label}: ${status}${hintStr}`;\n });\n\n console.log(\"\");\n console.log(`${c.bold} Channel status${c.reset}`);\n for (const line of lines) console.log(line);\n console.log(\"\");\n}\n\nasync function promptConfiguredAction(label: string): Promise<ConfiguredChannelAction> {\n return guardCancel(\n await clack.select({\n message: `${label} already configured. What do you want to do?`,\n options: [\n { value: \"modify\" as const, label: \"Modify settings\" },\n { value: \"disable\" as const, label: \"Disable bot\" },\n { value: \"delete\" as const, label: \"Delete config\" },\n { value: \"skip\" as const, label: \"Skip (leave as-is)\" },\n ],\n initialValue: \"modify\" as const,\n }),\n );\n}\n\nasync function configureViaPlugin(channelId: ChannelId): Promise<void> {\n const pluginImports: Record<ChannelId, () => Promise<any>> = {\n telegram: () => import('../../plugins/telegram/index.js'),\n discord: async () => {\n const pkg = '@openacp/adapter-discord';\n try {\n return await import(/* webpackIgnore: true */ pkg);\n } catch {\n throw new Error(\n `${pkg} is not installed. Run: openacp plugin add ${pkg}`,\n );\n }\n },\n };\n\n const importer = pluginImports[channelId];\n if (!importer) return;\n\n const { SettingsManager } = await import('../plugin/settings-manager.js');\n const { createInstallContext } = await import('../plugin/install-context.js');\n const basePath = path.join(os.homedir(), '.openacp', 'plugins');\n const settingsManager = new SettingsManager(basePath);\n\n const pluginModule = await importer();\n const plugin = pluginModule.default;\n\n if (plugin?.configure) {\n const ctx = createInstallContext({\n pluginName: plugin.name,\n settingsManager,\n basePath,\n });\n await plugin.configure(ctx);\n }\n}\n\nexport async function configureChannels(config: Config): Promise<{ config: Config; changed: boolean }> {\n const next = structuredClone(config);\n let changed = false;\n\n noteChannelStatus(next);\n\n while (true) {\n const statuses = getChannelStatuses(next);\n const options = statuses.map((s) => {\n const status = s.enabled ? \"enabled\" : s.configured ? \"disabled\" : \"not configured\";\n return {\n value: s.id,\n label: `${s.label} (${CHANNEL_META[s.id].method})`,\n hint: status + (s.hint ? ` · ${s.hint}` : \"\"),\n };\n });\n\n const choice = guardCancel(\n await clack.select({\n message: \"Select a channel\",\n options: [\n ...options,\n { value: \"__done__\" as const, label: \"Finished\" },\n ],\n }),\n );\n\n if (choice === \"__done__\") break;\n\n const channelId = choice as ChannelId;\n const meta = CHANNEL_META[channelId];\n const existing = next.channels[channelId] as Record<string, unknown> | undefined;\n const isConfigured = !!existing && Object.keys(existing).length > 1;\n\n if (isConfigured) {\n const action = await promptConfiguredAction(meta.label);\n\n if (action === \"skip\") continue;\n if (action === \"disable\") {\n (next.channels[channelId] as Record<string, unknown>).enabled = false;\n changed = true;\n console.log(ok(`${meta.label} disabled`));\n continue;\n }\n if (action === \"delete\") {\n const confirmed = guardCancel(\n await clack.confirm({\n message: `Delete ${meta.label} config? This cannot be undone.`,\n initialValue: false,\n }),\n );\n if (confirmed) {\n delete next.channels[channelId];\n changed = true;\n console.log(ok(`${meta.label} config deleted`));\n }\n continue;\n }\n // action === \"modify\" — fall through to plugin configure\n }\n\n // Run channel configuration via plugin configure()\n await configureViaPlugin(channelId);\n changed = true;\n }\n\n return { config: next, changed };\n}\n"],"mappings":"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","names":["clack","text","clack","clack","clack","clack","clack","spinner"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
telegram_default
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-P2G275VD.js";
|
|
4
4
|
import "./chunk-VUNV25KB.js";
|
|
5
5
|
export {
|
|
6
6
|
telegram_default as default
|
|
7
7
|
};
|
|
8
|
-
//# sourceMappingURL=telegram-
|
|
8
|
+
//# sourceMappingURL=telegram-E65IWFBW.js.map
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugins/slack/adapter.ts","../../src/plugins/slack/utils.ts","../../src/plugins/slack/formatter.ts","../../src/plugins/slack/renderer.ts","../../src/plugins/slack/send-queue.ts","../../src/plugins/slack/slug.ts","../../src/plugins/slack/channel-manager.ts","../../src/plugins/slack/permission-handler.ts","../../src/plugins/slack/event-router.ts","../../src/plugins/slack/text-buffer.ts"],"sourcesContent":["// src/adapters/slack/adapter.ts\nimport fs from \"node:fs\";\nimport { App } from \"@slack/bolt\";\nimport { WebClient } from \"@slack/web-api\";\nimport type { OpenACPCore } from \"../../core/core.js\";\nimport type {\n OutgoingMessage,\n PermissionRequest,\n NotificationMessage,\n Attachment,\n} from \"../../core/types.js\";\nimport type { AdapterCapabilities } from \"../../core/channel.js\";\nimport type { FileServiceInterface } from \"../../core/plugin/types.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\nimport { MessagingAdapter, type MessagingAdapterConfig } from \"../../core/adapter-primitives/messaging-adapter.js\";\nimport type { DisplayVerbosity } from \"../../core/adapter-primitives/format-types.js\";\nimport type { IRenderer } from \"../../core/adapter-primitives/rendering/renderer.js\";\nimport { SlackRenderer } from \"./renderer.js\";\nconst log = createChildLogger({ module: \"slack\" });\n\nimport type { SlackChannelConfig } from \"./types.js\";\nimport type { SlackSessionMeta, SlackFileInfo } from \"./types.js\";\nimport { SlackSendQueue } from \"./send-queue.js\";\nimport { SlackFormatter } from \"./formatter.js\";\nimport { SlackChannelManager } from \"./channel-manager.js\";\nimport { SlackPermissionHandler } from \"./permission-handler.js\";\nimport { SlackEventRouter } from \"./event-router.js\";\nimport { SlackTextBuffer } from \"./text-buffer.js\";\nimport { toSlug } from \"./slug.js\";\nimport { isAudioClip } from \"./utils.js\";\n\nexport class SlackAdapter extends MessagingAdapter {\n readonly name = 'slack';\n readonly renderer!: IRenderer;\n readonly capabilities: AdapterCapabilities = {\n streaming: true, richFormatting: true, threads: true,\n reactions: false, fileUpload: true, voice: true,\n };\n\n private core: OpenACPCore;\n private app!: App;\n private webClient!: WebClient;\n private queue!: SlackSendQueue;\n private formatter: SlackFormatter;\n private channelManager!: SlackChannelManager;\n private permissionHandler!: SlackPermissionHandler;\n private eventRouter!: SlackEventRouter;\n private sessions = new Map<string, SlackSessionMeta>();\n private textBuffers = new Map<string, SlackTextBuffer>();\n private botUserId = \"\";\n private slackConfig: SlackChannelConfig;\n private fileService!: FileServiceInterface;\n\n constructor(core: OpenACPCore, config: SlackChannelConfig) {\n super(\n { configManager: core.configManager },\n { ...config as Record<string, unknown>, maxMessageLength: 3000, enabled: config.enabled ?? true } as MessagingAdapterConfig,\n );\n this.core = core;\n this.slackConfig = config;\n this.formatter = new SlackFormatter();\n (this as { renderer: IRenderer }).renderer = new SlackRenderer(this.formatter);\n }\n\n async start(): Promise<void> {\n const { botToken, appToken, signingSecret } = this.slackConfig;\n\n if (!botToken || !appToken || !signingSecret) {\n throw new Error(\"Slack adapter requires botToken, appToken, and signingSecret\");\n }\n\n this.app = new App({\n token: botToken,\n appToken,\n signingSecret,\n socketMode: true,\n });\n\n this.webClient = new WebClient(botToken);\n this.queue = new SlackSendQueue(this.webClient);\n this.fileService = this.core.fileService;\n\n // Resolve bot user ID — required to filter bot's own messages (prevent infinite loop)\n const authResult = await this.webClient.auth.test();\n if (!authResult.user_id) {\n throw new Error(\"Slack auth.test() did not return user_id — verify botToken is valid\");\n }\n this.botUserId = authResult.user_id as string;\n log.info({ botUserId: this.botUserId }, \"Slack bot authenticated\");\n\n this.channelManager = new SlackChannelManager(this.queue, this.slackConfig);\n\n // Permission handler — resolve permission gate when user clicks a button\n this.permissionHandler = new SlackPermissionHandler(\n this.queue,\n (requestId, optionId) => {\n for (const [sessionId, _meta] of this.sessions) {\n const session = this.core.sessionManager.getSession(sessionId);\n if (session && session.permissionGate.requestId === requestId) {\n session.permissionGate.resolve(optionId);\n log.info({ sessionId, requestId, optionId }, \"Permission resolved\");\n return;\n }\n }\n log.warn({ requestId, optionId }, \"No matching session found for permission response\");\n },\n );\n this.permissionHandler.register(this.app);\n\n // Event router — dispatch incoming messages from session channels to core\n this.eventRouter = new SlackEventRouter(\n (slackChannelId) => {\n for (const meta of this.sessions.values()) {\n if (meta.channelId === slackChannelId) return meta;\n }\n return undefined;\n },\n (sessionChannelSlug, text, userId, files) => {\n const processFiles = async (): Promise<Attachment[] | undefined> => {\n if (!files?.length) return undefined;\n const audioFiles = files.filter((f) => isAudioClip(f));\n if (!audioFiles.length) return undefined;\n\n const attachments: Attachment[] = [];\n for (const file of audioFiles) {\n const buffer = await this.downloadSlackFile(file.url_private);\n if (!buffer) continue;\n const mimeType = file.mimetype === \"video/mp4\" ? \"audio/mp4\" : file.mimetype;\n const sessionId = this.core.sessionManager.getSessionByThread(\"slack\", sessionChannelSlug)?.id;\n if (!sessionId) continue;\n const att = await this.fileService.saveFile(sessionId, file.name, buffer, mimeType);\n attachments.push(att);\n }\n return attachments.length > 0 ? attachments : undefined;\n };\n\n processFiles()\n .then((attachments) => {\n this.core\n .handleMessage({\n channelId: \"slack\",\n threadId: sessionChannelSlug,\n userId,\n text,\n attachments,\n })\n .catch((err) => log.error({ err }, \"handleMessage error\"));\n })\n .catch((err) => log.error({ err }, \"Failed to process audio files\"));\n },\n this.botUserId,\n this.slackConfig.notificationChannelId,\n // onNewSession: reply with guidance when user messages the notification channel\n async (_text, _userId) => {\n if (this.slackConfig.notificationChannelId) {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: this.slackConfig.notificationChannelId,\n text: \"💬 To start a new session, use the `/openacp-new` slash command in any channel.\",\n }).catch((err: unknown) => log.warn({ err }, \"Failed to send onNewSession reply\"));\n }\n },\n this.slackConfig,\n this.core.configManager.get().security.allowedUserIds,\n );\n this.eventRouter.register(this.app);\n\n // Start Bolt (Socket Mode)\n await this.app.start();\n log.info(\"Slack adapter started (Socket Mode)\");\n\n // Create startup session + channel (configurable — set autoCreateSession: false to skip)\n if (this.slackConfig.autoCreateSession !== false) {\n await this._createStartupSession();\n }\n }\n\n private async downloadSlackFile(url: string): Promise<Buffer | null> {\n try {\n const resp = await fetch(url, {\n headers: { Authorization: `Bearer ${this.slackConfig.botToken}` },\n });\n if (!resp.ok) {\n log.warn({ status: resp.status }, \"Failed to download Slack file\");\n return null;\n }\n // Slack returns 200 with HTML login page if bot lacks files:read scope\n const contentType = resp.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"text/html\")) {\n log.warn(\"Slack file download returned HTML instead of binary — bot likely missing files:read scope. Reinstall the Slack app with files:read scope.\");\n return null;\n }\n return Buffer.from(await resp.arrayBuffer());\n } catch (err) {\n log.error({ err }, \"Error downloading Slack file\");\n return null;\n }\n }\n\n private async uploadAudioFile(channelId: string, att: Attachment): Promise<void> {\n const fileBuffer = await fs.promises.readFile(att.filePath);\n await this.webClient.files.uploadV2({\n channel_id: channelId,\n file: fileBuffer,\n filename: att.fileName,\n });\n }\n\n private async _createStartupSession(): Promise<void> {\n try {\n let reuseChannelId = this.slackConfig.startupChannelId;\n\n // Try to reuse existing startup channel (Telegram ensureTopics pattern)\n if (reuseChannelId) {\n try {\n const info = await this.queue.enqueue<Record<string, unknown>>(\n \"conversations.info\", { channel: reuseChannelId },\n );\n const channel = (info as Record<string, unknown>)?.channel as Record<string, unknown> | undefined;\n if (!channel || typeof channel.is_archived !== \"boolean\") {\n log.warn({ reuseChannelId }, \"Unexpected conversations.info response shape, creating new channel\");\n reuseChannelId = undefined;\n } else if (channel.is_archived) {\n await this.queue.enqueue(\"conversations.unarchive\", { channel: reuseChannelId });\n log.info({ channelId: reuseChannelId }, \"Unarchived startup channel for reuse\");\n }\n } catch {\n // Channel deleted or inaccessible — will create new\n reuseChannelId = undefined;\n }\n }\n\n if (reuseChannelId) {\n // Reuse existing channel — create session pointing to it\n let hasSession = false;\n for (const m of this.sessions.values()) {\n if (m.channelId === reuseChannelId) { hasSession = true; break; }\n }\n if (!hasSession) {\n const session = await this.core.handleNewSession(\"slack\", undefined, undefined, { createThread: false });\n const slug = `startup-${session.id.slice(0, 8)}`;\n this.sessions.set(session.id, { channelId: reuseChannelId, channelSlug: slug });\n session.threadId = slug;\n // Persist slug to session store so session resume after restart can find it\n await this.core.sessionManager.patchRecord(session.id, {\n platform: { topicId: slug },\n });\n log.info({ sessionId: session.id, channelId: reuseChannelId }, \"Reused startup channel\");\n }\n } else {\n // Create new channel + session\n const session = await this.core.handleNewSession(\"slack\", undefined, undefined, { createThread: true });\n if (!session.threadId) {\n log.error({ sessionId: session.id }, \"Startup session created without threadId\");\n return;\n }\n\n // Persist channel ID to config for reuse on next restart\n const meta = this.sessions.get(session.id);\n if (meta) {\n await this.core.configManager.save(\n { channels: { slack: { startupChannelId: meta.channelId } } },\n );\n log.info({ sessionId: session.id, channelId: meta.channelId }, \"Saved startup channel to config\");\n }\n }\n\n // Notify\n if (this.slackConfig.notificationChannelId) {\n const startupMeta = [...this.sessions.values()].find(m =>\n m.channelId === (reuseChannelId ?? this.slackConfig.startupChannelId)\n );\n if (startupMeta) {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: this.slackConfig.notificationChannelId,\n text: `✅ OpenACP ready — chat with the agent in <#${startupMeta.channelId}>`,\n });\n }\n }\n } catch (err) {\n log.error({ err }, \"Failed to create/reuse Slack startup session\");\n }\n }\n\n async stop(): Promise<void> {\n // Flush all active text buffers before stopping to prevent data loss\n for (const [sessionId, buf] of this.textBuffers) {\n try {\n await buf.flush();\n } catch (err) {\n log.warn({ err, sessionId }, \"Flush failed during stop\");\n }\n buf.destroy();\n }\n this.textBuffers.clear();\n await this.app.stop();\n log.info(\"Slack adapter stopped\");\n }\n\n // --- MessagingAdapter implementations ---\n\n async createSessionThread(sessionId: string, name: string): Promise<string> {\n const meta = await this.channelManager.createChannel(sessionId, name);\n this.sessions.set(sessionId, meta);\n log.info({ sessionId, channelId: meta.channelId, slug: meta.channelSlug }, \"Session channel created\");\n // Return the slug as the threadId so that lookups via getSessionByThread work\n return meta.channelSlug;\n }\n\n async renameSessionThread(sessionId: string, newName: string): Promise<void> {\n const meta = this.sessions.get(sessionId);\n if (!meta) return;\n\n const newSlug = toSlug(newName, this.slackConfig.channelPrefix ?? \"openacp\");\n\n try {\n await this.queue.enqueue(\"conversations.rename\", {\n channel: meta.channelId,\n name: newSlug,\n });\n meta.channelSlug = newSlug;\n // Update session.threadId so getSessionByThread() keeps working after rename\n const session = this.core.sessionManager.getSession(sessionId);\n if (session) session.threadId = newSlug;\n const existingRecord = this.core.sessionManager.getSessionRecord(sessionId);\n await this.core.sessionManager.patchRecord(sessionId, {\n name: newName,\n platform: { ...(existingRecord?.platform ?? {}), topicId: newSlug },\n });\n log.info({ sessionId, newSlug }, \"Session channel renamed\");\n } catch (err) {\n log.warn({ err, sessionId }, \"Failed to rename Slack channel\");\n }\n }\n\n async deleteSessionThread(sessionId: string): Promise<void> {\n const meta = this.sessions.get(sessionId);\n if (!meta) return;\n\n try {\n await this.permissionHandler.cleanupSession(meta.channelId);\n } catch (err) {\n log.warn({ err, sessionId }, \"Failed to clean up permission buttons\");\n }\n\n try {\n await this.channelManager.archiveChannel(meta.channelId);\n log.info({ sessionId, channelId: meta.channelId }, \"Session channel archived\");\n } catch (err) {\n log.warn({ err, sessionId }, \"Failed to archive Slack channel\");\n }\n this.sessions.delete(sessionId);\n const buf = this.textBuffers.get(sessionId);\n if (buf) { buf.destroy(); this.textBuffers.delete(sessionId); }\n }\n\n private _sessionMetas = new Map<string, SlackSessionMeta>();\n\n private getSessionMeta(sessionId: string): SlackSessionMeta | undefined {\n return this._sessionMetas.get(sessionId);\n }\n\n private getTextBuffer(sessionId: string, channelId: string): SlackTextBuffer {\n let buf = this.textBuffers.get(sessionId);\n if (!buf) {\n buf = new SlackTextBuffer(channelId, sessionId, this.queue);\n this.textBuffers.set(sessionId, buf);\n }\n return buf;\n }\n\n async sendMessage(sessionId: string, content: OutgoingMessage): Promise<void> {\n const meta = this.sessions.get(sessionId);\n if (!meta) {\n log.warn({ sessionId }, \"No Slack channel for session, skipping message\");\n return;\n }\n\n // Store meta per-session so concurrent calls for different sessions don't overwrite each other\n this._sessionMetas.set(sessionId, meta);\n try {\n await super.sendMessage(sessionId, content);\n } finally {\n this._sessionMetas.delete(sessionId);\n }\n }\n\n // --- Handler overrides (dispatched by base class) ---\n\n protected async handleText(sessionId: string, content: OutgoingMessage): Promise<void> {\n const meta = this.getSessionMeta(sessionId);\n if (!meta) return;\n // Text chunks are buffered and flushed as a single message after idle timeout\n const buf = this.getTextBuffer(sessionId, meta.channelId);\n buf.append(content.text ?? \"\");\n }\n\n protected async handleSessionEnd(sessionId: string, content: OutgoingMessage): Promise<void> {\n const meta = this.getSessionMeta(sessionId);\n if (!meta) return;\n // Flush any pending text first\n await this.flushTextBuffer(sessionId);\n\n const blocks = this.formatter.formatOutgoing(content);\n if (blocks.length === 0) return;\n\n try {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: meta.channelId,\n text: content.text ?? content.type,\n blocks,\n });\n } catch (err) {\n log.error({ err, sessionId, type: content.type }, \"Failed to post Slack message\");\n }\n }\n\n protected async handleError(sessionId: string, content: OutgoingMessage): Promise<void> {\n const meta = this.getSessionMeta(sessionId);\n if (!meta) return;\n // Flush any pending text first\n await this.flushTextBuffer(sessionId);\n\n const blocks = this.formatter.formatOutgoing(content);\n if (blocks.length === 0) return;\n\n try {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: meta.channelId,\n text: content.text ?? content.type,\n blocks,\n });\n } catch (err) {\n log.error({ err, sessionId, type: content.type }, \"Failed to post Slack message\");\n }\n }\n\n protected async handleAttachment(sessionId: string, content: OutgoingMessage): Promise<void> {\n const meta = this.getSessionMeta(sessionId);\n if (!meta || !content.attachment) return;\n if (content.attachment.type === \"audio\") {\n try {\n await this.uploadAudioFile(meta.channelId, content.attachment);\n const buf = this.textBuffers.get(sessionId);\n if (buf) await buf.stripTtsBlock();\n } catch (err) {\n log.error({ err, sessionId }, \"Failed to upload audio to Slack\");\n }\n }\n }\n\n protected async handleThought(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void> {\n await this.postFormattedMessage(sessionId, content);\n }\n\n protected async handleToolCall(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void> {\n await this.postFormattedMessage(sessionId, content);\n }\n\n protected async handleToolUpdate(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void> {\n await this.postFormattedMessage(sessionId, content);\n }\n\n protected async handlePlan(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void> {\n await this.postFormattedMessage(sessionId, content);\n }\n\n protected async handleUsage(sessionId: string, content: OutgoingMessage, _verbosity: DisplayVerbosity): Promise<void> {\n await this.postFormattedMessage(sessionId, content);\n }\n\n protected async handleSystem(sessionId: string, content: OutgoingMessage): Promise<void> {\n await this.postFormattedMessage(sessionId, content);\n }\n\n // --- Private helpers ---\n\n private async flushTextBuffer(sessionId: string): Promise<void> {\n const buf = this.textBuffers.get(sessionId);\n if (buf) {\n try {\n await buf.flush();\n } catch (err) {\n log.warn({ err, sessionId }, \"Flush failed on session_end\");\n }\n buf.destroy();\n this.textBuffers.delete(sessionId);\n }\n }\n\n private async postFormattedMessage(sessionId: string, content: OutgoingMessage): Promise<void> {\n const meta = this.getSessionMeta(sessionId);\n if (!meta) return;\n const blocks = this.formatter.formatOutgoing(content);\n if (blocks.length === 0) return;\n\n try {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: meta.channelId,\n text: content.text ?? content.type,\n blocks,\n });\n } catch (err) {\n log.error({ err, sessionId, type: content.type }, \"Failed to post Slack message\");\n }\n }\n\n // NOTE: Async flow — different from Telegram adapter.\n // Telegram: sendPermissionRequest awaits user response inline.\n // Slack: posts interactive buttons and returns immediately.\n // Resolution happens asynchronously via the Bolt action handler in\n // SlackPermissionHandler, which calls the PermissionResponseCallback\n // passed during construction. The callback iterates sessions to find\n // the matching permissionGate and resolves it.\n async sendPermissionRequest(\n sessionId: string,\n request: PermissionRequest,\n ): Promise<void> {\n const meta = this.sessions.get(sessionId);\n if (!meta) return;\n\n log.info({ sessionId, requestId: request.id }, \"Sending Slack permission request\");\n const blocks = this.formatter.formatPermissionRequest(request);\n\n try {\n const result = await this.queue.enqueue(\"chat.postMessage\", {\n channel: meta.channelId,\n text: `Permission request: ${request.description}`,\n blocks,\n });\n const ts = (result as { ts?: string })?.ts;\n if (ts) {\n this.permissionHandler.trackPendingMessage(request.id, meta.channelId, ts);\n }\n } catch (err) {\n log.error({ err, sessionId }, \"Failed to post Slack permission request\");\n }\n }\n\n async sendNotification(notification: NotificationMessage): Promise<void> {\n if (!this.slackConfig.notificationChannelId) return;\n\n const emoji: Record<string, string> = {\n completed: \"✅\",\n error: \"❌\",\n permission: \"🔐\",\n input_required: \"💬\",\n };\n const icon = emoji[notification.type] ?? \"ℹ️\";\n const text = `${icon} *${notification.sessionName ?? \"Session\"}*\\n${notification.summary}`;\n const blocks = this.formatter.formatNotification(text);\n\n try {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: this.slackConfig.notificationChannelId,\n text,\n blocks,\n });\n } catch (err) {\n log.warn({ err, sessionId: notification.sessionId }, \"Failed to send Slack notification\");\n }\n }\n}\n\nexport type { SlackChannelConfig } from \"./types.js\";\n","// src/adapters/slack/utils.ts\n// Shared utilities for Slack adapter modules.\n\nimport type { SlackFileInfo } from \"./types.js\";\n\n/** Detect Slack audio clips — MIME type or filename pattern */\nexport function isAudioClip(file: SlackFileInfo): boolean {\n return (file.mimetype === \"video/mp4\" && file.name?.startsWith(\"audio_message\")) ||\n file.mimetype?.startsWith(\"audio/\");\n}\n\nconst SECTION_LIMIT = 3000;\n\n/**\n * Split text at nearest newline boundary before `limit`.\n * Does NOT track code fence state — a triple-backtick block straddling\n * the boundary will be split mid-block.\n * Used by SlackFormatter and SlackTextBuffer to avoid exceeding Slack's\n * 3000-char section limit.\n */\nexport function splitSafe(text: string, limit = SECTION_LIMIT): string[] {\n if (text.length <= limit) return [text];\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (remaining.length <= limit) { chunks.push(remaining); break; }\n let cut = remaining.lastIndexOf(\"\\n\", limit);\n if (cut <= 0) cut = limit;\n chunks.push(remaining.slice(0, cut));\n remaining = remaining.slice(cut).trimStart();\n }\n return chunks;\n}\n","// src/adapters/slack/formatter.ts\nimport type { types } from \"@slack/bolt\";\nimport type { OutgoingMessage, PermissionRequest } from \"../../core/types.js\";\nimport { splitSafe } from \"./utils.js\";\n\ntype KnownBlock = types.KnownBlock;\n\nexport interface ISlackFormatter {\n formatOutgoing(message: OutgoingMessage): KnownBlock[];\n formatPermissionRequest(req: PermissionRequest): KnownBlock[];\n formatNotification(text: string): KnownBlock[];\n formatSessionEnd(reason?: string): KnownBlock[];\n}\n\n/**\n * Convert a markdown string to Slack mrkdwn format.\n * Handles the most common patterns from AI responses.\n */\nexport function markdownToMrkdwn(text: string): string {\n return text\n // Fenced code blocks — preserve as-is (Slack supports ``` natively)\n // Headers: # H1 → placeholder (protected from italic regex)\n .replace(/^#{1,6}\\s+(.+)$/gm, \"\\x00BOLD\\x00$1\\x00BOLD\\x00\")\n // Bold: **text** → placeholder\n .replace(/\\*\\*(.+?)\\*\\*/g, \"\\x00BOLD\\x00$1\\x00BOLD\\x00\")\n // Italic: *text* → _text_ (won't match placeholder tokens)\n .replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, \"_$1_\")\n // Restore bold/header placeholders → *text*\n .replace(/\\x00BOLD\\x00(.+?)\\x00BOLD\\x00/g, \"*$1*\")\n // Inline code: `code` — kept as-is (Slack supports backtick)\n // Strikethrough: ~~text~~ → ~text~\n .replace(/~~(.+?)~~/g, \"~$1~\")\n // Links: [text](url) → <url|text>\n .replace(/\\[([^\\]]+)\\]\\((https?:\\/\\/[^)]+)\\)/g, \"<$2|$1>\")\n // Unordered lists: \"- item\" or \"* item\" → \"• item\"\n .replace(/^[ \\t]*[-*]\\s+/gm, \"• \")\n // Ordered lists: \"1. item\" → \"1. item\" (already fine in mrkdwn)\n .trim();\n}\n\n// Slack mrkdwn text block, max 3000 chars per section\nconst SECTION_LIMIT = 3000;\n\nfunction section(text: string): KnownBlock {\n return { type: \"section\", text: { type: \"mrkdwn\", text: text.slice(0, SECTION_LIMIT) } };\n}\n\nfunction context(text: string): KnownBlock {\n return { type: \"context\", elements: [{ type: \"mrkdwn\", text }] };\n}\n\nexport class SlackFormatter implements ISlackFormatter {\n formatOutgoing(message: OutgoingMessage): KnownBlock[] {\n switch (message.type) {\n case \"text\": {\n const text = message.text ?? \"\";\n if (!text.trim()) return [];\n const converted = markdownToMrkdwn(text);\n return splitSafe(converted).map(chunk => section(chunk));\n }\n\n case \"thought\":\n return [context(`💭 _${(message.text ?? \"\").slice(0, 500)}_`)];\n\n case \"tool_call\": {\n const name = (message as OutgoingMessage & { metadata?: { name?: string; input?: unknown } }).metadata?.name ?? \"tool\";\n const input = (message as OutgoingMessage & { metadata?: { input?: unknown } }).metadata?.input;\n const inputStr = input ? `\\n\\`\\`\\`\\n${JSON.stringify(input, null, 2).slice(0, 500)}\\n\\`\\`\\`` : \"\";\n return [context(`🔧 \\`${name}\\`${inputStr}`)];\n }\n\n case \"tool_update\": {\n const name = (message as OutgoingMessage & { metadata?: { name?: string; status?: string } }).metadata?.name ?? \"tool\";\n const status = (message as OutgoingMessage & { metadata?: { status?: string } }).metadata?.status ?? \"done\";\n const icon = status === \"error\" ? \"❌\" : \"✅\";\n return [context(`${icon} \\`${name}\\` — ${status}`)];\n }\n\n case \"plan\":\n return [\n { type: \"divider\" },\n section(`📋 *Plan*\\n${message.text ?? \"\"}`),\n ];\n\n case \"usage\": {\n const meta = (message as OutgoingMessage & { metadata?: { input_tokens?: number; output_tokens?: number; cost_usd?: number } }).metadata ?? {};\n const parts = [\n meta.input_tokens != null ? `in: ${meta.input_tokens}` : null,\n meta.output_tokens != null ? `out: ${meta.output_tokens}` : null,\n meta.cost_usd != null ? `$${Number(meta.cost_usd).toFixed(4)}` : null,\n ].filter((p): p is string => p !== null);\n return parts.length ? [context(`📊 ${parts.join(\" · \")}`)] : [];\n }\n\n case \"session_end\":\n return this.formatSessionEnd(message.text);\n\n case \"error\":\n return [section(`⚠️ *Error:* ${message.text ?? \"Unknown error\"}`)];\n\n default:\n return [];\n }\n }\n\n formatPermissionRequest(req: PermissionRequest): KnownBlock[] {\n return [\n section(`🔐 *Permission Request*\\n${req.description}`),\n {\n type: \"actions\",\n block_id: `perm_${req.id}`,\n elements: req.options.map(opt => ({\n type: \"button\" as const,\n text: { type: \"plain_text\" as const, text: opt.label, emoji: true },\n value: `${req.id}:${opt.id}`,\n action_id: `perm_action_${opt.id}_${req.id}`,\n style: (opt.isAllow ? \"primary\" : \"danger\") as \"primary\" | \"danger\",\n })),\n } as KnownBlock,\n ];\n }\n\n formatNotification(text: string): KnownBlock[] {\n return [section(text)];\n }\n\n formatSessionEnd(reason?: string): KnownBlock[] {\n return [\n { type: \"divider\" },\n context(`✅ Session ended${reason ? ` — ${reason}` : \"\"}`),\n ];\n }\n}\n","import { BaseRenderer } from '../../core/adapter-primitives/rendering/renderer.js'\nimport type { RenderedMessage, RenderedPermission } from '../../core/adapter-primitives/rendering/renderer.js'\nimport type { OutgoingMessage, PermissionRequest, NotificationMessage } from '../../core/types.js'\nimport type { DisplayVerbosity } from '../../core/adapter-primitives/format-types.js'\nimport { SlackFormatter, markdownToMrkdwn } from './formatter.js'\n\n/**\n * SlackRenderer — renders messages as Slack Block Kit structures.\n * Delegates to the existing SlackFormatter for block generation,\n * wrapping results into RenderedMessage with format: 'structured'.\n */\nexport class SlackRenderer extends BaseRenderer {\n private formatter: SlackFormatter\n\n constructor(formatter?: SlackFormatter) {\n super()\n this.formatter = formatter ?? new SlackFormatter()\n }\n\n renderText(content: OutgoingMessage): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderThought(content: OutgoingMessage, _verbosity: DisplayVerbosity): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderToolCall(content: OutgoingMessage, _verbosity: DisplayVerbosity): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderToolUpdate(content: OutgoingMessage, _verbosity: DisplayVerbosity): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderPlan(content: OutgoingMessage, _verbosity: DisplayVerbosity): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderUsage(content: OutgoingMessage, _verbosity: DisplayVerbosity): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderError(content: OutgoingMessage): RenderedMessage {\n const blocks = this.formatter.formatOutgoing(content)\n return {\n body: content.text ?? '',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderSessionEnd(content: OutgoingMessage): RenderedMessage {\n const blocks = this.formatter.formatSessionEnd(content.text)\n return {\n body: content.text ?? 'Session ended',\n format: 'structured',\n components: blocks,\n }\n }\n\n renderPermission(request: PermissionRequest): RenderedPermission {\n const blocks = this.formatter.formatPermissionRequest(request)\n return {\n body: request.description,\n format: 'structured',\n components: blocks,\n actions: request.options.map(o => ({ id: o.id, label: o.label, isAllow: o.isAllow })),\n }\n }\n\n renderNotification(notification: NotificationMessage): RenderedMessage {\n const emoji: Record<string, string> = {\n completed: '✅', error: '❌', permission: '🔐', input_required: '💬', budget_warning: '⚠️',\n }\n const icon = emoji[notification.type] || 'ℹ️'\n const text = `${icon} *${notification.sessionName ?? 'Session'}*\\n${notification.summary}`\n const blocks = this.formatter.formatNotification(text)\n return {\n body: text,\n format: 'structured',\n components: blocks,\n }\n }\n\n renderSystemMessage(content: OutgoingMessage): RenderedMessage {\n const mrkdwn = markdownToMrkdwn(content.text ?? '')\n return {\n body: mrkdwn,\n format: 'structured',\n components: [{ type: 'section' as const, text: { type: 'mrkdwn' as const, text: mrkdwn } }],\n }\n }\n\n renderModeChange(content: OutgoingMessage): RenderedMessage {\n const modeId = (content.metadata as Record<string, unknown>)?.modeId ?? ''\n const text = `🔄 *Mode:* ${modeId}`\n return {\n body: text,\n format: 'structured',\n components: [{ type: 'context' as const, elements: [{ type: 'mrkdwn' as const, text }] }],\n }\n }\n\n renderConfigUpdate(): RenderedMessage {\n const text = '⚙️ *Config updated*'\n return {\n body: text,\n format: 'structured',\n components: [{ type: 'context' as const, elements: [{ type: 'mrkdwn' as const, text }] }],\n }\n }\n\n renderModelUpdate(content: OutgoingMessage): RenderedMessage {\n const modelId = (content.metadata as Record<string, unknown>)?.modelId ?? ''\n const text = `🤖 *Model:* ${modelId}`\n return {\n body: text,\n format: 'structured',\n components: [{ type: 'context' as const, elements: [{ type: 'mrkdwn' as const, text }] }],\n }\n }\n}\n","import PQueue from \"p-queue\";\nimport type { WebClient } from \"@slack/web-api\";\n\nexport type SlackMethod =\n | \"chat.postMessage\"\n | \"chat.update\"\n | \"conversations.create\"\n | \"conversations.rename\"\n | \"conversations.archive\"\n | \"conversations.invite\"\n | \"conversations.join\"\n | \"conversations.unarchive\"\n | \"conversations.info\";\n\n// Requests per minute per method (Slack Tier definitions)\nconst METHOD_RPM: Record<SlackMethod, number> = {\n \"chat.postMessage\": 50, // Tier 3\n \"chat.update\": 50, // Tier 3\n \"conversations.create\": 20, // Tier 2\n \"conversations.rename\": 20, // Tier 2\n \"conversations.archive\": 20, // Tier 2\n \"conversations.invite\": 20, // Tier 2\n \"conversations.join\": 20, // Tier 2\n \"conversations.unarchive\": 20, // Tier 2\n \"conversations.info\": 50, // Tier 3\n};\n\nexport interface ISlackSendQueue {\n enqueue<T = unknown>(method: SlackMethod, params: Record<string, unknown>): Promise<T>;\n}\n\nexport class SlackSendQueue implements ISlackSendQueue {\n private queues = new Map<SlackMethod, PQueue>();\n\n constructor(private client: WebClient) {\n for (const [method, rpm] of Object.entries(METHOD_RPM) as [SlackMethod, number][]) {\n // Spread requests evenly across the minute\n this.queues.set(method, new PQueue({\n interval: Math.ceil(60_000 / rpm),\n intervalCap: 1,\n carryoverConcurrencyCount: true,\n }));\n }\n }\n\n async enqueue<T = unknown>(method: SlackMethod, params: Record<string, unknown>): Promise<T> {\n const queue = this.queues.get(method);\n if (!queue) throw new Error(`Unknown Slack method: ${method}`);\n return queue.add(() => this.client.apiCall(method, params) as Promise<T>);\n }\n}\n","// src/adapters/slack/slug.ts\nimport { customAlphabet } from \"nanoid\";\n\nconst nanoidAlpha = customAlphabet(\"abcdefghijklmnopqrstuvwxyz0123456789\", 4);\n\n/**\n * Convert a human-readable session name to a valid Slack channel name.\n * Rules: lowercase, ≤80 chars, only [a-z0-9-], unique suffix appended.\n *\n * Examples:\n * \"Fix authentication bug\" → \"openacp-fix-authentication-bug-a3k9\"\n * \"New Session\" → \"openacp-new-session-x7p2\"\n * \"Implement OAuth 2.0 & JWT refresh\" → \"openacp-implement-oauth-20-jwt-refresh-b8qr\"\n */\nexport function toSlug(name: string, prefix = \"openacp\"): string {\n const base = name\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, \"\") // strip special chars\n .trim()\n .replace(/\\s+/g, \"-\") // spaces → dashes\n .replace(/-+/g, \"-\") // collapse consecutive dashes\n .slice(0, 60); // leave room for prefix and suffix\n\n const suffix = nanoidAlpha();\n return `${prefix}-${base}-${suffix}`.replace(/-+/g, \"-\");\n}\n","// src/adapters/slack/channel-manager.ts\nimport type { ISlackSendQueue } from \"./send-queue.js\";\nimport { toSlug } from \"./slug.js\";\nimport type { SlackSessionMeta } from \"./types.js\";\nimport type { SlackChannelConfig } from \"./types.js\";\n\nexport interface ISlackChannelManager {\n createChannel(sessionId: string, sessionName: string): Promise<SlackSessionMeta>;\n archiveChannel(channelId: string): Promise<void>;\n notifyChannel(text: string): Promise<void>;\n}\n\nexport class SlackChannelManager implements ISlackChannelManager {\n constructor(\n private queue: ISlackSendQueue,\n private config: SlackChannelConfig,\n ) {}\n\n async createChannel(sessionId: string, sessionName: string): Promise<SlackSessionMeta> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt < 3; attempt++) {\n const finalSlug = toSlug(sessionName, this.config.channelPrefix ?? \"openacp\");\n\n try {\n const res = await this.queue.enqueue<{ channel: { id: string } }>(\n \"conversations.create\",\n { name: finalSlug, is_private: true },\n );\n const channelId = res.channel.id;\n\n // Bot is automatically a member of private channels it creates — no join/invite needed.\n // Invite configured users so they can access the channel.\n const userIds = this.config.allowedUserIds ?? [];\n if (userIds.length > 0) {\n await this.queue.enqueue(\"conversations.invite\", {\n channel: channelId,\n users: userIds.join(\",\"),\n });\n }\n\n return { channelId, channelSlug: finalSlug };\n } catch (err: any) {\n if (err?.data?.error === \"name_taken\" && attempt < 2) {\n lastError = err;\n continue;\n }\n throw err;\n }\n }\n\n throw lastError;\n }\n\n async archiveChannel(channelId: string): Promise<void> {\n await this.queue.enqueue(\"conversations.archive\", { channel: channelId });\n }\n\n async notifyChannel(text: string): Promise<void> {\n if (this.config.notificationChannelId) {\n await this.queue.enqueue(\"chat.postMessage\", {\n channel: this.config.notificationChannelId,\n text,\n });\n }\n }\n}\n","import type { App, BlockAction, ButtonAction } from \"@slack/bolt\";\nimport type { ISlackSendQueue } from \"./send-queue.js\";\n\nexport type PermissionResponseCallback = (requestId: string, optionId: string) => void;\n\nexport interface ISlackPermissionHandler {\n register(app: App): void;\n trackPendingMessage(requestId: string, channelId: string, messageTs: string): void;\n cleanupSession(channelId: string): Promise<void>;\n}\n\nexport class SlackPermissionHandler implements ISlackPermissionHandler {\n private pendingMessages = new Map<string, { channelId: string; messageTs: string }>();\n\n constructor(\n private queue: ISlackSendQueue,\n private onResponse: PermissionResponseCallback,\n ) {}\n\n trackPendingMessage(requestId: string, channelId: string, messageTs: string): void {\n this.pendingMessages.set(requestId, { channelId, messageTs });\n }\n\n async cleanupSession(channelId: string): Promise<void> {\n for (const [requestId, info] of this.pendingMessages) {\n if (info.channelId !== channelId) continue;\n await this.queue.enqueue(\"chat.update\", {\n channel: info.channelId,\n ts: info.messageTs,\n blocks: [],\n });\n this.pendingMessages.delete(requestId);\n }\n }\n\n register(app: App): void {\n // Match any action starting with \"perm_action_\"\n app.action<BlockAction<ButtonAction>>(\n /^perm_action_/,\n async ({ ack, body, action }) => {\n await ack();\n\n const value: string = action.value ?? \"\";\n const colonIdx = value.indexOf(\":\");\n if (colonIdx === -1) return;\n\n const requestId = value.slice(0, colonIdx);\n const optionId = value.slice(colonIdx + 1);\n\n this.onResponse(requestId, optionId);\n\n // Remove from pending tracking since the user has responded\n this.pendingMessages.delete(requestId);\n\n // Update message to remove action buttons and show confirmation\n const message = body.message;\n if (message) {\n await this.queue.enqueue(\"chat.update\", {\n channel: body.channel?.id ?? \"\",\n ts: message.ts,\n text: `✅ Permission response: *${optionId}*`,\n blocks: [],\n });\n }\n }\n );\n }\n}\n","// src/adapters/slack/event-router.ts\nimport type { App } from \"@slack/bolt\";\nimport type { SlackSessionMeta, SlackFileInfo } from \"./types.js\";\nimport type { SlackChannelConfig } from \"./types.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\nconst log = createChildLogger({ module: \"slack-event-router\" });\n\n/** Subset of Bolt's message event fields used by the router */\ninterface SlackMessageEvent {\n bot_id?: string;\n subtype?: string;\n channel: string;\n text?: string;\n user?: string;\n files?: Array<{\n id: string;\n name: string;\n mimetype: string;\n size: number;\n url_private: string;\n }>;\n}\n\n// Callback to look up which session (if any) owns a Slack channelId\nexport type SessionLookup = (channelId: string) => SlackSessionMeta | undefined;\n\n// Callback to dispatch an incoming message to core\nexport type IncomingMessageCallback = (sessionId: string, text: string, userId: string, files?: SlackFileInfo[]) => void;\n\n// Callback to create a new session when user messages the notification channel\nexport type NewSessionCallback = (text: string, userId: string) => void;\n\nexport interface ISlackEventRouter {\n register(app: App): void;\n}\n\nexport class SlackEventRouter implements ISlackEventRouter {\n constructor(\n private sessionLookup: SessionLookup,\n private onIncoming: IncomingMessageCallback,\n private botUserId: string,\n private notificationChannelId: string | undefined,\n private onNewSession: NewSessionCallback,\n private config: SlackChannelConfig,\n private globalAllowedUserIds: string[] = [],\n ) {}\n\n private isAllowedUser(userId: string): boolean {\n const slackAllowed = this.config.allowedUserIds ?? [];\n const allowed = slackAllowed.length > 0 ? slackAllowed : this.globalAllowedUserIds;\n if (allowed.length === 0) return true;\n return allowed.includes(userId);\n }\n\n register(app: App): void {\n app.message(async ({ message }) => {\n log.debug({ message }, \"Slack raw message event\");\n\n const msg = message as unknown as SlackMessageEvent;\n\n if (msg.bot_id) return;\n const subtype = msg.subtype;\n if (subtype && subtype !== \"file_share\") return; // edited, deleted, etc.\n\n const channelId = msg.channel;\n const text: string = msg.text ?? \"\";\n const userId: string = msg.user ?? \"\";\n\n const files: SlackFileInfo[] | undefined = msg.files?.map((f) => ({\n id: f.id,\n name: f.name,\n mimetype: f.mimetype,\n size: f.size,\n url_private: f.url_private,\n }));\n\n log.debug({ channelId, userId, text }, \"Slack message received\");\n\n // Ignore messages from the bot itself\n if (userId === this.botUserId) return;\n\n // Enforce allowedUserIds\n if (!this.isAllowedUser(userId)) {\n log.warn({ userId }, \"slack: message from non-allowed user rejected\");\n return;\n }\n\n const session = this.sessionLookup(channelId);\n if (session) {\n // Message to an existing session channel\n log.debug({ channelId, sessionSlug: session.channelSlug }, \"Routing to session\");\n this.onIncoming(session.channelSlug, text, userId, files);\n return;\n }\n\n log.debug({ channelId, notificationChannelId: this.notificationChannelId }, \"No session found for channel\");\n\n // Message to the notification channel → create new session\n if (this.notificationChannelId && channelId === this.notificationChannelId) {\n this.onNewSession(text, userId);\n return;\n }\n });\n }\n}\n","// src/adapters/slack/text-buffer.ts\n// Buffers streamed text chunks per session and flushes as a single Slack message.\n// This prevents the \"many tiny messages\" problem from streaming AI responses.\n\nimport type { ISlackSendQueue } from \"./send-queue.js\";\nimport { markdownToMrkdwn } from \"./formatter.js\";\nimport { splitSafe } from \"./utils.js\";\nimport { createChildLogger } from \"../../core/utils/log.js\";\n\nconst log = createChildLogger({ module: \"slack-text-buffer\" });\n\nconst FLUSH_IDLE_MS = 2000; // flush after 2s of no new chunks\n\nexport class SlackTextBuffer {\n private buffer = \"\";\n private timer: ReturnType<typeof setTimeout> | undefined;\n private flushPromise: Promise<void> | undefined;\n private lastMessageTs: string | undefined;\n private lastPostedText: string | undefined;\n\n constructor(\n private channelId: string,\n private sessionId: string,\n private queue: ISlackSendQueue,\n ) {}\n\n append(text: string): void {\n if (!text) return;\n this.buffer += text;\n this.resetTimer();\n }\n\n private resetTimer(): void {\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.timer = undefined;\n this.flush().catch((err) => log.error({ err, sessionId: this.sessionId }, \"Text buffer flush error\"));\n }, FLUSH_IDLE_MS);\n }\n\n async flush(): Promise<void> {\n if (this.flushPromise) return this.flushPromise;\n const text = this.buffer.trim();\n if (!text) return;\n this.buffer = \"\";\n if (this.timer) { clearTimeout(this.timer); this.timer = undefined; }\n\n this.flushPromise = (async () => {\n try {\n const converted = markdownToMrkdwn(text);\n const chunks = splitSafe(converted);\n for (const chunk of chunks) {\n if (!chunk.trim()) continue;\n const result = await this.queue.enqueue(\"chat.postMessage\", {\n channel: this.channelId,\n text: chunk,\n blocks: [{ type: \"section\", text: { type: \"mrkdwn\", text: chunk } }],\n });\n // Track last posted message for potential TTS block editing\n this.lastMessageTs = (result as { ts?: string } | undefined)?.ts;\n this.lastPostedText = chunk;\n }\n } finally {\n this.flushPromise = undefined;\n // Re-flush if content arrived while we were flushing\n if (this.buffer.trim()) {\n await this.flush();\n }\n }\n })();\n\n return this.flushPromise;\n }\n\n destroy(): void {\n if (this.timer) { clearTimeout(this.timer); this.timer = undefined; }\n this.buffer = \"\";\n }\n\n /** Remove [TTS]...[/TTS] blocks — from buffer if unflushed, or edit posted message */\n async stripTtsBlock(): Promise<void> {\n // Case 1: TTS block still in unflushed buffer\n if (/\\[TTS\\][\\s\\S]*?\\[\\/TTS\\]/.test(this.buffer)) {\n this.buffer = this.buffer.replace(/\\[TTS\\][\\s\\S]*?\\[\\/TTS\\]/g, \"\").replace(/\\s{2,}/g, \" \").trim();\n return;\n }\n\n // Case 2: Already flushed — edit the posted message via chat.update\n if (this.lastMessageTs && this.lastPostedText && /\\[TTS\\][\\s\\S]*?\\[\\/TTS\\]/.test(this.lastPostedText)) {\n const cleaned = this.lastPostedText.replace(/\\[TTS\\][\\s\\S]*?\\[\\/TTS\\]/g, \"\").replace(/\\s{2,}/g, \" \").trim();\n if (cleaned) {\n await this.queue.enqueue(\"chat.update\", {\n channel: this.channelId,\n ts: this.lastMessageTs,\n text: cleaned,\n blocks: [{ type: \"section\", text: { type: \"mrkdwn\", text: cleaned } }],\n });\n }\n this.lastPostedText = cleaned;\n }\n }\n}\n"],"mappings":"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","names":["SECTION_LIMIT","log","log"]}
|