← Public packages
@kody/raycast
Raycast launcher: store execute commands in package storage and run them over minted webhooks.
src/setup-launcher-token.ts
43 lines · 1.6 KB · TypeScriptimport { packageContext } from 'kody:runtime'
import { storeLauncherToken } from './launcher-auth.ts'
function randomToken() {
const bytes = new Uint8Array(32)
crypto.getRandomValues(bytes)
let out = ''
for (const b of bytes) out += b.toString(16).padStart(2, '0')
return `kody_raycast_${out}`
}
/**
* Mint (or rotate) the optional Raycast launcher bearer token for the package app.
* Stores only a SHA-256 hash in package storage. Returns the plaintext once so an
* agent can write `~/.config/kody/raycast.json` on the owner's machine — never
* paste the token into chat.
*
* Prefer minted `list-commands` / `run` webhooks for Raycast. Package apps on
* `*.kody.run` need a Kody browser handoff, so webhooks are the external-client path.
*
* @returns token (once), hint, and hosted API base when available
*
* @example
* import setupLauncherToken from 'kody:@kody/raycast/setup-launcher-token'
* const { token, apiBaseUrl } = await setupLauncherToken()
*/
export default async function setupLauncherToken(input: { token?: string } = {}) {
const token = (input.token?.trim() || randomToken()).trim()
const stored = await storeLauncherToken(token)
const apiBaseUrl =
typeof packageContext?.hostedUrl === 'string' && packageContext.hostedUrl
? packageContext.hostedUrl.replace(/\/+$/, '')
: null
return {
ok: true as const,
token,
hint: stored.hint,
apiBaseUrl,
configPath: '~/.config/kody/raycast.json',
preferred: 'minted-webhooks',
note: 'Prefer listCommandsWebhookUrl + runWebhookUrl in configPath. Optional apiBaseUrl + token is package-app only (needs browser handoff). Never paste token into chat.',
}
}