Skip to content
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e211797
fix headings levels in component decision tree
reidbarber Apr 15, 2026
4a4e7c1
better illustration examples in SKILL.md
reidbarber Apr 15, 2026
b9f837e
skip redirects in markdown output
reidbarber Apr 15, 2026
5beabc0
fix stripped inline code from page descriptions in markdown output
reidbarber Apr 15, 2026
c6572c4
fix S2 Routers rendering in markdown output
reidbarber Apr 16, 2026
56422c5
add dnd tag for RAC dnd docs page
reidbarber Apr 16, 2026
4212bd5
improve Style Macro docs page markdown output
reidbarber Apr 16, 2026
9c78fcb
remove error pages from output
reidbarber Apr 16, 2026
e4bac2f
better JSDoc for focusRing (mention passing isFocusVisible)
reidbarber Apr 16, 2026
41694ef
improve skill with guidance on Buttons with icons and text
reidbarber Apr 16, 2026
91cb93c
improve skill with guidance to avoid concatenating class names from t…
reidbarber Apr 16, 2026
d1a3a62
testing skill differ (#9947)
reidbarber Apr 20, 2026
ccdf1c9
Merge branch 'main' into s2-skill-fixes
reidbarber Apr 20, 2026
33408ec
Merge remote-tracking branch 'origin/main' into s2-skill-fixes
reidbarber May 11, 2026
46ca23c
format
reidbarber May 11, 2026
f50e586
Merge remote-tracking branch 'origin/main' into s2-skill-fixes
reidbarber May 13, 2026
5403166
fix formatting
reidbarber May 13, 2026
d1c90fb
skill improvements
reidbarber May 14, 2026
3363135
more skill improvements
reidbarber May 14, 2026
753bd92
add figma-to-s2 resource
reidbarber May 14, 2026
41e3f4e
add creating-custom-components.md reference
reidbarber May 14, 2026
fd46a80
reference new creating-custom-components.md elsewhere
reidbarber May 14, 2026
91dfb8d
Merge remote-tracking branch 'origin/main' into s2-skill-fixes
reidbarber May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .circleci/build-skills.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Build agent skills for the current working tree and copy the resulting
# .well-known/skills directories into $1 for later diffing.
#
# Runs the two node scripts directly (rather than via yarn) so the command
# works from a `git worktree` / `git archive` checkout that doesn't have
# its own installed node_modules — node will resolve deps by walking up to
# the nearest parent node_modules, letting us reuse a sibling checkout's
# installed deps via a symlink.
set -euo pipefail

if [ -z "${1-}" ]; then
echo "usage: $0 <destination-dir>" >&2
exit 1
fi

DEST="$1"

rm -rf packages/dev/s2-docs/dist
node packages/dev/s2-docs/scripts/generateMarkdownDocs.mjs
node packages/dev/s2-docs/scripts/generateAgentSkills.mjs

rm -rf "$DEST"
mkdir -p "$DEST"
for lib in s2 react-aria; do
src="packages/dev/s2-docs/dist/$lib/.well-known/skills"
if [ -d "$src" ]; then
mkdir -p "$DEST/$lib"
cp -R "$src" "$DEST/$lib/"
fi
done
49 changes: 49 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,45 @@ jobs:
paths:
- 'ts-diff.txt'

skills-diff:
executor: rsp-large
steps:
- restore_cache:
key: react-spectrum-{{ .Environment.CACHE_VERSION }}-{{ .Environment.CIRCLE_SHA1 }}

- run:
name: build agent skills (branch)
command: ./.circleci/build-skills.sh /tmp/dist/skills-branch

- run:
name: build agent skills (main)
command: |
mkdir -p ~/.ssh
curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | sed -e 's/^/github.com /' >> ~/.ssh/known_hosts
BRANCH_ROOT="$(pwd)"
BUILD_SKILLS="$BRANCH_ROOT/.circleci/build-skills.sh"
git worktree add --detach /tmp/main-worktree origin/main
# Reuse the branch's installed node_modules since `build-skills.sh`
# only invokes node scripts (no yarn install needed in the worktree).
ln -s "$BRANCH_ROOT/node_modules" /tmp/main-worktree/node_modules
cd /tmp/main-worktree && "$BUILD_SKILLS" /tmp/dist/skills-main

- run:
name: diff agent skills
command: |
mkdir -p dist
node .circleci/skills-diff.js \
/tmp/dist/skills-main /tmp/dist/skills-branch \
> dist/skills-diff.md || true

- store_artifacts:
path: dist/skills-diff.md

- persist_to_workspace:
root: dist
paths:
- 'skills-diff.md'

typecheck-docs:
executor: rsp-large
steps:
Expand Down Expand Up @@ -903,6 +942,7 @@ jobs:
if [ $GITHUB_TOKEN ]; then
node .circleci/comment.js
node .circleci/api-comment.js
node .circleci/skills-comment.js
fi

publish-nightly:
Expand Down Expand Up @@ -982,6 +1022,14 @@ workflows:
ignore:
- /main$/
- /gh-readonly-queue\/.*$/
- skills-diff:
requires:
- install
filters:
branches:
ignore:
- /main$/
- /gh-readonly-queue\/.*$/
- typecheck-docs:
requires:
- install
Expand Down Expand Up @@ -1091,6 +1139,7 @@ workflows:
ignore: main
requires:
- ts-diff
- skills-diff
- deploy
- deploy-s3-commit
- comment:
Expand Down
129 changes: 129 additions & 0 deletions .circleci/skills-comment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
const Octokit = require('@octokit/rest');
const fs = require('fs');

const octokit = new Octokit({
auth: `token ${process.env.GITHUB_TOKEN}`
});

run();

let commentKey = '<!-- AgentSkillsDiffComment -->';

async function run() {
let pr;
// If we aren't running on a PR commit, double check if this is a branch created for a fork. If so, we'll need to
// comment the build link on the fork.
if (!process.env.CIRCLE_PULL_REQUEST) {
try {
const commit = await octokit.git.getCommit({
owner: 'adobe',
repo: 'react-spectrum',
commit_sha: process.env.CIRCLE_SHA1
});

// Check if it is a merge commit from the github "Branch from fork action"
if (
commit &&
commit.data?.parents?.length === 2 &&
commit.data.message.indexOf('Merge') > -1
) {
// Unfortunately listPullRequestsAssociatedWithCommit doesn't return fork prs so have to use search api
// to find the fork PR the original commit lives in
const forkHeadCommit = commit.data.parents[1].sha;
const searchRes = await octokit.search.issuesAndPullRequests({
q: `${forkHeadCommit}+repo:adobe/react-spectrum+is:pr+is:open`
});

// Look for a PR that is from a fork and has a matching head commit as the current branch
const pullNumbers = searchRes.data.items
.filter(i => i.pull_request !== undefined)
.map(j => j.number);
for (let pull_number of pullNumbers) {
const {data} = await octokit.pulls.get({
owner: 'adobe',
repo: 'react-spectrum',
pull_number
});
if (
data &&
data.head.repo.full_name !== 'adobe/react-spectrum' &&
data.head.sha === forkHeadCommit
) {
pr = pull_number;
break;
}
}
}
} catch (error) {
console.error(error);
}
} else {
pr = process.env.CIRCLE_PULL_REQUEST.split('/').pop();
}

if (pr != null) {
let commentId = await findDifferComment(pr);
let diff;
try {
diff = fs.readFileSync('/tmp/dist/skills-diff.md', 'utf8');
} catch (e) {
console.log('No Agent Skills diff output to post.');
return;
}
if (diff.trim().length > 0) {
const body = `${commentKey}
## Agent Skills Changes

${diff}
`;
if (commentId != null) {
await octokit.issues.deleteComment({
owner: 'adobe',
repo: 'react-spectrum',
comment_id: commentId
});
}
await octokit.issues.createComment({
owner: 'adobe',
repo: 'react-spectrum',
issue_number: pr,
body
});
} else if (commentId != null) {
// No changes — delete any prior comment so the PR doesn't show stale output.
await octokit.issues.deleteComment({
owner: 'adobe',
repo: 'react-spectrum',
comment_id: commentId
});
}
}
}

async function findDifferComment(pr, page = 1) {
let comments = null;
try {
comments = await octokit.issues.listComments({
owner: 'adobe',
repo: 'react-spectrum',
issue_number: pr,
page
});
} catch (err) {
console.log(err);
return null;
}

let commentId;
for (let comment of comments.data) {
if (comment.body.includes(commentKey)) {
commentId = comment.id;
break;
}
}
// default results per page is 30
if (commentId == null && comments.data.length === 30) {
commentId = await findDifferComment(pr, page + 1);
}
return commentId;
}
Loading
Loading