Add project structure eval shape

This commit is contained in:
adi-georgian
2026-08-17 10:38:45 -04:00
parent 57d052734d
commit f260890ec7
6 changed files with 103 additions and 3 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "expo",
"version": "1.10.2",
"version": "1.10.3",
"description": "Official Expo skills for building, deploying, upgrading, and debugging Expo apps",
"author": {
"name": "Expo Team",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "expo",
"version": "1.10.2",
"version": "1.10.3",
"description": "Official Expo skills for building, deploying, upgrading, and debugging Expo and React Native apps.",
"author": {
"name": "Expo Team",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "expo",
"displayName": "Expo",
"version": "1.10.2",
"version": "1.10.3",
"description": "Official Expo skills for building, deploying, upgrading, and debugging Expo and React Native apps.",
"author": {
"name": "Expo Team",
@@ -0,0 +1,63 @@
import { agentEval, expect } from '@expo/skill-eval-kit';
import { setupProject } from './setup';
// This is a proposed consumer of a future skill-only agentEval setup. The
// current kit requires an npm package under test and cannot run this case yet.
agentEval(
import.meta.url,
{
title: 'scaffold a maintainable Expo Router project',
prompt: `You're starting a new Expo Router app for a small task tracker. Add home and settings routes, a reusable primary button shared by both screens, and a date-formatting utility with a unit test. Organize the new project so another team can grow it, use TypeScript throughout, and configure clean non-relative imports. Replace the starter structure as needed.`,
projectSetup: setupProject(),
},
(check) => {
check('puts routes under src/app', (ws) => {
expect(ws.exists('src/app')).toBe(true);
expect(ws.glob('src/app/**/index.tsx').length).toBeGreaterThan(0);
expect(ws.glob('src/app/**/*settings*.tsx').length).toBeGreaterThan(0);
});
check('keeps reusable UI under src/components', (ws) => {
expect(ws.exists('src/components')).toBe(true);
expect(ws.glob('src/components/**/*button*.tsx').length).toBeGreaterThan(0);
});
check('keeps non-route code out of src/app', (ws) => {
const misplacedFiles = [
...ws.glob('src/app/**/*button*.ts'),
...ws.glob('src/app/**/*button*.tsx'),
...ws.glob('src/app/**/*date*.ts'),
...ws.glob('src/app/**/*date*.tsx'),
];
expect(misplacedFiles).toEqual([]);
});
check('keeps styles with their components', (ws) => {
const separateStyleFiles = [
...ws.glob('**/*.styles.ts'),
...ws.glob('**/*.styles.tsx'),
...ws.glob('**/*.styles.js'),
...ws.glob('**/*.styles.jsx'),
];
expect(separateStyleFiles).toEqual([]);
});
check('colocates the date utility and its test', (ws) => {
const dateUtilities = ws
.glob('src/utils/**/*date*.ts')
.filter((file) => !file.endsWith('.test.ts'));
const dateTests = ws.glob('src/utils/**/*date*.test.ts');
expect(dateUtilities.length).toBeGreaterThan(0);
expect(dateTests.length).toBeGreaterThan(0);
expect(ws.glob('**/__tests__/**')).toEqual([]);
});
check('configures the @/* path alias', (ws) => {
expect(ws.read('tsconfig.json')).toMatch(
/"@\/\*"\s*:\s*\[\s*"\.\/src\/\*"\s*\]/
);
});
}
);
@@ -0,0 +1,23 @@
# Expo project structure evals
This directory sketches the maintainer-owned TypeScript eval shape proposed for the `expo-project-structure` skill. It follows the colocated `agentEval()` style used by the `expo-sqlite` skill in the Expo SDK repository.
## Experimental status
This eval is **not runnable yet**:
- `@expo/skill-eval-kit` is not published.
- The current draft kit assumes every skill belongs to an npm package under test. This plugin-owned skill has no package to link.
- The existing `eval-experiments` EAS workflow does not discover or execute evals from `expo/skills`.
The files intentionally show the consumer API we want to discuss before finalizing that runtime contract. Do not vendor an agent runner here.
## Intended execution
Once the shared harness supports plugin-owned skills, it should run this task in both with-skill and without-skill conditions. `eval-experiments` should continue to own agent launch, authentication, traces, artifacts, repetitions, and reporting.
## Distribution note
Because `.evals` currently lives inside the skill directory, `npx skills` copies it and installed plugin payloads may include it. The directory has no `SKILL.md`, so it is not discovered as a separate skill or automatically loaded into agent context.
This is a temporary compromise for reviewing true colocation. Before this pattern is adopted across more skills, move eval assets outside the distributed plugin area unless every supported installer gains a reliable shared exclusion mechanism.
@@ -0,0 +1,14 @@
/**
* Proposed setup descriptor for a plugin-owned skill eval.
*
* The current @expo/skill-eval-kit ProjectSetup requires an npm package under
* test. expo-project-structure belongs to the Expo plugin instead, so this
* shape deliberately contains only the skill and scaffold facts that a future
* shared runner needs.
*/
export function setupProject() {
return {
skillDir: new URL('..', import.meta.url),
baseTemplate: 'blank-typescript',
} as const;
}