Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kody/raycast

src/guide.ts

70 lines · 2.4 KB · TypeScript
import { kody } from 'kody:runtime'
import {
	KODY_ID,
	OFFICIAL_PACKAGE_ID,
	PACKAGE_NAME,
	PUBLIC_URL,
	asRecord,
	invocationUrl,
	optionalString,
	tokenSetupUrl,
} from './helpers.ts'

export type GuideInput = {
	packageId?: string
	username?: string
}

/**
 * Agent setup: prefilled invocation-token URL and HTTP invocation shape.
 *
 * This package does not use account secrets. External clients mint a package
 * invocation token in the browser and store the raw bearer in Raycast
 * preferences (or another local secret store). Never paste the token in chat.
 *
 * @example
 * import guide from 'kody:@kody/raycast/guide'
 * const setup = await guide()
 */
export default async function guide(input: GuideInput = {}) {
	const record = asRecord(input)
	const username = optionalString(record, 'username') ?? 'YOUR_USERNAME'
	let packageId = optionalString(record, 'packageId')

	if (!packageId) {
		const listed = await kody.package_list({})
		packageId =
			listed.packages.find(pkg => pkg.kody_id === KODY_ID)?.package_id ??
			OFFICIAL_PACKAGE_ID
	}

	const setupUrl = tokenSetupUrl(packageId)
	return {
		name: PACKAGE_NAME,
		kodyId: KODY_ID,
		publicUrl: PUBLIC_URL,
		packageId,
		auth: 'package-invocation-token',
		secrets: [],
		secretUrls: {},
		tokenSetupUrl: setupUrl,
		invocation: {
			method: 'POST',
			listPackagesUrl: invocationUrl(username, 'list-packages'),
			getPackageUrl: invocationUrl(username, 'get-package'),
			invokeUrl: invocationUrl(username, 'invoke'),
			guideUrl: invocationUrl(username, 'guide'),
			source: 'raycast',
		},
		steps: [
			'Share https://kody.codes/@kody/raycast — not a /community/{listing_id} URL.',
			'For a personal launcher, fork or install this listing into the user account so list-packages sees their packages. Live @kody/raycast lists official kody-scope packages.',
			`Open the prefilled token form: ${setupUrl}`,
			'Leave the raw token out of the URL. Generate or paste it in the form, then store it only in Raycast preferences or a local secret store.',
			`POST https://kody.codes/@${username}/api/package-invocations/raycast/<export> with Authorization: Bearer <token>.`,
			'Call ./invoke to run another owned package. The bearer stays scoped to raycast; packages.invoke enters the target runtime.',
			'Mutations on ./invoke support dryRun: true (preview, no target call). This package declares no jobs.',
			'Never paste invocation tokens or other secrets into chat.',
		],
	}
}