Atlas / Skills / chrismessina / raycast-extensions-skills

raycast-extensions-skillsBLOCK

skills/chrismessina/raycast-extensions-skills

Claude Code skills for building, shipping, and reviewing Raycast extensions

Verdict
BLOCK
Grade
D
Trust score
69 /100
Version
—
Hosts
4 documented
License
MIT
Stars
0
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

A Claude Code plugin for building, shipping, and reviewing Raycast extensions — from a blank directory to a merged Store PR.

The skills come out of shipping and maintaining a couple dozen extensions in `raycast/extensions`. Every rule in them was earned: each one records the defect or review round it prevents.

Install

claude plugin marketplace add chrismessina/raycast-extensions-skills
claude plugin install raycast-extensions@raycast-extensions-skills

Restart Claude Code so the skills load. To pick up a new release later:

claude plugin marketplace update raycast-extensions-skills
claude plugin update raycast-extensions   # then restart Claude Code

A GitHub install is a copy kept in ~/.claude/plugins/cache/; it changes only when you update it.

scaffold builds on `superpowers:brainstorming` for ideation; the other skills have no plugin dependencies.

Skills

Skills are keyed to lifecycle stages (verbs), not roles, so their triggers don't overlap.

Read from source at commit 895f36160fe2OBSERVED · 2026-10-11
Advertisement
02

Install

Commands as the repository documents them. They are shown, not run.

claude plugin install raycast-extensions@raycast-extensions-skills
claude plugin install raycast-extensions@raycast-extensions-skills
npm install
git clone https://github.com/chrismessina/<repo>.git
npm install
git clone
03

Host compatibility

What the documentation claims. We have not run a compatibility test.

HostStatusNotes
claude-codementioned
codexmentioned
cursormentioned
windsurfmentioned
04

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: api-changelog
description: Derive what changed between two published versions of @raycast/api, which Raycast ships with no release notes. Fires on "what's new in @raycast/api X", "is it safe to upgrade", "derive a changelog", "they don't publish a changelog", or a pasted npmjs.com/package/@raycast/api URL. Produces a verified entry in docs/reference/raycast-api-changelog.md. Does NOT change extension code (that's `develop`) and does NOT submit anything (that's `ship`).
metadata:
  stage: "0 — vendor intelligence, feeds every other stage"
---

# api-changelog

