refactor(deps-dev): bump vitest from 3.2.4 to 4.1.8 (#7581)
## Thinking Path > - Paperclip orchestrates AI agents for zero-human companies > - Test infrastructure across server, ui, packages/* runs on Vitest > - Dependabot opened a narrow bump (3.2.4 → 3.2.6), but the wider workspace is on 3.2.4 and the major-version bridge to v4 needs a coordinated change set across configs and tests > - Staying on 3.x indefinitely leaves us behind on Vitest 4 (perf, pool, and config improvements) and forces repeated patch-only dependabot churn > - This pull request upgrades Vitest to 4.1.8 across the workspace, updates `server/vitest.config.ts` and `scripts/run-vitest-stable.mjs` for the new API, and adjusts two UI tests for the new assertion semantics > - The benefit is a single, coherent Vitest 4 upgrade that supersedes #7570 and gets us on the supported major line ## What Changed - Bump `vitest` from `3.2.4` to `4.1.8` across root, `server`, `ui`, and all `packages/*` (including plugin examples and sandbox providers) - Update `server/vitest.config.ts` for Vitest 4 config surface - Update `scripts/run-vitest-stable.mjs` to match the new runner behavior - Adjust `ui/src/components/CommentThread.test.tsx` and `ui/src/components/MarkdownEditor.test.tsx` for Vitest 4 matcher/timing semantics - Refresh `pnpm-lock.yaml` ## Verification - `pnpm install` resolves cleanly with the new lockfile - `pnpm -w -r test` (server, ui, packages) runs under Vitest 4.1.8 ## Risks - Major-version Vitest bump: behavioral changes in pools, fake timers, and matcher strictness can surface flake. Test config and the two UI tests were updated to match v4 semantics; broader test runs should be watched on CI before merge. - Supersedes dependabot PR #7570 (3.2.4 → 3.2.6); that PR should be closed. ## Model Used - Claude (Anthropic) — `claude-opus-4-7`, extended thinking, tool use enabled ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [ ] I have run tests locally and they pass - [ ] I have added or updated tests where applicable - [ ] If this change affects the UI, I have included before/after screenshots - [ ] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] I will address all Greptile and reviewer comments before requesting merge Closes #7570
This commit is contained in:
@@ -308,15 +308,20 @@ jobs:
|
|||||||
# `--skip-verify` bypasses the initial verification gate. release.sh
|
# `--skip-verify` bypasses the initial verification gate. release.sh
|
||||||
# also requires a clean working tree, so any in-place lockfile churn
|
# also requires a clean working tree, so any in-place lockfile churn
|
||||||
# from `pnpm install --frozen-lockfile` must be reverted first — unless
|
# from `pnpm install --frozen-lockfile` must be reverted first — unless
|
||||||
# the policy job uploaded a regenerated lockfile (manifest-only PRs),
|
# the policy job uploaded a regenerated lockfile (manifest-changing
|
||||||
# in which case we keep the artifact-restored copy so the workspace
|
# PRs), in which case we stage the artifact-restored copy into an
|
||||||
# build sees a lockfile that matches the manifest.
|
# ephemeral local commit so release.sh sees a clean tree and its
|
||||||
|
# workspace build sees a lockfile that matches the manifest.
|
||||||
- name: Release canary dry run via release.sh internal build
|
- name: Release canary dry run via release.sh internal build
|
||||||
env:
|
env:
|
||||||
USED_ARTIFACT_LOCKFILE: ${{ needs.policy.outputs.lockfile_regenerated || '0' }}
|
USED_ARTIFACT_LOCKFILE: ${{ needs.policy.outputs.lockfile_regenerated || '0' }}
|
||||||
run: |
|
run: |
|
||||||
git checkout -B master HEAD
|
git checkout -B master HEAD
|
||||||
if [ "$USED_ARTIFACT_LOCKFILE" != "1" ]; then
|
if [ "$USED_ARTIFACT_LOCKFILE" = "1" ]; then
|
||||||
|
git add pnpm-lock.yaml
|
||||||
|
git -c user.email=ci@paperclip.local -c user.name=CI \
|
||||||
|
commit --no-verify -m "ci(canary): stage regenerated lockfile"
|
||||||
|
else
|
||||||
git checkout -- pnpm-lock.yaml
|
git checkout -- pnpm-lock.yaml
|
||||||
fi
|
fi
|
||||||
./scripts/release.sh canary --skip-verify --dry-run
|
./scripts/release.sh canary --skip-verify --dry-run
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ describe("skills CLI commands", () => {
|
|||||||
"http://paperclip.test/api/skills/catalog?kind=bundled&category=software-development&q=github",
|
"http://paperclip.test/api/skills/catalog?kind=bundled&category=software-development&q=github",
|
||||||
expect.objectContaining({ method: "GET" }),
|
expect.objectContaining({ method: "GET" }),
|
||||||
);
|
);
|
||||||
const rendered = logSpy.mock.calls.map((call) => String(call[0])).join("\n");
|
const rendered = logSpy.mock.calls.map((call: unknown[]) => String(call[0])).join("\n");
|
||||||
expect(rendered).toContain("id");
|
expect(rendered).toContain("id");
|
||||||
expect(rendered).toContain("paperclipai:bundled:software-development:github-pr-workflow");
|
expect(rendered).toContain("paperclipai:bundled:software-development:github-pr-workflow");
|
||||||
expect(rendered).toContain("roles");
|
expect(rendered).toContain("roles");
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ describe("teams CLI commands", () => {
|
|||||||
"http://paperclip.test/api/teams/catalog?kind=bundled&category=software-development&q=engineering",
|
"http://paperclip.test/api/teams/catalog?kind=bundled&category=software-development&q=engineering",
|
||||||
expect.objectContaining({ method: "GET" }),
|
expect.objectContaining({ method: "GET" }),
|
||||||
);
|
);
|
||||||
const rendered = logSpy.mock.calls.map((call) => String(call[0])).join("\n");
|
const rendered = logSpy.mock.calls.map((call: unknown[]) => String(call[0])).join("\n");
|
||||||
expect(rendered).toContain("id");
|
expect(rendered).toContain("id");
|
||||||
expect(rendered).toContain("paperclipai:bundled:software-development:product-engineering");
|
expect(rendered).toContain("paperclipai:bundled:software-development:product-engineering");
|
||||||
});
|
});
|
||||||
@@ -188,7 +188,7 @@ describe("teams CLI commands", () => {
|
|||||||
"http://paperclip.test/api/companies/company-1/teams/catalog/installed",
|
"http://paperclip.test/api/companies/company-1/teams/catalog/installed",
|
||||||
expect.objectContaining({ method: "GET" }),
|
expect.objectContaining({ method: "GET" }),
|
||||||
);
|
);
|
||||||
const rendered = logSpy.mock.calls.map((call) => String(call[0])).join("\n");
|
const rendered = logSpy.mock.calls.map((call: unknown[]) => String(call[0])).join("\n");
|
||||||
expect(rendered).toContain("installedStatus");
|
expect(rendered).toContain("installedStatus");
|
||||||
expect(rendered).toContain("out_of_date");
|
expect(rendered).toContain("out_of_date");
|
||||||
expect(rendered).toContain("not_installed");
|
expect(rendered).toContain("not_installed");
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@
|
|||||||
"cross-env": "^10.1.0",
|
"cross-env": "^10.1.0",
|
||||||
"esbuild": "^0.28.0",
|
"esbuild": "^0.28.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
|
|||||||
@@ -54,6 +54,6 @@
|
|||||||
"drizzle-kit": "^0.31.9",
|
"drizzle-kit": "^0.31.9",
|
||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
"rollup": "^4.61.1",
|
"rollup": "^4.61.1",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=18"
|
"react": ">=18"
|
||||||
|
|||||||
@@ -38,7 +38,7 @@
|
|||||||
"rollup": "^4.61.1",
|
"rollup": "^4.61.1",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=18"
|
"react": ">=18"
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
"rollup": "^4.61.1",
|
"rollup": "^4.61.1",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=18"
|
"react": ">=18"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=18",
|
"react": ">=18",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@cloudflare/workers-types": "^4.20260501.0",
|
"@cloudflare/workers-types": "^4.20260501.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4",
|
"vitest": "^4.1.8",
|
||||||
"wrangler": "^4.15.0"
|
"wrangler": "^4.15.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^24.6.0",
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
"zod": "^3.24.2"
|
"zod": "^3.24.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/node": "^24.6.0",
|
||||||
"typescript": "^5.7.3"
|
"typescript": "^5.7.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,8 @@
|
|||||||
"test": "pnpm -w exec vitest run --root packages/skills-catalog --config vitest.config.ts",
|
"test": "pnpm -w exec vitest run --root packages/skills-catalog --config vitest.config.ts",
|
||||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||||
"validate": "node ../../cli/node_modules/tsx/dist/cli.mjs scripts/validate-catalog.ts"
|
"validate": "node ../../cli/node_modules/tsx/dist/cli.mjs scripts/validate-catalog.ts"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^24.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,8 @@
|
|||||||
"test": "pnpm -w exec vitest run --root packages/teams-catalog --config vitest.config.ts",
|
"test": "pnpm -w exec vitest run --root packages/teams-catalog --config vitest.config.ts",
|
||||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||||
"validate": "node ../../cli/node_modules/tsx/dist/cli.mjs scripts/validate-catalog.ts"
|
"validate": "node ../../cli/node_modules/tsx/dist/cli.mjs scripts/validate-catalog.ts"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^24.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ const generalGroupNames = [generalServerGroupName, generalWorkspacesAGroupName,
|
|||||||
const serializedServerVitestArgs = [
|
const serializedServerVitestArgs = [
|
||||||
"--no-file-parallelism",
|
"--no-file-parallelism",
|
||||||
"--maxWorkers=1",
|
"--maxWorkers=1",
|
||||||
"--minWorkers=1",
|
|
||||||
];
|
];
|
||||||
|
|
||||||
function walk(dir) {
|
function walk(dir) {
|
||||||
@@ -322,7 +321,7 @@ function runSerializedSuites(routeTests, shardIndex, shardCount) {
|
|||||||
"@paperclipai/server",
|
"@paperclipai/server",
|
||||||
routeTest.repoPath,
|
routeTest.repoPath,
|
||||||
"--pool=forks",
|
"--pool=forks",
|
||||||
"--poolOptions.forks.isolate=true",
|
"--isolate",
|
||||||
],
|
],
|
||||||
routeTest.repoPath,
|
routeTest.repoPath,
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-1
@@ -93,6 +93,6 @@
|
|||||||
"tsx": "^4.19.2",
|
"tsx": "^4.19.2",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vite": "^6.1.0",
|
"vite": "^6.1.0",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,6 @@ export default defineConfig({
|
|||||||
maxWorkers: 1,
|
maxWorkers: 1,
|
||||||
minWorkers: 1,
|
minWorkers: 1,
|
||||||
pool: "forks",
|
pool: "forks",
|
||||||
poolOptions: {
|
|
||||||
forks: {
|
|
||||||
isolate: true,
|
|
||||||
maxForks: 1,
|
|
||||||
minForks: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
sequence: {
|
sequence: {
|
||||||
concurrent: false,
|
concurrent: false,
|
||||||
hooks: "list",
|
hooks: "list",
|
||||||
|
|||||||
+1
-1
@@ -79,6 +79,6 @@
|
|||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"storybook": "10.3.5",
|
"storybook": "10.3.5",
|
||||||
"vite": "^6.1.0",
|
"vite": "^6.1.0",
|
||||||
"vitest": "^3.0.5"
|
"vitest": "^4.1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,16 +61,16 @@ vi.mock("@/plugins/slots", () => ({
|
|||||||
|
|
||||||
describe("CommentThread", () => {
|
describe("CommentThread", () => {
|
||||||
let container: HTMLDivElement;
|
let container: HTMLDivElement;
|
||||||
let writeTextMock: ReturnType<typeof vi.fn>;
|
let writeTextMock: ReturnType<typeof vi.fn<(text: string) => Promise<void>>>;
|
||||||
let execCommandMock: ReturnType<typeof vi.fn>;
|
let execCommandMock: ReturnType<typeof vi.fn<typeof document.execCommand>>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
container = document.createElement("div");
|
container = document.createElement("div");
|
||||||
document.body.appendChild(container);
|
document.body.appendChild(container);
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
vi.setSystemTime(new Date("2026-03-11T12:00:00.000Z"));
|
vi.setSystemTime(new Date("2026-03-11T12:00:00.000Z"));
|
||||||
writeTextMock = vi.fn(async () => {});
|
writeTextMock = vi.fn<(text: string) => Promise<void>>(async () => {});
|
||||||
execCommandMock = vi.fn(() => true);
|
execCommandMock = vi.fn<typeof document.execCommand>(() => true);
|
||||||
Object.assign(navigator, {
|
Object.assign(navigator, {
|
||||||
clipboard: {
|
clipboard: {
|
||||||
writeText: writeTextMock,
|
writeText: writeTextMock,
|
||||||
|
|||||||
@@ -685,7 +685,7 @@ describe("MarkdownEditor", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function openMentionMenuFor(
|
async function openMentionMenuFor(
|
||||||
handleChange: ReturnType<typeof vi.fn>,
|
handleChange: ReturnType<typeof vi.fn<(value: string) => void>>,
|
||||||
mentions = [
|
mentions = [
|
||||||
{
|
{
|
||||||
id: "project:project-123",
|
id: "project:project-123",
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ describe("IssueDetail", () => {
|
|||||||
expect(container.textContent).toContain("Issue detail smoke");
|
expect(container.textContent).toContain("Issue detail smoke");
|
||||||
expect(container.textContent).toContain("Chat thread");
|
expect(container.textContent).toContain("Chat thread");
|
||||||
expect(
|
expect(
|
||||||
consoleErrorSpy.mock.calls.some((call) =>
|
consoleErrorSpy.mock.calls.some((call: unknown[]) =>
|
||||||
String(call[0]).includes("React has detected a change in the order of Hooks"),
|
String(call[0]).includes("React has detected a change in the order of Hooks"),
|
||||||
),
|
),
|
||||||
).toBe(false);
|
).toBe(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user