← Public packages
@charlesmatte/granola
Search and read Granola meeting notes, summaries and transcripts from any agent; manage webhooks and legal holds safely.
src/accounts.ts
42 lines · 2.1 KB · TypeScriptimport { KEY_TYPES_HINT } from './lib/client.ts'
import { GRANOLA_HOST, SECRET_PREFIX } from './lib/account.ts'
import { credentialStatus, discoverAccounts, userSecrets } from './lib/secrets.ts'
import { DOCS, secretSetupUrl } from './lib/urls.ts'
import { ACCOUNT_NAME_PATTERN, parseInput } from './lib/validate.ts'
/**
* List the Granola accounts configured in this Kody account — every user secret named
* `granola-<account>` — with whether each may be sent to public-api.granola.ai. Metadata only:
* key values are never read. Pass `account` to check (or get the setup link for) one name.
* No Granola request; use ./verify to prove a key works.
*
* @param input.account - Optional single account name to check.
* @returns `{ convention, host, accounts: [{ account, secretName, saved, hostApproved, ready, setupUrl?, hostApprovalUrl? }], setup }`
*
* @example
* import accounts from 'kody:@charlesmatte/granola/accounts'
*
* const { accounts: list } = await accounts({})
*/
export default async function granolaAccounts(input: unknown) {
const p = parseInput<{ account?: string }>(input, { account: { type: 'string', pattern: ACCOUNT_NAME_PATTERN } }, 'accounts')
const secrets = await userSecrets()
const setup = {
step1: `Create a Granola API key in the Granola desktop app: Settings → Connectors → API keys → Create new key (Business or Enterprise plan). ${DOCS.apiKeys}`,
keyTypes: KEY_TYPES_HINT,
step2: `Save it in Kody as user secret ${SECRET_PREFIX}<account> with allowed host ${GRANOLA_HOST}, e.g. ${secretSetupUrl(`${SECRET_PREFIX}work`)}`,
step3: 'Call ./verify({ account }) to confirm the key works.',
}
if (p.account) {
const status = credentialStatus(`${SECRET_PREFIX}${p.account}`, secrets)
return { convention: `${SECRET_PREFIX}<account>`, host: GRANOLA_HOST, accounts: [{ account: p.account, ...status }], setup }
}
const accounts = discoverAccounts(secrets)
return {
convention: `${SECRET_PREFIX}<account>`,
host: GRANOLA_HOST,
accounts: accounts ?? [],
...(accounts === null ? { note: 'Kody did not allow listing secrets from here; pass account to get the setup link, or just call ./verify.' } : {}),
setup,
}
}