agent-slack 0.2.12

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.
@@ -0,0 +1,52 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/lib/version.ts", "../src/auth/chrome.ts", "../src/auth/curl.ts", "../src/auth/desktop.ts", "../src/lib/leveldb-reader.ts", "../src/auth/paths.ts", "../src/lib/fs.ts", "../src/auth/schema.ts", "../src/auth/keychain.ts", "../src/auth/store.ts", "../src/slack/channels.ts", "../src/slack/client.ts", "../src/cli/context.ts", "../src/lib/compact-json.ts", "../src/lib/redact.ts", "../src/cli/auth-command.ts", "../src/slack/files.ts", "../src/slack/html-to-md.ts", "../src/lib/tmp-paths.ts", "../src/lib/app-dir.ts", "../src/slack/canvas.ts", "../src/cli/canvas-command.ts", "../src/slack/emoji.ts", "../src/slack/mrkdwn.ts", "../src/slack/render.ts", "../src/slack/messages.ts", "../src/slack/url.ts", "../src/cli/targets.ts", "../src/cli/message-actions.ts", "../src/cli/message-command.ts", "../src/slack/search-guards.ts", "../src/slack/search-query.ts", "../src/slack/search-raw.ts", "../src/slack/search-file-ext.ts", "../src/slack/search-files.ts", "../src/slack/search-messages.ts", "../src/slack/search.ts", "../src/cli/search-command.ts", "../src/lib/update.ts", "../src/cli/update-command.ts", "../src/slack/users.ts", "../src/cli/user-command.ts"],
4
+ "sourcesContent": [
5
+ "import { Command } from \"commander\";\nimport { getPackageVersion } from \"./lib/version.ts\";\nimport { createCliContext } from \"./cli/context.ts\";\nimport { registerAuthCommand } from \"./cli/auth-command.ts\";\nimport { registerCanvasCommand } from \"./cli/canvas-command.ts\";\nimport { registerMessageCommand } from \"./cli/message-command.ts\";\nimport { registerSearchCommand } from \"./cli/search-command.ts\";\nimport { registerUpdateCommand } from \"./cli/update-command.ts\";\nimport { registerUserCommand } from \"./cli/user-command.ts\";\nimport { backgroundUpdateCheck } from \"./lib/update.ts\";\n\nconst program = new Command();\nprogram\n .name(\"agent-slack\")\n .description(\"Slack automation CLI for AI agents\")\n .version(getPackageVersion());\n\nconst ctx = createCliContext();\n\nregisterAuthCommand({ program, ctx });\nregisterMessageCommand({ program, ctx });\nregisterCanvasCommand({ program, ctx });\nregisterSearchCommand({ program, ctx });\nregisterUpdateCommand({ program });\nregisterUserCommand({ program, ctx });\n\nprogram.parse(process.argv);\nif (!process.argv.slice(2).length) {\n program.outputHelp();\n}\n\n// Fire-and-forget background update check (throttled to once/24h, stderr only).\n// Skip for the update command itself to avoid duplicate output.\nconst [subcommand] = process.argv.slice(2);\nif (subcommand && subcommand !== \"update\") {\n backgroundUpdateCheck();\n}\n",
6
+ "import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n// Injected at build time via --define AGENT_SLACK_BUILD_VERSION='\"x.y.z\"'\ndeclare const AGENT_SLACK_BUILD_VERSION: string | undefined;\n\nlet cachedVersion: string | undefined;\n\nexport function getPackageVersion(): string {\n if (cachedVersion !== undefined) {\n return cachedVersion;\n }\n\n // 1. Check build-time injected version (for compiled binaries)\n if (typeof AGENT_SLACK_BUILD_VERSION === \"string\" && AGENT_SLACK_BUILD_VERSION) {\n cachedVersion = AGENT_SLACK_BUILD_VERSION;\n return cachedVersion;\n }\n\n // 2. Check environment variables\n const envVersion =\n process.env.AGENT_SLACK_VERSION?.trim() || process.env.npm_package_version?.trim();\n if (envVersion) {\n cachedVersion = envVersion;\n return cachedVersion;\n }\n\n // 3. Try to read from package.json (for development)\n try {\n let dir = dirname(fileURLToPath(import.meta.url));\n for (let i = 0; i < 6; i++) {\n const candidate = join(dir, \"package.json\");\n if (existsSync(candidate)) {\n const raw = readFileSync(candidate, \"utf8\");\n const pkg = JSON.parse(raw) as { version?: unknown };\n const v = typeof pkg.version === \"string\" ? pkg.version.trim() : \"\";\n cachedVersion = v || \"0.0.0\";\n return cachedVersion;\n }\n const next = dirname(dir);\n if (next === dir) {\n break;\n }\n dir = next;\n }\n } catch {\n // fall through\n }\n\n cachedVersion = \"0.0.0\";\n return cachedVersion;\n}\n\nexport function getUserAgent(): string {\n return `agent-slack/${getPackageVersion()}`;\n}\n",
7
+ "import { execSync } from \"node:child_process\";\nimport { platform } from \"node:os\";\n\ntype ChromeExtractedTeam = { url: string; name?: string; token: string };\n\nexport type ChromeExtracted = {\n cookie_d: string;\n teams: ChromeExtractedTeam[];\n};\n\nconst IS_MACOS = platform() === \"darwin\";\n\nfunction escapeOsaScript(script: string): string {\n // osascript -e '...'\n return script.replace(/'/g, `'\"'\"'`);\n}\n\nfunction osascript(script: string): string {\n return execSync(`osascript -e '${escapeOsaScript(script)}'`, {\n encoding: \"utf8\",\n timeout: 7000,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n }).trim();\n}\n\nfunction cookieScript(): string {\n return `\n tell application \"Google Chrome\"\n repeat with w in windows\n repeat with t in tabs of w\n if URL of t contains \"slack.com\" then\n return execute t javascript \"document.cookie.split('; ').find(c => c.startsWith('d='))?.split('=')[1] || ''\"\n end if\n end repeat\n end repeat\n return \"\"\n end tell\n `;\n}\n\nconst TEAM_JSON_PATHS = [\n // Current known storage\n \"JSON.stringify(JSON.parse(localStorage.localConfig_v2).teams)\",\n \"JSON.stringify(JSON.parse(localStorage.localConfig_v3).teams)\",\n \"JSON.stringify(JSON.parse(localStorage.getItem('reduxPersist:localConfig'))?.teams || {})\",\n \"JSON.stringify(window.boot_data?.teams || {})\",\n];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction toChromeTeam(value: unknown): ChromeExtractedTeam | null {\n if (!isRecord(value)) {\n return null;\n }\n const token = typeof value.token === \"string\" ? value.token : null;\n const url = typeof value.url === \"string\" ? value.url : null;\n if (!token || !url || !token.startsWith(\"xoxc-\")) {\n return null;\n }\n const name = typeof value.name === \"string\" ? value.name : undefined;\n return { url, name, token };\n}\n\nfunction teamsScript(): string {\n const tryPaths = TEAM_JSON_PATHS.map(\n (expr) => `try { var v = ${expr}; if (v && v !== '{}' && v !== 'null') return v; } catch(e) {}`,\n );\n return `\n tell application \"Google Chrome\"\n repeat with w in windows\n repeat with t in tabs of w\n if URL of t contains \"slack.com\" then\n return execute t javascript \"(function(){ ${tryPaths.join(\" \")} return '{}'; })()\"\n end if\n end repeat\n end repeat\n return \"{}\"\n end tell\n `;\n}\n\nexport function extractFromChrome(): ChromeExtracted | null {\n if (!IS_MACOS) {\n return null;\n }\n try {\n const cookie = osascript(cookieScript());\n if (!cookie || !cookie.startsWith(\"xoxd-\")) {\n return null;\n }\n\n const teamsRaw = osascript(teamsScript());\n let teamsObj: unknown = {};\n try {\n teamsObj = JSON.parse(teamsRaw || \"{}\");\n } catch {\n teamsObj = {};\n }\n\n const teamsRecord = isRecord(teamsObj) ? teamsObj : {};\n const teams: ChromeExtractedTeam[] = Object.values(teamsRecord)\n .map((t) => toChromeTeam(t))\n .filter((t): t is ChromeExtractedTeam => t !== null);\n\n if (teams.length === 0) {\n return null;\n }\n return { cookie_d: cookie, teams };\n } catch {\n return null;\n }\n}\n",
8
+ "export type ParsedCurlTokens = {\n workspace_url: string;\n xoxc_token: string;\n xoxd_cookie: string;\n};\n\nexport function parseSlackCurlCommand(curlInput: string): ParsedCurlTokens {\n const urlMatch = curlInput.match(/curl\\s+['\"]?(https?:\\/\\/([^.]+)\\.slack\\.com[^'\"\\s]*)/i);\n if (!urlMatch) {\n throw new Error(\"Could not find Slack workspace URL in cURL command\");\n }\n const workspace_url = `https://${urlMatch[2]}.slack.com`;\n\n const cookieMatch = curlInput.match(\n /(?:-b|--cookie)\\s+\\$?'([^']+)'|(?:-b|--cookie)\\s+\\$?\"([^\"]+)\"|-H\\s+\\$?'[Cc]ookie:\\s*([^']+)'|-H\\s+\\$?\"[Cc]ookie:\\s*([^\"]+)\"/,\n );\n const cookieHeader = cookieMatch\n ? cookieMatch[1] || cookieMatch[2] || cookieMatch[3] || cookieMatch[4] || \"\"\n : \"\";\n const xoxdMatch = cookieHeader.match(/(?:^|;\\s*)d=(xoxd-[^;]+)/);\n if (!xoxdMatch) {\n throw new Error(\"Could not find xoxd cookie (d=xoxd-...) in cURL command\");\n }\n const xoxd_cookie = decodeURIComponent(xoxdMatch[1]!);\n\n // Token can appear in various forms: token=..., \"token\":\"...\", or name=\"token\"... in form bodies.\n // Try common patterns first, then fall back to the first xoxc-* we can find.\n const tokenPatterns: RegExp[] = [\n /(?:^|[?&\\s])token=(xoxc-[A-Za-z0-9-]+)/,\n /\"token\"\\s*:\\s*\"(xoxc-[A-Za-z0-9-]+)\"/,\n /name=\"token\"[^x]*?(xoxc-[A-Za-z0-9-]+)/,\n /\\b(xoxc-[A-Za-z0-9-]+)\\b/,\n ];\n\n let xoxc_token: string | null = null;\n for (const re of tokenPatterns) {\n const m = curlInput.match(re);\n if (m?.[1]) {\n const [, token] = m;\n xoxc_token = token ?? null;\n break;\n }\n }\n if (!xoxc_token) {\n throw new Error(\"Could not find xoxc token in cURL command\");\n }\n\n return { workspace_url, xoxc_token, xoxd_cookie };\n}\n",
9
+ "// Desktop auth extraction approach inspired by:\n// - slacktokens: https://github.com/hraftery/slacktokens\nimport { cp, mkdir, rm, unlink } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport { execFileSync, execSync } from \"node:child_process\";\nimport { pbkdf2Sync, createDecipheriv } from \"node:crypto\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { findKeysContaining } from \"../lib/leveldb-reader.js\";\n\ntype SqliteRow = Record<string, unknown>;\n\n/**\n * Query a SQLite database in read-only mode.\n * Uses bun:sqlite when running under Bun, falls back to node:sqlite (Node >= 22.5).\n */\nasync function queryReadonlySqlite(dbPath: string, sql: string): Promise<SqliteRow[]> {\n try {\n const { Database } = await import(\"bun:sqlite\");\n const db = new Database(dbPath, { readonly: true });\n try {\n return db.query(sql).all() as SqliteRow[];\n } finally {\n db.close();\n }\n } catch {\n const { DatabaseSync } = await import(\"node:sqlite\");\n const db = new DatabaseSync(dbPath, { readOnly: true });\n try {\n return db.prepare(sql).all() as SqliteRow[];\n } finally {\n db.close();\n }\n }\n}\n\ntype DesktopTeam = { url: string; name?: string; token: string };\n\nexport type DesktopExtracted = {\n cookie_d: string;\n teams: DesktopTeam[];\n source: { leveldb_path: string; cookies_path: string };\n};\n\n// Electron (direct download) paths\nconst SLACK_SUPPORT_DIR_ELECTRON = join(homedir(), \"Library\", \"Application Support\", \"Slack\");\n// Mac App Store paths (sandboxed container)\nconst SLACK_SUPPORT_DIR_APPSTORE = join(\n homedir(),\n \"Library\",\n \"Containers\",\n \"com.tinyspeck.slackmacgap\",\n \"Data\",\n \"Library\",\n \"Application Support\",\n \"Slack\",\n);\n\nfunction getSlackPaths(): { leveldbDir: string; cookiesDb: string } {\n const candidates = [SLACK_SUPPORT_DIR_ELECTRON, SLACK_SUPPORT_DIR_APPSTORE];\n for (const dir of candidates) {\n const leveldbDir = join(dir, \"Local Storage\", \"leveldb\");\n if (existsSync(leveldbDir)) {\n return { leveldbDir, cookiesDb: join(dir, \"Cookies\") };\n }\n }\n throw new Error(\n `Slack Desktop data not found. Checked:\\n - ${candidates.map((d) => join(d, \"Local Storage\", \"leveldb\")).join(\"\\n - \")}`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction toDesktopTeam(value: unknown): DesktopTeam | null {\n if (!isRecord(value)) {\n return null;\n }\n const url = typeof value.url === \"string\" ? value.url : null;\n const token = typeof value.token === \"string\" ? value.token : null;\n if (!url || !token) {\n return null;\n }\n const name = typeof value.name === \"string\" ? value.name : undefined;\n return { url, name, token };\n}\n\nasync function snapshotLevelDb(srcDir: string): Promise<string> {\n const base = join(homedir(), \".config\", \"agent-slack\", \"cache\", \"leveldb-snapshots\");\n const dest = join(base, `${Date.now()}`);\n await mkdir(base, { recursive: true });\n // Hacky but fast on macOS: copy-on-write clone. Falls back to normal copy.\n try {\n execFileSync(\"cp\", [\"-cR\", srcDir, dest], {\n stdio: [\"ignore\", \"ignore\", \"ignore\"],\n });\n } catch {\n await cp(srcDir, dest, { recursive: true, force: true });\n }\n try {\n await unlink(join(dest, \"LOCK\"));\n } catch {\n // ignore\n }\n return dest;\n}\n\nfunction parseLocalConfig(raw: Buffer): unknown {\n if (!raw || raw.length === 0) {\n throw new Error(\"localConfig is empty\");\n }\n\n const [first] = raw;\n const data = first === 0x00 || first === 0x01 || first === 0x02 ? raw.subarray(1) : raw;\n\n let nulCount = 0;\n for (const b of data) {\n if (b === 0) {\n nulCount++;\n }\n }\n\n const encodings: BufferEncoding[] =\n nulCount > data.length / 4 ? ([\"utf16le\", \"utf8\"] as const) : ([\"utf8\", \"utf16le\"] as const);\n\n let lastErr: unknown;\n for (const enc of encodings) {\n try {\n const text = data.toString(enc);\n try {\n return JSON.parse(text);\n } catch (err1) {\n lastErr = err1;\n }\n\n const start = text.indexOf(\"{\");\n const end = text.lastIndexOf(\"}\");\n if (start !== -1 && end !== -1 && end > start) {\n try {\n return JSON.parse(text.slice(start, end + 1));\n } catch (err2) {\n lastErr = err2;\n }\n }\n } catch (err) {\n lastErr = err;\n }\n }\n\n throw lastErr || new Error(\"localConfig not parseable\");\n}\n\nasync function extractTeamsFromSlackLevelDb(leveldbDir: string): Promise<DesktopTeam[]> {\n if (!existsSync(leveldbDir)) {\n throw new Error(`Slack LevelDB not found: ${leveldbDir}`);\n }\n\n const snap = await snapshotLevelDb(leveldbDir);\n\n try {\n // Use pure JS LevelDB reader - search for localConfig entries\n const localConfigV2 = Buffer.from(\"localConfig_v2\");\n const localConfigV3 = Buffer.from(\"localConfig_v3\");\n\n const entries = await findKeysContaining(snap, Buffer.from(\"localConfig_v\"));\n\n let configBuf: Buffer | null = null;\n for (const entry of entries) {\n if (entry.key.includes(localConfigV2) || entry.key.includes(localConfigV3)) {\n if (entry.value && entry.value.length > 0) {\n configBuf = entry.value;\n break;\n }\n }\n }\n\n if (!configBuf) {\n throw new Error(\"Slack LevelDB did not contain localConfig_v2/v3\");\n }\n\n const cfg = parseLocalConfig(configBuf);\n const teamsValue = isRecord(cfg) ? cfg.teams : undefined;\n const teamsObj = isRecord(teamsValue) ? teamsValue : {};\n const teams: DesktopTeam[] = Object.values(teamsObj)\n .map((t) => toDesktopTeam(t))\n .filter((t): t is DesktopTeam => t !== null)\n .filter((t) => t.token.startsWith(\"xoxc-\"));\n\n if (teams.length === 0) {\n throw new Error(\"No xoxc tokens found in Slack localConfig\");\n }\n return teams;\n } finally {\n try {\n await rm(snap, { recursive: true, force: true });\n } catch {\n // ignore\n }\n }\n}\n\nfunction getSafeStoragePassword(): string {\n const services = [\"Slack Safe Storage\", \"Chrome Safe Storage\", \"Chromium Safe Storage\"];\n for (const svc of services) {\n try {\n const out = execSync(\n `security find-generic-password -w -s ${JSON.stringify(svc)} 2>/dev/null`,\n {\n encoding: \"utf8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n },\n ).trim();\n if (out) {\n return out;\n }\n } catch {\n // continue\n }\n }\n throw new Error(\n 'Could not read Safe Storage password from Keychain (tried \"Slack Safe Storage\").',\n );\n}\n\nfunction decryptChromiumCookieValue(encrypted: Buffer, password: string): string {\n if (!encrypted || encrypted.length === 0) {\n return \"\";\n }\n\n const prefix = encrypted.subarray(0, 3).toString(\"utf8\");\n const data = prefix === \"v10\" || prefix === \"v11\" ? encrypted.subarray(3) : encrypted;\n\n const salt = Buffer.from(\"saltysalt\", \"utf8\");\n const iv = Buffer.alloc(16, \" \");\n const key = pbkdf2Sync(password, salt, 1003, 16, \"sha1\");\n\n const decipher = createDecipheriv(\"aes-128-cbc\", key, iv);\n decipher.setAutoPadding(true);\n const plain = Buffer.concat([decipher.update(data), decipher.final()]);\n const marker = Buffer.from(\"xoxd-\");\n const idx = plain.indexOf(marker);\n if (idx === -1) {\n return plain.toString(\"utf8\");\n }\n\n let end = idx;\n while (end < plain.length) {\n const b = plain[end]!;\n if (b < 0x21 || b > 0x7e) {\n break;\n }\n end++;\n }\n const rawToken = plain.subarray(idx, end).toString(\"utf8\");\n try {\n return decodeURIComponent(rawToken);\n } catch {\n return rawToken;\n }\n}\n\nasync function extractCookieDFromSlackCookiesDb(cookiesPath: string): Promise<string> {\n if (!existsSync(cookiesPath)) {\n throw new Error(`Slack Cookies DB not found: ${cookiesPath}`);\n }\n\n const rows = (await queryReadonlySqlite(\n cookiesPath,\n \"select host_key, name, value, encrypted_value from cookies where name = 'd' and host_key like '%slack.com' order by length(encrypted_value) desc\",\n )) as {\n host_key: string;\n name: string;\n value: string;\n encrypted_value: Uint8Array;\n }[];\n\n if (!rows || rows.length === 0) {\n throw new Error(\"No Slack 'd' cookie found\");\n }\n const row = rows[0]!;\n if (row.value && row.value.startsWith(\"xoxd-\")) {\n return row.value;\n }\n\n const encrypted = Buffer.from(row.encrypted_value || []);\n if (encrypted.length === 0) {\n throw new Error(\"Slack 'd' cookie had no encrypted_value\");\n }\n\n const password = getSafeStoragePassword();\n const decrypted = decryptChromiumCookieValue(encrypted, password);\n const match = decrypted.match(/xoxd-[A-Za-z0-9%/+_=.-]+/);\n if (!match) {\n throw new Error(\"Could not locate xoxd-* in decrypted Slack cookie\");\n }\n return match[0]!;\n}\n\nexport async function extractFromSlackDesktop(): Promise<DesktopExtracted> {\n const { leveldbDir, cookiesDb } = getSlackPaths();\n const teams = await extractTeamsFromSlackLevelDb(leveldbDir);\n const cookie_d = await extractCookieDFromSlackCookiesDb(cookiesDb);\n return {\n cookie_d,\n teams,\n source: { leveldb_path: leveldbDir, cookies_path: cookiesDb },\n };\n}\n",
10
+ "/**\n * Pure JavaScript LevelDB reader for Chromium Local Storage.\n * Reads SSTable (.ldb) and log (.log) files without native modules.\n *\n * This is a minimal implementation that only supports reading - no writes.\n * Designed for extracting Slack tokens from Chromium-based apps.\n */\n\nimport { readdir, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { snappyUncompress } from \"hysnappy\";\n\n// LevelDB magic number (little-endian): 0xdb4775248b80fb57\nconst LEVELDB_MAGIC = Buffer.from([0x57, 0xfb, 0x80, 0x8b, 0x24, 0x75, 0x47, 0xdb]);\n\n// Block compression types\nconst COMPRESSION_NONE = 0;\nconst COMPRESSION_SNAPPY = 1;\n\n// Log record types\nconst LOG_RECORD_FULL = 1;\nconst LOG_RECORD_FIRST = 2;\nconst LOG_RECORD_MIDDLE = 3;\nconst LOG_RECORD_LAST = 4;\n\nexport type LevelDBEntry = {\n key: Buffer;\n value: Buffer;\n};\n\n/**\n * Read a varint from buffer at offset. Returns [value, bytesRead].\n */\nfunction readVarint(buf: Buffer, offset: number): [number, number] {\n let result = 0;\n let shift = 0;\n let bytesRead = 0;\n\n while (offset + bytesRead < buf.length) {\n const byte = buf[offset + bytesRead]!;\n bytesRead++;\n result |= (byte & 0x7f) << shift;\n if ((byte & 0x80) === 0) {\n return [result, bytesRead];\n }\n shift += 7;\n if (shift >= 35) {\n throw new Error(\"Varint too long\");\n }\n }\n throw new Error(\"Unexpected end of buffer reading varint\");\n}\n\n/**\n * Read a varint64 from buffer. For our use case, we only need 32-bit precision.\n */\nfunction readVarint64(buf: Buffer, offset: number): [number, number] {\n let result = 0;\n let shift = 0;\n let bytesRead = 0;\n\n while (offset + bytesRead < buf.length && bytesRead < 10) {\n const byte = buf[offset + bytesRead]!;\n bytesRead++;\n if (shift < 32) {\n result |= (byte & 0x7f) << shift;\n }\n if ((byte & 0x80) === 0) {\n return [result >>> 0, bytesRead];\n }\n shift += 7;\n }\n throw new Error(\"Unexpected end of buffer reading varint64\");\n}\n\n/**\n * Get uncompressed length from Snappy-compressed data.\n * Snappy format starts with uncompressed length as a varint.\n */\nfunction getSnappyUncompressedLength(compressed: Buffer): number {\n const [length] = readVarint(compressed, 0);\n return length;\n}\n\n/**\n * Parse a LevelDB block handle (offset + size as varints).\n */\nfunction parseBlockHandle(\n buf: Buffer,\n offset: number,\n): { offset: number; size: number; bytesRead: number } {\n const [blockOffset, n1] = readVarint64(buf, offset);\n const [blockSize, n2] = readVarint64(buf, offset + n1);\n return { offset: blockOffset, size: blockSize, bytesRead: n1 + n2 };\n}\n\n/**\n * Decompress a block if needed.\n */\nfunction decompressBlock(blockData: Buffer, compressionType: number): Buffer {\n if (compressionType === COMPRESSION_NONE) {\n return blockData;\n }\n if (compressionType === COMPRESSION_SNAPPY) {\n const uncompressedLength = getSnappyUncompressedLength(blockData);\n const result = snappyUncompress(blockData, uncompressedLength);\n return Buffer.from(result);\n }\n throw new Error(`Unknown compression type: ${compressionType}`);\n}\n\n/**\n * Parse entries from a data block.\n * LevelDB uses prefix compression within blocks.\n */\nfunction parseDataBlock(block: Buffer): LevelDBEntry[] {\n const entries: LevelDBEntry[] = [];\n\n if (block.length < 4) {\n return entries;\n }\n\n // Last 4 bytes are number of restart points\n const numRestarts = block.readUInt32LE(block.length - 4);\n // Restart array is numRestarts * 4 bytes before the count\n const restartsStart = block.length - 4 - numRestarts * 4;\n\n if (restartsStart < 0) {\n return entries;\n }\n\n let offset = 0;\n let prevKey = Buffer.alloc(0);\n\n while (offset < restartsStart) {\n try {\n const [shared, n1] = readVarint(block, offset);\n offset += n1;\n const [nonShared, n2] = readVarint(block, offset);\n offset += n2;\n const [valueLen, n3] = readVarint(block, offset);\n offset += n3;\n\n if (offset + nonShared + valueLen > restartsStart) {\n break;\n }\n\n // Build key from shared prefix + new bytes\n const keyDelta = block.subarray(offset, offset + nonShared);\n offset += nonShared;\n\n const key = Buffer.concat([prevKey.subarray(0, shared), keyDelta]);\n const value = block.subarray(offset, offset + valueLen);\n offset += valueLen;\n\n // Filter out deletion markers (keys starting with certain internal prefixes)\n // In LevelDB, user keys don't have the sequence number suffix for our read-only case\n entries.push({ key: Buffer.from(key), value: Buffer.from(value) });\n prevKey = key;\n } catch {\n break;\n }\n }\n\n return entries;\n}\n\n/**\n * Parse an SSTable (.ldb or .sst) file and extract all key-value pairs.\n */\nasync function parseSSTable(filePath: string): Promise<LevelDBEntry[]> {\n const entries: LevelDBEntry[] = [];\n\n let data: Buffer;\n try {\n data = await readFile(filePath);\n } catch {\n return entries;\n }\n\n if (data.length < 48) {\n return entries;\n }\n\n // Read footer (last 48 bytes)\n const footer = data.subarray(-48);\n\n // Verify magic number (last 8 bytes of footer)\n const magic = footer.subarray(40, 48);\n if (!magic.equals(LEVELDB_MAGIC)) {\n // Not a valid SSTable or different format\n return entries;\n }\n\n try {\n // Parse metaindex and index block handles from footer\n // Footer format: [metaindex_handle][index_handle][padding][magic]\n const { bytesRead: metaBytes } = parseBlockHandle(footer, 0);\n const indexHandle = parseBlockHandle(footer, metaBytes);\n\n // Read index block\n const indexBlockStart = indexHandle.offset;\n const indexBlockEnd = indexHandle.offset + indexHandle.size + 5; // +5 for type + crc\n\n if (indexBlockEnd > data.length - 48) {\n return entries;\n }\n\n const indexBlockRaw = data.subarray(indexBlockStart, indexBlockEnd);\n const indexCompressionType = indexBlockRaw.at(-5)!;\n const indexBlockData = indexBlockRaw.subarray(0, -5);\n const indexBlock = decompressBlock(indexBlockData, indexCompressionType);\n\n // Parse index block to get data block locations\n const indexEntries = parseDataBlock(indexBlock);\n\n // Read each data block\n for (const indexEntry of indexEntries) {\n try {\n // Index entry value contains a block handle\n const blockHandle = parseBlockHandle(indexEntry.value, 0);\n const blockStart = blockHandle.offset;\n const blockEnd = blockHandle.offset + blockHandle.size + 5; // +5 for type + crc\n\n if (blockEnd > data.length) {\n continue;\n }\n\n const blockRaw = data.subarray(blockStart, blockEnd);\n const compressionType = blockRaw.at(-5)!;\n const blockData = blockRaw.subarray(0, -5);\n const block = decompressBlock(blockData, compressionType);\n\n const blockEntries = parseDataBlock(block);\n entries.push(...blockEntries);\n } catch {\n // Skip malformed blocks\n continue;\n }\n }\n } catch {\n // If structured parsing fails, return empty\n return entries;\n }\n\n return entries;\n}\n\n/**\n * Parse a LevelDB log (.log) file for recent writes.\n * Log files contain records that haven't been compacted to SSTables yet.\n */\nasync function parseLogFile(filePath: string): Promise<LevelDBEntry[]> {\n const entries: LevelDBEntry[] = [];\n\n let data: Buffer;\n try {\n data = await readFile(filePath);\n } catch {\n return entries;\n }\n\n const BLOCK_SIZE = 32768;\n let offset = 0;\n let pendingRecord: Buffer[] = [];\n\n while (offset < data.length) {\n // Records are within 32KB blocks\n const blockOffset = offset % BLOCK_SIZE;\n const remaining = BLOCK_SIZE - blockOffset;\n\n // Skip to next block if not enough space for header\n if (remaining < 7) {\n offset += remaining;\n continue;\n }\n\n // Read record header: [crc32: 4][length: 2][type: 1]\n if (offset + 7 > data.length) {\n break;\n }\n\n const length = data.readUInt16LE(offset + 4);\n const type = data[offset + 6]!;\n\n if (length === 0 || offset + 7 + length > data.length) {\n offset += remaining;\n pendingRecord = [];\n continue;\n }\n\n const recordData = data.subarray(offset + 7, offset + 7 + length);\n offset += 7 + length;\n\n if (type === LOG_RECORD_FULL) {\n pendingRecord = [];\n parseLogBatch(recordData, entries);\n } else if (type === LOG_RECORD_FIRST) {\n pendingRecord = [recordData];\n } else if (type === LOG_RECORD_MIDDLE) {\n if (pendingRecord.length > 0) {\n pendingRecord.push(recordData);\n }\n } else if (type === LOG_RECORD_LAST) {\n if (pendingRecord.length > 0) {\n pendingRecord.push(recordData);\n const fullRecord = Buffer.concat(pendingRecord);\n parseLogBatch(fullRecord, entries);\n }\n pendingRecord = [];\n }\n }\n\n return entries;\n}\n\n/**\n * Parse a write batch from a log record.\n * Batch format: [sequence: 8][count: 4][records...]\n * Record format: [type: 1][key_len: varint][key][value_len: varint][value]\n */\nfunction parseLogBatch(batch: Buffer, entries: LevelDBEntry[]): void {\n if (batch.length < 12) {\n return;\n }\n\n // Skip sequence (8 bytes) and count (4 bytes)\n let offset = 12;\n\n while (offset < batch.length) {\n try {\n const recordType = batch[offset]!;\n offset++;\n\n if (recordType === 1) {\n // Value record\n const [keyLen, n1] = readVarint(batch, offset);\n offset += n1;\n const key = batch.subarray(offset, offset + keyLen);\n offset += keyLen;\n const [valueLen, n2] = readVarint(batch, offset);\n offset += n2;\n const value = batch.subarray(offset, offset + valueLen);\n offset += valueLen;\n\n entries.push({ key: Buffer.from(key), value: Buffer.from(value) });\n } else if (recordType === 0) {\n // Deletion record - skip\n const [keyLen, n1] = readVarint(batch, offset);\n offset += n1 + keyLen;\n } else {\n // Unknown record type\n break;\n }\n } catch {\n break;\n }\n }\n}\n\n/**\n * Read all key-value pairs from a Chromium LevelDB directory.\n * Scans both SSTable (.ldb) files and log (.log) files.\n */\nexport async function readChromiumLevelDB(dir: string): Promise<LevelDBEntry[]> {\n const entries: LevelDBEntry[] = [];\n\n let files: string[];\n try {\n files = await readdir(dir);\n } catch {\n return entries;\n }\n\n // Parse all .ldb and .sst files\n const sstFiles = files.filter((f) => f.endsWith(\".ldb\") || f.endsWith(\".sst\"));\n for (const file of sstFiles) {\n const fileEntries = await parseSSTable(join(dir, file));\n entries.push(...fileEntries);\n }\n\n // Parse all .log files\n const logFiles = files.filter((f) => f.endsWith(\".log\"));\n for (const file of logFiles) {\n const fileEntries = await parseLogFile(join(dir, file));\n entries.push(...fileEntries);\n }\n\n return entries;\n}\n\n/**\n * Find all entries containing a substring in their key.\n */\nexport async function findKeysContaining(dir: string, substring: Buffer): Promise<LevelDBEntry[]> {\n const allEntries = await readChromiumLevelDB(dir);\n return allEntries.filter((entry) => entry.key.includes(substring));\n}\n",
11
+ "import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport const AGENT_SLACK_DIR = join(homedir(), \".config\", \"agent-slack\");\nexport const CREDENTIALS_FILE = join(AGENT_SLACK_DIR, \"credentials.json\");\nexport const KEYCHAIN_SERVICE = \"agent-slack\";\n",
12
+ "import { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nexport async function readJsonFile<T>(path: string): Promise<T | null> {\n try {\n const raw = await readFile(path, \"utf8\");\n return JSON.parse(raw) as T;\n } catch (err: unknown) {\n if (isRecord(err) && err.code === \"ENOENT\") {\n return null;\n }\n // Corrupted JSON should not brick the CLI; treat as missing.\n if (err instanceof SyntaxError) {\n return null;\n }\n throw err;\n }\n}\n\nexport async function writeJsonFile(path: string, data: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${JSON.stringify(data, null, 2)}\\n`, { mode: 0o600 });\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n",
13
+ "import { z } from \"zod\";\n\nexport const WorkspaceAuthSchema = z.union([\n z.object({\n auth_type: z.literal(\"standard\"),\n token: z.string().min(1),\n }),\n z.object({\n auth_type: z.literal(\"browser\"),\n xoxc_token: z.string().min(1),\n xoxd_cookie: z.string().min(1),\n }),\n]);\n\nexport type WorkspaceAuth = z.infer<typeof WorkspaceAuthSchema>;\n\nexport const WorkspaceSchema = z.object({\n workspace_url: z.string().url(),\n workspace_name: z.string().optional(),\n team_id: z.string().optional(),\n team_domain: z.string().optional(),\n auth: WorkspaceAuthSchema,\n});\n\nexport type Workspace = z.infer<typeof WorkspaceSchema>;\n\nexport const CredentialsSchema = z.object({\n version: z.literal(1),\n updated_at: z.string().optional(),\n default_workspace_url: z.string().url().optional(),\n workspaces: z.array(WorkspaceSchema).default([]),\n});\n\nexport type Credentials = z.infer<typeof CredentialsSchema>;\n",
14
+ "import { platform } from \"node:os\";\nimport { execFileSync } from \"node:child_process\";\n\nconst IS_MACOS = platform() === \"darwin\";\n\nexport function keychainGet(account: string, service: string): string | null {\n if (!IS_MACOS) {\n return null;\n }\n try {\n const result = execFileSync(\n \"security\",\n [\"find-generic-password\", \"-s\", service, \"-a\", account, \"-w\"],\n { encoding: \"utf8\", stdio: [\"pipe\", \"pipe\", \"ignore\"] },\n );\n return result.trim() || null;\n } catch {\n return null;\n }\n}\n\nexport function keychainSet(input: { account: string; value: string; service: string }): boolean {\n if (!IS_MACOS) {\n return false;\n }\n const { account, value, service } = input;\n try {\n try {\n execFileSync(\"security\", [\"delete-generic-password\", \"-s\", service, \"-a\", account], {\n stdio: [\"pipe\", \"pipe\", \"ignore\"],\n });\n } catch {\n // ignore\n }\n execFileSync(\"security\", [\"add-generic-password\", \"-s\", service, \"-a\", account, \"-w\", value], {\n stdio: \"pipe\",\n });\n return true;\n } catch {\n return false;\n }\n}\n",
15
+ "import { CREDENTIALS_FILE, KEYCHAIN_SERVICE } from \"./paths.ts\";\nimport { readJsonFile, writeJsonFile } from \"../lib/fs.ts\";\nimport { CredentialsSchema, type Credentials, type Workspace } from \"./schema.ts\";\nimport { keychainGet, keychainSet } from \"./keychain.ts\";\nimport { platform } from \"node:os\";\n\nconst KEYCHAIN_PLACEHOLDER = \"__KEYCHAIN__\";\nconst IS_MACOS = platform() === \"darwin\";\n\nfunction normalizeWorkspaceUrl(workspaceUrl: string): string {\n const u = new URL(workspaceUrl);\n return `${u.protocol}//${u.host}`;\n}\n\nfunction isPlaceholderSecret(value: string | undefined): boolean {\n return !value || value === KEYCHAIN_PLACEHOLDER;\n}\n\nexport async function loadCredentials(): Promise<Credentials> {\n const fromFile = await readJsonFile<unknown>(CREDENTIALS_FILE);\n const parsed = CredentialsSchema.safeParse(fromFile ?? { version: 1, workspaces: [] });\n if (!parsed.success) {\n return { version: 1, workspaces: [] };\n }\n\n // Optional: hydrate browser cookie/token from keychain for security.\n const creds = parsed.data;\n const hydrated = creds.workspaces.map((w) => {\n if (w.auth.auth_type === \"browser\") {\n const account = `xoxc:${normalizeWorkspaceUrl(w.workspace_url)}`;\n const xoxc = keychainGet(account, KEYCHAIN_SERVICE);\n const xoxd = keychainGet(\"xoxd\", KEYCHAIN_SERVICE);\n return {\n ...w,\n auth: {\n auth_type: \"browser\" as const,\n xoxc_token: xoxc ?? w.auth.xoxc_token,\n xoxd_cookie: xoxd ?? w.auth.xoxd_cookie,\n },\n };\n }\n if (w.auth.auth_type === \"standard\") {\n const account = `token:${normalizeWorkspaceUrl(w.workspace_url)}`;\n const token = keychainGet(account, KEYCHAIN_SERVICE);\n return {\n ...w,\n auth: {\n auth_type: \"standard\" as const,\n token: token ?? w.auth.token,\n },\n };\n }\n return w;\n });\n\n return { ...creds, workspaces: hydrated };\n}\n\nexport async function saveCredentials(credentials: Credentials): Promise<void> {\n const payload: Credentials = {\n ...credentials,\n updated_at: new Date().toISOString(),\n workspaces: credentials.workspaces.map((w) => ({\n ...w,\n workspace_url: normalizeWorkspaceUrl(w.workspace_url),\n })),\n };\n\n // Store secrets in keychain when possible and avoid writing plaintext tokens to disk.\n // If keychain writes fail (or non-macOS), fall back to storing secrets in the file.\n const filePayload: Credentials = structuredClone(payload);\n\n if (IS_MACOS) {\n // Browser auth: xoxd is shared across workspaces, xoxc is per-workspace.\n const firstBrowser = payload.workspaces.find((w) => w.auth.auth_type === \"browser\");\n let xoxdStored = false;\n if (\n firstBrowser?.auth.auth_type === \"browser\" &&\n !isPlaceholderSecret(firstBrowser.auth.xoxd_cookie)\n ) {\n const existing = keychainGet(\"xoxd\", KEYCHAIN_SERVICE);\n xoxdStored =\n existing === firstBrowser.auth.xoxd_cookie ||\n keychainSet({\n account: \"xoxd\",\n value: firstBrowser.auth.xoxd_cookie,\n service: KEYCHAIN_SERVICE,\n });\n }\n\n for (const w of filePayload.workspaces) {\n if (w.auth.auth_type === \"browser\") {\n const account = `xoxc:${normalizeWorkspaceUrl(w.workspace_url)}`;\n const tokenStored =\n isPlaceholderSecret(w.auth.xoxc_token) ||\n keychainGet(account, KEYCHAIN_SERVICE) === w.auth.xoxc_token ||\n keychainSet({ account, value: w.auth.xoxc_token, service: KEYCHAIN_SERVICE });\n\n if (tokenStored) {\n w.auth.xoxc_token = KEYCHAIN_PLACEHOLDER;\n }\n if (xoxdStored) {\n w.auth.xoxd_cookie = KEYCHAIN_PLACEHOLDER;\n }\n }\n\n if (w.auth.auth_type === \"standard\") {\n const account = `token:${normalizeWorkspaceUrl(w.workspace_url)}`;\n const tokenStored =\n isPlaceholderSecret(w.auth.token) ||\n keychainGet(account, KEYCHAIN_SERVICE) === w.auth.token ||\n keychainSet({ account, value: w.auth.token, service: KEYCHAIN_SERVICE });\n if (tokenStored) {\n w.auth.token = KEYCHAIN_PLACEHOLDER;\n }\n }\n }\n }\n\n await writeJsonFile(CREDENTIALS_FILE, filePayload);\n}\n\nexport async function upsertWorkspace(workspace: Workspace): Promise<Workspace> {\n const creds = await loadCredentials();\n const normalizedUrl = normalizeWorkspaceUrl(workspace.workspace_url);\n const next: Workspace = { ...workspace, workspace_url: normalizedUrl };\n\n const idx = creds.workspaces.findIndex(\n (w) => normalizeWorkspaceUrl(w.workspace_url) === normalizedUrl,\n );\n if (idx === -1) {\n creds.workspaces.push(next);\n } else {\n creds.workspaces[idx] = {\n ...creds.workspaces[idx],\n ...next,\n auth: next.auth,\n };\n }\n\n if (!creds.default_workspace_url) {\n creds.default_workspace_url = normalizedUrl;\n }\n await saveCredentials(creds);\n return next;\n}\n\nexport async function upsertWorkspaces(workspaces: Workspace[]): Promise<void> {\n if (workspaces.length === 0) {\n return;\n }\n const creds = await loadCredentials();\n\n for (const workspace of workspaces) {\n const normalizedUrl = normalizeWorkspaceUrl(workspace.workspace_url);\n const next: Workspace = { ...workspace, workspace_url: normalizedUrl };\n\n const idx = creds.workspaces.findIndex(\n (w) => normalizeWorkspaceUrl(w.workspace_url) === normalizedUrl,\n );\n if (idx === -1) {\n creds.workspaces.push(next);\n } else {\n creds.workspaces[idx] = {\n ...creds.workspaces[idx],\n ...next,\n auth: next.auth,\n };\n }\n\n if (!creds.default_workspace_url) {\n creds.default_workspace_url = normalizedUrl;\n }\n }\n\n await saveCredentials(creds);\n}\n\nexport async function setDefaultWorkspace(workspaceUrl: string): Promise<void> {\n const creds = await loadCredentials();\n creds.default_workspace_url = normalizeWorkspaceUrl(workspaceUrl);\n await saveCredentials(creds);\n}\n\nexport async function removeWorkspace(workspaceUrl: string): Promise<void> {\n const creds = await loadCredentials();\n const normalized = normalizeWorkspaceUrl(workspaceUrl);\n creds.workspaces = creds.workspaces.filter(\n (w) => normalizeWorkspaceUrl(w.workspace_url) !== normalized,\n );\n if (creds.default_workspace_url === normalized) {\n creds.default_workspace_url = creds.workspaces[0]?.workspace_url;\n }\n await saveCredentials(creds);\n}\n\nexport async function resolveWorkspaceForUrl(workspaceUrl: string): Promise<Workspace | null> {\n const creds = await loadCredentials();\n const normalized = normalizeWorkspaceUrl(workspaceUrl);\n return (\n creds.workspaces.find((w) => normalizeWorkspaceUrl(w.workspace_url) === normalized) ?? null\n );\n}\n\nexport async function resolveDefaultWorkspace(): Promise<Workspace | null> {\n const creds = await loadCredentials();\n if (creds.default_workspace_url) {\n const byDefault = creds.workspaces.find((w) => w.workspace_url === creds.default_workspace_url);\n if (byDefault) {\n return byDefault;\n }\n }\n return creds.workspaces[0] ?? null;\n}\n\n// (reserved for future non-secret per-workspace metadata)\n",
16
+ "import type { SlackApiClient } from \"./client.ts\";\n\nexport function isChannelId(input: string): boolean {\n return /^[CDG][A-Z0-9]{8,}$/.test(input);\n}\n\nexport function normalizeChannelInput(input: string): {\n kind: \"id\" | \"name\";\n value: string;\n} {\n const trimmed = input.trim();\n if (trimmed.startsWith(\"#\")) {\n return { kind: \"name\", value: trimmed.slice(1) };\n }\n if (isChannelId(trimmed)) {\n return { kind: \"id\", value: trimmed };\n }\n return { kind: \"name\", value: trimmed };\n}\n\nexport async function resolveChannelId(client: SlackApiClient, input: string): Promise<string> {\n const normalized = normalizeChannelInput(input);\n if (normalized.kind === \"id\") {\n return normalized.value;\n }\n\n const name = normalized.value;\n if (!name) {\n throw new Error(\"Channel name is empty\");\n }\n\n let cursor: string | undefined;\n const matches: { id: string; name?: string; is_private?: boolean }[] = [];\n for (;;) {\n const resp = await client.api(\"conversations.list\", {\n exclude_archived: true,\n limit: 200,\n cursor,\n types: \"public_channel,private_channel\",\n });\n const chans = asArray(resp.channels).filter(isRecord);\n for (const c of chans) {\n if (getString(c.name) === name && getString(c.id)) {\n matches.push({\n id: getString(c.id) ?? \"\",\n name: getString(c.name) ?? undefined,\n is_private: typeof c.is_private === \"boolean\" ? c.is_private : undefined,\n });\n }\n }\n\n const meta = isRecord(resp.response_metadata) ? resp.response_metadata : null;\n const next = meta ? getString(meta.next_cursor) : undefined;\n if (!next) {\n break;\n }\n cursor = next;\n }\n\n if (matches.length === 1) {\n return matches[0]!.id;\n }\n if (matches.length === 0) {\n throw new Error(`Could not resolve channel name: #${name}`);\n }\n\n throw new Error(\n `Ambiguous channel name: #${name} (matched ${matches.length} channels: ${matches\n .map((m) => m.id)\n .join(\", \")})`,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n",
17
+ "import { WebClient } from \"@slack/web-api\";\nimport { getUserAgent } from \"../lib/version.ts\";\n\nexport type SlackAuth =\n | { auth_type: \"standard\"; token: string }\n | { auth_type: \"browser\"; xoxc_token: string; xoxd_cookie: string };\n\nexport class SlackApiClient {\n private auth: SlackAuth;\n private web?: WebClient;\n private workspaceUrl?: string;\n\n constructor(auth: SlackAuth, options?: { workspaceUrl?: string }) {\n this.auth = auth;\n this.workspaceUrl = options?.workspaceUrl;\n if (auth.auth_type === \"standard\") {\n this.web = new WebClient(auth.token);\n }\n }\n\n async api(\n method: string,\n params: Record<string, unknown> = {},\n ): Promise<Record<string, unknown>> {\n if (this.auth.auth_type === \"standard\") {\n if (!this.web) {\n throw new Error(\"WebClient not initialized\");\n }\n return (await this.web.apiCall(method, params)) as unknown as Record<string, unknown>;\n }\n\n if (!this.workspaceUrl) {\n throw new Error(\n \"Browser auth requires workspace URL. Provide --workspace-url or set SLACK_WORKSPACE_URL, or call via a Slack message URL.\",\n );\n }\n const { auth } = this;\n if (auth.auth_type !== \"browser\") {\n throw new Error(\"Browser API requires browser auth\");\n }\n return this.browserApi({\n workspaceUrl: this.workspaceUrl,\n auth,\n method,\n params,\n });\n }\n\n private async browserApi(input: {\n workspaceUrl: string;\n auth: Extract<SlackAuth, { auth_type: \"browser\" }>;\n method: string;\n params: Record<string, unknown>;\n attempt?: number;\n }): Promise<Record<string, unknown>> {\n const attempt = input.attempt ?? 0;\n const url = `${input.workspaceUrl.replace(/\\/$/, \"\")}/api/${input.method}`;\n const cleanedEntries = Object.entries(input.params)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => [k, String(v)]);\n const formBody = new URLSearchParams({\n token: input.auth.xoxc_token,\n ...Object.fromEntries(cleanedEntries),\n });\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Cookie: `d=${encodeURIComponent(input.auth.xoxd_cookie)}`,\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Origin: \"https://app.slack.com\",\n \"User-Agent\": getUserAgent(),\n },\n body: formBody,\n });\n\n if (response.status === 429 && attempt < 3) {\n const retryAfter = Number(response.headers.get(\"Retry-After\") ?? \"5\");\n const delayMs = Math.min(Math.max(retryAfter, 1) * 1000, 30000);\n await new Promise((r) => setTimeout(r, delayMs));\n return this.browserApi({\n ...input,\n attempt: attempt + 1,\n });\n }\n\n const data: unknown = await response.json().catch(() => ({}));\n if (!response.ok) {\n throw new Error(`Slack HTTP ${response.status} calling ${input.method}`);\n }\n if (!isRecord(data) || data.ok !== true) {\n const error = isRecord(data) && typeof data.error === \"string\" ? data.error : null;\n throw new Error(error || `Slack API error calling ${input.method}`);\n }\n return data;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n",
18
+ "import { extractFromChrome } from \"../auth/chrome.ts\";\nimport { parseSlackCurlCommand } from \"../auth/curl.ts\";\nimport { extractFromSlackDesktop } from \"../auth/desktop.ts\";\nimport {\n loadCredentials,\n resolveDefaultWorkspace,\n resolveWorkspaceForUrl,\n upsertWorkspace,\n upsertWorkspaces,\n} from \"../auth/store.ts\";\nimport { normalizeChannelInput } from \"../slack/channels.ts\";\nimport { SlackApiClient, type SlackAuth } from \"../slack/client.ts\";\n\nexport type CliContext = {\n effectiveWorkspaceUrl: (flag?: string) => string | undefined;\n assertWorkspaceSpecifiedForChannelNames: (input: {\n workspaceUrl: string | undefined;\n channels: string[];\n }) => Promise<void>;\n withAutoRefresh: <T>(input: {\n workspaceUrl: string | undefined;\n work: () => Promise<T>;\n }) => Promise<T>;\n getClientForWorkspace: (workspaceUrl?: string) => Promise<{\n client: SlackApiClient;\n auth: SlackAuth;\n workspace_url?: string;\n }>;\n normalizeUrl: (u: string) => string;\n errorMessage: (err: unknown) => string;\n parseContentType: (value: unknown) => \"any\" | \"text\" | \"image\" | \"snippet\" | \"file\";\n parseCurl: (curl: string) => ReturnType<typeof parseSlackCurlCommand>;\n importDesktop: () => ReturnType<typeof extractFromSlackDesktop>;\n importChrome: () => ReturnType<typeof extractFromChrome>;\n};\n\nfunction isEnvAuthConfigured(): boolean {\n return Boolean(process.env.SLACK_TOKEN?.trim());\n}\n\nfunction effectiveWorkspaceUrl(flag?: string): string | undefined {\n return flag?.trim() || process.env.SLACK_WORKSPACE_URL?.trim() || undefined;\n}\n\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\nfunction parseContentType(value: unknown): \"any\" | \"text\" | \"image\" | \"snippet\" | \"file\" {\n const raw = String(value ?? \"any\").toLowerCase();\n if (raw === \"text\" || raw === \"image\" || raw === \"snippet\" || raw === \"file\") {\n return raw;\n }\n return \"any\";\n}\n\nasync function assertWorkspaceSpecifiedForChannelNames(input: {\n workspaceUrl: string | undefined;\n channels: string[];\n}): Promise<void> {\n const hasName = input.channels.some((c) => normalizeChannelInput(c).kind === \"name\");\n if (!hasName) {\n return;\n }\n\n const creds = await loadCredentials();\n if ((creds.workspaces?.length ?? 0) <= 1) {\n return;\n }\n\n if (!input.workspaceUrl) {\n throw new Error(\n 'Ambiguous channel name across multiple workspaces. Pass --workspace \"https://...slack.com\" (or set SLACK_WORKSPACE_URL).',\n );\n }\n}\n\nfunction isAuthErrorMessage(message: string): boolean {\n return /(?:^|[^a-z])(invalid_auth|token_expired)(?:$|[^a-z])/i.test(message);\n}\n\nfunction normalizeUrl(u: string): string {\n const url = new URL(u);\n return `${url.protocol}//${url.host}`;\n}\n\nasync function refreshFromDesktopIfPossible(): Promise<boolean> {\n if (process.platform !== \"darwin\") {\n return false;\n }\n try {\n const extracted = await extractFromSlackDesktop();\n await upsertWorkspaces(\n extracted.teams.map((team) => ({\n workspace_url: normalizeUrl(team.url),\n workspace_name: team.name,\n auth: {\n auth_type: \"browser\" as const,\n xoxc_token: team.token,\n xoxd_cookie: extracted.cookie_d,\n },\n })),\n );\n return true;\n } catch {\n return false;\n }\n}\n\nasync function withAutoRefresh<T>(input: {\n workspaceUrl: string | undefined;\n work: () => Promise<T>;\n}): Promise<T> {\n try {\n return await input.work();\n } catch (err: unknown) {\n const message = errorMessage(err);\n if (isEnvAuthConfigured()) {\n throw err;\n }\n if (!isAuthErrorMessage(message)) {\n throw err;\n }\n\n const refreshed = await refreshFromDesktopIfPossible();\n if (!refreshed) {\n throw err;\n }\n return await input.work();\n }\n}\n\nfunction pickAuthFromEnv(): SlackAuth | null {\n const token = process.env.SLACK_TOKEN?.trim();\n if (!token) {\n return null;\n }\n if (token.startsWith(\"xoxc-\")) {\n const cookie = (process.env.SLACK_COOKIE_D || process.env.SLACK_COOKIE || \"\").trim();\n if (!cookie) {\n throw new Error(\"SLACK_TOKEN looks like xoxc- but SLACK_COOKIE_D is missing\");\n }\n return { auth_type: \"browser\", xoxc_token: token, xoxd_cookie: cookie };\n }\n return { auth_type: \"standard\", token };\n}\n\nasync function getClientForWorkspace(workspaceUrl?: string): Promise<{\n client: SlackApiClient;\n auth: SlackAuth;\n workspace_url?: string;\n}> {\n const env = pickAuthFromEnv();\n if (env) {\n const envWorkspaceUrl = process.env.SLACK_WORKSPACE_URL?.trim();\n const urlForBrowser = workspaceUrl || envWorkspaceUrl;\n return {\n client: new SlackApiClient(env, { workspaceUrl: urlForBrowser }),\n auth: env,\n workspace_url: urlForBrowser,\n };\n }\n\n if (workspaceUrl) {\n const ws = await resolveWorkspaceForUrl(workspaceUrl);\n if (ws) {\n return {\n client: new SlackApiClient(ws.auth as SlackAuth, {\n workspaceUrl: ws.workspace_url,\n }),\n auth: ws.auth as SlackAuth,\n workspace_url: ws.workspace_url,\n };\n }\n }\n\n const def = await resolveDefaultWorkspace();\n if (def) {\n return {\n client: new SlackApiClient(def.auth as SlackAuth, {\n workspaceUrl: def.workspace_url,\n }),\n auth: def.auth as SlackAuth,\n workspace_url: def.workspace_url,\n };\n }\n\n // Default: try Slack Desktop extraction (macOS). Does not require quitting Slack.\n try {\n const extracted = await extractFromSlackDesktop();\n await upsertWorkspaces(\n extracted.teams.map((team) => ({\n workspace_url: normalizeUrl(team.url),\n workspace_name: team.name,\n auth: {\n auth_type: \"browser\" as const,\n xoxc_token: team.token,\n xoxd_cookie: extracted.cookie_d,\n },\n })),\n );\n\n const desired = workspaceUrl\n ? await resolveWorkspaceForUrl(workspaceUrl)\n : await resolveDefaultWorkspace();\n const chosen = desired ?? (await resolveDefaultWorkspace());\n if (chosen) {\n return {\n client: new SlackApiClient(chosen.auth as SlackAuth, {\n workspaceUrl: chosen.workspace_url,\n }),\n auth: chosen.auth as SlackAuth,\n workspace_url: chosen.workspace_url,\n };\n }\n } catch {\n // Fall through to Chrome extraction.\n }\n\n // Fallback: try Chrome extraction (macOS).\n const chrome = extractFromChrome();\n if (chrome && chrome.teams.length > 0) {\n const chosen =\n (workspaceUrl\n ? chrome.teams.find((t) => normalizeUrl(t.url) === normalizeUrl(workspaceUrl))\n : null) ?? chrome.teams[0]!;\n const auth: SlackAuth = {\n auth_type: \"browser\",\n xoxc_token: chosen.token,\n xoxd_cookie: chrome.cookie_d,\n };\n await upsertWorkspace({\n workspace_url: normalizeUrl(chosen.url),\n workspace_name: chosen.name,\n auth: {\n auth_type: \"browser\",\n xoxc_token: chosen.token,\n xoxd_cookie: chrome.cookie_d,\n },\n });\n return {\n client: new SlackApiClient(auth, {\n workspaceUrl: normalizeUrl(chosen.url),\n }),\n auth,\n workspace_url: normalizeUrl(chosen.url),\n };\n }\n\n throw new Error(\n 'No Slack credentials available. Try \"agent-slack auth import-desktop\" or set SLACK_TOKEN / SLACK_COOKIE_D.',\n );\n}\n\nexport function createCliContext(): CliContext {\n return {\n effectiveWorkspaceUrl,\n assertWorkspaceSpecifiedForChannelNames,\n withAutoRefresh,\n getClientForWorkspace,\n normalizeUrl,\n errorMessage,\n parseContentType,\n parseCurl: parseSlackCurlCommand,\n importDesktop: extractFromSlackDesktop,\n importChrome: extractFromChrome,\n };\n}\n",
19
+ "export function pruneEmpty<T>(value: T): T {\n const pruned = pruneEmptyInternal(value);\n return (pruned === undefined ? ({} as T) : (pruned as T)) as T;\n}\n\nfunction pruneEmptyInternal(value: unknown): unknown {\n if (value === null || value === undefined) {\n return undefined;\n }\n\n if (typeof value === \"string\") {\n return value.trim() === \"\" ? undefined : value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return value;\n }\n\n if (Array.isArray(value)) {\n const next = value\n .map((v) => pruneEmptyInternal(v))\n .filter((v): v is Exclude<unknown, undefined> => v !== undefined);\n return next.length === 0 ? undefined : next;\n }\n\n if (typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n const next = pruneEmptyInternal(v);\n if (next !== undefined) {\n out[k] = next;\n }\n }\n return Object.keys(out).length === 0 ? undefined : out;\n }\n\n return value;\n}\n",
20
+ "export function redactSecret(\n value: string,\n options?: { keepStart?: number; keepEnd?: number },\n): string {\n const keepStart = options?.keepStart ?? 6;\n const keepEnd = options?.keepEnd ?? 4;\n if (!value) {\n return value;\n }\n if (value.length <= keepStart + keepEnd + 3) {\n return \"[redacted]\";\n }\n return `${value.slice(0, keepStart)}…${value.slice(-keepEnd)}`;\n}\n",
21
+ "import type { Command } from \"commander\";\nimport type { CliContext } from \"./context.ts\";\nimport {\n loadCredentials,\n removeWorkspace,\n setDefaultWorkspace,\n upsertWorkspace,\n upsertWorkspaces,\n} from \"../auth/store.ts\";\nimport { pruneEmpty } from \"../lib/compact-json.ts\";\nimport { redactSecret } from \"../lib/redact.ts\";\n\nasync function runAuthTest(input: {\n ctx: CliContext;\n workspaceUrl?: string;\n}): Promise<Record<string, unknown>> {\n return input.ctx.withAutoRefresh({\n workspaceUrl: input.workspaceUrl,\n work: async () => {\n const { client } = await input.ctx.getClientForWorkspace(input.workspaceUrl);\n return (await client.api(\"auth.test\", {})) as Record<string, unknown>;\n },\n });\n}\n\nexport function registerAuthCommand(input: { program: Command; ctx: CliContext }): void {\n const auth = input.program.command(\"auth\").description(\"Manage Slack authentication\");\n\n auth\n .command(\"whoami\")\n .description(\"Show configured workspaces and token sources\")\n .action(async () => {\n try {\n const creds = await loadCredentials();\n const sanitized = {\n ...creds,\n workspaces: creds.workspaces.map((w) => ({\n workspace_url: w.workspace_url,\n workspace_name: w.workspace_name,\n auth_type: w.auth.auth_type,\n token:\n w.auth.auth_type === \"standard\"\n ? redactSecret(w.auth.token)\n : redactSecret(w.auth.xoxc_token),\n cookie_d: w.auth.auth_type === \"browser\" ? redactSecret(w.auth.xoxd_cookie) : undefined,\n })),\n };\n console.log(JSON.stringify(pruneEmpty(sanitized), null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"test\")\n .description(\"Verify credentials (calls Slack auth.test)\")\n .option(\"--workspace <url>\", \"Workspace URL (needed when you have multiple workspaces)\")\n .action(async (...args) => {\n const [options] = args as [{ workspace?: string }];\n try {\n const resp = await runAuthTest({\n ctx: input.ctx,\n workspaceUrl: input.ctx.effectiveWorkspaceUrl(options.workspace),\n });\n console.log(JSON.stringify(pruneEmpty(resp), null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"import-chrome\")\n .description(\"Import xoxc/xoxd from a logged-in Slack tab in Google Chrome (macOS)\")\n .action(async () => {\n try {\n const extracted = input.ctx.importChrome();\n if (!extracted) {\n throw new Error(\n \"Could not extract tokens from Chrome. Open Slack in Chrome and ensure you're logged in.\",\n );\n }\n\n for (const team of extracted.teams) {\n await upsertWorkspace({\n workspace_url: input.ctx.normalizeUrl(team.url),\n workspace_name: team.name,\n auth: {\n auth_type: \"browser\",\n xoxc_token: team.token,\n xoxd_cookie: extracted.cookie_d,\n },\n });\n }\n console.log(`Imported ${extracted.teams.length} workspace token(s) from Chrome.`);\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"parse-curl\")\n .description(\"Paste a Slack API request copied as cURL (extracts xoxc/xoxd and saves locally)\")\n .action(async () => {\n try {\n const curlInput = await new Response(process.stdin).text();\n if (!curlInput.trim()) {\n throw new Error(\"Expected cURL command on stdin\");\n }\n const parsed = input.ctx.parseCurl(curlInput);\n await upsertWorkspace({\n workspace_url: input.ctx.normalizeUrl(parsed.workspace_url),\n auth: {\n auth_type: \"browser\",\n xoxc_token: parsed.xoxc_token,\n xoxd_cookie: parsed.xoxd_cookie,\n },\n });\n console.log(`Imported tokens for ${input.ctx.normalizeUrl(parsed.workspace_url)}.`);\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"import-desktop\")\n .description(\n \"Import xoxc token(s) + d cookie from Slack Desktop data (TypeScript; no need to quit Slack)\",\n )\n .action(async () => {\n try {\n const extracted = await input.ctx.importDesktop();\n await upsertWorkspaces(\n extracted.teams.map((team) => ({\n workspace_url: input.ctx.normalizeUrl(team.url),\n workspace_name: team.name,\n auth: {\n auth_type: \"browser\",\n xoxc_token: team.token,\n xoxd_cookie: extracted.cookie_d,\n },\n })),\n );\n const payload = {\n imported: extracted.teams.length,\n source: extracted.source,\n workspaces: extracted.teams.map((t) => ({\n workspace_url: input.ctx.normalizeUrl(t.url),\n workspace_name: t.name,\n })),\n };\n console.log(JSON.stringify(pruneEmpty(payload), null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"add\")\n .description(\"Add credentials (standard token or browser xoxc/xoxd)\")\n .requiredOption(\"--workspace-url <url>\", \"Workspace URL like https://myteam.slack.com\")\n .option(\"--token <token>\", \"Standard Slack token (xoxb/xoxp)\")\n .option(\"--xoxc <token>\", \"Browser token (xoxc-...)\")\n .option(\"--xoxd <cookie>\", \"Browser cookie d (xoxd-...)\")\n .action(async (...args) => {\n const [options] = args as [\n { workspaceUrl: string; token?: string; xoxc?: string; xoxd?: string },\n ];\n try {\n const workspaceUrl = input.ctx.normalizeUrl(options.workspaceUrl);\n if (options.token) {\n await upsertWorkspace({\n workspace_url: workspaceUrl,\n auth: { auth_type: \"standard\", token: options.token },\n });\n console.log(\"Saved standard token.\");\n return;\n }\n if (options.xoxc && options.xoxd) {\n await upsertWorkspace({\n workspace_url: workspaceUrl,\n auth: {\n auth_type: \"browser\",\n xoxc_token: options.xoxc,\n xoxd_cookie: options.xoxd,\n },\n });\n console.log(\"Saved browser tokens.\");\n return;\n }\n throw new Error(\"Provide either --token or both --xoxc and --xoxd\");\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"set-default\")\n .description(\"Set the default workspace URL\")\n .argument(\"<workspace-url>\", \"Workspace URL like https://myteam.slack.com\")\n .action(async (...args) => {\n const [workspaceUrl] = args as [string];\n try {\n await setDefaultWorkspace(workspaceUrl);\n console.log(\"Default workspace updated.\");\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n auth\n .command(\"remove\")\n .description(\"Remove a workspace from local config\")\n .argument(\"<workspace-url>\", \"Workspace URL like https://myteam.slack.com\")\n .action(async (...args) => {\n const [workspaceUrl] = args as [string];\n try {\n await removeWorkspace(workspaceUrl);\n console.log(\"Removed workspace.\");\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n}\n",
22
+ "import { mkdir, writeFile } from \"node:fs/promises\";\nimport { basename, join, resolve } from \"node:path\";\nimport type { SlackAuth } from \"./client.ts\";\nimport { existsSync } from \"node:fs\";\nimport { getUserAgent } from \"../lib/version.ts\";\n\nexport async function downloadSlackFile(input: {\n auth: SlackAuth;\n url: string;\n destDir: string;\n preferredName?: string;\n options?: { allowHtml?: boolean };\n}): Promise<string> {\n const { auth, url, destDir, preferredName, options } = input;\n const absDir = resolve(destDir);\n await mkdir(absDir, { recursive: true });\n const name = sanitizeFilename(preferredName || basename(new URL(url).pathname) || \"file\");\n const path = join(absDir, name);\n\n if (existsSync(path)) {\n return path;\n }\n\n const headers: Record<string, string> = {};\n if (auth.auth_type === \"standard\") {\n headers.Authorization = `Bearer ${auth.token}`;\n } else {\n headers.Authorization = `Bearer ${auth.xoxc_token}`;\n headers.Cookie = `d=${encodeURIComponent(auth.xoxd_cookie)}`;\n headers.Referer = \"https://app.slack.com/\";\n headers[\"User-Agent\"] = getUserAgent();\n }\n\n const resp = await fetch(url, { headers });\n if (!resp.ok) {\n throw new Error(`Failed to download file (${resp.status})`);\n }\n const contentType = resp.headers.get(\"content-type\") || \"\";\n if (!options?.allowHtml && contentType.includes(\"text/html\")) {\n const text = await resp.text();\n throw new Error(\n `Downloaded HTML instead of file (auth likely failed). First bytes: ${JSON.stringify(\n text.slice(0, 120),\n )}`,\n );\n }\n const buf = Buffer.from(await resp.arrayBuffer());\n await writeFile(path, buf);\n return path;\n}\n\nfunction sanitizeFilename(name: string): string {\n return name.replace(/[\\\\/<>:\"|?*]/g, \"_\");\n}\n",
23
+ "import TurndownService from \"turndown\";\nimport { gfm } from \"turndown-plugin-gfm\";\n\nexport function htmlToMarkdown(html: string): string {\n const service = new TurndownService({\n headingStyle: \"atx\",\n codeBlockStyle: \"fenced\",\n bulletListMarker: \"-\",\n emDelimiter: \"_\",\n });\n\n service.use(gfm);\n\n // Keep line breaks from <br>\n service.addRule(\"br\", {\n filter: \"br\",\n replacement: () => \"\\n\",\n });\n\n // Slack exports sometimes wrap content in <main> / <article>.\n // Turndown handles full documents fine, but prefer the primary content node.\n const extracted =\n extractTag(html, \"main\") ?? extractTag(html, \"article\") ?? extractTag(html, \"body\") ?? html;\n\n return service.turndown(extracted);\n}\n\nfunction extractTag(html: string, tag: string): string | null {\n const re = new RegExp(`<${tag}\\\\b[^>]*>([\\\\s\\\\S]*?)<\\\\/${tag}>`, \"i\");\n const m = html.match(re);\n return m ? m[1]! : null;\n}\n",
24
+ "import { join, resolve } from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\nimport { getAppDir } from \"./app-dir.ts\";\n\nexport function getDownloadsDir(): string {\n return resolve(join(getAppDir(), \"tmp\", \"downloads\"));\n}\n\nexport async function ensureDownloadsDir(): Promise<string> {\n const dir = getDownloadsDir();\n await mkdir(dir, { recursive: true });\n return dir;\n}\n",
25
+ "import { homedir, tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\n\nexport function getAppDir(): string {\n const xdg = process.env.XDG_RUNTIME_DIR?.trim();\n if (xdg) {\n return join(xdg, \"agent-slack\");\n }\n\n const home = homedir();\n if (home) {\n return join(home, \".agent-slack\");\n }\n\n return join(tmpdir(), \"agent-slack\");\n}\n",
26
+ "import type { SlackApiClient, SlackAuth } from \"./client.ts\";\nimport { downloadSlackFile } from \"./files.ts\";\nimport { htmlToMarkdown } from \"./html-to-md.ts\";\nimport { ensureDownloadsDir } from \"../lib/tmp-paths.ts\";\nimport { readFile } from \"node:fs/promises\";\nimport { getUserAgent } from \"../lib/version.ts\";\n\nexport type SlackCanvasRef = {\n workspace_url: string;\n canvas_id: string; // looks like a file id, e.g. F080JDE025R\n raw: string;\n};\n\nexport function parseSlackCanvasUrl(input: string): SlackCanvasRef {\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n throw new Error(`Invalid URL: ${input}`);\n }\n\n if (!/\\.slack\\.com$/i.test(url.hostname)) {\n throw new Error(`Not a Slack workspace URL: ${url.hostname}`);\n }\n\n // Common form: /docs/<team_id>/<canvas_id>\n // Example seen in Slack docs: https://workspace.slack.com/docs/T.../F...\n const parts = url.pathname.split(\"/\").filter(Boolean);\n if (parts[0] !== \"docs\") {\n throw new Error(`Unsupported Slack canvas URL path: ${url.pathname}`);\n }\n\n const canvas_id = parts.find((p) => /^F[A-Z0-9]{8,}$/.test(p));\n if (!canvas_id) {\n throw new Error(`Could not find canvas id in: ${url.pathname}`);\n }\n\n const workspace_url = `${url.protocol}//${url.host}`;\n return { workspace_url, canvas_id, raw: input };\n}\n\nexport async function fetchCanvasMarkdown(\n client: SlackApiClient,\n input: {\n auth: SlackAuth;\n workspaceUrl: string;\n canvasId: string;\n options?: { maxChars?: number; downloadHtml?: boolean };\n },\n): Promise<{ canvas: { id: string; title?: string; markdown: string } }> {\n const info = await client.api(\"files.info\", { file: input.canvasId });\n const file = isRecord(info.file) ? info.file : null;\n if (!file) {\n throw new Error(\"Canvas not found (files.info returned no file)\");\n }\n\n const title = (getString(file.title) || getString(file.name) || \"\").trim() || undefined;\n const downloadUrl = getString(file.url_private_download) ?? getString(file.url_private);\n if (!downloadUrl) {\n throw new Error(\"Canvas has no download URL\");\n }\n\n let html = \"\";\n if (input.options?.downloadHtml ?? true) {\n const htmlPath = await downloadSlackFile({\n auth: input.auth,\n url: downloadUrl,\n // keep canvases with other downloads (agent-friendly temp dir)\n // filename uses canvasId (unique)\n // Note: canvases download as HTML via Slack file endpoints\n // so allowHtml must be true.\n destDir: await ensureDownloadsDir(),\n preferredName: `${input.canvasId}.html`,\n options: { allowHtml: true },\n });\n html = await readFile(htmlPath, \"utf8\");\n } else {\n const headers: Record<string, string> = {};\n if (input.auth.auth_type === \"standard\") {\n headers.Authorization = `Bearer ${input.auth.token}`;\n } else {\n headers.Authorization = `Bearer ${input.auth.xoxc_token}`;\n headers.Cookie = `d=${encodeURIComponent(input.auth.xoxd_cookie)}`;\n headers.Referer = \"https://app.slack.com/\";\n headers[\"User-Agent\"] = getUserAgent();\n }\n const resp = await fetch(downloadUrl, { headers });\n if (!resp.ok) {\n throw new Error(`Failed to download canvas HTML (${resp.status})`);\n }\n html = await resp.text();\n }\n\n const markdownRaw = htmlToMarkdown(html).trim();\n const maxChars = input.options?.maxChars ?? 20000;\n const markdown =\n maxChars >= 0 && markdownRaw.length > maxChars\n ? `${markdownRaw.slice(0, maxChars)}\\n…`\n : markdownRaw;\n\n return {\n canvas: {\n id: input.canvasId,\n title,\n markdown,\n },\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n",
27
+ "import type { Command } from \"commander\";\nimport type { CliContext } from \"./context.ts\";\nimport { fetchCanvasMarkdown, parseSlackCanvasUrl } from \"../slack/canvas.ts\";\nimport { pruneEmpty } from \"../lib/compact-json.ts\";\n\nexport function registerCanvasCommand(input: { program: Command; ctx: CliContext }): void {\n const canvasCmd = input.program.command(\"canvas\").description(\"Work with Slack canvases\");\n\n canvasCmd\n .command(\"get\")\n .description(\"Fetch a Slack canvas and convert it to Markdown\")\n .argument(\"<canvas>\", \"Slack canvas URL (…/docs/…/F…) or canvas id (F…)\")\n .option(\n \"--workspace <url>\",\n \"Workspace URL (required if passing a canvas id and you have multiple workspaces)\",\n )\n .option(\n \"--max-chars <n>\",\n \"Max markdown characters to include (default 20000, -1 for unlimited)\",\n \"20000\",\n )\n .action(async (...args) => {\n const [value, options] = args as [string, { workspace?: string; maxChars: string }];\n try {\n let workspaceUrl: string | undefined;\n let canvasId: string;\n\n try {\n const ref = parseSlackCanvasUrl(value);\n workspaceUrl = ref.workspace_url;\n canvasId = ref.canvas_id;\n } catch {\n const trimmed = String(value).trim();\n if (!/^F[A-Z0-9]{8,}$/.test(trimmed)) {\n throw new Error(\n `Unsupported canvas input: ${value} (expected Slack canvas URL or id like F...)`,\n );\n }\n canvasId = trimmed;\n workspaceUrl = options.workspace?.trim() || undefined;\n }\n\n const payload = await input.ctx.withAutoRefresh({\n workspaceUrl,\n work: async () => {\n const { client, auth, workspace_url } =\n await input.ctx.getClientForWorkspace(workspaceUrl);\n const maxChars = Number.parseInt(options.maxChars, 10);\n return await fetchCanvasMarkdown(client, {\n auth,\n workspaceUrl: workspace_url ?? workspaceUrl ?? \"\",\n canvasId,\n options: { maxChars },\n });\n },\n });\n\n console.log(JSON.stringify(pruneEmpty(payload), null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n}\n",
28
+ "import * as emoji from \"node-emoji\";\n\nexport function slackEmojiShortcodesToUnicode(text: string): string {\n if (!text) {\n return \"\";\n }\n // Prefer Slack-style emoji shortcodes (node-emoji) since Slack uses names\n // that don't always match other shortcode sets.\n return emoji.emojify(text);\n}\n\nexport function normalizeSlackReactionName(input: string): string {\n const trimmed = String(input ?? \"\").trim();\n if (!trimmed) {\n throw new Error(\"Emoji is empty\");\n }\n\n // Accept :rocket:\n const shortcodeMatch = trimmed.match(/^:([^:\\s]+):$/);\n if (shortcodeMatch) {\n return shortcodeMatch[1]!;\n }\n\n // Accept already-normalized names (rocket, +1, white_check_mark, etc.)\n if (/^[A-Za-z0-9_+-]+$/.test(trimmed)) {\n return trimmed;\n }\n\n // Accept unicode emoji (🚀). Convert to :rocket: then strip colons.\n const viaNodeEmoji = emoji.which(trimmed);\n if (viaNodeEmoji) {\n return viaNodeEmoji;\n }\n\n throw new Error(\n `Unsupported emoji format: ${JSON.stringify(input)} (use :emoji: or unicode emoji)`,\n );\n}\n",
29
+ "import { slackEmojiShortcodesToUnicode } from \"./emoji.ts\";\n\nexport function slackMrkdwnToMarkdown(text: string): string {\n if (!text) {\n return \"\";\n }\n\n // Links: <http://x|label> or <http://x>\n let out = text.replace(/<((https?:\\/\\/)[^>|]+)\\|([^>]+)>/g, \"[$3]($1)\");\n out = out.replace(/<((https?:\\/\\/)[^>]+)>/g, \"$1\");\n\n // Channels: <#C123|name>\n out = out.replace(/<#[A-Z0-9]+\\|([^>]+)>/g, \"#$1\");\n\n // Users: <@U123> or <@U123|name>\n out = out.replace(/<@([A-Z0-9]+)\\|([^>]+)>/g, \"@$2\");\n out = out.replace(/<@([A-Z0-9]+)>/g, \"@$1\");\n\n // Special mentions: <!here>, <!channel>, <!everyone>\n out = out.replace(/<!([a-zA-Z]+)>/g, \"@$1\");\n\n // Decode basic HTML entities Slack sometimes includes\n out = out.replace(/&lt;/g, \"<\").replace(/&gt;/g, \">\").replace(/&amp;/g, \"&\");\n\n // Prefer unicode emoji for token efficiency (e.g. 🚀 vs :rocket:)\n out = slackEmojiShortcodesToUnicode(out);\n\n return out;\n}\n",
30
+ "import { slackMrkdwnToMarkdown } from \"./mrkdwn.ts\";\n\ntype UnknownRecord = Record<string, unknown>;\n\nexport function renderSlackMessageContent(msg: unknown): string {\n const msgObj = isRecord(msg) ? msg : {};\n const blockMrkdwn = extractMrkdwnFromBlocks(msgObj.blocks);\n if (blockMrkdwn.trim()) {\n return slackMrkdwnToMarkdown(blockMrkdwn).trim();\n }\n\n const attachmentMrkdwn = extractMrkdwnFromAttachments(msgObj.attachments);\n if (attachmentMrkdwn.trim()) {\n return slackMrkdwnToMarkdown(attachmentMrkdwn).trim();\n }\n\n const text = getString(msgObj.text).trim();\n if (text) {\n return slackMrkdwnToMarkdown(text).trim();\n }\n\n return \"\";\n}\n\nfunction extractMrkdwnFromBlocks(blocks: unknown): string {\n if (!Array.isArray(blocks)) {\n return \"\";\n }\n\n const out: string[] = [];\n for (const b of blocks) {\n if (!isRecord(b)) {\n continue;\n }\n const type = getString(b.type);\n if (type === \"section\") {\n const text = isRecord(b.text) ? b.text : null;\n const textType = text ? getString(text.type) : \"\";\n if (textType === \"mrkdwn\" || textType === \"plain_text\") {\n out.push(getString(text?.text));\n }\n if (Array.isArray(b.fields)) {\n for (const f of b.fields) {\n if (!isRecord(f)) {\n continue;\n }\n const fieldType = getString(f.type);\n if (fieldType === \"mrkdwn\" || fieldType === \"plain_text\") {\n out.push(getString(f.text));\n }\n }\n }\n // Buttons often carry the only URL (e.g. \"View Progress\")\n const accessory = isRecord(b.accessory) ? b.accessory : null;\n if (getString(accessory?.type) === \"button\") {\n const label = getString((accessory?.text as UnknownRecord | undefined)?.text);\n const url = getString(accessory?.url);\n if (url) {\n out.push(label ? `${label}: ${url}` : url);\n }\n }\n continue;\n }\n if (type === \"actions\" && Array.isArray(b.elements)) {\n for (const el of b.elements) {\n if (!isRecord(el)) {\n continue;\n }\n if (getString(el.type) === \"button\") {\n const label = getString((el.text as UnknownRecord | undefined)?.text);\n const url = getString(el.url);\n if (url) {\n out.push(label ? `${label}: ${url}` : url);\n }\n }\n }\n continue;\n }\n if (type === \"context\" && Array.isArray(b.elements)) {\n for (const el of b.elements) {\n if (!isRecord(el)) {\n continue;\n }\n const elType = getString(el.type);\n if (elType === \"mrkdwn\") {\n out.push(getString(el.text));\n }\n if (elType === \"plain_text\") {\n out.push(getString(el.text));\n }\n }\n continue;\n }\n if (type === \"image\") {\n const alt = getString(b.alt_text);\n const url = getString(b.image_url);\n if (url) {\n out.push(alt ? `${alt}: ${url}` : url);\n }\n continue;\n }\n if (type === \"rich_text\") {\n const rich = extractMrkdwnFromRichTextBlock(b);\n if (rich.trim()) {\n out.push(rich);\n }\n continue;\n }\n }\n\n return out.join(\"\\n\\n\");\n}\n\nfunction extractMrkdwnFromRichTextBlock(block: unknown): string {\n if (!isRecord(block)) {\n return \"\";\n }\n const elements = Array.isArray(block.elements) ? block.elements : [];\n const out: string[] = [];\n for (const el of elements) {\n const txt = extractMrkdwnFromRichTextElement(el);\n if (txt.trim()) {\n out.push(txt);\n }\n }\n return out.join(\"\\n\\n\");\n}\n\nfunction extractMrkdwnFromRichTextElement(el: unknown): string {\n if (!isRecord(el)) {\n return \"\";\n }\n const t = getString(el.type);\n\n if (t === \"rich_text_section\") {\n const parts: string[] = [];\n for (const child of Array.isArray(el.elements) ? el.elements : []) {\n parts.push(extractMrkdwnFromRichTextElement(child));\n }\n return parts.join(\"\");\n }\n\n if (t === \"rich_text_preformatted\") {\n const parts: string[] = [];\n for (const child of Array.isArray(el.elements) ? el.elements : []) {\n parts.push(extractMrkdwnFromRichTextElement(child));\n }\n const text = parts.join(\"\");\n return text ? `\\`\\`\\`${text}\\`\\`\\`` : \"\";\n }\n\n if (t === \"rich_text_quote\") {\n const parts: string[] = [];\n for (const child of Array.isArray(el.elements) ? el.elements : []) {\n parts.push(extractMrkdwnFromRichTextElement(child));\n }\n const text = parts.join(\"\").trim();\n if (!text) {\n return \"\";\n }\n return text\n .split(\"\\n\")\n .map((line) => `> ${line}`)\n .join(\"\\n\");\n }\n\n if (t === \"rich_text_list\") {\n const style = typeof el.style === \"string\" ? el.style : \"bullet\";\n const items: string[] = [];\n const itemEls = Array.isArray(el.elements) ? el.elements : [];\n for (let idx = 0; idx < itemEls.length; idx++) {\n const item = itemEls[idx];\n const txt = extractMrkdwnFromRichTextElement(item).trim();\n if (!txt) {\n continue;\n }\n const prefix = style === \"ordered\" ? `${idx + 1}. ` : \"- \";\n items.push(`${prefix}${txt}`);\n }\n return items.join(\"\\n\");\n }\n\n if (t === \"text\") {\n const raw = getString(el.text);\n const style = isRecord(el.style) ? el.style : null;\n if (!style) {\n return raw;\n }\n let text = raw;\n if (style.code) {\n text = `\\`${text}\\``;\n }\n if (style.bold) {\n text = `*${text}*`;\n }\n if (style.italic) {\n text = `_${text}_`;\n }\n if (style.strike) {\n text = `~${text}~`;\n }\n return text;\n }\n\n if (t === \"link\") {\n const url = getString(el.url);\n const text = getString(el.text);\n if (!url) {\n return text;\n }\n return text ? `<${url}|${text}>` : url;\n }\n\n if (t === \"emoji\") {\n const name = getString(el.name);\n return name ? `:${name}:` : \"\";\n }\n\n if (t === \"user\") {\n const userId = getString(el.user_id);\n return userId ? `<@${userId}>` : \"\";\n }\n\n if (t === \"channel\") {\n const channelId = getString(el.channel_id);\n return channelId ? `<#${channelId}>` : \"\";\n }\n\n return \"\";\n}\n\nfunction extractMrkdwnFromAttachments(attachments: unknown): string {\n if (!Array.isArray(attachments)) {\n return \"\";\n }\n\n const parts: string[] = [];\n for (const a of attachments) {\n if (!isRecord(a)) {\n continue;\n }\n const chunk: string[] = [];\n const blocks = extractMrkdwnFromBlocks(a.blocks);\n if (blocks.trim()) {\n chunk.push(blocks);\n }\n const pretext = getString(a.pretext);\n if (pretext) {\n chunk.push(pretext);\n }\n const title = getString(a.title);\n const titleLink = getString(a.title_link);\n if (titleLink && title) {\n chunk.push(`<${titleLink}|${title}>`);\n } else if (title) {\n chunk.push(title);\n } else if (titleLink) {\n chunk.push(titleLink);\n }\n const text = getString(a.text);\n if (text) {\n chunk.push(text);\n }\n if (Array.isArray(a.fields)) {\n for (const f of a.fields) {\n if (!isRecord(f)) {\n continue;\n }\n const fieldTitle = getString(f.title);\n const value = getString(f.value);\n if (fieldTitle && value) {\n chunk.push(`${fieldTitle}\\n${value}`);\n } else if (fieldTitle) {\n chunk.push(fieldTitle);\n } else if (value) {\n chunk.push(value);\n }\n }\n }\n const fallback = getString(a.fallback);\n if (chunk.length === 0 && fallback) {\n chunk.push(fallback);\n }\n if (chunk.length > 0) {\n parts.push(chunk.join(\"\\n\"));\n }\n }\n return parts.join(\"\\n\\n\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getString(value: unknown): string {\n return typeof value === \"string\" ? value : \"\";\n}\n",
31
+ "import type { SlackMessageRef } from \"./url.ts\";\nimport type { SlackApiClient } from \"./client.ts\";\nimport { slackMrkdwnToMarkdown } from \"./mrkdwn.ts\";\nimport { renderSlackMessageContent } from \"./render.ts\";\n\nexport type SlackFileSummary = {\n id: string;\n name?: string;\n title?: string;\n mimetype?: string;\n filetype?: string;\n mode?: string;\n permalink?: string;\n url_private?: string;\n url_private_download?: string;\n size?: number;\n snippet?: {\n content?: string;\n language?: string;\n };\n};\n\nexport type SlackMessageSummary = {\n channel_id: string;\n ts: string;\n thread_ts?: string;\n reply_count?: number;\n user?: string;\n bot_id?: string;\n text: string;\n markdown: string;\n blocks?: unknown[];\n attachments?: unknown[];\n files?: SlackFileSummary[];\n reactions?: unknown[];\n};\n\nexport type CompactSlackMessage = {\n channel_id: string;\n ts: string;\n thread_ts?: string;\n author?: { user_id?: string; bot_id?: string };\n content?: string;\n files?: {\n mimetype?: string;\n mode?: string;\n path: string;\n }[];\n reactions?: {\n name: string;\n users: string[];\n count?: number;\n }[];\n};\n\nexport function toCompactMessage(\n msg: SlackMessageSummary,\n input?: {\n maxSnippetChars?: number;\n maxBodyChars?: number;\n includeReactions?: boolean;\n downloadedPaths?: Record<string, string>;\n },\n): CompactSlackMessage {\n const maxBodyChars = input?.maxBodyChars ?? 8000;\n const includeReactions = input?.includeReactions ?? false;\n\n const rendered = renderSlackMessageContent(msg);\n const content =\n maxBodyChars >= 0 && rendered.length > maxBodyChars\n ? `${rendered.slice(0, maxBodyChars)}\\n…`\n : rendered;\n\n const files = msg.files\n ?.map((f) => {\n const path = input?.downloadedPaths?.[f.id];\n if (!path) {\n return null;\n }\n return {\n mimetype: f.mimetype,\n mode: f.mode,\n path,\n };\n })\n .filter((f): f is NonNullable<typeof f> => Boolean(f));\n\n return {\n channel_id: msg.channel_id,\n ts: msg.ts,\n thread_ts: msg.thread_ts ?? ((msg.reply_count ?? 0) > 0 ? msg.ts : undefined),\n author: msg.user || msg.bot_id ? { user_id: msg.user, bot_id: msg.bot_id } : undefined,\n content: content ? content : undefined,\n files: files && files.length > 0 ? files : undefined,\n reactions: includeReactions ? compactReactions(msg.reactions) : undefined,\n };\n}\n\nfunction compactReactions(\n reactions: unknown[] | undefined,\n): Array<{ name: string; users: string[]; count?: number }> | undefined {\n if (!Array.isArray(reactions) || reactions.length === 0) {\n return undefined;\n }\n const out: { name: string; users: string[]; count?: number }[] = [];\n for (const r of reactions) {\n if (!isRecord(r)) {\n continue;\n }\n const name = getString(r.name)?.trim() ?? \"\";\n if (!name) {\n continue;\n }\n const users = Array.isArray(r.users)\n ? r.users.map((u) => String(u)).filter((u) => /^U[A-Z0-9]{8,}$/.test(u))\n : [];\n const count = typeof r.count === \"number\" && r.count !== users.length ? r.count : undefined;\n out.push({ name, users, count });\n }\n return out.length ? out : undefined;\n}\n\nexport async function fetchMessage(\n client: SlackApiClient,\n input: { ref: SlackMessageRef; includeReactions?: boolean },\n): Promise<SlackMessageSummary> {\n const history = await client.api(\"conversations.history\", {\n channel: input.ref.channel_id,\n latest: input.ref.message_ts,\n inclusive: true,\n limit: 5,\n include_all_metadata: input.includeReactions ? true : undefined,\n });\n const historyMessages = asArray(history.messages);\n let msg = historyMessages.find(\n (m): m is Record<string, unknown> => isRecord(m) && getString(m.ts) === input.ref.message_ts,\n );\n\n // Thread replies are not guaranteed to appear in channel history. If the URL\n // includes ?thread_ts=..., scan the thread directly.\n if (!msg && input.ref.thread_ts_hint) {\n msg = await findMessageInThread(client, {\n channelId: input.ref.channel_id,\n threadTs: input.ref.thread_ts_hint,\n targetTs: input.ref.message_ts,\n includeReactions: input.includeReactions,\n });\n }\n\n // Fallback: if the message_ts is actually the thread root, replies can still\n // be fetched via conversations.replies even if history is missing it.\n if (!msg) {\n try {\n const rootResp = await client.api(\"conversations.replies\", {\n channel: input.ref.channel_id,\n ts: input.ref.message_ts,\n limit: 1,\n include_all_metadata: input.includeReactions ? true : undefined,\n });\n const [root] = asArray(rootResp.messages);\n if (isRecord(root) && getString(root.ts) === input.ref.message_ts) {\n msg = root;\n }\n } catch {\n // ignore\n }\n }\n\n if (!msg) {\n throw new Error(\"Message not found (no access or wrong URL)\");\n }\n\n const files = asArray(msg.files)\n .map((f) => toSlackFileSummary(f))\n .filter((f): f is SlackFileSummary => f !== null);\n const enrichedFiles = files.length > 0 ? await enrichFiles(client, files) : undefined;\n\n const text = getString(msg.text) ?? \"\";\n const ts = getString(msg.ts) ?? input.ref.message_ts;\n const blocks = Array.isArray(msg.blocks) ? (msg.blocks as unknown[]) : undefined;\n const attachments = Array.isArray(msg.attachments) ? (msg.attachments as unknown[]) : undefined;\n const reactions = Array.isArray(msg.reactions) ? (msg.reactions as unknown[]) : undefined;\n return {\n channel_id: input.ref.channel_id,\n ts,\n thread_ts: getString(msg.thread_ts),\n reply_count: getNumber(msg.reply_count),\n user: getString(msg.user),\n bot_id: getString(msg.bot_id),\n text,\n markdown: slackMrkdwnToMarkdown(text),\n blocks,\n attachments,\n files: enrichedFiles,\n reactions,\n };\n}\n\nasync function findMessageInThread(\n client: SlackApiClient,\n input: {\n channelId: string;\n threadTs: string;\n targetTs: string;\n includeReactions?: boolean;\n },\n): Promise<Record<string, unknown> | undefined> {\n let cursor: string | undefined;\n for (;;) {\n const resp = await client.api(\"conversations.replies\", {\n channel: input.channelId,\n ts: input.threadTs,\n limit: 200,\n cursor,\n include_all_metadata: input.includeReactions ? true : undefined,\n });\n const messages = asArray(resp.messages);\n const found = messages.find(\n (m): m is Record<string, unknown> => isRecord(m) && getString(m.ts) === input.targetTs,\n );\n if (found) {\n return found;\n }\n const meta = isRecord(resp.response_metadata) ? resp.response_metadata : null;\n const next = meta ? getString(meta.next_cursor) : undefined;\n if (!next) {\n break;\n }\n cursor = next;\n }\n return undefined;\n}\n\nexport async function fetchThread(\n client: SlackApiClient,\n input: { channelId: string; threadTs: string; includeReactions?: boolean },\n): Promise<SlackMessageSummary[]> {\n const out: SlackMessageSummary[] = [];\n let cursor: string | undefined;\n\n for (;;) {\n const resp = await client.api(\"conversations.replies\", {\n channel: input.channelId,\n ts: input.threadTs,\n limit: 200,\n cursor,\n include_all_metadata: input.includeReactions ? true : undefined,\n });\n const messages = asArray(resp.messages);\n for (const m of messages) {\n if (!isRecord(m)) {\n continue;\n }\n const files = asArray(m.files)\n .map((f) => toSlackFileSummary(f))\n .filter((f): f is SlackFileSummary => f !== null);\n const enrichedFiles = files.length > 0 ? await enrichFiles(client, files) : undefined;\n\n const text = getString(m.text) ?? \"\";\n out.push({\n channel_id: input.channelId,\n ts: getString(m.ts) ?? \"\",\n thread_ts: getString(m.thread_ts),\n reply_count: getNumber(m.reply_count),\n user: getString(m.user),\n bot_id: getString(m.bot_id),\n text,\n markdown: slackMrkdwnToMarkdown(text),\n blocks: Array.isArray(m.blocks) ? (m.blocks as unknown[]) : undefined,\n attachments: Array.isArray(m.attachments) ? (m.attachments as unknown[]) : undefined,\n files: enrichedFiles,\n reactions: Array.isArray(m.reactions) ? (m.reactions as unknown[]) : undefined,\n });\n }\n const meta = isRecord(resp.response_metadata) ? resp.response_metadata : null;\n const next = meta ? getString(meta.next_cursor) : undefined;\n if (!next) {\n break;\n }\n cursor = next;\n }\n\n // Slack returns newest-first for some methods; normalize to chronological.\n out.sort((a, b) => Number.parseFloat(a.ts) - Number.parseFloat(b.ts));\n return out;\n}\n\nasync function enrichFiles(\n client: SlackApiClient,\n files: SlackFileSummary[],\n): Promise<SlackFileSummary[]> {\n const out: SlackFileSummary[] = [];\n for (const f of files) {\n if (f.mode === \"snippet\" || !f.url_private_download) {\n try {\n const info = await client.api(\"files.info\", { file: f.id });\n const file = isRecord(info.file) ? info.file : null;\n out.push({\n ...f,\n name: f.name ?? getString(file?.name),\n title: f.title ?? getString(file?.title),\n mimetype: f.mimetype ?? getString(file?.mimetype),\n filetype: f.filetype ?? getString(file?.filetype),\n mode: f.mode ?? getString(file?.mode),\n permalink: f.permalink ?? getString(file?.permalink),\n url_private: f.url_private ?? getString(file?.url_private),\n url_private_download: f.url_private_download ?? getString(file?.url_private_download),\n snippet: {\n content: getString(file?.content),\n language: getString(file?.filetype),\n },\n });\n continue;\n } catch {\n // ignore and fall back to summary\n }\n }\n out.push(f);\n }\n return out;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nfunction getNumber(value: unknown): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction toSlackFileSummary(value: unknown): SlackFileSummary | null {\n if (!isRecord(value)) {\n return null;\n }\n const id = getString(value.id);\n if (!id) {\n return null;\n }\n return {\n id,\n name: getString(value.name),\n title: getString(value.title),\n mimetype: getString(value.mimetype),\n filetype: getString(value.filetype),\n mode: getString(value.mode),\n permalink: getString(value.permalink),\n url_private: getString(value.url_private),\n url_private_download: getString(value.url_private_download),\n size: getNumber(value.size),\n };\n}\n",
32
+ "export type SlackMessageRef = {\n workspace_url: string;\n channel_id: string;\n message_ts: string; // \"1234567890.123456\"\n thread_ts_hint?: string; // from URL query (?thread_ts=...)\n raw: string;\n /** True if the URL looks like it may have been truncated by shell & interpretation */\n possiblyTruncated?: boolean;\n};\n\nexport function parseSlackMessageUrl(input: string): SlackMessageRef {\n let url: URL;\n try {\n url = new URL(input);\n } catch {\n throw new Error(`Invalid URL: ${input}`);\n }\n\n if (!/\\.slack\\.com$/i.test(url.hostname)) {\n throw new Error(`Not a Slack workspace URL: ${url.hostname}`);\n }\n\n const parts = url.pathname.split(\"/\").filter(Boolean);\n // /archives/<channel>/p<digits>\n if (parts.length < 3 || parts[0] !== \"archives\") {\n throw new Error(`Unsupported Slack URL path: ${url.pathname}`);\n }\n\n const channel_id = parts[1]!;\n const messagePart = parts[2]!;\n const match = messagePart.match(/^p(\\d{7,})$/);\n if (!match) {\n throw new Error(`Unsupported Slack message id: ${messagePart}`);\n }\n\n const digits = match[1]!;\n if (digits.length <= 6) {\n throw new Error(`Invalid Slack message id: ${messagePart}`);\n }\n const seconds = digits.slice(0, -6);\n const micros = digits.slice(-6);\n const message_ts = `${seconds}.${micros}`;\n\n const threadTsParam = url.searchParams.get(\"thread_ts\");\n const thread_ts_hint =\n threadTsParam && /^\\d{6,}\\.\\d{6}$/.test(threadTsParam) ? threadTsParam : undefined;\n\n // Slack URLs with thread_ts typically also have cid param. If thread_ts exists but\n // cid doesn't, the URL was likely truncated by shell interpreting & as background.\n const hasCid = url.searchParams.has(\"cid\");\n const possiblyTruncated = Boolean(threadTsParam && !hasCid);\n\n const workspace_url = `${url.protocol}//${url.host}`;\n return { workspace_url, channel_id, message_ts, thread_ts_hint, raw: input, possiblyTruncated };\n}\n",
33
+ "import { parseSlackMessageUrl, type SlackMessageRef } from \"../slack/url.ts\";\nimport { isChannelId } from \"../slack/channels.ts\";\n\nexport type MsgTarget =\n | { kind: \"url\"; ref: SlackMessageRef }\n | { kind: \"channel\"; channel: string };\n\nexport function parseMsgTarget(input: string): MsgTarget {\n const trimmed = input.trim();\n if (!trimmed) {\n throw new Error(\"Missing target\");\n }\n\n try {\n const ref = parseSlackMessageUrl(trimmed);\n return { kind: \"url\", ref };\n } catch {\n // not a slack message URL\n }\n\n if (trimmed.startsWith(\"#\")) {\n return { kind: \"channel\", channel: trimmed };\n }\n if (isChannelId(trimmed)) {\n return { kind: \"channel\", channel: trimmed };\n }\n\n // Allow bare channel names (\"general\") for convenience.\n return { kind: \"channel\", channel: `#${trimmed}` };\n}\n",
34
+ "import type { CliContext } from \"./context.ts\";\nimport type { SlackAuth } from \"../slack/client.ts\";\nimport type { SlackMessageSummary, CompactSlackMessage } from \"../slack/messages.ts\";\nimport { fetchMessage, fetchThread, toCompactMessage } from \"../slack/messages.ts\";\nimport { pruneEmpty } from \"../lib/compact-json.ts\";\nimport { ensureDownloadsDir } from \"../lib/tmp-paths.ts\";\nimport { parseMsgTarget } from \"./targets.ts\";\nimport { resolveChannelId } from \"../slack/channels.ts\";\nimport { downloadSlackFile } from \"../slack/files.ts\";\nimport { normalizeSlackReactionName } from \"../slack/emoji.ts\";\n\nexport type MessageCommandOptions = {\n maxBodyChars: string;\n workspace?: string;\n ts?: string;\n threadTs?: string;\n includeReactions?: boolean;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction getNumber(value: unknown): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\n\nasync function getThreadSummary(\n client: { api: (method: string, params?: Record<string, unknown>) => Promise<unknown> },\n input: {\n channelId: string;\n msg: { ts: string; thread_ts?: string; reply_count?: number };\n },\n): Promise<{ ts: string; length: number } | null> {\n const replyCount = input.msg.reply_count ?? 0;\n const rootTs = input.msg.thread_ts ?? (replyCount > 0 ? input.msg.ts : null);\n if (!rootTs) {\n return null;\n }\n\n if (!input.msg.thread_ts && replyCount > 0) {\n return { ts: rootTs, length: 1 + replyCount };\n }\n\n const resp = await client.api(\"conversations.replies\", {\n channel: input.channelId,\n ts: rootTs,\n limit: 1,\n });\n const [root] = asArray(isRecord(resp) ? resp.messages : undefined);\n const rootReplyCount = isRecord(root) ? getNumber(root.reply_count) : undefined;\n if (rootReplyCount === undefined) {\n return { ts: rootTs, length: 1 };\n }\n return { ts: rootTs, length: 1 + rootReplyCount };\n}\n\nfunction inferExt(file: {\n mimetype?: string;\n filetype?: string;\n name?: string;\n title?: string;\n}): string | null {\n const mt = (file.mimetype || \"\").toLowerCase();\n const ft = (file.filetype || \"\").toLowerCase();\n\n if (mt === \"image/png\" || ft === \"png\") {\n return \"png\";\n }\n if (mt === \"image/jpeg\" || mt === \"image/jpg\" || ft === \"jpg\" || ft === \"jpeg\") {\n return \"jpg\";\n }\n if (mt === \"image/webp\" || ft === \"webp\") {\n return \"webp\";\n }\n if (mt === \"image/gif\" || ft === \"gif\") {\n return \"gif\";\n }\n\n if (mt === \"text/plain\" || ft === \"text\") {\n return \"txt\";\n }\n if (mt === \"text/markdown\" || ft === \"markdown\" || ft === \"md\") {\n return \"md\";\n }\n if (mt === \"application/json\" || ft === \"json\") {\n return \"json\";\n }\n\n const name = file.name || file.title || \"\";\n const m = name.match(/\\.([A-Za-z0-9]{1,10})$/);\n return m ? m[1]!.toLowerCase() : null;\n}\n\nasync function downloadFilesForMessages(input: {\n auth: SlackAuth;\n messages: SlackMessageSummary[];\n}): Promise<Record<string, string>> {\n const downloadedPaths: Record<string, string> = {};\n const downloadsDir = await ensureDownloadsDir();\n\n for (const m of input.messages) {\n for (const f of m.files ?? []) {\n if (downloadedPaths[f.id]) {\n continue;\n }\n const url = f.url_private_download || f.url_private;\n if (!url) {\n continue;\n }\n const ext = inferExt(f);\n const path = await downloadSlackFile({\n auth: input.auth,\n url,\n destDir: downloadsDir,\n preferredName: `${f.id}${ext ? `.${ext}` : \"\"}`,\n });\n downloadedPaths[f.id] = path;\n }\n }\n return downloadedPaths;\n}\n\nfunction toThreadListMessage(\n m: CompactSlackMessage,\n): Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\"> {\n const { channel_id: _channelId, thread_ts: _threadTs, ...rest } = m;\n return rest;\n}\n\nfunction warnIfTruncated(ref: { possiblyTruncated?: boolean }): void {\n if (ref.possiblyTruncated) {\n console.error(\n 'Hint: URL may have been truncated by shell. Quote URLs containing \"&\":\\n' +\n ' agent-slack message get \"https://...?thread_ts=...&cid=...\"',\n );\n }\n}\n\nexport async function handleMessageGet(input: {\n ctx: CliContext;\n targetInput: string;\n options: MessageCommandOptions;\n}): Promise<Record<string, unknown>> {\n const target = parseMsgTarget(input.targetInput);\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(input.options.workspace);\n\n return input.ctx.withAutoRefresh({\n workspaceUrl: target.kind === \"url\" ? target.ref.workspace_url : workspaceUrl,\n work: async () => {\n if (target.kind === \"url\") {\n const { ref } = target;\n warnIfTruncated(ref);\n const { client, auth } = await input.ctx.getClientForWorkspace(ref.workspace_url);\n const includeReactions = Boolean(input.options.includeReactions);\n const msg = await fetchMessage(client, { ref, includeReactions });\n const thread = await getThreadSummary(client, { channelId: ref.channel_id, msg });\n const downloadedPaths = await downloadFilesForMessages({ auth, messages: [msg] });\n const maxBodyChars = Number.parseInt(input.options.maxBodyChars, 10);\n const message = toCompactMessage(msg, { maxBodyChars, includeReactions, downloadedPaths });\n return pruneEmpty({ message, thread }) as Record<string, unknown>;\n }\n\n const ts = input.options.ts?.trim();\n if (!ts) {\n throw new Error('When targeting a channel, you must pass --ts \"<seconds>.<micros>\"');\n }\n\n await input.ctx.assertWorkspaceSpecifiedForChannelNames({\n workspaceUrl,\n channels: [target.channel],\n });\n\n const includeReactions = Boolean(input.options.includeReactions);\n const { client, auth, workspace_url } = await input.ctx.getClientForWorkspace(workspaceUrl);\n const channelId = await resolveChannelId(client, target.channel);\n const ref = {\n workspace_url: workspace_url ?? workspaceUrl ?? \"\",\n channel_id: channelId,\n message_ts: ts,\n thread_ts_hint: input.options.threadTs?.trim() || undefined,\n raw: input.targetInput,\n };\n\n const msg = await fetchMessage(client, { ref, includeReactions });\n const thread = await getThreadSummary(client, { channelId, msg });\n const downloadedPaths = await downloadFilesForMessages({ auth, messages: [msg] });\n const maxBodyChars = Number.parseInt(input.options.maxBodyChars, 10);\n const message = toCompactMessage(msg, { maxBodyChars, includeReactions, downloadedPaths });\n return pruneEmpty({ message, thread }) as Record<string, unknown>;\n },\n });\n}\n\nexport async function handleMessageList(input: {\n ctx: CliContext;\n targetInput: string;\n options: MessageCommandOptions;\n}): Promise<Record<string, unknown>> {\n const target = parseMsgTarget(input.targetInput);\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(input.options.workspace);\n\n return input.ctx.withAutoRefresh({\n workspaceUrl: target.kind === \"url\" ? target.ref.workspace_url : workspaceUrl,\n work: async () => {\n if (target.kind === \"url\") {\n const { ref } = target;\n warnIfTruncated(ref);\n const { client, auth } = await input.ctx.getClientForWorkspace(ref.workspace_url);\n const includeReactions = Boolean(input.options.includeReactions);\n const msg = await fetchMessage(client, { ref, includeReactions });\n const rootTs = msg.thread_ts ?? msg.ts;\n const threadMessages = await fetchThread(client, {\n channelId: ref.channel_id,\n threadTs: rootTs,\n includeReactions,\n });\n const downloadedPaths = await downloadFilesForMessages({ auth, messages: threadMessages });\n const maxBodyChars = Number.parseInt(input.options.maxBodyChars, 10);\n return pruneEmpty({\n messages: threadMessages\n .map((m) => toCompactMessage(m, { maxBodyChars, includeReactions, downloadedPaths }))\n .map(toThreadListMessage),\n }) as Record<string, unknown>;\n }\n\n const { client, auth, workspace_url } = await input.ctx.getClientForWorkspace(workspaceUrl);\n\n await input.ctx.assertWorkspaceSpecifiedForChannelNames({\n workspaceUrl,\n channels: [target.channel],\n });\n\n const channelId = await resolveChannelId(client, target.channel);\n\n const threadTs = input.options.threadTs?.trim();\n const ts = input.options.ts?.trim();\n if (!threadTs && !ts) {\n throw new Error(\n 'When targeting a channel, you must pass --thread-ts \"<seconds>.<micros>\" (or --ts to resolve a message to its thread)',\n );\n }\n\n const rootTs =\n threadTs ??\n (await (async () => {\n const ref = {\n workspace_url: workspace_url ?? workspaceUrl ?? \"\",\n channel_id: channelId,\n message_ts: ts!,\n raw: input.targetInput,\n };\n const includeReactions = Boolean(input.options.includeReactions);\n const msg = await fetchMessage(client, { ref, includeReactions });\n return msg.thread_ts ?? msg.ts;\n })());\n\n const includeReactions = Boolean(input.options.includeReactions);\n const threadMessages = await fetchThread(client, {\n channelId,\n threadTs: rootTs,\n includeReactions,\n });\n const downloadedPaths = await downloadFilesForMessages({ auth, messages: threadMessages });\n const maxBodyChars = Number.parseInt(input.options.maxBodyChars, 10);\n return pruneEmpty({\n messages: threadMessages\n .map((m) => toCompactMessage(m, { maxBodyChars, includeReactions, downloadedPaths }))\n .map(toThreadListMessage),\n }) as Record<string, unknown>;\n },\n });\n}\n\nexport async function sendMessage(input: {\n ctx: CliContext;\n targetInput: string;\n text: string;\n options: { workspace?: string; threadTs?: string };\n}): Promise<Record<string, unknown>> {\n const target = parseMsgTarget(String(input.targetInput));\n if (target.kind === \"url\") {\n const { ref } = target;\n warnIfTruncated(ref);\n await input.ctx.withAutoRefresh({\n workspaceUrl: ref.workspace_url,\n work: async () => {\n const { client } = await input.ctx.getClientForWorkspace(ref.workspace_url);\n const msg = await fetchMessage(client, { ref });\n const threadTs = msg.thread_ts ?? msg.ts;\n await client.api(\"chat.postMessage\", {\n channel: ref.channel_id,\n text: input.text,\n thread_ts: threadTs,\n });\n },\n });\n return { ok: true };\n }\n\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(input.options.workspace);\n await input.ctx.assertWorkspaceSpecifiedForChannelNames({\n workspaceUrl,\n channels: [String(target.channel)],\n });\n await input.ctx.withAutoRefresh({\n workspaceUrl,\n work: async () => {\n const { client } = await input.ctx.getClientForWorkspace(workspaceUrl);\n const channelId = await resolveChannelId(client, String(target.channel));\n await client.api(\"chat.postMessage\", {\n channel: channelId,\n text: input.text,\n thread_ts: input.options.threadTs ? String(input.options.threadTs) : undefined,\n });\n },\n });\n return { ok: true };\n}\n\nexport async function reactOnTarget(input: {\n ctx: CliContext;\n action: \"add\" | \"remove\";\n targetInput: string;\n emoji: string;\n options?: { workspace?: string; ts?: string };\n}): Promise<Record<string, unknown>> {\n const target = parseMsgTarget(input.targetInput);\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(input.options?.workspace);\n\n await input.ctx.withAutoRefresh({\n workspaceUrl: target.kind === \"url\" ? target.ref.workspace_url : workspaceUrl,\n work: async () => {\n if (target.kind === \"url\") {\n const { ref } = target;\n warnIfTruncated(ref);\n const { client } = await input.ctx.getClientForWorkspace(ref.workspace_url);\n const name = normalizeSlackReactionName(input.emoji);\n await client.api(`reactions.${input.action}`, {\n channel: ref.channel_id,\n timestamp: ref.message_ts,\n name,\n });\n return;\n }\n\n const ts = input.options?.ts?.trim();\n if (!ts) {\n throw new Error('When targeting a channel, you must pass --ts \"<seconds>.<micros>\"');\n }\n\n await input.ctx.assertWorkspaceSpecifiedForChannelNames({\n workspaceUrl,\n channels: [target.channel],\n });\n\n const { client } = await input.ctx.getClientForWorkspace(workspaceUrl);\n const channelId = await resolveChannelId(client, target.channel);\n const name = normalizeSlackReactionName(input.emoji);\n await client.api(`reactions.${input.action}`, {\n channel: channelId,\n timestamp: ts,\n name,\n });\n },\n });\n\n return { ok: true };\n}\n",
35
+ "import type { Command } from \"commander\";\nimport type { CliContext } from \"./context.ts\";\nimport {\n handleMessageGet,\n handleMessageList,\n reactOnTarget,\n sendMessage,\n type MessageCommandOptions,\n} from \"./message-actions.ts\";\n\nexport function registerMessageCommand(input: { program: Command; ctx: CliContext }): void {\n const messageCmd = input.program\n .command(\"message\")\n .description(\"Read/write Slack messages (token-efficient JSON)\");\n\n messageCmd\n .command(\"get\", { isDefault: true })\n .description(\"Fetch a single Slack message (with thread summary if any)\")\n .argument(\"<target>\", \"Slack message URL, #channel, or channel ID\")\n .option(\n \"--workspace <url>\",\n \"Workspace URL (needed when using #channel/channel id and you have multiple workspaces)\",\n )\n .option(\"--ts <ts>\", \"Message ts (required when using #channel/channel id)\")\n .option(\"--thread-ts <ts>\", \"Thread root ts hint (useful for thread permalinks)\")\n .option(\n \"--max-body-chars <n>\",\n \"Max content characters to include (default 8000, -1 for unlimited)\",\n \"8000\",\n )\n .option(\"--include-reactions\", \"Include reactions + reacting users\")\n .action(async (...args) => {\n const [targetInput, options] = args as [string, MessageCommandOptions];\n try {\n const payload = await handleMessageGet({ ctx: input.ctx, targetInput, options });\n console.log(JSON.stringify(payload, null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n messageCmd\n .command(\"list\")\n .description(\"Fetch the full thread for a Slack message URL\")\n .argument(\"<target>\", \"Slack message URL, #channel, or channel ID\")\n .option(\n \"--workspace <url>\",\n \"Workspace URL (needed when using #channel/channel id and you have multiple workspaces)\",\n )\n .option(\n \"--thread-ts <ts>\",\n \"Thread root ts (required when using #channel/channel id unless you pass --ts)\",\n )\n .option(\"--ts <ts>\", \"Message ts (optional: resolve message to its thread)\")\n .option(\n \"--max-body-chars <n>\",\n \"Max content characters to include (default 8000, -1 for unlimited)\",\n \"8000\",\n )\n .option(\"--include-reactions\", \"Include reactions + reacting users\")\n .action(async (...args) => {\n const [targetInput, options] = args as [string, MessageCommandOptions];\n try {\n const payload = await handleMessageList({ ctx: input.ctx, targetInput, options });\n console.log(JSON.stringify(payload, null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n messageCmd\n .command(\"send\")\n .description(\"Send a message (optionally into a thread)\")\n .argument(\"<target>\", \"Slack message URL, #name/name, or channel id\")\n .argument(\"<text>\", \"Message text to post\")\n .option(\n \"--workspace <url>\",\n \"Workspace URL (needed when using #channel/channel id and you have multiple workspaces)\",\n )\n .option(\"--thread-ts <ts>\", \"Thread root ts to post into (optional)\")\n .action(async (...args) => {\n const [targetInput, text, options] = args as [\n string,\n string,\n { workspace?: string; threadTs?: string },\n ];\n try {\n const payload = await sendMessage({\n ctx: input.ctx,\n targetInput,\n text,\n options,\n });\n console.log(JSON.stringify(payload, null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n const reactCmd = messageCmd.command(\"react\").description(\"Add or remove reactions\");\n\n reactCmd\n .command(\"add\")\n .description(\"Add a reaction to a message\")\n .argument(\"<target>\", \"Slack message URL, #channel, or channel ID\")\n .argument(\"<emoji>\", \"Emoji to react with (:rocket:, rocket, or 🚀)\")\n .option(\n \"--workspace <url>\",\n \"Workspace URL (needed when using #channel/channel id and you have multiple workspaces)\",\n )\n .option(\"--ts <ts>\", \"Message ts (required when using #channel/channel id)\")\n .action(async (...args) => {\n const [targetInput, emoji, options] = args as [\n string,\n string,\n { workspace?: string; ts?: string },\n ];\n try {\n const payload = await reactOnTarget({\n ctx: input.ctx,\n action: \"add\",\n targetInput,\n emoji,\n options,\n });\n console.log(JSON.stringify(payload, null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n reactCmd\n .command(\"remove\")\n .description(\"Remove a reaction from a message\")\n .argument(\"<target>\", \"Slack message URL, #channel, or channel ID\")\n .argument(\"<emoji>\", \"Emoji to remove (:rocket:, rocket, or 🚀)\")\n .option(\n \"--workspace <url>\",\n \"Workspace URL (needed when using #channel/channel id and you have multiple workspaces)\",\n )\n .option(\"--ts <ts>\", \"Message ts (required when using #channel/channel id)\")\n .action(async (...args) => {\n const [targetInput, emoji, options] = args as [\n string,\n string,\n { workspace?: string; ts?: string },\n ];\n try {\n const payload = await reactOnTarget({\n ctx: input.ctx,\n action: \"remove\",\n targetInput,\n emoji,\n options,\n });\n console.log(JSON.stringify(payload, null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n}\n",
36
+ "export function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nexport function asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nexport function getString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n\nexport function getNumber(value: unknown): number | undefined {\n return typeof value === \"number\" ? value : undefined;\n}\n",
37
+ "import type { SlackApiClient } from \"./client.ts\";\nimport { normalizeChannelInput } from \"./channels.ts\";\nimport { asArray, getString, isRecord } from \"./search-guards.ts\";\n\nexport async function buildSlackSearchQuery(\n client: SlackApiClient,\n input: {\n query: string;\n channels?: string[];\n user?: string;\n after?: string;\n before?: string;\n },\n): Promise<string> {\n const parts: string[] = [];\n const base = input.query.trim();\n if (base) {\n parts.push(base);\n }\n\n if (input.after) {\n parts.push(`after:${validateDate(input.after)}`);\n }\n if (input.before) {\n parts.push(`before:${validateDate(input.before)}`);\n }\n\n if (input.user) {\n const token = await userTokenForSearch(client, input.user);\n if (token) {\n parts.push(token);\n }\n }\n\n if (input.channels && input.channels.length > 0) {\n for (const ch of input.channels) {\n const inToken = await channelTokenForSearch(client, ch);\n if (inToken) {\n parts.push(inToken);\n }\n }\n }\n\n return parts.join(\" \");\n}\n\nexport function validateDate(s: string): string {\n const v = s.trim();\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(v)) {\n throw new Error(`Invalid date: ${s} (expected YYYY-MM-DD)`);\n }\n return v;\n}\n\nexport function dateToUnixSeconds(date: string, edge: \"start\" | \"end\"): number {\n const d = validateDate(date);\n const iso = edge === \"start\" ? `${d}T00:00:00.000Z` : `${d}T23:59:59.999Z`;\n return Math.floor(Date.parse(iso) / 1000);\n}\n\nasync function userTokenForSearch(client: SlackApiClient, user: string): Promise<string | null> {\n const trimmed = user.trim();\n if (!trimmed) {\n return null;\n }\n\n // Accept @name or name\n if (trimmed.startsWith(\"@\")) {\n return `from:@${trimmed.slice(1)}`;\n }\n if (/^U[A-Z0-9]{8,}$/.test(trimmed)) {\n try {\n const info = await client.api(\"users.info\", { user: trimmed });\n const infoUser = isRecord(info) ? info.user : null;\n const name = isRecord(infoUser) ? (getString(infoUser.name) ?? \"\").trim() : \"\";\n return name ? `from:@${name}` : null;\n } catch {\n return null;\n }\n }\n return `from:@${trimmed}`;\n}\n\nasync function channelTokenForSearch(\n client: SlackApiClient,\n channel: string,\n): Promise<string | null> {\n const normalized = normalizeChannelInput(channel);\n if (normalized.kind === \"name\") {\n const name = normalized.value.trim();\n if (!name) {\n return null;\n }\n return `in:#${name}`;\n }\n\n // Channel id -> name for use in search query.\n try {\n const info = await client.api(\"conversations.info\", {\n channel: normalized.value,\n });\n const channelInfo = isRecord(info) ? info.channel : null;\n const name = isRecord(channelInfo) ? (getString(channelInfo.name) ?? \"\").trim() : \"\";\n if (name) {\n return `in:#${name}`;\n }\n } catch {\n // ignore\n }\n return null;\n}\n\nexport async function resolveUserId(\n client: SlackApiClient,\n input: string,\n): Promise<string | undefined> {\n const trimmed = input.trim();\n if (!trimmed) {\n return undefined;\n }\n if (/^U[A-Z0-9]{8,}$/.test(trimmed)) {\n return trimmed;\n }\n const name = trimmed.startsWith(\"@\") ? trimmed.slice(1) : trimmed;\n\n let cursor: string | undefined;\n for (;;) {\n const resp = await client.api(\"users.list\", { limit: 200, cursor });\n const members = isRecord(resp) ? asArray(resp.members).filter(isRecord) : [];\n const found = members.find((m) => {\n const mName = getString(m.name);\n const profile = isRecord(m.profile) ? m.profile : null;\n const display = profile ? getString(profile.display_name) : undefined;\n return mName === name || display === name;\n });\n const foundId = found ? getString(found.id) : undefined;\n if (foundId) {\n return foundId;\n }\n const meta = isRecord(resp) ? resp.response_metadata : null;\n const next = isRecord(meta) ? getString(meta.next_cursor) : undefined;\n if (!next) {\n break;\n }\n cursor = next;\n }\n return undefined;\n}\n",
38
+ "import type { SlackApiClient } from \"./client.ts\";\nimport { asArray, isRecord } from \"./search-guards.ts\";\n\nexport async function searchMessagesRaw(\n client: SlackApiClient,\n input: { query: string; limit: number },\n): Promise<Record<string, unknown>[]> {\n const pageSize = Math.min(Math.max(input.limit, 1), 100);\n const out: Record<string, unknown>[] = [];\n let page = 1;\n let pages = 1;\n\n for (;;) {\n const resp = await client.api(\"search.messages\", {\n query: input.query,\n count: pageSize,\n page,\n highlight: false,\n sort: \"timestamp\",\n sort_dir: \"desc\",\n });\n const messages = isRecord(resp) ? resp.messages : null;\n const matches = isRecord(messages) ? asArray(messages.matches).filter(isRecord) : [];\n out.push(...matches);\n\n const paging = isRecord(messages) ? (messages.paging ?? messages.pagination) : null;\n const totalPages = Number(isRecord(paging) ? (paging.pages ?? 1) : 1);\n if (Number.isFinite(totalPages) && totalPages > 0) {\n pages = totalPages;\n }\n\n if (out.length >= input.limit) {\n break;\n }\n if (matches.length === 0) {\n break;\n }\n if (page >= pages) {\n break;\n }\n page++;\n }\n\n return out.slice(0, input.limit);\n}\n\nexport async function searchFilesRaw(\n client: SlackApiClient,\n input: { query: string; limit: number },\n): Promise<Record<string, unknown>[]> {\n const pageSize = Math.min(Math.max(input.limit, 1), 100);\n const out: Record<string, unknown>[] = [];\n let page = 1;\n let pages = 1;\n\n for (;;) {\n const resp = await client.api(\"search.files\", {\n query: input.query,\n count: pageSize,\n page,\n highlight: false,\n sort: \"timestamp\",\n sort_dir: \"desc\",\n });\n const files = isRecord(resp) ? resp.files : null;\n const matches = isRecord(files) ? asArray(files.matches).filter(isRecord) : [];\n out.push(...matches);\n\n const paging = isRecord(files) ? (files.paging ?? files.pagination) : null;\n const totalPages = Number(isRecord(paging) ? (paging.pages ?? 1) : 1);\n if (Number.isFinite(totalPages) && totalPages > 0) {\n pages = totalPages;\n }\n\n if (out.length >= input.limit) {\n break;\n }\n if (matches.length === 0) {\n break;\n }\n if (page >= pages) {\n break;\n }\n page++;\n }\n\n return out.slice(0, input.limit);\n}\n",
39
+ "export function inferExt(file: {\n mimetype?: string;\n filetype?: string;\n name?: string;\n title?: string;\n}): string | null {\n const mt = (file.mimetype || \"\").toLowerCase();\n const ft = (file.filetype || \"\").toLowerCase();\n\n if (mt === \"image/png\" || ft === \"png\") {\n return \"png\";\n }\n if (mt === \"image/jpeg\" || mt === \"image/jpg\" || ft === \"jpg\" || ft === \"jpeg\") {\n return \"jpg\";\n }\n if (mt === \"image/webp\" || ft === \"webp\") {\n return \"webp\";\n }\n if (mt === \"image/gif\" || ft === \"gif\") {\n return \"gif\";\n }\n\n if (mt === \"text/plain\" || ft === \"text\") {\n return \"txt\";\n }\n if (mt === \"text/markdown\" || ft === \"markdown\" || ft === \"md\") {\n return \"md\";\n }\n if (mt === \"application/json\" || ft === \"json\") {\n return \"json\";\n }\n\n const name = file.name || file.title || \"\";\n const m = name.match(/\\.([A-Za-z0-9]{1,10})$/);\n return m ? m[1]!.toLowerCase() : null;\n}\n",
40
+ "import type { SlackApiClient, SlackAuth } from \"./client.ts\";\nimport { ensureDownloadsDir } from \"../lib/tmp-paths.ts\";\nimport { resolveChannelId } from \"./channels.ts\";\nimport { downloadSlackFile } from \"./files.ts\";\nimport { inferExt } from \"./search-file-ext.ts\";\nimport { dateToUnixSeconds, resolveUserId } from \"./search-query.ts\";\nimport { asArray, getString, isRecord } from \"./search-guards.ts\";\n\nexport type ContentType = \"any\" | \"text\" | \"image\" | \"snippet\" | \"file\";\n\nexport async function searchFilesViaSearchApi(\n client: SlackApiClient,\n input: {\n auth: SlackAuth;\n slack_query: string;\n limit: number;\n contentType: ContentType;\n rawMatches: Record<string, unknown>[];\n },\n): Promise<{ title?: string; mimetype?: string; mode?: string; path: string }[]> {\n const matches = input.rawMatches;\n if (matches.length === 0) {\n return [];\n }\n\n const downloadsDir = await ensureDownloadsDir();\n const out: { title?: string; mimetype?: string; mode?: string; path: string }[] = [];\n\n for (const f of matches) {\n const mode = getString(f.mode);\n const mimetype = getString(f.mimetype);\n if (!passesFileContentTypeFilter({ mode, mimetype }, input.contentType)) {\n continue;\n }\n const url = getString(f.url_private_download) ?? getString(f.url_private);\n if (!url) {\n continue;\n }\n const ext = inferExt({\n mimetype,\n filetype: getString(f.filetype),\n name: getString(f.name),\n title: getString(f.title),\n });\n const id = getString(f.id);\n if (!id) {\n continue;\n }\n const path = await downloadSlackFile({\n auth: input.auth,\n url,\n destDir: downloadsDir,\n preferredName: `${id}${ext ? `.${ext}` : \"\"}`,\n });\n const title = (getString(f.title) || getString(f.name) || \"\").trim();\n out.push({\n title: title || undefined,\n mimetype,\n mode,\n path,\n });\n if (out.length >= input.limit) {\n break;\n }\n }\n\n return out;\n}\n\nexport async function searchFilesInChannelsFallback(\n client: SlackApiClient,\n input: {\n auth: SlackAuth;\n query: string;\n channels: string[];\n user?: string;\n after?: string;\n before?: string;\n limit: number;\n contentType: ContentType;\n },\n): Promise<{ title?: string; mimetype?: string; mode?: string; path: string }[]> {\n const channelIds = await Promise.all(input.channels.map((c) => resolveChannelId(client, c)));\n const userId = input.user ? await resolveUserId(client, input.user) : undefined;\n const queryLower = input.query.trim().toLowerCase();\n\n const ts_from = input.after ? dateToUnixSeconds(input.after, \"start\") : undefined;\n const ts_to = input.before ? dateToUnixSeconds(input.before, \"end\") : undefined;\n\n const downloadsDir = await ensureDownloadsDir();\n const out: { title?: string; mimetype?: string; mode?: string; path: string }[] = [];\n\n for (const channelId of channelIds) {\n let page = 1;\n for (;;) {\n const resp = await client.api(\"files.list\", {\n channel: channelId,\n user: userId,\n ts_from,\n ts_to,\n count: 100,\n page,\n });\n const files = isRecord(resp) ? asArray(resp.files).filter(isRecord) : [];\n if (files.length === 0) {\n break;\n }\n\n for (const f of files) {\n const mode = getString(f.mode);\n const mimetype = getString(f.mimetype);\n if (!passesFileContentTypeFilter({ mode, mimetype }, input.contentType)) {\n continue;\n }\n\n const title = (getString(f.title) || getString(f.name) || \"\").trim();\n if (queryLower && !title.toLowerCase().includes(queryLower)) {\n continue;\n }\n\n const url = getString(f.url_private_download) ?? getString(f.url_private);\n if (!url) {\n continue;\n }\n\n const ext = inferExt({\n mimetype,\n filetype: getString(f.filetype),\n name: getString(f.name),\n title: getString(f.title),\n });\n const id = getString(f.id);\n if (!id) {\n continue;\n }\n const path = await downloadSlackFile({\n auth: input.auth,\n url,\n destDir: downloadsDir,\n preferredName: `${id}${ext ? `.${ext}` : \"\"}`,\n });\n out.push({\n title: title || undefined,\n mimetype,\n mode,\n path,\n });\n if (out.length >= input.limit) {\n return out;\n }\n }\n\n const paging = isRecord(resp)\n ? isRecord(resp.paging)\n ? resp.paging\n : resp.pagination\n : null;\n const pages = Number(isRecord(paging) ? (paging.pages ?? paging.page_count) : undefined);\n if (Number.isFinite(pages) && page >= pages) {\n break;\n }\n page++;\n }\n }\n\n return out;\n}\n\nfunction passesFileContentTypeFilter(\n f: { mode?: string; mimetype?: string },\n contentType: ContentType,\n): boolean {\n if (contentType === \"any\") {\n return true;\n }\n if (contentType === \"file\") {\n return true;\n }\n if (contentType === \"snippet\") {\n return f.mode === \"snippet\";\n }\n if (contentType === \"image\") {\n return String(f.mimetype ?? \"\")\n .toLowerCase()\n .startsWith(\"image/\");\n }\n if (contentType === \"text\") {\n return String(f.mimetype ?? \"\") === \"text/plain\";\n }\n return true;\n}\n",
41
+ "import type { SlackApiClient, SlackAuth } from \"./client.ts\";\nimport type { CompactSlackMessage, SlackFileSummary, SlackMessageSummary } from \"./messages.ts\";\nimport { fetchMessage, toCompactMessage } from \"./messages.ts\";\nimport { resolveChannelId } from \"./channels.ts\";\nimport { ensureDownloadsDir } from \"../lib/tmp-paths.ts\";\nimport { downloadSlackFile } from \"./files.ts\";\nimport { renderSlackMessageContent } from \"./render.ts\";\nimport { parseSlackMessageUrl } from \"./url.ts\";\nimport { inferExt } from \"./search-file-ext.ts\";\nimport { dateToUnixSeconds, resolveUserId } from \"./search-query.ts\";\nimport { asArray, getNumber, getString, isRecord } from \"./search-guards.ts\";\nimport { slackMrkdwnToMarkdown } from \"./mrkdwn.ts\";\n\nexport type ContentType = \"any\" | \"text\" | \"image\" | \"snippet\" | \"file\";\n\nexport async function searchMessagesViaSearchApi(\n client: SlackApiClient,\n input: {\n auth: SlackAuth;\n workspace_url?: string;\n slack_query: string;\n limit: number;\n maxContentChars: number;\n contentType: ContentType;\n download: boolean;\n rawMatches: Record<string, unknown>[];\n },\n): Promise<Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\">[]> {\n const matches = input.rawMatches;\n if (matches.length === 0) {\n return [];\n }\n\n const messageRefs: {\n channel_id: string;\n message_ts: string;\n permalink?: string;\n }[] = [];\n for (const m of matches) {\n const ts = getString(m.ts)?.trim() ?? \"\";\n if (!ts) {\n continue;\n }\n const channelValue = isRecord(m.channel) ? m.channel : null;\n const channelId =\n channelValue && getString(channelValue.id)\n ? getString(channelValue.id)!\n : channelValue && getString(channelValue.name)\n ? await resolveChannelId(client, `#${getString(channelValue.name)}`)\n : \"\";\n if (!channelId) {\n continue;\n }\n messageRefs.push({\n channel_id: channelId,\n message_ts: ts,\n permalink: getString(m.permalink),\n });\n if (messageRefs.length >= input.limit) {\n break;\n }\n }\n\n const downloadedPaths: Record<string, string> = {};\n const downloadsDir = input.download ? await ensureDownloadsDir() : null;\n const out: Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\">[] = [];\n\n for (const ref of messageRefs) {\n let full: SlackMessageSummary | null = null;\n try {\n const parsed =\n ref.permalink && typeof ref.permalink === \"string\"\n ? (() => {\n try {\n return parseSlackMessageUrl(ref.permalink);\n } catch {\n return null;\n }\n })()\n : null;\n\n full = await fetchMessage(client, {\n ref: {\n workspace_url: parsed?.workspace_url ?? input.workspace_url ?? \"\",\n channel_id: ref.channel_id,\n message_ts: ref.message_ts,\n thread_ts_hint: parsed?.thread_ts_hint,\n raw: parsed?.raw ?? ref.permalink ?? `${ref.channel_id}:${ref.message_ts}`,\n },\n });\n } catch {\n continue;\n }\n\n if (downloadsDir) {\n await downloadFilesForMessage({\n auth: input.auth,\n downloadsDir,\n message: full,\n downloadedPaths,\n });\n }\n\n const compact = toCompactMessage(full, {\n maxBodyChars: input.maxContentChars,\n downloadedPaths,\n });\n if (!passesContentTypeFilter(compact, input.contentType)) {\n continue;\n }\n out.push(stripThreadListFields(compact));\n if (out.length >= input.limit) {\n break;\n }\n }\n\n return out;\n}\n\nexport async function searchMessagesInChannelsFallback(\n client: SlackApiClient,\n input: {\n auth: SlackAuth;\n query: string;\n channels: string[];\n user?: string;\n after?: string;\n before?: string;\n limit: number;\n maxContentChars: number;\n contentType: ContentType;\n download: boolean;\n },\n): Promise<Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\">[]> {\n const channelIds = await Promise.all(input.channels.map((c) => resolveChannelId(client, c)));\n const queryLower = input.query.trim().toLowerCase();\n\n const userId = input.user ? await resolveUserId(client, input.user) : undefined;\n\n const afterSec = input.after ? dateToUnixSeconds(input.after, \"start\") : null;\n const beforeSec = input.before ? dateToUnixSeconds(input.before, \"end\") : null;\n\n const downloadsDir = input.download ? await ensureDownloadsDir() : null;\n const downloadedPaths: Record<string, string> = {};\n\n const results: Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\">[] = [];\n\n for (const channelId of channelIds) {\n let cursorLatest: string | undefined;\n for (;;) {\n const resp = await client.api(\"conversations.history\", {\n channel: channelId,\n limit: 200,\n latest: cursorLatest,\n });\n const messages = isRecord(resp) ? asArray(resp.messages).filter(isRecord) : [];\n if (messages.length === 0) {\n break;\n }\n\n for (const m of messages) {\n const summary = messageSummaryFromApiMessage(channelId, m);\n\n const tsNum = Number.parseFloat(summary.ts);\n if (Number.isFinite(tsNum)) {\n if (beforeSec !== null && tsNum > beforeSec) {\n continue;\n }\n if (afterSec !== null && tsNum < afterSec) {\n cursorLatest = undefined;\n break;\n }\n }\n\n if (userId && summary.user !== userId) {\n continue;\n }\n\n const content = renderSlackMessageContent(summary);\n if (queryLower && !content.toLowerCase().includes(queryLower)) {\n continue;\n }\n\n if (downloadsDir) {\n await downloadFilesForMessage({\n auth: input.auth,\n downloadsDir,\n message: summary,\n downloadedPaths,\n });\n }\n\n const compact = toCompactMessage(summary, {\n maxBodyChars: input.maxContentChars,\n downloadedPaths,\n });\n if (!passesContentTypeFilter(compact, input.contentType)) {\n continue;\n }\n\n results.push(stripThreadListFields(compact));\n if (results.length >= input.limit) {\n return results;\n }\n }\n\n if (!cursorLatest) {\n break;\n }\n\n const last = messages.at(-1);\n cursorLatest = last ? getString(last.ts) : undefined;\n if (!cursorLatest) {\n break;\n }\n }\n }\n\n return results;\n}\n\nfunction passesContentTypeFilter(m: CompactSlackMessage, contentType: ContentType): boolean {\n if (contentType === \"any\") {\n return true;\n }\n const hasFiles = Boolean(m.files && m.files.length > 0);\n if (contentType === \"text\") {\n return !hasFiles;\n }\n if (!hasFiles) {\n return false;\n }\n\n if (contentType === \"file\") {\n return true;\n }\n if (contentType === \"snippet\") {\n return (m.files ?? []).some((f) => f.mode === \"snippet\");\n }\n if (contentType === \"image\") {\n return (m.files ?? []).some((f) => String(f.mimetype ?? \"\").startsWith(\"image/\"));\n }\n return true;\n}\n\nfunction stripThreadListFields(\n m: CompactSlackMessage,\n): Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\"> {\n const { channel_id: _channelId, thread_ts: _threadTs, ...rest } = m;\n return rest;\n}\n\nasync function downloadFilesForMessage(input: {\n auth: SlackAuth;\n downloadsDir: string;\n message: SlackMessageSummary;\n downloadedPaths: Record<string, string>;\n}): Promise<void> {\n for (const f of input.message.files ?? []) {\n if (input.downloadedPaths[f.id]) {\n continue;\n }\n const url = f.url_private_download || f.url_private;\n if (!url) {\n continue;\n }\n const ext = inferExt(f);\n const path = await downloadSlackFile({\n auth: input.auth,\n url,\n destDir: input.downloadsDir,\n preferredName: `${f.id}${ext ? `.${ext}` : \"\"}`,\n });\n input.downloadedPaths[f.id] = path;\n }\n}\n\nfunction messageSummaryFromApiMessage(\n channelId: string,\n msg: Record<string, unknown>,\n): SlackMessageSummary {\n const text = getString(msg.text) ?? \"\";\n const files = asArray(msg.files)\n .map((f) => toSlackFileSummary(f))\n .filter((f): f is SlackFileSummary => f !== null);\n\n return {\n channel_id: channelId,\n ts: getString(msg.ts) ?? \"\",\n thread_ts: getString(msg.thread_ts),\n reply_count: getNumber(msg.reply_count),\n user: getString(msg.user),\n bot_id: getString(msg.bot_id),\n text,\n markdown: slackMrkdwnToMarkdown(text),\n blocks: Array.isArray(msg.blocks) ? (msg.blocks as unknown[]) : undefined,\n attachments: Array.isArray(msg.attachments) ? (msg.attachments as unknown[]) : undefined,\n files: files.length > 0 ? files : undefined,\n reactions: Array.isArray(msg.reactions) ? (msg.reactions as unknown[]) : undefined,\n };\n}\n\nfunction toSlackFileSummary(value: unknown): SlackFileSummary | null {\n if (!isRecord(value)) {\n return null;\n }\n const id = getString(value.id);\n if (!id) {\n return null;\n }\n return {\n id,\n name: getString(value.name),\n title: getString(value.title),\n mimetype: getString(value.mimetype),\n filetype: getString(value.filetype),\n mode: getString(value.mode),\n permalink: getString(value.permalink),\n url_private: getString(value.url_private),\n url_private_download: getString(value.url_private_download),\n size: getNumber(value.size),\n };\n}\n",
42
+ "import type { SlackApiClient, SlackAuth } from \"./client.ts\";\nimport type { CompactSlackMessage } from \"./messages.ts\";\nimport { buildSlackSearchQuery } from \"./search-query.ts\";\nimport { searchFilesRaw, searchMessagesRaw } from \"./search-raw.ts\";\nimport { searchFilesInChannelsFallback, searchFilesViaSearchApi } from \"./search-files.ts\";\nimport { searchMessagesInChannelsFallback, searchMessagesViaSearchApi } from \"./search-messages.ts\";\n\nexport type SearchKind = \"messages\" | \"files\" | \"all\";\nexport type ContentType = \"any\" | \"text\" | \"image\" | \"snippet\" | \"file\";\n\nexport type SearchOptions = {\n workspace_url?: string;\n query: string;\n kind: SearchKind;\n channels?: string[];\n user?: string; // @name, name, or U...\n after?: string; // YYYY-MM-DD\n before?: string; // YYYY-MM-DD\n content_type?: ContentType;\n limit?: number;\n max_content_chars?: number;\n download?: boolean;\n};\n\nexport type SearchResult = {\n messages?: Omit<CompactSlackMessage, \"channel_id\" | \"thread_ts\">[];\n files?: { title?: string; mimetype?: string; mode?: string; path: string }[];\n};\n\nexport async function searchSlack(input: {\n client: SlackApiClient;\n auth: SlackAuth;\n options: SearchOptions;\n}): Promise<SearchResult> {\n const limit = Math.min(Math.max(input.options.limit ?? 20, 1), 200);\n const maxContentChars = input.options.max_content_chars ?? 4000;\n const contentType = input.options.content_type ?? \"any\";\n const download = input.options.download ?? true;\n if (!download && (input.options.kind === \"files\" || input.options.kind === \"all\")) {\n throw new Error(\"File search requires downloads enabled (so agents get local file paths).\");\n }\n\n const slackQuery = await buildSlackSearchQuery(input.client, {\n query: input.options.query,\n channels: input.options.channels,\n user: input.options.user,\n after: input.options.after,\n before: input.options.before,\n });\n\n const out: SearchResult = {};\n\n if (input.options.kind === \"messages\" || input.options.kind === \"all\") {\n if (input.options.channels?.length) {\n out.messages = await searchMessagesInChannelsFallback(input.client, {\n auth: input.auth,\n query: input.options.query,\n channels: input.options.channels,\n user: input.options.user,\n after: input.options.after,\n before: input.options.before,\n limit,\n maxContentChars,\n contentType,\n download,\n });\n } else {\n const rawMatches = await searchMessagesRaw(input.client, { query: slackQuery, limit });\n out.messages = await searchMessagesViaSearchApi(input.client, {\n auth: input.auth,\n workspace_url: input.options.workspace_url,\n slack_query: slackQuery,\n limit,\n maxContentChars,\n contentType,\n download,\n rawMatches,\n });\n }\n }\n\n if (input.options.kind === \"files\" || input.options.kind === \"all\") {\n if (input.options.channels?.length) {\n out.files = await searchFilesInChannelsFallback(input.client, {\n auth: input.auth,\n query: input.options.query,\n channels: input.options.channels,\n user: input.options.user,\n after: input.options.after,\n before: input.options.before,\n limit,\n contentType,\n });\n } else {\n const rawMatches = await searchFilesRaw(input.client, { query: slackQuery, limit });\n out.files = await searchFilesViaSearchApi(input.client, {\n auth: input.auth,\n slack_query: slackQuery,\n limit,\n contentType,\n rawMatches,\n });\n }\n }\n\n return out;\n}\n",
43
+ "import type { Command } from \"commander\";\nimport type { CliContext } from \"./context.ts\";\nimport { pruneEmpty } from \"../lib/compact-json.ts\";\nimport { searchSlack } from \"../slack/search.ts\";\n\ntype SearchCommandOptions = {\n workspace?: string;\n channel?: string[] | string;\n user?: string;\n after?: string;\n before?: string;\n contentType?: string;\n limit?: string;\n maxContentChars?: string;\n};\n\nfunction addSearchOptions(cmd: Command): Command {\n return cmd\n .option(\"--workspace <url>\", \"Workspace URL (needed when searching across multiple workspaces)\")\n .option(\"--channel <channel...>\", \"Channel filter (#name, name, or id). Repeatable.\")\n .option(\"--user <user>\", \"User filter (@name, name, or user id U...)\")\n .option(\"--after <date>\", \"Only results after YYYY-MM-DD\")\n .option(\"--before <date>\", \"Only results before YYYY-MM-DD\")\n .option(\n \"--content-type <type>\",\n \"Filter content type: any|text|image|snippet|file (default any)\",\n )\n .option(\"--limit <n>\", \"Max results (default 20)\", \"20\")\n .option(\n \"--max-content-chars <n>\",\n \"Max message content characters (default 4000, -1 for unlimited)\",\n \"4000\",\n );\n}\n\nasync function runSearch(input: {\n ctx: CliContext;\n kind: \"messages\" | \"files\" | \"all\";\n query: string;\n options: SearchCommandOptions;\n}): Promise<void> {\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(input.options.workspace);\n const channels = Array.isArray(input.options.channel)\n ? input.options.channel\n : input.options.channel\n ? [input.options.channel]\n : [];\n\n await input.ctx.assertWorkspaceSpecifiedForChannelNames({ workspaceUrl, channels });\n\n const payload = await input.ctx.withAutoRefresh({\n workspaceUrl,\n work: async () => {\n const { client, auth, workspace_url } = await input.ctx.getClientForWorkspace(workspaceUrl);\n const limit = Number.parseInt(input.options.limit || \"20\", 10);\n const maxContentChars = Number.parseInt(input.options.maxContentChars || \"4000\", 10);\n const contentType = input.ctx.parseContentType(input.options.contentType);\n return await searchSlack({\n client,\n auth,\n options: {\n workspace_url: workspace_url ?? workspaceUrl ?? \"\",\n query: input.query,\n kind: input.kind,\n channels,\n user: input.options.user,\n after: input.options.after,\n before: input.options.before,\n content_type: contentType,\n limit,\n max_content_chars: maxContentChars,\n download: true,\n },\n });\n },\n });\n\n console.log(JSON.stringify(pruneEmpty(payload), null, 2));\n}\n\nexport function registerSearchCommand(input: { program: Command; ctx: CliContext }): void {\n const searchCmd = input.program\n .command(\"search\")\n .description(\"Search Slack messages and files (token-efficient JSON)\");\n\n const create = (spec: {\n kind: \"messages\" | \"files\" | \"all\";\n name: string;\n desc: string;\n }): Command =>\n addSearchOptions(searchCmd.command(spec.name).description(spec.desc))\n .argument(\"<query>\", \"Search query\")\n .action(async (...args) => {\n const [query, options] = args as [string, SearchCommandOptions];\n try {\n await runSearch({ ctx: input.ctx, kind: spec.kind, query, options });\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n create({ kind: \"all\", name: \"all\", desc: \"Search messages and files\" });\n create({ kind: \"messages\", name: \"messages\", desc: \"Search messages\" });\n create({ kind: \"files\", name: \"files\", desc: \"Search files\" });\n}\n",
44
+ "import { createHash } from \"node:crypto\";\nimport { chmod, copyFile, mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { getAppDir } from \"./app-dir.ts\";\nimport { readJsonFile, writeJsonFile } from \"./fs.ts\";\nimport { getPackageVersion } from \"./version.ts\";\n\nconst REPO = \"stablyai/agent-slack\";\nconst CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours\n\ntype UpdateCheckCache = {\n latest_version: string;\n checked_at: number; // epoch ms\n};\n\ntype GitHubRelease = {\n tag_name: string;\n assets: { name: string; browser_download_url: string }[];\n};\n\nfunction getCachePath(): string {\n return join(getAppDir(), \"update-check.json\");\n}\n\n/**\n * Compare two semver strings. Returns:\n * negative if a < b, 0 if equal, positive if a > b\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.replace(/^v/, \"\").split(\".\").map(Number);\n const pb = b.replace(/^v/, \"\").split(\".\").map(Number);\n for (let i = 0; i < 3; i++) {\n const diff = (pa[i] ?? 0) - (pb[i] ?? 0);\n if (diff !== 0) {\n return diff;\n }\n }\n return 0;\n}\n\n/**\n * Fetch the latest release version from GitHub.\n * Returns null on any network/API error (never throws).\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n try {\n const resp = await fetch(`https://api.github.com/repos/${REPO}/releases/latest`, {\n headers: { Accept: \"application/vnd.github+json\", \"User-Agent\": \"agent-slack-updater\" },\n signal: AbortSignal.timeout(5000),\n });\n if (!resp.ok) {\n return null;\n }\n const data = (await resp.json()) as GitHubRelease;\n return data.tag_name?.replace(/^v/, \"\") ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if a newer version is available. Uses a local cache to avoid\n * hitting GitHub more than once per CHECK_INTERVAL_MS.\n *\n * @param force Skip the cache and always fetch from GitHub.\n * @returns `{ current, latest, updateAvailable }` or null on error.\n */\nexport async function checkForUpdate(force = false): Promise<{\n current: string;\n latest: string;\n update_available: boolean;\n} | null> {\n const current = getPackageVersion();\n\n if (!force) {\n const cached = await readJsonFile<UpdateCheckCache>(getCachePath());\n if (cached && Date.now() - cached.checked_at < CHECK_INTERVAL_MS) {\n return {\n current,\n latest: cached.latest_version,\n update_available: compareSemver(cached.latest_version, current) > 0,\n };\n }\n }\n\n const latest = await fetchLatestVersion();\n if (!latest) {\n return null;\n }\n\n // Persist cache (best-effort, never throw)\n try {\n await writeJsonFile(getCachePath(), {\n latest_version: latest,\n checked_at: Date.now(),\n } satisfies UpdateCheckCache);\n } catch {\n // ignore\n }\n\n return {\n current,\n latest,\n update_available: compareSemver(latest, current) > 0,\n };\n}\n\nfunction detectPlatformAsset(): string {\n const platform = process.platform === \"win32\" ? \"windows\" : process.platform;\n const archMap: Record<string, string> = { x64: \"x64\", arm64: \"arm64\" };\n const arch = archMap[process.arch] ?? process.arch;\n const ext = platform === \"windows\" ? \".exe\" : \"\";\n return `agent-slack-${platform}-${arch}${ext}`;\n}\n\nasync function sha256(filePath: string): Promise<string> {\n const data = await readFile(filePath);\n return createHash(\"sha256\").update(data).digest(\"hex\");\n}\n\n/**\n * Download, verify, and replace the current binary with the latest release.\n * Returns `true` on success.\n */\nexport async function performUpdate(\n latest: string,\n): Promise<{ success: boolean; message: string }> {\n const asset = detectPlatformAsset();\n const tag = `v${latest}`;\n const baseUrl = `https://github.com/${REPO}/releases/download/${tag}`;\n\n const tmp = join(tmpdir(), `agent-slack-update-${Date.now()}`);\n await mkdir(tmp, { recursive: true });\n\n const binTmp = join(tmp, asset);\n const sumsTmp = join(tmp, \"checksums-sha256.txt\");\n\n try {\n // Download binary + checksums in parallel\n const [binResp, sumsResp] = await Promise.all([\n fetch(`${baseUrl}/${asset}`, { signal: AbortSignal.timeout(120_000) }),\n fetch(`${baseUrl}/checksums-sha256.txt`, { signal: AbortSignal.timeout(30_000) }),\n ]);\n\n if (!binResp.ok) {\n return { success: false, message: `Failed to download ${asset}: HTTP ${binResp.status}` };\n }\n if (!sumsResp.ok) {\n return { success: false, message: `Failed to download checksums: HTTP ${sumsResp.status}` };\n }\n\n await writeFile(binTmp, Buffer.from(await binResp.arrayBuffer()));\n const sumsText = await sumsResp.text();\n await writeFile(sumsTmp, sumsText);\n\n // Verify checksum\n const expected = sumsText\n .split(\"\\n\")\n .map((line) => line.trim().split(/\\s+/))\n .find((parts) => parts[1] === asset)?.[0];\n\n if (!expected) {\n return { success: false, message: `Checksum not found for ${asset} in release checksums` };\n }\n\n const actual = await sha256(binTmp);\n if (actual !== expected) {\n return { success: false, message: `Checksum mismatch: expected ${expected}, got ${actual}` };\n }\n\n // Replace current binary\n const currentBin = process.execPath;\n const backupPath = `${currentBin}.bak`;\n\n // Rename current -> backup, copy new -> current, remove backup\n await rename(currentBin, backupPath);\n try {\n await copyFile(binTmp, currentBin);\n await chmod(currentBin, 0o755);\n await rm(backupPath, { force: true });\n } catch (err) {\n // Restore backup on failure\n try {\n await rename(backupPath, currentBin);\n } catch {\n // ignore restore failure\n }\n throw err;\n }\n\n return { success: true, message: `Updated agent-slack to ${latest}` };\n } finally {\n await rm(tmp, { recursive: true, force: true }).catch(() => {});\n }\n}\n\n/**\n * Background update check. Writes a notice to stderr if an update is available.\n * Swallows all errors silently. Respects the 24-hour throttle.\n * Disable with AGENT_SLACK_NO_UPDATE_CHECK=1.\n */\nexport async function backgroundUpdateCheck(): Promise<void> {\n if (process.env.AGENT_SLACK_NO_UPDATE_CHECK === \"1\") {\n return;\n }\n try {\n const result = await checkForUpdate();\n if (result?.update_available) {\n process.stderr.write(\n `\\nUpdate available: ${result.current} → ${result.latest}. Run \"agent-slack update\" to upgrade.\\n`,\n );\n }\n } catch {\n // never interfere with normal operation\n }\n}\n",
45
+ "import type { Command } from \"commander\";\nimport { checkForUpdate, performUpdate } from \"../lib/update.ts\";\nimport { pruneEmpty } from \"../lib/compact-json.ts\";\n\nexport function registerUpdateCommand(input: { program: Command }): void {\n input.program\n .command(\"update\")\n .description(\"Update agent-slack to the latest version\")\n .option(\"--check\", \"Only check for updates (don't install)\")\n .action(async (...args) => {\n const [options] = args as [{ check?: boolean }];\n try {\n const result = await checkForUpdate(true);\n\n if (!result) {\n console.error(\"Could not check for updates. Check your network connection.\");\n process.exitCode = 1;\n return;\n }\n\n if (!result.update_available) {\n console.log(JSON.stringify(pruneEmpty({ ...result, status: \"up_to_date\" }), null, 2));\n return;\n }\n\n if (options.check) {\n console.log(\n JSON.stringify(pruneEmpty({ ...result, status: \"update_available\" }), null, 2),\n );\n return;\n }\n\n process.stderr.write(`Updating agent-slack ${result.current} → ${result.latest}...\\n`);\n const outcome = await performUpdate(result.latest);\n\n if (!outcome.success) {\n console.error(outcome.message);\n process.exitCode = 1;\n return;\n }\n\n console.log(\n JSON.stringify(\n pruneEmpty({\n status: \"updated\",\n previous_version: result.current,\n new_version: result.latest,\n message: outcome.message,\n }),\n null,\n 2,\n ),\n );\n } catch (err: unknown) {\n console.error(err instanceof Error ? err.message : String(err));\n process.exitCode = 1;\n }\n });\n}\n",
46
+ "import type { SlackApiClient } from \"./client.ts\";\n\nexport type CompactSlackUser = {\n id: string;\n name?: string; // handle\n real_name?: string;\n display_name?: string;\n email?: string;\n title?: string;\n tz?: string;\n is_bot?: boolean;\n deleted?: boolean;\n};\n\nexport async function listUsers(\n client: SlackApiClient,\n options?: {\n limit?: number;\n cursor?: string;\n includeBots?: boolean;\n },\n): Promise<{ users: CompactSlackUser[]; next_cursor?: string }> {\n const limit = Math.min(Math.max(options?.limit ?? 200, 1), 1000);\n const includeBots = options?.includeBots ?? false;\n\n const out: CompactSlackUser[] = [];\n let cursor = options?.cursor;\n\n while (out.length < limit) {\n const pageSize = Math.min(200, limit - out.length);\n const resp = await client.api(\"users.list\", {\n limit: pageSize,\n cursor,\n });\n const members = asArray(resp.members).filter(isRecord);\n for (const m of members) {\n const id = getString(m.id);\n if (!id) {\n continue;\n }\n if (!includeBots && m.is_bot) {\n continue;\n }\n out.push(toCompactUser(m));\n if (out.length >= limit) {\n break;\n }\n }\n const meta = isRecord(resp.response_metadata) ? resp.response_metadata : null;\n const next = meta ? getString(meta.next_cursor) : undefined;\n if (!next) {\n return { users: out };\n }\n cursor = next;\n }\n\n return { users: out, next_cursor: cursor };\n}\n\nexport async function getUser(client: SlackApiClient, input: string): Promise<CompactSlackUser> {\n const trimmed = input.trim();\n if (!trimmed) {\n throw new Error(\"User is empty\");\n }\n\n const userId = await resolveUserId(client, trimmed);\n if (!userId) {\n throw new Error(`Could not resolve user: ${input}`);\n }\n\n const resp = await client.api(\"users.info\", { user: userId });\n const u = isRecord(resp.user) ? resp.user : null;\n if (!u || !getString(u.id)) {\n throw new Error(\"users.info returned no user\");\n }\n return toCompactUser(u);\n}\n\nasync function resolveUserId(client: SlackApiClient, input: string): Promise<string | null> {\n const trimmed = input.trim();\n if (/^U[A-Z0-9]{8,}$/.test(trimmed)) {\n return trimmed;\n }\n\n const handle = trimmed.startsWith(\"@\") ? trimmed.slice(1) : trimmed;\n if (!handle) {\n return null;\n }\n\n let cursor: string | undefined;\n for (;;) {\n const resp = await client.api(\"users.list\", { limit: 200, cursor });\n const members = asArray(resp.members).filter(isRecord);\n const found = members.find((m) => getString(m.name) === handle);\n if (found) {\n const id = getString(found.id);\n if (id) {\n return id;\n }\n }\n const meta = isRecord(resp.response_metadata) ? resp.response_metadata : null;\n const next = meta ? getString(meta.next_cursor) : undefined;\n if (!next) {\n break;\n }\n cursor = next;\n }\n return null;\n}\n\nfunction toCompactUser(u: Record<string, unknown>): CompactSlackUser {\n const profile = isRecord(u.profile) ? u.profile : {};\n return {\n id: getString(u.id) ?? \"\",\n name: getString(u.name) ?? undefined,\n real_name: getString(u.real_name) ?? undefined,\n display_name: getString(profile.display_name) ?? undefined,\n email: getString(profile.email) ?? undefined,\n title: getString(profile.title) ?? undefined,\n tz: getString(u.tz) ?? undefined,\n is_bot: typeof u.is_bot === \"boolean\" ? u.is_bot : undefined,\n deleted: typeof u.deleted === \"boolean\" ? u.deleted : undefined,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction getString(value: unknown): string | undefined {\n return typeof value === \"string\" ? value : undefined;\n}\n",
47
+ "import type { Command } from \"commander\";\nimport type { CliContext } from \"./context.ts\";\nimport { pruneEmpty } from \"../lib/compact-json.ts\";\nimport { getUser, listUsers } from \"../slack/users.ts\";\n\nexport function registerUserCommand(input: { program: Command; ctx: CliContext }): void {\n const userCmd = input.program.command(\"user\").description(\"Workspace user directory\");\n\n userCmd\n .command(\"list\")\n .description(\"List users in the workspace\")\n .option(\"--workspace <url>\", \"Workspace URL (required if you have multiple workspaces)\")\n .option(\"--limit <n>\", \"Max users (default 200)\", \"200\")\n .option(\"--cursor <cursor>\", \"Pagination cursor\")\n .option(\"--include-bots\", \"Include bot users\")\n .action(async (...args) => {\n const [options] = args as [\n { workspace?: string; limit: string; cursor?: string; includeBots?: boolean },\n ];\n try {\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(options.workspace);\n const payload = await input.ctx.withAutoRefresh({\n workspaceUrl,\n work: async () => {\n const { client } = await input.ctx.getClientForWorkspace(workspaceUrl);\n const limit = Number.parseInt(options.limit, 10);\n return await listUsers(client, {\n limit,\n cursor: options.cursor,\n includeBots: Boolean(options.includeBots),\n });\n },\n });\n console.log(JSON.stringify(pruneEmpty(payload), null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n\n userCmd\n .command(\"get\")\n .description(\"Get a single user by id (U...) or handle (@name)\")\n .argument(\"<user>\", \"User id (U...) or @handle/handle\")\n .option(\"--workspace <url>\", \"Workspace URL (required if you have multiple workspaces)\")\n .action(async (...args) => {\n const [user, options] = args as [string, { workspace?: string }];\n try {\n const workspaceUrl = input.ctx.effectiveWorkspaceUrl(options.workspace);\n const payload = await input.ctx.withAutoRefresh({\n workspaceUrl,\n work: async () => {\n const { client } = await input.ctx.getClientForWorkspace(workspaceUrl);\n return await getUser(client, user);\n },\n });\n console.log(JSON.stringify(pruneEmpty(payload), null, 2));\n } catch (err: unknown) {\n console.error(input.ctx.errorMessage(err));\n process.exitCode = 1;\n }\n });\n}\n"
48
+ ],
49
+ "mappings": "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",
50
+ "debugId": "09DBB443871FCCB664756E2164756E21",
51
+ "names": []
52
+ }