← Public packages
@kentcdodds/grok-bot
Wake a named Grok Bot from Kody by posting a prompt to that bot's own Cursor webhook.
src/list.ts
72 lines · 2.1 KB · TypeScriptimport {
listChannelMappings,
readCategoryId,
type ChannelMapping,
} from './discord-map.ts'
import { plusAddressFor } from './plus-alias.ts'
import {
listBotRecords,
listWakeSecrets,
normalizeName,
secretNameFor,
secretUseStatusFrom,
urlHostOf,
type BotSummary,
} from './registry.ts'
import { plainClone } from './plain.ts'
export type ListResult = {
categoryId: string
channels: ChannelMapping[]
bots: BotSummary[]
}
/**
* List registered Grok Bots without full webhook URLs.
*
* @returns Roster summaries with urlHost, pendingSecret, needsHostApproval, channelId, and plus-alias emailAddress
* @example
* import list from 'kody:@kentcdodds/grok-bot/list'
* const roster = await list()
* // => { categoryId, channels, bots: [{ id, name, aliases, secretName, pendingSecret, needsHostApproval, urlHost, channelId, emailAddress }] }
*/
export default async function list(): Promise<ListResult> {
const [records, secrets, categoryId, channels] = await Promise.all([
listBotRecords(),
listWakeSecrets(),
readCategoryId(),
listChannelMappings(),
])
const bots: BotSummary[] = records.map((record) => {
const secret = secretUseStatusFrom(secrets, record.secretName)
return {
id: record.id,
name: record.name,
aliases: record.aliases,
secretName: record.secretName,
pendingSecret: !secret.exists,
needsHostApproval: secret.needsHostApproval,
urlHost: urlHostOf(record.url),
emailAddress: plusAddressFor(record.name),
...(secret.approvalUrl && secret.needsHostApproval
? { approvalUrl: secret.approvalUrl }
: {}),
...(record.channelId ? { channelId: record.channelId } : {}),
}
})
for (const channel of channels) {
if (bots.some((bot) => bot.id === channel.botId)) continue
bots.push({
id: channel.botId,
name: channel.name,
aliases: [normalizeName(channel.name)],
secretName: secretNameFor(channel.botId),
pendingSecret: true,
needsHostApproval: false,
urlHost: '',
emailAddress: plusAddressFor(channel.name),
channelId: channel.channelId,
})
}
return plainClone({ categoryId, channels, bots })
}