diff --git a/apps/website/project.json b/apps/website/project.json index af8c7f438..5f2e49997 100644 --- a/apps/website/project.json +++ b/apps/website/project.json @@ -64,6 +64,12 @@ ] }, "e2e": { + "executor": "nx:run-commands", + "options": { + "command": "npx tsx apps/website/scripts/run-e2e-with-next-env-restore.ts -- npx nx run website:e2e-playwright --skip-nx-cache" + } + }, + "e2e-playwright": { "executor": "@nx/playwright:playwright", "options": { "config": "apps/website/playwright.config.ts" diff --git a/apps/website/scripts/run-e2e-with-next-env-restore.ts b/apps/website/scripts/run-e2e-with-next-env-restore.ts new file mode 100644 index 000000000..aeeaf9603 --- /dev/null +++ b/apps/website/scripts/run-e2e-with-next-env-restore.ts @@ -0,0 +1,48 @@ +import { spawn } from 'node:child_process'; +import { writeFile } from 'node:fs/promises'; +import { fileURLToPath } from 'node:url'; + +const CANONICAL_NEXT_ENV = `/// +/// +import "./../../dist/apps/website/.next/types/routes.d.ts"; + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. +`; + +async function restoreNextEnv(): Promise { + await writeFile(new URL('../next-env.d.ts', import.meta.url), CANONICAL_NEXT_ENV); +} + +function run(command: string, args: string[]): Promise { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { stdio: 'inherit' }); + child.on('error', reject); + child.on('close', (code) => resolve(code)); + }); +} + +async function main(): Promise { + const separator = process.argv.indexOf('--'); + const commandLine = separator === -1 ? process.argv.slice(2) : process.argv.slice(separator + 1); + const [command, ...args] = commandLine; + + if (!command) { + throw new Error('Expected a command after --'); + } + + let exitCode: number | null = 1; + try { + exitCode = await run(command, args); + } finally { + await restoreNextEnv(); + } + process.exitCode = exitCode ?? 1; +} + +if (process.argv[1] === fileURLToPath(import.meta.url)) { + main().catch((error: unknown) => { + console.error(error); + process.exitCode = 1; + }); +} diff --git a/libs/middleware/src/integration.spec.ts b/libs/middleware/src/integration.spec.ts index ef3a62720..e0e03c1b0 100644 --- a/libs/middleware/src/integration.spec.ts +++ b/libs/middleware/src/integration.spec.ts @@ -9,7 +9,8 @@ class FakeModel { bound: unknown[] = []; private turn = 0; bindTools(tools: unknown[]) { this.bound = tools; return this; } - async invoke(_messages: unknown[]) { + async invoke(messages: unknown[]) { + void messages; this.turn += 1; if (this.turn === 1) { return new AIMessage({ content: '', tool_calls: [{ name: 'get_weather', args: { city: 'SF' }, id: 'call_1' }] }); diff --git a/libs/telemetry/src/node/postinstall.spec.ts b/libs/telemetry/src/node/postinstall.spec.ts index 5bb498ec7..e859283ca 100644 --- a/libs/telemetry/src/node/postinstall.spec.ts +++ b/libs/telemetry/src/node/postinstall.spec.ts @@ -80,7 +80,7 @@ describe('postinstall script', () => { await expect( capturePostinstallScript({ readPackageJson: () => { throw new Error('not found'); }, - write: (_s: string) => undefined, + write: () => undefined, env: { ...process.env }, cwd: () => '/tmp/project/node_modules/@threadplane/telemetry', }), @@ -103,7 +103,7 @@ describe('postinstall script', () => { test('skips local top-level installs by default', async () => { await capturePostinstallScript({ readPackageJson: () => ({ name: '@threadplane/chat', version: '0.0.31' }), - write: (_s: string) => undefined, + write: () => undefined, env: { ...process.env, INIT_CWD: '/repo/libs/chat' }, cwd: () => '/repo/libs/chat', }); @@ -118,7 +118,7 @@ describe('postinstall script', () => { symlinkSync(root, link, 'dir'); await capturePostinstallScript({ readPackageJson: () => ({ name: '@threadplane/chat', version: '0.0.31' }), - write: (_s: string) => undefined, + write: () => undefined, env: { ...process.env, INIT_CWD: join(link, 'pkg') }, cwd: () => join(root, 'pkg'), }); @@ -132,7 +132,7 @@ describe('postinstall script', () => { test('allows global installs even when INIT_CWD matches cwd', async () => { await capturePostinstallScript({ readPackageJson: () => ({ name: '@threadplane/chat', version: '0.0.31' }), - write: (_s: string) => undefined, + write: () => undefined, env: { ...process.env, INIT_CWD: '/repo/libs/chat', npm_config_global: 'true' }, cwd: () => '/repo/libs/chat', }); diff --git a/package-lock.json b/package-lock.json index 7aa26eb8f..886f4d15d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,7 +61,7 @@ "@angular/elements": "~21.1.0", "@angular/language-service": "~21.1.0", "@anthropic-ai/sdk": "^0.79.0", - "@copilotkit/aimock": "^1.23.0", + "@copilotkit/aimock": "^1.35.1", "@eslint/js": "^9.8.0", "@json-render/core": "^0.16.0", "@langchain/langgraph": "^1.4.2", @@ -7287,9 +7287,9 @@ "license": "MIT" }, "node_modules/@copilotkit/aimock": { - "version": "1.23.0", - "resolved": "https://registry.npmjs.org/@copilotkit/aimock/-/aimock-1.23.0.tgz", - "integrity": "sha512-9DDFk5sL9cMCq4aphDHM4j0BMAkmEtdMvkmbq4BUUiVZONd0gMy8B9qlbsbKW9REAQsKTQeTRnsfoxafieNayA==", + "version": "1.35.1", + "resolved": "https://registry.npmjs.org/@copilotkit/aimock/-/aimock-1.35.1.tgz", + "integrity": "sha512-d+bJFOGjydly9ayh6kK3bhj6m8xskz5Z/G/kSAvcK1WJ2OwRgMjnSG+9nv7INyBmx+5P1DIBg85+ua1Hd5tlNw==", "dev": true, "license": "MIT", "bin": { @@ -7297,7 +7297,7 @@ "llmock": "dist/cli.js" }, "engines": { - "node": ">=24.0.0" + "node": ">=20.15.0" }, "peerDependencies": { "jest": ">=29", diff --git a/package.json b/package.json index ecdfb9661..3d4bbc089 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "@angular/elements": "~21.1.0", "@angular/language-service": "~21.1.0", "@anthropic-ai/sdk": "^0.79.0", - "@copilotkit/aimock": "^1.23.0", + "@copilotkit/aimock": "^1.35.1", "@eslint/js": "^9.8.0", "@json-render/core": "^0.16.0", "@langchain/langgraph": "^1.4.2",