Raycast ships `@raycast/api` to npm with **no changelog, no release notes, and no readable tags**.
Its docs site does keep a changelog —
[developers.raycast.com/misc/changelog](https://developers.raycast.com/misc/changelog) — but it
**skips releases**: fetched 2026-09-24, it has 2.5.0 and no 2.4.0 or 2.4.1, so the Skills capability
that shipped in the 2.4.0 CLI first appears there under 2.5.0. Treat it as Tier 3: a list of leads
to verify, and a check on what you might have missed, never a source.

This skill is that derivation. It exists because the answers change what the other skills do: 2.3.0
silently repointed AI model ids, and 2.4.0 added a whole extension capability (Skills).

**Scope: `@raycast/api` only.** Every path, heuristic, and output location below is specific to it.
`@raycast/utils` and `@raycast/eslint-plugin` ship different layouts — the *method* transfers, the
commands do not. Adapt deliberately; do not run these verbatim against another package.

## The core discipline

**Every claim in the output must come from an artifact you read.**

| Tier | Artifact | Authoritative for |
|---|---|---|
| 1 | The installed **Raycast.app** JS bundles | What the runtime does — real values, gates, limits |
| 2 | The published **npm tarball** | The API surface, the CLI, what the build emits |
| 3 | Vendor prose (docs site, Slack, blog) | **Nothing.** A lead to verify, never a source |

Tier 3 is where the failures come from — **in both directions**. On 2026-09-07
`developers.raycast.com` documented `Common.Pin` as ⌘⇧P while the runtime bound ⌘., and two
automated reviewers filed the same wrong finding from that page. Raycast then **fixed the docs**
(`raycast/extensions` #30879, #30538), and by 2026-09-15 all 17 documented rows matched the runtime
exactly — but the warning written in September was still sitting in our reference file asserting the
docs were wrong, and got repeated into this skill as present-tense fact. It took a Raycast engineer
pushing back to catch it.

**So: date every Tier-3 claim, and re-fetch before repeating one.** A stale note saying a vendor
doc is wrong is as damaging as the wrong doc was — it survives the fix, and it sounds like earned
institutional knowledge.

**Tier 3 never becomes a changelog claim.** If vendor prose is the only support for something, it
belongs in the entry as an explicitly attributed, unverified assertion ("Raycast's release note
says X; these diffs neither confirm nor contradict it") — never as a derived finding.

## Setup — do this first, everything below depends on it

Take an OLD and a NEW version as inputs. Never guess them.

```bash
SCRATCH="${SCRATCH:-$(mktemp -d)}"; cd "$SCRATCH" || exit 1
OLD=2.3.0        # baseline
NEW=2.4.1        # the version being asked about
```

**Compute the version window** — every release between the two, inclusive, in publish order. The
intermediates matter: a change attributed to `$NEW` is often several releases old, and "your version
added nothing" is a real answer you can only give by checking the gaps.

```bash
npm view @raycast/api time --json > time.json
VERSIONS=$(python3 - "$OLD" "$NEW" <<'EOF'
import json, sys
old, new = sys.argv[1], sys.argv[2]
t = {k: v for k, v in json.load(open("time.json")).items() if k not in ("created", "modified")}
order = sorted(t, key=lambda k: t[k])          # publish order, not semver order
i, j = order.index(old), order.index(new)
print("\n".join(order[min(i, j):max(i, j) + 1]))   # ONE PER LINE — see the zsh note below
EOF
) || { echo "could not resolve version window"; exit 1; }
echo "window:"; echo "$VERSIONS"
```

> 🚨 **Loop with `while read`, never `for v in $VERSIONS`.** Chris's shell is **zsh**, which does
> *not* word-split unquoted parameter expansions the way bash does. `for v in $VERSIONS` passes the
> whole string as ONE argument, and you get
> `npm error notarget No matching version found for @raycast/[email protected] 2.3.1 2.4.0 2.4.1`.
> Verified by running this skill's own recipe, 2026-09-15. Newline-separated + `while read` behaves
> identically in bash and zsh.
```

**Fetch and extract, failing loudly.** A silently missing tarball is how an empty diff gets misread
as "no changes".

```bash
while IFS= read -r v; do
  [ -n "$v" ] || continue
  npm pack "@raycast/api@$v" >/dev/null 2>&1 || { echo "FAILED to pack $v"; break; }   # notices are on STDERR
  d="v$(echo "$v" | tr -d '.')"; mkdir -p "$d"
  tar xzf "raycast-api-$v.tgz" -C "$d" || { echo "FAILED to extract $v"; break; }
  [ -f "$d/package/types/index.d.ts" ] || { echo "$v: missing types/index.d.ts"; break; }
  echo "ok $v -> $d"
done <<< "$VERSIONS"

OLDD="v$(echo "$OLD" | tr -d '.')/package"      # use these two everywhere below
NEWD="v$(echo "$NEW" | tr -d '.')/package"
```

Record the installed app, which you will need in step 5 and must cite by build:

```bash
plutil -p /Applications/Raycast.app/Contents/Info.plist | grep CFBundleShortVersionString
```

> App and package version numbers have coincided on every pair checked (2.3.0/2.3.0.0,
> 2.4.1/2.4.1.0). That is **not** a stated policy. It is only good enough to pick which app to open,
> and a runtime observation is evidence about *that installed build* — never about a historical
> tarball you did not have an app for.

## 1. Inventory what moved

Never start by diffing 4 MB minified bundles. Start with what changed at all.

```bash
(cd "$OLDD" && find . -type f | sort) > /tmp/a
05

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
declared (3 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
found

Findings (10)

HIGHPrompt injection · prompt.hide_from_user · CWE-94, CWE-1427
plugins/raycast-extensions/skills/ship/SKILL.md:950
do not post; tell the user and let them decide.
Why it matters. asks the agent to act without the user's knowledge
HIGHPrompt injection · prompt.zero_width · CWE-94, CWE-1427
plugins/raycast-extensions/reference/house-style.md:1760
- **`hooks/`** — React state hooks, each file/export prefixed `use*`.
Why it matters. invisible characters in instruction text
Fix. strip non-printing characters
MEDIUMHard-coded secrets · secret.anthropic · CWE-798, CWE-321
plugins/raycast-extensions/learnings/security-issues/error-display-is-a-credential-disclosure-surface.md:45
headers: { authorization: "Bearer sk-ant-api03-REALKEYMATERIAL..." },
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
plugins/raycast-extensions/learnings/security-issues/error-display-is-a-credential-disclosure-surface.md:54
- `postgres://admin:hunter2@db:5432/prod` passed through untouched, while
MEDIUMHard-coded secrets · secret.db_uri · CWE-798, CWE-321
plugins/raycast-extensions/learnings/security-issues/error-display-is-a-credential-disclosure-surface.md:153
masked and `postgres://user:pw@db:5432` was not. One passing variant is not
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
plugins/raycast-extensions/learnings/security-issues/error-display-is-a-credential-disclosure-surface.md:141
["pem",           "-----BEGIN RSA PRIVATE KEY-----\nMIIEow\n-----END RSA PRIVATE KEY-----"],
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
prettier
Why it matters. 1 dependency range(s) float
Fix. pin exact versions or ship a lockfile
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
plugins/raycast-extensions/learnings/design-patterns/read-installed-raycast-extensions-from-config-not-application-support.md:50
cannot be read without the export password.
Why it matters. asks the agent to read credentials
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
plugins/raycast-extensions/reference/house-style.md:615
> server's echo of the request. Read [`error-display-is-a-credential-disclosure-surface`](../learnings/security-issues/error-display-is-a-credential-disclosure-surface.md)
Why it matters. asks the agent to read credentials

Gates applied: instruction_override, no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 895f36160fe2full audit observations/trust-audit/skill/chrismessina__raycast-extensions-skills.json · Report an issue / request a re-scan
06

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-11895f36160fe2BLOCKD69first audit
07

Questions

What does the raycast-extensions-skills skill do?

Claude Code skills for building, shipping, and reviewing Raycast extensions

Is raycast-extensions-skills safe to install?

No — not without reading the findings first. The audit graded it D (69/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What can raycast-extensions-skills access on my machine?

The audit observed that it reaches the network. Each of those is consistent with what it says it does. Secrets in the source: found — see the findings.

Which assistants does raycast-extensions-skills work with?

Its documentation mentions claude-code, codex, cursor and windsurf. That is what the text claims, not a compatibility test we ran.

How current is this page?

The grade is for one exact copy of the source (895f36160fe2), read on 2026-10-11. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement