Skip to content

Commit 346ac29

Browse files
gladyshautofix-ci[bot]rmarescu
authored
feat(ai): introduce vercel ai sdk support (#316)
Resolves #291 * Integrate [Vercel AI SDK](https://sdk.vercel.ai/docs/introduction) * Improved logging * New config structure --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Razvan Marescu <[email protected]>
1 parent 3bc223a commit 346ac29

38 files changed

+2725
-1986
lines changed

README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ npx @antiwork/shortest init
3333
```
3434

3535
This will:
36+
3637
- Automatically install the `@antiwork/shortest` package as a dev dependency if it is not already installed
3738
- Create a default `shortest.config.ts` file with boilerplate configuration
3839
- Generate a `.env.local` file (unless present) with placeholders for required environment variables, such as `ANTHROPIC_API_KEY`
@@ -49,9 +50,12 @@ export default {
4950
headless: false,
5051
baseUrl: "http://localhost:3000",
5152
testPattern: "**/*.test.ts",
52-
anthropicKey: process.env.ANTHROPIC_API_KEY,
53+
ai: {
54+
provider: "anthropic",
55+
},
5356
} satisfies ShortestConfig;
5457
```
58+
Anthropic API key will default to `SHORTEST_ANTHROPIC_API_KEY` / `ANTHROPIC_API_KEY` environment variables. Can be overwritten via `ai.config.apiKey`.
5559

5660
2. Create test files using the pattern specified in the config: `app/login.test.ts`
5761

@@ -245,12 +249,14 @@ This guide will help you set up the Shortest web app for local development.
245249
### Getting started
246250

247251
1. Clone the repository:
252+
248253
```bash
249254
git clone https://github.com/anti-work/shortest.git
250255
cd shortest
251256
```
252257

253258
2. Install dependencies:
259+
254260
```bash
255261
npm install -g pnpm
256262
pnpm install
@@ -335,6 +341,7 @@ You'll need to set up the following services for local development. If you're no
335341
<summary>GitHub OAuth</summary>
336342

337343
1. Create a GitHub OAuth App:
344+
338345
- Go to your GitHub account settings.
339346
- Navigate to `Developer settings` > `OAuth Apps` > `New OAuth App`.
340347
- Fill in the application details:
@@ -349,7 +356,7 @@ You'll need to set up the following services for local development. If you're no
349356
- Select `Use custom credentials`
350357
- Enter your `Client ID` and `Client Secret` from the GitHub OAuth app you just created.
351358
- Add `repo` to the `Scopes`
352-
![Clerk Custom Credentials](https://github.com/user-attachments/assets/31d414e1-4e1e-4725-8649-ec1826c6e53e)
359+
![Clerk Custom Credentials](https://github.com/user-attachments/assets/31d414e1-4e1e-4725-8649-ec1826c6e53e)
353360

354361
</details>
355362

lib/config/index.ts

+38-10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ const CONFIG_FILE_PATH = "shortest.yml";
1111

1212
let config: Readonly<Config> = Object.freeze({});
1313

14+
/**
15+
* Loads configuration file.
16+
*
17+
* @throws {Error} When configuration file cannot be parsed
18+
*
19+
* @private
20+
*/
1421
async function loadConfig(): Promise<void> {
1522
try {
1623
const fileContents = await fs.readFile(CONFIG_FILE_PATH, "utf8");
@@ -37,14 +44,32 @@ async function loadConfig(): Promise<void> {
3744
}
3845
}
3946

40-
async function getConfig(): Promise<Readonly<Config>> {
47+
/**
48+
* Returns the current configuration, loading it if necessary.
49+
*
50+
* @returns {Promise<Readonly<Config>>} Frozen configuration object
51+
* @throws {Error} When configuration cannot be loaded
52+
*
53+
* @private
54+
*/
55+
export async function getConfig(): Promise<Readonly<Config>> {
4156
if (Object.keys(config).length === 0) {
4257
await loadConfig();
4358
}
4459
return config;
4560
}
4661

47-
async function getRepoConfig({
62+
/**
63+
* Gets repository-specific configuration.
64+
*
65+
* @param {Object} params - Repository parameters
66+
* @param {string} params.owner - Repository owner
67+
* @param {string} params.repo - Repository name
68+
* @returns {Promise<RepositoryConfig>} Repository configuration
69+
*
70+
* @private
71+
*/
72+
export async function getRepoConfig({
4873
owner,
4974
repo,
5075
}: {
@@ -58,7 +83,17 @@ async function getRepoConfig({
5883
);
5984
}
6085

61-
async function getTestPatternsConfig({
86+
/**
87+
* Gets test patterns configuration for a repository.
88+
*
89+
* @param {Object} params - Repository parameters
90+
* @param {string} params.owner - Repository owner
91+
* @param {string} params.repo - Repository name
92+
* @returns {Promise<RepositoryConfig["test_patterns"]>} Test patterns configuration
93+
*
94+
* @private
95+
*/
96+
export async function getTestPatternsConfig({
6297
owner,
6398
repo,
6499
}: {
@@ -68,10 +103,3 @@ async function getTestPatternsConfig({
68103
const repoConfig = await getRepoConfig({ owner, repo });
69104
return repoConfig.test_patterns;
70105
}
71-
72-
export { getConfig, getRepoConfig, getTestPatternsConfig };
73-
74-
// Add this export for testing
75-
export function _resetConfigForTesting(): void {
76-
config = Object.freeze({});
77-
}

packages/shortest/README.md

+14-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
AI-powered natural language end-to-end testing framework.
44

55
## Features
6+
67
- Natural language test writing
78
- AI-powered test execution using Claude computer use API
89
- Built on Playwright
@@ -19,9 +20,11 @@ npx @antiwork/shortest init
1920
```
2021

2122
This will:
23+
2224
- Automatically install the `@antiwork/shortest` package as a dev dependency if it is not already installed
2325
- Create a default `shortest.config.ts` file with boilerplate configuration
24-
- Generate a `.env.local` file (unless present) with placeholders for required environment variables, such as `ANTHROPIC_API_KEY`
26+
- Generate a `.env.local` file (unless present) with placeholders for required environment variables, such as
27+
`SHORTEST_ANTHROPIC_API_KEY` or `ANTHROPIC_API_KEY`
2528
- Add `.env.local` and `.shortest/` to `.gitignore`
2629

2730
### Quick start
@@ -35,9 +38,13 @@ export default {
3538
headless: false,
3639
baseUrl: "http://localhost:3000",
3740
testPattern: "**/*.test.ts",
38-
anthropicKey: process.env.ANTHROPIC_API_KEY,
41+
ai: {
42+
provider: "anthropic",
43+
},
3944
} satisfies ShortestConfig;
4045
```
46+
Anthropic API key will default to `SHORTEST_ANTHROPIC_API_KEY` / `ANTHROPIC_API_KEY` environment variables. Can be overwritten via `ai.config.apiKey`.
47+
4148

4249
2. Create test files using the pattern specified in the config: `app/login.test.ts`
4350

@@ -217,11 +224,13 @@ GITHUB_TOTP_SECRET=your_secret # Only for GitHub auth tests
217224
You can run Shortest in your CI/CD pipeline by running tests in headless mode. Make sure to add your Anthropic API key to your CI/CD pipeline secrets.
218225

219226
## Resources
220-
* Visit [GitHub](https://github.com/anti-work/shortest) for detailed docs
221-
* [Contributing guide](./CONTRIBUTING.md)
222-
* [Changelog](https://github.com/anti-work/shortest/releases)
227+
228+
- Visit [GitHub](https://github.com/anti-work/shortest) for detailed docs
229+
- [Contributing guide](./CONTRIBUTING.md)
230+
- [Changelog](https://github.com/anti-work/shortest/releases)
223231

224232
### Prerequisites
233+
225234
- React >=19.0.0 (if using with Next.js 14+ or Server Actions)
226235
- Next.js >=14.0.0 (if using Server Components/Actions)
227236

packages/shortest/package.json

+7-5
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727
"prepare": "pnpm build",
2828
"prepublishOnly": "pnpm build",
2929
"postinstall": "node -e \"if (process.platform !== 'win32') { try { require('child_process').execSync('chmod +x dist/cli/bin.js') } catch (_) {} }\"",
30-
"build:types": "tsup src/index.ts --dts-only --format esm --outDir dist",
31-
"build:js": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:esbuild --external:punycode --external:playwright --external:@anthropic-ai/sdk --external:expect --external:dotenv",
32-
"build:cjs": "esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/index.cjs --external:esbuild --external:punycode --external:playwright --external:@anthropic-ai/sdk --external:expect --external:dotenv",
33-
"build:cli": "esbuild src/cli/bin.ts --bundle --platform=node --format=esm --outdir=dist/cli --metafile=dist/meta-cli.json --external:fsevents --external:chokidar --external:glob --external:esbuild --external:events --external:path --external:fs --external:util --external:stream --external:os --external:assert --external:url --external:playwright --external:@anthropic-ai/sdk --external:expect --external:dotenv --external:otplib --external:picocolors --external:punycode --external:https --external:http --external:net --external:tls --external:crypto --external:mailosaur",
30+
"build:types": "tsup src/index.ts --dts-only --format esm --outDir dist",
31+
"build:js": "esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:esbuild --external:punycode --external:playwright --external:expect --external:dotenv --external:ai --external:@ai-sdk/*",
32+
"build:cjs": "esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dist/index.cjs --external:esbuild --external:punycode --external:playwright --external:expect --external:dotenv --external:ai --external:@ai-sdk/*",
33+
"build:cli": "esbuild src/cli/bin.ts --bundle --platform=node --format=esm --outdir=dist/cli --metafile=dist/meta-cli.json --external:fsevents --external:chokidar --external:glob --external:esbuild --external:events --external:path --external:fs --external:util --external:stream --external:os --external:assert --external:url --external:playwright --external:expect --external:dotenv --external:otplib --external:picocolors --external:punycode --external:https --external:http --external:net --external:tls --external:crypto --external:mailosaur --external:ai --external:@ai-sdk/*",
3434
"dev": "pnpm build --watch",
3535
"test:unit": "npx vitest run",
3636
"test:unit:watch": "npx vitest --watch",
@@ -57,7 +57,9 @@
5757
"node": ">=18"
5858
},
5959
"peerDependencies": {
60-
"@anthropic-ai/sdk": "^0.32.0",
60+
"@ai-sdk/anthropic": "^1.1.8",
61+
"@ai-sdk/provider": "^1.0.7",
62+
"ai": "^3.4.0",
6163
"dotenv": "^16.4.5",
6264
"esbuild": "^0.20.1",
6365
"expect": "^29.7.0",

0 commit comments

Comments
 (0)