# @kody/raycast — agent notes Human setup and intent live in [`README.md`](./README.md). Extension source: [`extension/`](./extension/). Never paste minted webhook URLs or tokens in chat. Do not disable live webhooks or jobs. ## When the user asks for a Raycast command 1. Write an ESM module string with `export default async function main(params)`. 2. Prefer `kody:@…` imports and `kody.*` capabilities (same as MCP execute). 3. Call `upsert-command` with `title`, `description`, `icon`, `code` (optional `id`). 4. Tell the user to open **Kody Commands** in Raycast and refresh (or reopen the list). ```js import upsertCommand from 'kody:@kody/raycast/upsert-command' export default async function main() { return await upsertCommand({ id: 'example-list-packages', title: 'List my Kody packages', description: 'Smoke: list-packages via execute', icon: 'Box', code: `import listPackages from 'kody:@kody/raycast/list-packages' export default async function main() { return await listPackages() }`, }) } ``` Icon: prefer a Raycast `Icon` key (`Terminal`, `Hammer`, `SpeechBubble`, `Box`, …) or a single emoji. ## Imports | Export | Import | | --- | --- | | overview | `kody:@kody/raycast` | | list-commands | `kody:@kody/raycast/list-commands` | | upsert-command | `kody:@kody/raycast/upsert-command` | | delete-command | `kody:@kody/raycast/delete-command` | | run | `kody:@kody/raycast/run` | | list-packages | `kody:@kody/raycast/list-packages` | | get-package | `kody:@kody/raycast/get-package` | | invoke | `kody:@kody/raycast/invoke` | | adapt | `kody:@kody/raycast/adapt` | | guide | `kody:@kody/raycast/guide` | | setup-launcher-token | `kody:@kody/raycast/setup-launcher-token` | Prefer static `kody:@kody/raycast/...` imports from `execute`. ## Webhooks (do not disable) | name | export | | --- | --- | | `list-commands` | `./list-commands` | | `upsert-command` | `./upsert-command` | | `delete-command` | `./delete-command` | | `run` | `./run` | | `list-packages` | `./list-packages` | | `get-package` | `./get-package` | | `invoke` | `./invoke` | | `root` | `.` | Raycast reads minted URLs for **`list-commands`** and **`run`** from `~/.config/kody/raycast.json` (preferred) or extension preferences. ``` POST Content-Type: application/json Idempotency-Key: raycast:: {"params":{ ... }} ``` If webhook URLs are also applied to a GitHub repo so a local machine can read them via `gh api`, `./run` ignores GitHub-shaped payloads (ping/`hook_id`, `repository`, `installation`, org/advisory, and sender+action) with `{ ok: true, ignored: true }` so they do not 502. Legitimate Raycast callers still send `commandId` or `code`. ## Fork / adapt ```js import adapt from 'kody:@kody/raycast/adapt' export default async function main() { return await adapt() } ``` After a fork, mint webhooks on **that** package id, write local `raycast.json`, import `extension/`, then publish. Live `@kody/raycast` lists official packages and starts with empty command storage — keep personal automations in the user’s fork. ## Smoke ```js import listCommands from 'kody:@kody/raycast/list-commands' export default async function main() { return await listCommands() } ``` ```js import run from 'kody:@kody/raycast/run' export default async function main() { return await run({ code: `export default async function main() { return { ok: true, smoke: true } }`, }) } ``` ```js import invoke from 'kody:@kody/raycast/invoke' export default async function main() { return await invoke({ kodyId: 'notify', exportName: '.', params: { dryRun: true }, dryRun: true, }) } ``` ## Edge cases - Share as `https://kody.codes/@kody/raycast` — never `/community/{listing_id}`. - Prefer webhooks over `./setup-launcher-token` / package-app bearer for Raycast. - `./invoke` supports `dryRun: true` (preview, no target call). - Never paste webhook URLs, launcher tokens, or invocation tokens into chat or commits. - Keep `LICENSE` (MIT), `## Intent`, and `community-icon.svg` for community listing.