From c1e31514ff08fc1bbb33a1e78de3e6a97f89b56f Mon Sep 17 00:00:00 2001 From: Chris Scott <99081550+chriswritescode-dev@users.noreply.github.com> Date: Sat, 6 Jun 2026 13:32:42 -0400 Subject: [PATCH] chore: unify vitest config across the project --- bun.lock | 71 +---- bunfig.toml | 50 ---- package.json | 6 +- pnpm-lock.yaml | 254 ++---------------- pnpm-workspace.yaml | 2 - test/__shims__/bun-sqlite.mjs | 53 +++- test/__shims__/bun-test.mjs | 20 -- test/agent-tools-map.test.ts | 2 +- test/agents.test.ts | 2 +- test/audit-session.test.ts | 32 +-- test/config.test.ts | 2 +- test/dashboard/data.test.ts | 2 +- test/dashboard/launch.test.ts | 33 ++- test/dashboard/render.test.ts | 2 +- test/dashboard/server.test.ts | 2 +- test/helpers/loops-test-db.ts | 1 + test/hooks.test.ts | 2 +- test/hooks/loop-event-gate.test.ts | 2 +- test/hooks/loop-final-audit-rewind.test.ts | 2 +- test/hooks/loop-section-advancement.test.ts | 2 +- test/hooks/loop-section-audit-retry.test.ts | 2 +- test/loop-findings-gate.test.ts | 2 +- test/loop-format.test.ts | 2 +- test/loop-helpers.test.ts | 2 +- test/loop-permission-ruleset.test.ts | 46 ++-- test/loop-plan-text.test.ts | 2 +- test/loop-runtime-audit-permissions.test.ts | 2 +- test/loop-service-notify.test.ts | 2 +- test/loop-service.test.ts | 2 +- test/loop-session-usage-repo.test.ts | 2 +- test/loop-status-tool.test.ts | 2 +- test/loop/cancel.test.ts | 2 +- test/loop/runtime.test.ts | 6 +- test/loop/start.test.ts | 2 +- test/loop/token-usage.test.ts | 2 +- test/loops-repo.test.ts | 2 +- test/lru-cache.test.ts | 2 +- test/parent-session-lookup.test.ts | 2 +- test/partial-match.test.ts | 2 +- test/plan-approval.test.ts | 2 +- test/plan-capture.test.ts | 2 +- test/plan-kv.test.ts | 2 +- test/plans-repo.test.ts | 2 +- test/plugin.test.ts | 2 +- test/resolve-project-root.test.ts | 2 +- test/review-findings-repo.test.ts | 2 +- test/review.test.ts | 2 +- test/sandbox-docker.test.ts | 2 +- test/sandbox-manager.test.ts | 2 +- test/sandbox-path.test.ts | 2 +- test/sandbox-tools.test.ts | 2 +- test/sandbox/manager.test.ts | 26 +- test/sandbox/reconcile.test.ts | 30 +-- test/section-management.test.ts | 2 +- test/section-plans-repo.test.ts | 2 +- test/services/attach-loop.test.ts | 36 +-- .../services/execution-attach-cleanup.test.ts | 2 +- .../execution-in-flight-guard.test.ts | 2 +- test/services/execution-restart.test.ts | 3 +- test/services/parse-section-summary.test.ts | 2 +- test/session-loop-resolver.test.ts | 2 +- test/session-titles.test.ts | 2 +- test/setup.test.ts | 19 +- test/storage-database.test.ts | 2 +- test/storage-migrations.test.ts | 2 +- test/storage-sweep.test.ts | 2 +- test/tool-blocking.test.ts | 2 +- test/tools/bash.test.ts | 2 +- test/tools/bash/truncate.test.ts | 2 +- test/tools/index-bash-registration.test.ts | 2 +- test/tools/review-section-scope.test.ts | 2 +- test/tools/section-read.test.ts | 2 +- test/tui-execution-preferences.test.ts | 2 +- test/tui-models.test.ts | 26 +- test/utils/loop-session.test.ts | 2 +- test/utils/model-fallback.test.ts | 2 +- test/utils/plan-from-messages.test.ts | 38 +-- test/utils/sandbox-ready.test.ts | 2 +- .../utils/tui-execution-context-cache.test.ts | 2 +- test/watchdog.test.ts | 2 +- test/workspace-recovery.test.ts | 2 +- test/workspace/forge-adapter-e2e.test.ts | 4 +- test/workspace/forge-adapter.test.ts | 14 +- test/worktree-log.test.ts | 2 +- vitest.config.ts | 78 +----- 85 files changed, 303 insertions(+), 671 deletions(-) delete mode 100644 bunfig.toml delete mode 100644 test/__shims__/bun-test.mjs diff --git a/bun.lock b/bun.lock index ba73638d09..b52762f053 100644 --- a/bun.lock +++ b/bun.lock @@ -19,7 +19,6 @@ "@types/node": "^25.6.0", "@typescript-eslint/eslint-plugin": "^8.58.0", "@typescript-eslint/parser": "^8.58.0", - "better-sqlite3": "^12.9.0", "bun-types": "latest", "eslint": "^10.2.0", "eslint-plugin-solid": "^0.14.5", @@ -413,19 +412,13 @@ "baseline-browser-mapping": ["baseline-browser-mapping@2.10.12", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ=="], - "better-sqlite3": ["better-sqlite3@12.10.0", "", { "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, "sha512-CyzaZRQKyHkB2ZInfTTl2nvT33EbDpjkLEbE8/Zck3Ll6O0qqvuGdrJ45HgtH+HykRg88ITY3AdreBGN70aBSQ=="], - - "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="], - - "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="], - "bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="], "brace-expansion": ["brace-expansion@5.0.5", "", { "dependencies": { "balanced-match": "4.0.4" } }, "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ=="], "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "2.10.12", "caniuse-lite": "1.0.30001782", "electron-to-chromium": "1.5.328", "node-releases": "2.0.36", "update-browserslist-db": "1.2.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], - "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="], + "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "1.5.1", "ieee754": "1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], "bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "5.9.3" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="], @@ -449,8 +442,6 @@ "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], - "chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="], - "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "3.1.1", "shebang-command": "2.0.0", "which": "2.0.2" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], @@ -459,12 +450,8 @@ "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="], - "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], - "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], - "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], @@ -477,8 +464,6 @@ "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], - "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="], - "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], @@ -515,8 +500,6 @@ "exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="], - "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], - "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], "fast-check": ["fast-check@4.7.0", "", { "dependencies": { "pure-rand": "^8.0.0" } }, "sha512-NsZRtqvSSoCP0HbNjUD+r1JH8zqZalyp6gLY9e7OYs7NK9b6AHOs2baBFeBG7bVNsuoukh89x2Yg3rPsul8ziQ=="], @@ -533,8 +516,6 @@ "file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "3.0.4", "strtok3": "6.3.0", "token-types": "4.2.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="], - "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="], - "find-babel-config": ["find-babel-config@2.1.2", "", { "dependencies": { "json5": "2.2.3" } }, "sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg=="], "find-my-way-ts": ["find-my-way-ts@0.1.6", "", {}, "sha512-a85L9ZoXtNAey3Y6Z+eBWW658kO/MwR7zIafkIUPUMf3isZG0NCs2pjW2wtjxAKuJPxMAsHUIP4ZPGv0o5gyTA=="], @@ -545,8 +526,6 @@ "flatted": ["flatted@3.4.2", "", {}, "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA=="], - "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="], - "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -559,8 +538,6 @@ "gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "4.0.0", "omggif": "1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="], - "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="], - "glob": ["glob@9.3.5", "", { "dependencies": { "fs.realpath": "1.0.0", "minimatch": "8.0.7", "minipass": "4.2.8", "path-scurry": "1.11.1" } }, "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q=="], "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], @@ -579,8 +556,6 @@ "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], - "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], - "ini": ["ini@6.0.0", "", {}, "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ=="], "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="], @@ -643,16 +618,10 @@ "mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], - "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="], - "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], - "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], - "minipass": ["minipass@4.2.8", "", {}, "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="], - "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="], - "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "msgpackr": ["msgpackr@1.11.9", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.2" } }, "sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw=="], @@ -663,20 +632,14 @@ "nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="], - "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="], - "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], - "node-abi": ["node-abi@3.92.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ=="], - "node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="], "node-releases": ["node-releases@2.0.36", "", {}, "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA=="], "omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="], - "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "0.1.4", "fast-levenshtein": "2.0.6", "levn": "0.4.1", "prelude-ls": "1.2.1", "type-check": "0.4.0", "word-wrap": "1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], @@ -723,23 +686,17 @@ "postcss": ["postcss@8.5.13", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag=="], - "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="], - "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="], - "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="], - "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], "pure-rand": ["pure-rand@8.4.0", "", {}, "sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A=="], - "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], - - "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], + "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "3.0.0", "buffer": "6.0.3", "events": "3.3.0", "process": "0.11.10", "string_decoder": "1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="], @@ -767,10 +724,6 @@ "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], - "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="], - - "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="], - "simple-xml-to-json": ["simple-xml-to-json@1.2.4", "", {}, "sha512-3MY16e0ocMHL7N1ufpdObURGyX+lCo0T/A+y6VCwosLdH1HSda4QZl1Sdt/O+2qWp48WFi26XEp5rF0LoaL0Dg=="], "solid-js": ["solid-js@1.9.12", "", { "dependencies": { "csstype": "3.2.3", "seroval": "1.5.1", "seroval-plugins": "1.5.1" } }, "sha512-QzKaSJq2/iDrWR1As6MHZQ8fQkdOBf8GReYb7L5iKwMGceg7HxDcaOHk0at66tNgn9U2U7dXo8ZZpLIAmGMzgw=="], @@ -789,18 +742,12 @@ "strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], - "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], - "strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "0.3.0", "peek-readable": "4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="], "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="], "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="], - - "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], - "three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="], "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], @@ -823,8 +770,6 @@ "ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": "5.9.3" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="], - "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="], - "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "typedoc": ["typedoc@0.28.19", "", { "dependencies": { "@gerrit0/mini-shiki": "^3.23.0", "lunr": "^2.3.9", "markdown-it": "^14.1.1", "minimatch": "^10.2.5", "yaml": "^2.8.3" }, "peerDependencies": { "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x" }, "bin": { "typedoc": "bin/typedoc" } }, "sha512-wKh+lhdmMFivMlc6vRRcMGXeGEHGU2g8a2CkPTJjJlwRf1iXbimWIPcFolCqe4E0d/FRtGszpIrsp3WLpDB8Pw=="], @@ -845,8 +790,6 @@ "utif2": ["utif2@4.1.0", "", { "dependencies": { "pako": "1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="], - "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], - "uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="], "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], @@ -863,8 +806,6 @@ "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], - "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], - "xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="], "xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": "1.6.0", "xmlbuilder": "11.0.1" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], @@ -931,8 +872,6 @@ "markdown-it/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "node-abi/semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], - "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], @@ -943,10 +882,6 @@ "pkg-up/find-up": ["find-up@3.0.0", "", { "dependencies": { "locate-path": "3.0.0" } }, "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg=="], - "rc/ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], - - "readable-web-to-node-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "3.0.0", "buffer": "6.0.3", "events": "3.3.0", "process": "0.11.10", "string_decoder": "1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "rollup/@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.60.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg=="], "@opentui/keymap/@opentui/core/@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.2.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iS4NZQkOKX2EP5rsNjDcU7inDLcKhPaSBn8ENjDXKx2smOh7p/rgM2qlEaiLI3njtL784QoF+nxTzSXbEI6+Jw=="], @@ -971,8 +906,6 @@ "pkg-up/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "3.0.0", "path-exists": "3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="], - "readable-web-to-node-stream/readable-stream/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "1.5.1", "ieee754": "1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "pkg-up/find-up/locate-path/p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "2.3.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], diff --git a/bunfig.toml b/bunfig.toml deleted file mode 100644 index b94431c072..0000000000 --- a/bunfig.toml +++ /dev/null @@ -1,50 +0,0 @@ -# Files that import from 'vitest' must be ignored by `bun test`. -# Bun executes their top-level `vi.mock(...)` calls, which can replace -# real modules (e.g. `bun:sqlite`) and corrupt unrelated `bun:test` files -# that run in the same process. -# Keep in sync with the test files that use `import ... from 'vitest'`. -[test] -pathIgnorePatterns = [ - "test/constants/loop.test.ts", - "test/deterministic-decomposer.test.ts", - "test/hooks/audit-rotate-ordering.test.ts", - "test/hooks/forge-session-attach.test.ts", - "test/hooks/host-side-effects-unwarp.test.ts", - "test/hooks/loop-event-gate.test.ts", - "test/hooks/loop-idle-gate.test.ts", - "test/hooks/loop-section-audit-retry.test.ts", - "test/hooks/plan-approval-dedupe.test.ts", - "test/hooks/plan-approval-worktree-timing.test.ts", - "test/index/session-lookup.test.ts", - "test/loop-runtime-audit-permissions.test.ts", - "test/loop-status-tool.test.ts", - "test/loop/cancel.test.ts", - "test/loop/in-flight-guard.test.ts", - "test/loop/prompts.test.ts", - "test/loop/state-mapper.test.ts", - "test/loop/termination.test.ts", - "test/loop/transitions.test.ts", - "test/plan-approval.test.ts", - "test/plan-execution.test.ts", - "test/sandbox/context.test.ts", - "test/services/execution-attach-cleanup.test.ts", - "test/services/execution-in-flight-guard.test.ts", - "test/services/execution-restart.test.ts", - "test/services/execution.start-loop.test.ts", - "test/services/parse-section-summary.test.ts", - "test/services/select-initial-worktree-session.test.ts", - "test/tui/execute-plan-panel-busy.test.ts", - "test/utils/tui-client-await-workspace-connected.test.ts", - "test/utils/tui-client-loop-inline-plan.test.ts", - "test/utils/tui-client-select-session.test.ts", - "test/utils/tui-client-variants.test.ts", - "test/utils/tui-client-warp-flow.test.ts", - "test/utils/tui-client-workspaces.test.ts", - "test/utils/workspace-status-registry.test.ts", - "test/utils/worktree-cleanup.test.ts", - "test/workspace/classify-stale.test.ts", - "test/workspace/forge-adapter-e2e.test.ts", - "test/workspace/forge-adapter.test.ts", - "test/workspace/forge-worktree.test.ts", - "test/workspace/sweep-stale.test.ts", -] diff --git a/package.json b/package.json index 58502f28fc..bd71866134 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,9 @@ ], "license": "MIT", "homepage": "https://github.com/chriswritescode-dev/opencode-forge", + "engines": { + "node": ">=22.5.0" + }, "dependencies": { "@opencode-ai/plugin": "1.15.5", "@opencode-ai/sdk": "1.15.5", @@ -73,7 +76,6 @@ "@types/node": "^25.6.0", "@typescript-eslint/eslint-plugin": "^8.58.0", "@typescript-eslint/parser": "^8.58.0", - "better-sqlite3": "^12.9.0", "bun-types": "latest", "eslint": "^10.2.0", "eslint-plugin-solid": "^0.14.5", @@ -90,14 +92,12 @@ "lint": "eslint .", "prepublishOnly": "pnpm build", "test": "vitest run", - "test:bun": "bun test --max-concurrency=1", "typecheck": "tsc --noEmit", "docs:api": "typedoc", "docs": "pnpm docs:api" }, "pnpm": { "onlyBuiltDependencies": [ - "better-sqlite3", "esbuild", "msgpackr-extract" ] diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4cd2317723..c9a27e8d7e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -45,9 +45,6 @@ importers: '@typescript-eslint/parser': specifier: ^8.58.0 version: 8.58.0(eslint@10.2.0)(typescript@5.9.3) - better-sqlite3: - specifier: ^12.9.0 - version: 12.9.0 bun-types: specifier: latest version: 1.3.14 @@ -660,16 +657,19 @@ packages: resolution: {integrity: sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==} cpu: [arm] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.60.2': resolution: {integrity: sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==} cpu: [arm] os: [linux] + libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.60.2': resolution: {integrity: sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==} cpu: [arm64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-arm64-gnu@4.60.3': resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==} @@ -680,51 +680,61 @@ packages: resolution: {integrity: sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==} cpu: [arm64] os: [linux] + libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.60.2': resolution: {integrity: sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==} cpu: [loong64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.60.2': resolution: {integrity: sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==} cpu: [loong64] os: [linux] + libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.60.2': resolution: {integrity: sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==} cpu: [ppc64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.60.2': resolution: {integrity: sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==} cpu: [ppc64] os: [linux] + libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.60.2': resolution: {integrity: sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==} cpu: [riscv64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.60.2': resolution: {integrity: sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==} cpu: [riscv64] os: [linux] + libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.60.2': resolution: {integrity: sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==} cpu: [s390x] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.60.2': resolution: {integrity: sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==} cpu: [x64] os: [linux] + libc: [glibc] '@rollup/rollup-linux-x64-musl@4.60.2': resolution: {integrity: sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==} cpu: [x64] os: [linux] + libc: [musl] '@rollup/rollup-openbsd-x64@4.60.2': resolution: {integrity: sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==} @@ -952,16 +962,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - better-sqlite3@12.9.0: - resolution: {integrity: sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==} - engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - bmp-ts@1.0.9: resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==} @@ -977,9 +977,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} @@ -1029,9 +1026,6 @@ packages: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1051,18 +1045,10 @@ packages: supports-color: optional: true - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1080,9 +1066,6 @@ packages: electron-to-chromium@1.5.328: resolution: {integrity: sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==} - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1174,10 +1157,6 @@ packages: exif-parser@0.1.12: resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - expect-type@1.3.0: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} @@ -1212,9 +1191,6 @@ packages: resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} engines: {node: '>=10'} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - find-babel-config@2.1.2: resolution: {integrity: sha512-ZfZp1rQyp4gyuxqt1ZqjFGVeVBvmpURMqdIWXbPRfB97Bf6BzdK/xSIbylEINzQ0kB5tlDQfn9HkNXXWsqTqLg==} @@ -1236,9 +1212,6 @@ packages: flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1257,9 +1230,6 @@ packages: gifwrap@0.10.1: resolution: {integrity: sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==} - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} @@ -1298,12 +1268,6 @@ packages: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - ini@6.0.0: resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} engines: {node: ^20.17.0 || >=22.9.0} @@ -1421,10 +1385,6 @@ packages: engines: {node: '>=10.0.0'} hasBin: true - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - minimatch@10.2.5: resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} engines: {node: 18 || 20 || >=22} @@ -1433,9 +1393,6 @@ packages: resolution: {integrity: sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==} engines: {node: '>=16 || 14 >=14.17'} - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@4.2.8: resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} engines: {node: '>=8'} @@ -1444,9 +1401,6 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1465,16 +1419,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - node-abi@3.92.0: - resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} - engines: {node: '>=10'} - node-gyp-build-optional-packages@5.2.2: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true @@ -1485,9 +1432,6 @@ packages: omggif@1.0.10: resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -1590,12 +1534,6 @@ packages: resolution: {integrity: sha512-qif0+jGGZoLWdHey3UFHHWP0H7Gbmsk8T5VEqyYFbWqPr1XqvLGBbk/sl8V5exGmcYJklJOhOQq1pV9IcsiFag==} engines: {node: ^10 || ^12 || >=14} - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. - hasBin: true - prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -1604,9 +1542,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - punycode.js@2.3.1: resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} engines: {node: '>=6'} @@ -1618,14 +1553,6 @@ packages: pure-rand@8.4.0: resolution: {integrity: sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==} - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - readable-stream@4.7.0: resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1687,12 +1614,6 @@ packages: siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - simple-xml-to-json@1.2.4: resolution: {integrity: sha512-3MY16e0ocMHL7N1ufpdObURGyX+lCo0T/A+y6VCwosLdH1HSda4QZl1Sdt/O+2qWp48WFi26XEp5rF0LoaL0Dg==} engines: {node: '>=20.12.2'} @@ -1717,10 +1638,6 @@ packages: string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - strtok3@6.3.0: resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} engines: {node: '>=10'} @@ -1732,13 +1649,6 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - tar-fs@2.1.4: - resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - three@0.177.0: resolution: {integrity: sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==} @@ -1781,9 +1691,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -1831,9 +1738,6 @@ packages: utif2@4.1.0: resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==} - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - uuid@13.0.0: resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} hasBin: true @@ -1921,9 +1825,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - xml-parse-from-string@1.0.1: resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} @@ -2878,21 +2779,6 @@ snapshots: baseline-browser-mapping@2.10.12: {} - better-sqlite3@12.9.0: - dependencies: - bindings: 1.5.0 - prebuild-install: 7.1.3 - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - bmp-ts@1.0.9: {} brace-expansion@2.0.3: @@ -2911,11 +2797,6 @@ snapshots: node-releases: 2.0.36 update-browserslist-db: 1.2.3(browserslist@4.28.1) - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - buffer@6.0.3: dependencies: base64-js: 1.5.1 @@ -2965,8 +2846,6 @@ snapshots: check-error@2.1.3: {} - chownr@1.1.4: {} - convert-source-map@2.0.0: {} cross-spawn@7.0.6: @@ -2981,17 +2860,12 @@ snapshots: dependencies: ms: 2.1.3 - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - deep-eql@5.0.2: {} - deep-extend@0.6.0: {} - deep-is@0.1.4: {} - detect-libc@2.1.2: {} + detect-libc@2.1.2: + optional: true diff@8.0.2: {} @@ -3010,10 +2884,6 @@ snapshots: electron-to-chromium@1.5.328: {} - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - entities@4.5.0: {} entities@6.0.1: {} @@ -3139,8 +3009,6 @@ snapshots: exif-parser@0.1.12: {} - expand-template@2.0.3: {} - expect-type@1.3.0: {} fast-check@4.7.0: @@ -3167,8 +3035,6 @@ snapshots: strtok3: 6.3.0 token-types: 4.2.1 - file-uri-to-path@1.0.0: {} - find-babel-config@2.1.2: dependencies: json5: 2.2.3 @@ -3191,8 +3057,6 @@ snapshots: flatted@3.4.2: {} - fs-constants@1.0.0: {} - fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -3207,8 +3071,6 @@ snapshots: image-q: 4.0.0 omggif: 1.0.10 - github-from-package@0.0.0: {} - glob-parent@6.0.2: dependencies: is-glob: 4.0.3 @@ -3240,10 +3102,6 @@ snapshots: imurmurhash@0.1.4: {} - inherits@2.0.4: {} - - ini@1.3.8: {} - ini@6.0.0: {} inline-style-parser@0.2.7: {} @@ -3367,8 +3225,6 @@ snapshots: mime@3.0.0: {} - mimic-response@3.1.0: {} - minimatch@10.2.5: dependencies: brace-expansion: 5.0.5 @@ -3377,14 +3233,10 @@ snapshots: dependencies: brace-expansion: 2.0.3 - minimist@1.2.8: {} - minipass@4.2.8: {} minipass@7.1.3: {} - mkdirp-classic@0.5.3: {} - ms@2.1.3: {} msgpackr-extract@3.0.3: @@ -3407,14 +3259,8 @@ snapshots: nanoid@3.3.11: {} - napi-build-utils@2.0.0: {} - natural-compare@1.4.0: {} - node-abi@3.92.0: - dependencies: - semver: 7.7.4 - node-gyp-build-optional-packages@5.2.2: dependencies: detect-libc: 2.1.2 @@ -3424,10 +3270,6 @@ snapshots: omggif@1.0.10: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3516,49 +3358,16 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - prebuild-install@7.1.3: - dependencies: - detect-libc: 2.1.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.92.0 - pump: 3.0.4 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.4 - tunnel-agent: 0.6.0 - prelude-ls@1.2.1: {} process@0.11.10: {} - pump@3.0.4: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - punycode.js@2.3.1: {} punycode@2.3.1: {} pure-rand@8.4.0: {} - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - readable-stream@4.7.0: dependencies: abort-controller: 3.0.0 @@ -3634,14 +3443,6 @@ snapshots: siginfo@2.0.0: {} - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - simple-xml-to-json@1.2.4: {} solid-js@1.9.12: @@ -3663,8 +3464,6 @@ snapshots: dependencies: safe-buffer: 5.2.1 - strip-json-comments@2.0.1: {} - strtok3@6.3.0: dependencies: '@tokenizer/token': 0.3.0 @@ -3676,21 +3475,6 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - tar-fs@2.1.4: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.4 - tar-stream: 2.2.0 - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.5 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - three@0.177.0: optional: true @@ -3722,10 +3506,6 @@ snapshots: dependencies: typescript: 5.9.3 - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -3774,8 +3554,6 @@ snapshots: dependencies: pako: 1.0.11 - util-deprecate@1.0.2: {} - uuid@13.0.0: {} vite-node@2.1.9(@types/node@25.6.0): @@ -3853,8 +3631,6 @@ snapshots: word-wrap@1.2.5: {} - wrappy@1.0.2: {} - xml-parse-from-string@1.0.1: {} xml2js@0.5.0: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 253c5f406f..94efce0306 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,8 +1,6 @@ allowBuilds: - better-sqlite3: true esbuild: true msgpackr-extract: true onlyBuiltDependencies: - - better-sqlite3 - esbuild - msgpackr-extract diff --git a/test/__shims__/bun-sqlite.mjs b/test/__shims__/bun-sqlite.mjs index 50f4707d20..5e75018db4 100644 --- a/test/__shims__/bun-sqlite.mjs +++ b/test/__shims__/bun-sqlite.mjs @@ -1,18 +1,55 @@ -import BetterSqlite3 from 'better-sqlite3' +import { createRequire } from 'module' +const require = createRequire(import.meta.url) +const { DatabaseSync } = require('node:sqlite') -class Database extends BetterSqlite3 { - constructor(pathOrHandle) { - super(pathOrHandle) +class Database { + #db + #path + constructor(pathOrHandle, options) { + this.#path = pathOrHandle == null ? ':memory:' : pathOrHandle + this.#db = new DatabaseSync(this.#path, { + open: true, + readOnly: options?.readonly ?? false, + }) } + get name() { return this.#path } + run(sql, ...params) { - // If parameters are provided, use prepare for parameterized queries if (params.length > 0) { - const stmt = this.prepare(sql) + const stmt = this.#db.prepare(sql) + if (params.length === 1 && Array.isArray(params[0])) { + return stmt.run(...params[0]) + } return stmt.run(...params) } - // Otherwise use exec for multi-statement SQL (CREATE TABLE, etc.) - return this.exec(sql) + return this.#db.exec(sql) + } + + exec(sql) { + return this.#db.exec(sql) + } + + prepare(sql) { + return this.#db.prepare(sql) + } + + transaction(fn) { + return (...args) => { + this.#db.exec('BEGIN') + try { + const result = fn(...args) + this.#db.exec('COMMIT') + return result + } catch (err) { + this.#db.exec('ROLLBACK') + throw err + } + } + } + + close() { + return this.#db.close() } } diff --git a/test/__shims__/bun-test.mjs b/test/__shims__/bun-test.mjs deleted file mode 100644 index f65b7b1bed..0000000000 --- a/test/__shims__/bun-test.mjs +++ /dev/null @@ -1,20 +0,0 @@ -// Shim for bun:test that re-exports vitest APIs. -// Used when running bun:test files under vitest via the vitest alias. -// Note: vi.mock() needs globals to resolve properly — see vitest.config.ts. -import { describe, it, test, expect, vi, beforeEach, afterEach, beforeAll, afterAll } from 'vitest' - -// bun:test's `mock()` is equivalent to vitest's `vi.fn()`. -const mock = vi.fn - -export { - describe, - it, - test, - expect, - vi, - mock, - beforeEach, - afterEach, - beforeAll, - afterAll, -} diff --git a/test/agent-tools-map.test.ts b/test/agent-tools-map.test.ts index aa6e268133..cadfde1ed4 100644 --- a/test/agent-tools-map.test.ts +++ b/test/agent-tools-map.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { buildAgents } from '../src/agents' const agents = buildAgents() diff --git a/test/agents.test.ts b/test/agents.test.ts index 54ceb9ea0e..174f33611a 100644 --- a/test/agents.test.ts +++ b/test/agents.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { architectAgent, buildArchitectAgent } from '../src/agents/architect' import { codeAgent, buildCodeAgent } from '../src/agents/code' import { auditorAgent, auditorLoopAgent, buildAuditorAgent, buildAuditorLoopAgent } from '../src/agents/auditor' diff --git a/test/audit-session.test.ts b/test/audit-session.test.ts index cc7e92863b..af8a7dc1cc 100644 --- a/test/audit-session.test.ts +++ b/test/audit-session.test.ts @@ -1,22 +1,22 @@ -import { describe, test, expect, mock } from 'bun:test' +import { describe, test, expect, vi } from 'vitest' import { createAuditSession, promptAuditSession } from '../src/utils/audit-session' import { buildAuditSessionPermissionRuleset } from '../src/constants/loop' import type { Logger } from '../src/types' interface MockV2Client { session: { - create: ReturnType Promise<{ data?: { id: string }; error?: unknown }>>> - promptAsync: ReturnType Promise<{ data?: unknown; error?: unknown }>>> - delete: ReturnType Promise>> + create: ReturnType Promise<{ data?: { id: string }; error?: unknown }>>> + promptAsync: ReturnType Promise<{ data?: unknown; error?: unknown }>>> + delete: ReturnType Promise>> } } function createMockV2Client(): MockV2Client { return { session: { - create: mock(() => Promise.resolve({ data: { id: 'sess_mock_123' } })), - promptAsync: mock(() => Promise.resolve({ data: {} })), - delete: mock(() => Promise.resolve()), + create: vi.fn(() => Promise.resolve({ data: { id: 'sess_mock_123' } })), + promptAsync: vi.fn(() => Promise.resolve({ data: {} })), + delete: vi.fn(() => Promise.resolve()), }, } } @@ -24,7 +24,7 @@ function createMockV2Client(): MockV2Client { describe('createAuditSession', () => { test('creates session with correct audit ruleset', async () => { const mockV2 = createMockV2Client() - const logger = { log: mock(), error: mock() } as unknown as Logger + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger const result = await createAuditSession({ v2: mockV2 as any, @@ -48,8 +48,8 @@ describe('createAuditSession', () => { test('returns null on session creation error', async () => { const mockV2 = createMockV2Client() - mockV2.session.create = mock(() => Promise.resolve({ error: new Error('create failed') })) - const logger = { log: mock(), error: mock() } as unknown as Logger + mockV2.session.create = vi.fn(() => Promise.resolve({ error: new Error('create failed') })) + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger const result = await createAuditSession({ v2: mockV2 as any, @@ -68,7 +68,7 @@ describe('createAuditSession', () => { test('uses non-sandbox ruleset when isSandbox is false', async () => { const mockV2 = createMockV2Client() - const logger = { log: mock(), error: mock() } as unknown as Logger + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger await createAuditSession({ v2: mockV2 as any, @@ -88,7 +88,7 @@ describe('createAuditSession', () => { test('creates audit session as top-level session even when previous code session exists', async () => { const mockV2 = createMockV2Client() - const logger = { log: mock(), error: mock() } as unknown as Logger + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger await createAuditSession({ v2: mockV2 as any, @@ -110,7 +110,7 @@ describe('createAuditSession', () => { test('formats title with section context for sectioned loops', async () => { const mockV2 = createMockV2Client() - const logger = { log: mock(), error: mock() } as unknown as Logger + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger await createAuditSession({ v2: mockV2 as any, @@ -132,7 +132,7 @@ describe('createAuditSession', () => { describe('promptAuditSession', () => { test('returns ok:true on success', async () => { const mockV2 = createMockV2Client() - mockV2.session.promptAsync = mock(() => Promise.resolve({ data: {} })) + mockV2.session.promptAsync = vi.fn(() => Promise.resolve({ data: {} })) const result = await promptAuditSession(mockV2 as any, { sessionId: 'sess_audit_123', @@ -147,7 +147,7 @@ describe('promptAuditSession', () => { test('returns ok:false on error', async () => { const mockV2 = createMockV2Client() const testError = new Error('prompt failed') - mockV2.session.promptAsync = mock(() => Promise.resolve({ error: testError })) + mockV2.session.promptAsync = vi.fn(() => Promise.resolve({ error: testError })) const result = await promptAuditSession(mockV2 as any, { sessionId: 'sess_audit_123', @@ -160,7 +160,7 @@ describe('promptAuditSession', () => { test('passes auditorModel when provided', async () => { const mockV2 = createMockV2Client() - mockV2.session.promptAsync = mock(() => Promise.resolve({ data: {} })) + mockV2.session.promptAsync = vi.fn(() => Promise.resolve({ data: {} })) await promptAuditSession(mockV2 as any, { sessionId: 'sess_audit_123', diff --git a/test/config.test.ts b/test/config.test.ts index df44a03f33..df69c35c0e 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { createConfigHandler } from '../src/config' import { buildAgents } from '../src/agents' diff --git a/test/dashboard/data.test.ts b/test/dashboard/data.test.ts index b66377d46f..9e5c1f0807 100644 --- a/test/dashboard/data.test.ts +++ b/test/dashboard/data.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { openForgeDatabase, closeDatabase } from '../../src/storage/database' import { collectDashboardData, type DashboardPayload } from '../../src/dashboard/data' diff --git a/test/dashboard/launch.test.ts b/test/dashboard/launch.test.ts index 7ce6971ae2..8f08483c6b 100644 --- a/test/dashboard/launch.test.ts +++ b/test/dashboard/launch.test.ts @@ -1,7 +1,38 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach, beforeAll, afterAll, vi } from 'vitest' import { openForgeDatabase, closeDatabase } from '../../src/storage/database' import { resolveDashboardDbPath, startDashboardServer, type DashboardServerHandle } from '../../src/dashboard/launch' +const MOCK_PORT = 18_472 + +// Bun global is not available under Vitest/Node. +// Mock Bun.serve to capture the handler and route fetch through it. +beforeAll(() => { + let currentFetch: ((req: Request) => Response | Promise) | null = null + + ;(globalThis as any).Bun = { + serve: (config: { fetch: (req: Request) => Response | Promise }) => { + currentFetch = config.fetch + return { port: MOCK_PORT, stop: vi.fn() } + }, + spawn: vi.fn(), + } as any + + const originalFetch = globalThis.fetch + vi.spyOn(globalThis, 'fetch').mockImplementation((url, ...rest) => { + const urlStr = typeof url === 'string' ? url : url.toString() + if (urlStr.startsWith(`http://localhost:${MOCK_PORT}`) && currentFetch) { + const req = new Request(urlStr, rest[0]) + return Promise.resolve(currentFetch(req)) + } + return originalFetch(url, ...rest) + }) +}) + +afterAll(() => { + delete (globalThis as any).Bun + vi.restoreAllMocks() +}) + describe('resolveDashboardDbPath', () => { const originalForgeDb = process.env.FORGE_DB diff --git a/test/dashboard/render.test.ts b/test/dashboard/render.test.ts index 1327d99fbc..782b9043ac 100644 --- a/test/dashboard/render.test.ts +++ b/test/dashboard/render.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { renderDashboardHtml } from '../../src/dashboard/render' describe('renderDashboardHtml', () => { diff --git a/test/dashboard/server.test.ts b/test/dashboard/server.test.ts index 47ed3be44b..6ebeda50aa 100644 --- a/test/dashboard/server.test.ts +++ b/test/dashboard/server.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { openForgeDatabase, closeDatabase } from '../../src/storage/database' import { createRequestHandler } from '../../src/dashboard/server' diff --git a/test/helpers/loops-test-db.ts b/test/helpers/loops-test-db.ts index 4a8e8ac9ff..0401afa0d3 100644 --- a/test/helpers/loops-test-db.ts +++ b/test/helpers/loops-test-db.ts @@ -3,6 +3,7 @@ import { migrations } from '../../src/storage/migrations' type TestDatabase = { prepare(sql: string): { run(...params: unknown[]): unknown } exec(sql: string): unknown + run(sql: string, ...params: unknown[]): unknown } /** diff --git a/test/hooks.test.ts b/test/hooks.test.ts index ec9fa8bf4b..26bb4eb67d 100644 --- a/test/hooks.test.ts +++ b/test/hooks.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, mock } from 'bun:test' +import { describe, test, expect, beforeEach } from 'vitest' import { createSessionHooks } from '../src/hooks/session' import { createLoopEventHandler } from '../src/hooks/loop' import { createLoopService } from '../src/loop/service' diff --git a/test/hooks/loop-event-gate.test.ts b/test/hooks/loop-event-gate.test.ts index 9f2efb0d9b..5d3234900d 100644 --- a/test/hooks/loop-event-gate.test.ts +++ b/test/hooks/loop-event-gate.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' import { tmpdir } from 'os' diff --git a/test/hooks/loop-final-audit-rewind.test.ts b/test/hooks/loop-final-audit-rewind.test.ts index c72a438a0a..697261fce3 100644 --- a/test/hooks/loop-final-audit-rewind.test.ts +++ b/test/hooks/loop-final-audit-rewind.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import type { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/hooks/loop-section-advancement.test.ts b/test/hooks/loop-section-advancement.test.ts index 2a8e7ef41e..e30dc46dc0 100644 --- a/test/hooks/loop-section-advancement.test.ts +++ b/test/hooks/loop-section-advancement.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/hooks/loop-section-audit-retry.test.ts b/test/hooks/loop-section-audit-retry.test.ts index 86f62fee40..db95e9e0fe 100644 --- a/test/hooks/loop-section-audit-retry.test.ts +++ b/test/hooks/loop-section-audit-retry.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' import { tmpdir } from 'os' diff --git a/test/loop-findings-gate.test.ts b/test/loop-findings-gate.test.ts index aad77b8706..8f52bb336c 100644 --- a/test/loop-findings-gate.test.ts +++ b/test/loop-findings-gate.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import type { Database } from 'bun:sqlite' import { createLoopService } from '../src/loop/service' import { createLoopsRepo } from '../src/storage/repos/loops-repo' diff --git a/test/loop-format.test.ts b/test/loop-format.test.ts index 3356738c97..1c55a9c76e 100644 --- a/test/loop-format.test.ts +++ b/test/loop-format.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { formatTokens, formatSessionOutput, formatAuditResult, formatUsageSummary } from '../src/utils/loop-format' import type { LoopSessionOutput } from '../src/loop/session-output' import type { LoopUsageSummary } from '../src/loop/token-usage' diff --git a/test/loop-helpers.test.ts b/test/loop-helpers.test.ts index 0a39a5186b..e4a9508586 100644 --- a/test/loop-helpers.test.ts +++ b/test/loop-helpers.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'bun:test' +import { describe, it, expect } from 'vitest' import { resolveLoopModel, resolveLoopAuditorModel, formatDuration, computeElapsedSeconds } from '../src/utils/loop-helpers' import type { PluginConfig } from '../src/types' diff --git a/test/loop-permission-ruleset.test.ts b/test/loop-permission-ruleset.test.ts index 2ba26aa442..63cd34c66b 100644 --- a/test/loop-permission-ruleset.test.ts +++ b/test/loop-permission-ruleset.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, mock, beforeEach } from 'bun:test' +import { describe, test, expect, vi, beforeEach } from 'vitest' import { buildLoopPermissionRuleset, buildAuditSessionPermissionRuleset } from '../src/constants/loop' import { createLoopPermissionRejectHook, __resetLoopPermissionCache } from '../src/hooks/loop-permission' import { createAuditSession } from '../src/utils/audit-session' @@ -136,8 +136,8 @@ describe('buildAuditSessionPermissionRuleset', () => { describe('createAuditSession passes audit permission rules into session creation', () => { test('session.create receives permission equal to buildAuditSessionPermissionRuleset()', async () => { const expectedPermission = buildAuditSessionPermissionRuleset({ sandbox: false }) - const mockCreate = mock(async (params: any) => ({ data: { id: 'audit-session' }, error: null })) - const mockGet = mock(async () => ({ data: { permission: expectedPermission }, error: null })) + const mockCreate = vi.fn(async (params: any) => ({ data: { id: 'audit-session' }, error: null })) + const mockGet = vi.fn(async () => ({ data: { permission: expectedPermission }, error: null })) const mockV2 = { session: { create: mockCreate, @@ -145,7 +145,7 @@ describe('createAuditSession passes audit permission rules into session creation }, } as any - const logger = { log: mock(), error: mock() } as unknown as Logger + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger await createAuditSession({ v2: mockV2, @@ -174,8 +174,8 @@ describe('createAuditSession passes audit permission rules into session creation describe('createLoopSessionWithWorkspace passes loop permission rules into session creation', () => { test('session.create receives permission exactly equal to buildLoopPermissionRuleset()', async () => { const expectedPermission = buildLoopPermissionRuleset() - const mockCreate = mock(async (params: any) => ({ data: { id: 'loop-session' }, error: null })) - const mockGet = mock(async () => ({ data: {} })) + const mockCreate = vi.fn(async (params: any) => ({ data: { id: 'loop-session' }, error: null })) + const mockGet = vi.fn(async () => ({ data: {} })) const mockV2 = { session: { create: mockCreate, @@ -183,7 +183,7 @@ describe('createLoopSessionWithWorkspace passes loop permission rules into sessi }, } as any - const logger = { log: mock(), error: mock() } as unknown as Logger + const logger = { log: vi.fn(), error: vi.fn() } as unknown as Logger await createLoopSessionWithWorkspace({ v2: mockV2, @@ -208,10 +208,10 @@ describe('createLoopSessionWithWorkspace passes loop permission rules into sessi describe('createLoopPermissionRejectHook', () => { test('does not update subagent session permissions when the session is outside an active loop', async () => { - const mockGet = mock(async () => ({ data: { permission: buildLoopPermissionRuleset() } })) - const mockUpdate = mock(async () => ({ data: {}, error: null })) - const mockResolve = mock(async () => null) - const logger = { log: mock(), error: mock(), debug: mock() } as unknown as Logger + const mockGet = vi.fn(async () => ({ data: { permission: buildLoopPermissionRuleset() } })) + const mockUpdate = vi.fn(async () => ({ data: {}, error: null })) + const mockResolve = vi.fn(async () => null) + const logger = { log: vi.fn(), error: vi.fn(), debug: vi.fn() } as unknown as Logger const hook = createLoopPermissionRejectHook({ v2: { @@ -247,9 +247,9 @@ describe('createLoopPermissionRejectHook', () => { test('copies active loop parent permissions onto child subagent sessions', async () => { const parentPermission = buildLoopPermissionRuleset({ sandbox: true }) - const mockGet = mock(async () => ({ data: { permission: parentPermission } })) - const mockUpdate = mock(async () => ({ data: {}, error: null })) - const logger = { log: mock(), error: mock(), debug: mock() } as unknown as Logger + const mockGet = vi.fn(async () => ({ data: { permission: parentPermission } })) + const mockUpdate = vi.fn(async () => ({ data: {}, error: null })) + const logger = { log: vi.fn(), error: vi.fn(), debug: vi.fn() } as unknown as Logger const hook = createLoopPermissionRejectHook({ v2: { @@ -259,7 +259,7 @@ describe('createLoopPermissionRejectHook', () => { }, } as any, sessionLoopResolver: { - resolveActiveLoopForSession: mock(async () => ({ + resolveActiveLoopForSession: vi.fn(async () => ({ loopName: 'active-loop', active: true, worktreeDir: '/repo/.worktrees/active-loop', @@ -294,14 +294,14 @@ describe('createLoopPermissionRejectHook', () => { }) test('falls back to worktree-only rules when parent permissions are unavailable for a non-sandbox loop', async () => { - const mockGet = mock(async () => ({ data: {} })) - const mockUpdate = mock(async () => ({ data: {}, error: null })) - const logger = { log: mock(), error: mock(), debug: mock() } as unknown as Logger + const mockGet = vi.fn(async () => ({ data: {} })) + const mockUpdate = vi.fn(async () => ({ data: {}, error: null })) + const logger = { log: vi.fn(), error: vi.fn(), debug: vi.fn() } as unknown as Logger const hook = createLoopPermissionRejectHook({ v2: { session: { get: mockGet, update: mockUpdate } } as any, sessionLoopResolver: { - resolveActiveLoopForSession: mock(async () => ({ + resolveActiveLoopForSession: vi.fn(async () => ({ loopName: 'active-loop', active: true, worktreeDir: '/repo/.worktrees/active-loop', @@ -328,14 +328,14 @@ describe('createLoopPermissionRejectHook', () => { test('is idempotent: firing twice for the same child session results in a single session.update call', async () => { const parentPermission = buildLoopPermissionRuleset({ sandbox: true }) - const mockGet = mock(async () => ({ data: { permission: parentPermission } })) - const mockUpdate = mock(async () => ({ data: {}, error: null })) - const logger = { log: mock(), error: mock(), debug: mock() } as unknown as Logger + const mockGet = vi.fn(async () => ({ data: { permission: parentPermission } })) + const mockUpdate = vi.fn(async () => ({ data: {}, error: null })) + const logger = { log: vi.fn(), error: vi.fn(), debug: vi.fn() } as unknown as Logger const hook = createLoopPermissionRejectHook({ v2: { session: { get: mockGet, update: mockUpdate } } as any, sessionLoopResolver: { - resolveActiveLoopForSession: mock(async () => ({ + resolveActiveLoopForSession: vi.fn(async () => ({ loopName: 'active-loop', active: true, worktreeDir: '/repo/.worktrees/active-loop', diff --git a/test/loop-plan-text.test.ts b/test/loop-plan-text.test.ts index ec74154900..8137edb24b 100644 --- a/test/loop-plan-text.test.ts +++ b/test/loop-plan-text.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'bun:test' +import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { initializeDatabase } from '../src/storage' import { createLoopsRepo } from '../src/storage/repos/loops-repo' diff --git a/test/loop-runtime-audit-permissions.test.ts b/test/loop-runtime-audit-permissions.test.ts index 9cffec48a0..c8a04c1be5 100644 --- a/test/loop-runtime-audit-permissions.test.ts +++ b/test/loop-runtime-audit-permissions.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' type DB = InstanceType import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/loop-service-notify.test.ts b/test/loop-service-notify.test.ts index fd8f29db74..8091652da1 100644 --- a/test/loop-service-notify.test.ts +++ b/test/loop-service-notify.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, mock } from 'bun:test' +import { describe, it, expect } from 'vitest' import { createLoop } from '../src/loop/runtime' import type { LoopChangeNotifier } from '../src/loop/service' import type { LoopsRepo } from '../src/storage/repos/loops-repo' diff --git a/test/loop-service.test.ts b/test/loop-service.test.ts index f9038c67d0..3ecae7ae8f 100644 --- a/test/loop-service.test.ts +++ b/test/loop-service.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/loop-session-usage-repo.test.ts b/test/loop-session-usage-repo.test.ts index 50230340ac..0131b45f2b 100644 --- a/test/loop-session-usage-repo.test.ts +++ b/test/loop-session-usage-repo.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { createLoopSessionUsageRepo, type LoopSessionUsageRow } from '../src/storage' diff --git a/test/loop-status-tool.test.ts b/test/loop-status-tool.test.ts index dde4719a1e..27ddb53421 100644 --- a/test/loop-status-tool.test.ts +++ b/test/loop-status-tool.test.ts @@ -15,7 +15,7 @@ import { buildLoopPermissionRuleset, buildAuditSessionPermissionRuleset } from ' import { tmpdir } from 'os' import { join } from 'path' import { randomUUID } from 'crypto' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { setupLoopsTestDb } from './helpers/loops-test-db' const TEST_DIR = '/tmp/opencode-loop-status-test-' + Date.now() diff --git a/test/loop/cancel.test.ts b/test/loop/cancel.test.ts index c4758125fc..f1f16eaca1 100644 --- a/test/loop/cancel.test.ts +++ b/test/loop/cancel.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' import { tmpdir } from 'os' diff --git a/test/loop/runtime.test.ts b/test/loop/runtime.test.ts index 630ba9fd8b..c97f36db8e 100644 --- a/test/loop/runtime.test.ts +++ b/test/loop/runtime.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' @@ -486,10 +486,10 @@ describe('runtime re-provisioning updates state.workspaceId', () => { ], } - const wsCreateMock = mock(async () => ({ + const wsCreateMock = vi.fn(async () => ({ data: { id: 'ws_new', directory: '/tmp/wt/new', branch: 'opencode/new' }, })) - const warpMock = mock(async () => ({ error: null })) + const warpMock = vi.fn(async () => ({ error: null })) const v2Client = { ...createMockV2Client(clientState), diff --git a/test/loop/start.test.ts b/test/loop/start.test.ts index 56bacf60be..f10ccf0668 100644 --- a/test/loop/start.test.ts +++ b/test/loop/start.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/loop/token-usage.test.ts b/test/loop/token-usage.test.ts index b32d39f15a..7c02bd4763 100644 --- a/test/loop/token-usage.test.ts +++ b/test/loop/token-usage.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { emptyTokenBreakdown, normalizeTokens, diff --git a/test/loops-repo.test.ts b/test/loops-repo.test.ts index 807088fed9..5e8496395d 100644 --- a/test/loops-repo.test.ts +++ b/test/loops-repo.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { createLoopsRepo, type LoopRow, type LoopLargeFields } from '../src/storage/repos/loops-repo' import { mkdtempSync, rmSync } from 'fs' diff --git a/test/lru-cache.test.ts b/test/lru-cache.test.ts index 7a4f26e0e4..f1a55607ea 100644 --- a/test/lru-cache.test.ts +++ b/test/lru-cache.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { LRUCache } from '../src/utils/lru-cache' describe('LRUCache', () => { diff --git a/test/parent-session-lookup.test.ts b/test/parent-session-lookup.test.ts index c9d77cbe78..13b8cf3612 100644 --- a/test/parent-session-lookup.test.ts +++ b/test/parent-session-lookup.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { createParentSessionLookup, type CreateParentSessionLookupOptions } from '../src/index' import type { Logger } from '../src/types' diff --git a/test/partial-match.test.ts b/test/partial-match.test.ts index dba50ec17f..cc574b9c7f 100644 --- a/test/partial-match.test.ts +++ b/test/partial-match.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { findPartialMatch, filterByPartial } from '../src/utils/partial-match' interface TestItem { diff --git a/test/plan-approval.test.ts b/test/plan-approval.test.ts index bb6e1f5160..e816a1d37f 100644 --- a/test/plan-approval.test.ts +++ b/test/plan-approval.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest' -// Database is resolved via vitest alias to better-sqlite3 at runtime +// Database is resolved via vitest alias to bun:sqlite at runtime import { existsSync, mkdirSync, rmSync, writeFileSync, statSync } from 'fs' import { execSync, spawnSync } from 'child_process' import { join } from 'path' diff --git a/test/plan-capture.test.ts b/test/plan-capture.test.ts index e8cb1887af..bf1fdcb661 100644 --- a/test/plan-capture.test.ts +++ b/test/plan-capture.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { extractMarkedPlan, normalizePastedPlanText, diff --git a/test/plan-kv.test.ts b/test/plan-kv.test.ts index 5f2c799e0a..c63659d890 100644 --- a/test/plan-kv.test.ts +++ b/test/plan-kv.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import type { Database } from 'bun:sqlite' import { createPlansRepo } from '../src/storage/repos/plans-repo' import { createLoopsRepo } from '../src/storage/repos/loops-repo' diff --git a/test/plans-repo.test.ts b/test/plans-repo.test.ts index 9877d39f48..7857bc8120 100644 --- a/test/plans-repo.test.ts +++ b/test/plans-repo.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { createPlansRepo, type PlanRow } from '../src/storage' diff --git a/test/plugin.test.ts b/test/plugin.test.ts index 8c08aab8d6..0a3d52a1d2 100644 --- a/test/plugin.test.ts +++ b/test/plugin.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { createForgePlugin } from '../src/index' import { mkdirSync, rmSync, existsSync, writeFileSync } from 'fs' import { join } from 'path' diff --git a/test/resolve-project-root.test.ts b/test/resolve-project-root.test.ts index cbd8cab076..8432bacf1c 100644 --- a/test/resolve-project-root.test.ts +++ b/test/resolve-project-root.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { resolveHostSessionDirectory } from '../src/utils/resolve-project-root' import type { OpencodeClient } from '@opencode-ai/sdk/v2' diff --git a/test/review-findings-repo.test.ts b/test/review-findings-repo.test.ts index 8ba4075129..fcdbfd73ab 100644 --- a/test/review-findings-repo.test.ts +++ b/test/review-findings-repo.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { createReviewFindingsRepo } from '../src/storage' diff --git a/test/review.test.ts b/test/review.test.ts index b2b357c4f2..321f19c530 100644 --- a/test/review.test.ts +++ b/test/review.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import type { Database } from 'bun:sqlite' import { createReviewTools } from '../src/tools/review' import { createLoopService } from '../src/loop/service' diff --git a/test/sandbox-docker.test.ts b/test/sandbox-docker.test.ts index 66c632dd0a..a3f624468f 100644 --- a/test/sandbox-docker.test.ts +++ b/test/sandbox-docker.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { createDockerService } from '../src/sandbox/docker' function createMockLogger() { diff --git a/test/sandbox-manager.test.ts b/test/sandbox-manager.test.ts index 49b767c120..6b4ac01569 100644 --- a/test/sandbox-manager.test.ts +++ b/test/sandbox-manager.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { mkdtempSync, rmSync, existsSync } from 'fs' import { tmpdir } from 'os' import { join, resolve } from 'path' diff --git a/test/sandbox-path.test.ts b/test/sandbox-path.test.ts index ab5c7ff05a..96edfdeff5 100644 --- a/test/sandbox-path.test.ts +++ b/test/sandbox-path.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { toContainerPath, rewriteOutput, isInsideWorkspace } from '../src/sandbox/path' describe('toContainerPath', () => { diff --git a/test/sandbox-tools.test.ts b/test/sandbox-tools.test.ts index 8e9ad8cc2b..61628cfd88 100644 --- a/test/sandbox-tools.test.ts +++ b/test/sandbox-tools.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach } from 'bun:test' +import { describe, test, expect, beforeEach } from 'vitest' import { createSandboxToolBeforeHook, createSandboxToolAfterHook } from '../src/hooks/sandbox-tools' import type { Logger } from '../src/types' import type { SandboxContext } from '../src/sandbox/context' diff --git a/test/sandbox/manager.test.ts b/test/sandbox/manager.test.ts index 16aa00a49c..80b5815c1a 100644 --- a/test/sandbox/manager.test.ts +++ b/test/sandbox/manager.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, mock } from 'bun:test' +import { describe, it, expect, vi } from 'vitest' import { createSandboxManager, type SandboxManagerConfig } from '../../src/sandbox/manager' import type { DockerService } from '../../src/sandbox/docker' import type { Logger } from '../../src/types' @@ -6,27 +6,27 @@ import type { Logger } from '../../src/types' describe('SandboxManager.isLiveByName', () => { function createMockDocker(): Partial { return { - checkDocker: mock(async () => true), - imageExists: mock(async () => true), + checkDocker: vi.fn(async () => true), + imageExists: vi.fn(async () => true), containerName: (worktreeName: string) => `forge-${worktreeName}`, - isRunning: mock(async () => false), - createContainer: mock(async () => {}), - removeContainer: mock(async () => {}), - listContainersByPrefix: mock(async () => []), + isRunning: vi.fn(async () => false), + createContainer: vi.fn(async () => {}), + removeContainer: vi.fn(async () => {}), + listContainersByPrefix: vi.fn(async () => []), } } function createMockLogger(): Partial { return { - log: mock(), - error: mock(), - debug: mock(), + log: vi.fn(), + error: vi.fn(), + debug: vi.fn(), } } it('should return true when Docker reports container is running', async () => { const mockDocker = createMockDocker() - mockDocker.isRunning = mock(async () => true) + mockDocker.isRunning = vi.fn(async () => true) const mockLogger = createMockLogger() const config: SandboxManagerConfig = { image: 'oc-forge-sandbox:latest' } @@ -40,7 +40,7 @@ describe('SandboxManager.isLiveByName', () => { it('should return false when Docker reports container is not running', async () => { const mockDocker = createMockDocker() - mockDocker.isRunning = mock(async () => false) + mockDocker.isRunning = vi.fn(async () => false) const mockLogger = createMockLogger() const config: SandboxManagerConfig = { image: 'oc-forge-sandbox:latest' } @@ -54,7 +54,7 @@ describe('SandboxManager.isLiveByName', () => { it('should not modify activeSandboxes map', async () => { const mockDocker = createMockDocker() - mockDocker.isRunning = mock(async () => true) + mockDocker.isRunning = vi.fn(async () => true) const mockLogger = createMockLogger() const config: SandboxManagerConfig = { image: 'oc-forge-sandbox:latest' } diff --git a/test/sandbox/reconcile.test.ts b/test/sandbox/reconcile.test.ts index 0710565b9c..4eb416f434 100644 --- a/test/sandbox/reconcile.test.ts +++ b/test/sandbox/reconcile.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, mock } from 'bun:test' +import { describe, it, expect, beforeEach, vi } from 'vitest' import { reconcileSandboxes, type ReconcileSandboxesDeps } from '../../src/sandbox/reconcile' import type { SandboxManager } from '../../src/sandbox/manager' import type { LoopService } from '../../src/loop/service' @@ -17,25 +17,25 @@ describe('reconcileSandboxes', () => { loopRegistry.clear() mockSandboxManager = { - isActive: mock(), - isLive: mock(async () => true), - getActive: mock(), - start: mock(), - restore: mock(), - stop: mock(), - cleanupOrphans: mock(), + isActive: vi.fn(), + isLive: vi.fn(async () => true), + getActive: vi.fn(), + start: vi.fn(), + restore: vi.fn(), + stop: vi.fn(), + cleanupOrphans: vi.fn(), } mockLoopService = { - listActive: mock(), - setSandboxContainer: mock(), - getActiveState: mock(), + listActive: vi.fn(), + setSandboxContainer: vi.fn(), + getActiveState: vi.fn(), } mockLogger = { - log: mock(), - error: mock(), - debug: mock(), + log: vi.fn(), + error: vi.fn(), + debug: vi.fn(), } deps = { @@ -280,7 +280,7 @@ describe('reconcileSandboxes', () => { // Simulate isLive checking Docker and finding container not running const mockManagerWithIsLive = { ...mockSandboxManager, - isLive: mock(async () => { + isLive: vi.fn(async () => { // Container not in Docker - stale map entry return false }), diff --git a/test/section-management.test.ts b/test/section-management.test.ts index 9226e8c3a7..e416afa396 100644 --- a/test/section-management.test.ts +++ b/test/section-management.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import type { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/section-plans-repo.test.ts b/test/section-plans-repo.test.ts index c774dd9e5d..b2c4fbf715 100644 --- a/test/section-plans-repo.test.ts +++ b/test/section-plans-repo.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { createSectionPlansRepo } from '../src/storage/repos/section-plans-repo' import type { ParsedSection } from '../src/utils/section-capture' diff --git a/test/services/attach-loop.test.ts b/test/services/attach-loop.test.ts index 5da82ff13d..93e071d7a6 100644 --- a/test/services/attach-loop.test.ts +++ b/test/services/attach-loop.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync } from 'fs' import { join } from 'path' @@ -147,8 +147,8 @@ describe('attachLoopToSession', () => { sectionPlansRepo, ) - const promptAsyncMock = mock(async () => ({ error: null })) - const tuiSelectSessionMock = mock(async () => undefined) + const promptAsyncMock = vi.fn(async () => ({ error: null })) + const tuiSelectSessionMock = vi.fn(async () => undefined) const deps = { projectId: PROJECT_ID, @@ -162,17 +162,17 @@ describe('attachLoopToSession', () => { dataDir: '/tmp', v2: { session: { - create: mock(async () => ({ data: { id: 'new-session' } })), - get: mock(async () => ({ data: {} })), - update: mock(async () => ({ data: {} })), + create: vi.fn(async () => ({ data: { id: 'new-session' } })), + get: vi.fn(async () => ({ data: {} })), + update: vi.fn(async () => ({ data: {} })), promptAsync: promptAsyncMock, - abort: mock(async () => ({})), - delete: mock(async () => ({})), - messages: mock(async () => ({ data: [] })), - status: mock(async () => ({ data: {} })), + abort: vi.fn(async () => ({})), + delete: vi.fn(async () => ({})), + messages: vi.fn(async () => ({ data: [] })), + status: vi.fn(async () => ({ data: {} })), }, tui: { - publish: mock(() => {}), + publish: vi.fn(() => {}), selectSession: tuiSelectSessionMock, }, }, @@ -183,15 +183,15 @@ describe('attachLoopToSession', () => { loop: loopService as any, loopHandler: { runExclusive: async (name: string, fn: () => Promise) => fn(), - startWatchdog: mock(() => {}), + startWatchdog: vi.fn(() => {}), clearLoopTimers: noopFn, }, sandboxManager: null, workspaceStatusRegistry: { - recordEvent: mock(() => {}), - getStatus: mock(() => 'connected' as const), - awaitConnected: mock(async () => ({ connected: true, elapsedMs: 0, source: 'cached' as const })), - primeFromSnapshot: mock(() => {}), + recordEvent: vi.fn(() => {}), + getStatus: vi.fn(() => 'connected' as const), + awaitConnected: vi.fn(async () => ({ connected: true, elapsedMs: 0, source: 'cached' as const })), + primeFromSnapshot: vi.fn(() => {}), }, } @@ -249,7 +249,7 @@ describe('attachLoopToSession', () => { test('onStarted callback is invoked after state persistence', async () => { const { deps } = buildDeps() - const onStartedSpy = mock(() => {}) + const onStartedSpy = vi.fn(() => {}) const { attachLoopToSession } = await import('../../src/services/execution') @@ -328,7 +328,7 @@ describe('attachLoopToSession', () => { const originalDeleteState = deps.loop.deleteState.bind(deps.loop) deps.loop.deleteState = (...args: any[]) => { deleteStateCalled = true; return originalDeleteState(...args) } - ;(deps.loop as any).setState = mock((...args: any[]) => { + ;(deps.loop as any).setState = vi.fn((...args: any[]) => { throw new Error('setState: loop "my-feature" already exists') }) diff --git a/test/services/execution-attach-cleanup.test.ts b/test/services/execution-attach-cleanup.test.ts index a9c0eb4d08..6a06023d13 100644 --- a/test/services/execution-attach-cleanup.test.ts +++ b/test/services/execution-attach-cleanup.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach, vi } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { mkdtempSync } from 'fs' import { join } from 'path' import { tmpdir } from 'os' diff --git a/test/services/execution-in-flight-guard.test.ts b/test/services/execution-in-flight-guard.test.ts index 557ceb7476..2594586586 100644 --- a/test/services/execution-in-flight-guard.test.ts +++ b/test/services/execution-in-flight-guard.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { mkdtempSync } from 'fs' import { join } from 'path' import { tmpdir } from 'os' diff --git a/test/services/execution-restart.test.ts b/test/services/execution-restart.test.ts index 72febfce28..4b458f0370 100644 --- a/test/services/execution-restart.test.ts +++ b/test/services/execution-restart.test.ts @@ -13,9 +13,8 @@ import type { PlansRepo } from '../../src/storage/repos/plans-repo' import type { ReviewFindingsRepo } from '../../src/storage/repos/review-findings-repo' import type { SectionPlansRepo } from '../../src/storage/repos/section-plans-repo' import type { LoopService } from '../../src/loop/service' -const Database = require('better-sqlite3') +import Database from 'bun:sqlite' import { setupLoopsTestDb } from '../helpers/loops-test-db' -type Database = ReturnType const mockLogger: Logger = { log: () => {}, diff --git a/test/services/parse-section-summary.test.ts b/test/services/parse-section-summary.test.ts index 3ffbef190d..18e1dfb881 100644 --- a/test/services/parse-section-summary.test.ts +++ b/test/services/parse-section-summary.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect, beforeEach, afterEach } from 'vitest' -import Database from 'better-sqlite3' +import Database from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' import { tmpdir } from 'os' diff --git a/test/session-loop-resolver.test.ts b/test/session-loop-resolver.test.ts index ffbc955268..fd06493b9d 100644 --- a/test/session-loop-resolver.test.ts +++ b/test/session-loop-resolver.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'bun:test' +import { describe, it, expect } from 'vitest' import { createSessionLoopResolver } from '../src/services/session-loop-resolver' describe('createSessionLoopResolver', () => { diff --git a/test/session-titles.test.ts b/test/session-titles.test.ts index 554a7d632c..734ef06c0a 100644 --- a/test/session-titles.test.ts +++ b/test/session-titles.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from 'bun:test' +import { describe, expect, test } from 'vitest' import { MAX_SESSION_TITLE_LENGTH, truncateSessionTitle, diff --git a/test/setup.test.ts b/test/setup.test.ts index 29d244d8c3..4e149a77e0 100644 --- a/test/setup.test.ts +++ b/test/setup.test.ts @@ -1,8 +1,11 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { loadPluginConfig, resolveConfigPath } from '../src/setup' import { mkdirSync, rmSync, writeFileSync, existsSync, readFileSync } from 'fs' -import { join } from 'path' +import { join, dirname } from 'path' import { homedir } from 'os' +import { fileURLToPath } from 'url' + +const __dirname = dirname(fileURLToPath(import.meta.url)) const TEST_DIR = '/tmp/opencode-forge-setup-test-' + Date.now() @@ -125,7 +128,7 @@ describe('bundled sample config', () => { }) test('bundled forge-config.jsonc is valid JSONC and parses successfully', () => { - const bundledConfigPath = join(import.meta.dir, '..', 'forge-config.jsonc') + const bundledConfigPath = join(__dirname, '..', 'forge-config.jsonc') expect(existsSync(bundledConfigPath)).toBe(true) const content = readFileSync(bundledConfigPath, 'utf-8') @@ -137,7 +140,7 @@ describe('bundled sample config', () => { }) test('bundled config includes all supported top-level keys', () => { - const bundledConfigPath = join(import.meta.dir, '..', 'forge-config.jsonc') + const bundledConfigPath = join(__dirname, '..', 'forge-config.jsonc') const content = readFileSync(bundledConfigPath, 'utf-8') const stripComments = (text: string): string => { @@ -171,7 +174,7 @@ describe('bundled sample config', () => { }) test('bundled config compaction includes maxContextTokens', () => { - const bundledConfigPath = join(import.meta.dir, '..', 'forge-config.jsonc') + const bundledConfigPath = join(__dirname, '..', 'forge-config.jsonc') const content = readFileSync(bundledConfigPath, 'utf-8') const stripComments = (text: string): string => { @@ -196,7 +199,7 @@ describe('bundled sample config', () => { }) test('bundled config includes dataDir and completedLoopTtlMs', () => { - const bundledConfigPath = join(import.meta.dir, '..', 'forge-config.jsonc') + const bundledConfigPath = join(__dirname, '..', 'forge-config.jsonc') const content = readFileSync(bundledConfigPath, 'utf-8') const stripComments = (text: string): string => { @@ -222,7 +225,7 @@ describe('bundled sample config', () => { }) test('bundled config includes loop.worktreeLogging and is disabled by default', () => { - const bundledConfigPath = join(import.meta.dir, '..', 'forge-config.jsonc') + const bundledConfigPath = join(__dirname, '..', 'forge-config.jsonc') const content = readFileSync(bundledConfigPath, 'utf-8') const stripComments = (text: string): string => { @@ -248,7 +251,7 @@ describe('bundled sample config', () => { }) test('bundled config includes sandbox.enabled defaulting to true', () => { - const bundledConfigPath = join(import.meta.dir, '..', 'forge-config.jsonc') + const bundledConfigPath = join(__dirname, '..', 'forge-config.jsonc') const content = readFileSync(bundledConfigPath, 'utf-8') const stripComments = (text: string): string => { diff --git a/test/storage-database.test.ts b/test/storage-database.test.ts index 86a44cc5c4..f7bb18a85d 100644 --- a/test/storage-database.test.ts +++ b/test/storage-database.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { initializeDatabase, closeDatabase, resolveDataDir } from '../src/storage/database' import { existsSync, rmSync, mkdirSync, writeFileSync } from 'fs' import { join } from 'path' diff --git a/test/storage-migrations.test.ts b/test/storage-migrations.test.ts index 81b503ba5e..ab1aa2ed63 100644 --- a/test/storage-migrations.test.ts +++ b/test/storage-migrations.test.ts @@ -1,4 +1,4 @@ -import { test, expect, beforeEach } from 'bun:test' +import { test, expect, beforeEach } from 'vitest' import { Database } from 'bun:sqlite' import { tmpdir } from 'os' import { join } from 'path' diff --git a/test/storage-sweep.test.ts b/test/storage-sweep.test.ts index 5d1399c8c0..c5d43b887c 100644 --- a/test/storage-sweep.test.ts +++ b/test/storage-sweep.test.ts @@ -1,4 +1,4 @@ -import { test, expect } from 'bun:test' +import { test, expect } from 'vitest' import { Database } from 'bun:sqlite' import { tmpdir } from 'os' import { join } from 'path' diff --git a/test/tool-blocking.test.ts b/test/tool-blocking.test.ts index 7a6004de4e..893ca4d870 100644 --- a/test/tool-blocking.test.ts +++ b/test/tool-blocking.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import type { Database } from 'bun:sqlite' import { createLoopsRepo } from '../src/storage/repos/loops-repo' import { createPlansRepo } from '../src/storage/repos/plans-repo' diff --git a/test/tools/bash.test.ts b/test/tools/bash.test.ts index 3cf040ad07..bc888acdeb 100644 --- a/test/tools/bash.test.ts +++ b/test/tools/bash.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach } from 'bun:test' +import { describe, test, expect, beforeEach } from 'vitest' import { mkdtempSync } from 'fs' import { tmpdir } from 'os' import { join } from 'path' diff --git a/test/tools/bash/truncate.test.ts b/test/tools/bash/truncate.test.ts index 41b946d333..93a61a50ce 100644 --- a/test/tools/bash/truncate.test.ts +++ b/test/tools/bash/truncate.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { mkdtempSync, readFileSync, existsSync } from 'fs' import { tmpdir } from 'os' import { join } from 'path' diff --git a/test/tools/index-bash-registration.test.ts b/test/tools/index-bash-registration.test.ts index 255972fed6..3fcd273de9 100644 --- a/test/tools/index-bash-registration.test.ts +++ b/test/tools/index-bash-registration.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { createTools } from '../../src/tools' import type { ToolContext } from '../../src/tools/types' diff --git a/test/tools/review-section-scope.test.ts b/test/tools/review-section-scope.test.ts index ab41c498b3..18b7cb9024 100644 --- a/test/tools/review-section-scope.test.ts +++ b/test/tools/review-section-scope.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/tools/section-read.test.ts b/test/tools/section-read.test.ts index 046aa4a552..44250df5fc 100644 --- a/test/tools/section-read.test.ts +++ b/test/tools/section-read.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { mkdtempSync, rmSync } from 'fs' import { join } from 'path' diff --git a/test/tui-execution-preferences.test.ts b/test/tui-execution-preferences.test.ts index 1bb6b41879..73cb62abf0 100644 --- a/test/tui-execution-preferences.test.ts +++ b/test/tui-execution-preferences.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { deriveExecutionPreferencesFromWorkspaces, resolveExecutionDialogDefaults, diff --git a/test/tui-models.test.ts b/test/tui-models.test.ts index 1f7a4e0c9a..db8f1bd28c 100644 --- a/test/tui-models.test.ts +++ b/test/tui-models.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, mock } from 'bun:test' +import { describe, test, expect, vi } from 'vitest' import type { TuiPluginApi } from '@opencode-ai/plugin/tui' import { fetchAvailableModels, @@ -19,7 +19,7 @@ import { } from '../src/utils/tui-models' function createMockApi(configProviders?: string[], providerListFn?: any): TuiPluginApi { - const listFn = providerListFn ?? mock(() => Promise.resolve({ data: { all: [], connected: [] } })) + const listFn = providerListFn ?? vi.fn(() => Promise.resolve({ data: { all: [], connected: [] } })) return { state: { config: { @@ -35,9 +35,9 @@ function createMockApi(configProviders?: string[], providerListFn?: any): TuiPlu }, } as any, ui: { - toast: mock(() => {}), + toast: vi.fn(() => {}), dialog: { - clear: mock(() => {}), + clear: vi.fn(() => {}), }, }, theme: { @@ -76,7 +76,7 @@ describe('fetchAvailableModels', () => { }, ] - const providerListMock = mock(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) + const providerListMock = vi.fn(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) const mockApi = createMockApi(['anthropic'], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -93,7 +93,7 @@ describe('fetchAvailableModels', () => { }) test('returns empty providers array when no providers exist', async () => { - const providerListMock = mock(() => Promise.resolve({ data: { all: [], connected: [] } })) + const providerListMock = vi.fn(() => Promise.resolve({ data: { all: [], connected: [] } })) const mockApi = createMockApi([], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -104,7 +104,7 @@ describe('fetchAvailableModels', () => { }) test('returns error when API returns error', async () => { - const providerListMock = mock(() => Promise.resolve({ + const providerListMock = vi.fn(() => Promise.resolve({ error: { data: { message: 'Authentication failed' }, name: 'APIError', @@ -120,7 +120,7 @@ describe('fetchAvailableModels', () => { }) test('returns error when API throws', async () => { - const providerListMock = mock(() => Promise.reject(new Error('Network error'))) + const providerListMock = vi.fn(() => Promise.reject(new Error('Network error'))) const mockApi = createMockApi(['openai'], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -131,7 +131,7 @@ describe('fetchAvailableModels', () => { }) test('returns error when no data returned', async () => { - const providerListMock = mock(() => Promise.resolve({ data: null })) + const providerListMock = vi.fn(() => Promise.resolve({ data: null })) const mockApi = createMockApi(['google'], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -150,7 +150,7 @@ describe('fetchAvailableModels', () => { }, ] - const providerListMock = mock(() => Promise.resolve({ data: { all: mockProviders, connected: ['empty-provider'] } })) + const providerListMock = vi.fn(() => Promise.resolve({ data: { all: mockProviders, connected: ['empty-provider'] } })) const mockApi = createMockApi([], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -184,7 +184,7 @@ describe('fetchAvailableModels', () => { }, ] - const providerListMock = mock(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) + const providerListMock = vi.fn(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) const mockApi = createMockApi([], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -216,7 +216,7 @@ describe('fetchAvailableModels', () => { }, ] - const providerListMock = mock(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) + const providerListMock = vi.fn(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) const mockApi = createMockApi([], providerListMock) const result = await fetchAvailableModels(mockApi) @@ -595,7 +595,7 @@ describe('fetchAvailableModels with variants', () => { }, ] - const providerListMock = mock(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) + const providerListMock = vi.fn(() => Promise.resolve({ data: { all: mockProviders, connected: ['anthropic'] } })) const mockApi = createMockApi(['anthropic'], providerListMock) const result = await fetchAvailableModels(mockApi) diff --git a/test/utils/loop-session.test.ts b/test/utils/loop-session.test.ts index 2d90fc5d66..235f2ed578 100644 --- a/test/utils/loop-session.test.ts +++ b/test/utils/loop-session.test.ts @@ -1,4 +1,4 @@ -import { test, expect } from 'bun:test' +import { test, expect } from 'vitest' import { createLoopSessionWithWorkspace } from '../../src/utils/loop-session' import type { OpencodeClient } from '@opencode-ai/sdk/v2' import type { Logger } from '../../src/types' diff --git a/test/utils/model-fallback.test.ts b/test/utils/model-fallback.test.ts index 2e0dc01f64..0ea93a9154 100644 --- a/test/utils/model-fallback.test.ts +++ b/test/utils/model-fallback.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect } from 'bun:test' +import { describe, test, expect } from 'vitest' import { parseModelString } from '../../src/utils/model-fallback' describe('parseModelString', () => { diff --git a/test/utils/plan-from-messages.test.ts b/test/utils/plan-from-messages.test.ts index 193cef003c..317937bb6d 100644 --- a/test/utils/plan-from-messages.test.ts +++ b/test/utils/plan-from-messages.test.ts @@ -1,11 +1,11 @@ -import { describe, test, expect, mock } from 'bun:test' +import { describe, test, expect, vi } from 'vitest' import type { OpencodeClient } from '@opencode-ai/sdk/v2' import { fetchLatestPlanForSession } from '../../src/utils/plan-from-messages' import { PLAN_START_MARKER, PLAN_END_MARKER } from '../../src/utils/marked-plan-parser' type MessagesFn = OpencodeClient['session']['messages'] -function makeClient(messagesFn: ReturnType): OpencodeClient { +function makeClient(messagesFn: ReturnType): OpencodeClient { return { session: { messages: messagesFn as unknown as MessagesFn, @@ -33,7 +33,7 @@ const VALID_PLAN_TEXT = '# Implementation Plan\n\n## Phase 1\nDo stuff.' describe('fetchLatestPlanForSession', () => { test('returns the marked plan text when present in the latest assistant message', async () => { - const messages = mock(async () => ({ data: [assistantMessage(`Some preamble\n${VALID_PLAN}\nSome closing words`)] })) + const messages = vi.fn(async () => ({ data: [assistantMessage(`Some preamble\n${VALID_PLAN}\nSome closing words`)] })) const client = makeClient(messages) const result = await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj') expect(result).toBe(VALID_PLAN_TEXT) @@ -45,14 +45,14 @@ describe('fetchLatestPlanForSession', () => { }) test('omits `directory` from the SDK call when not provided', async () => { - const messages = mock(async () => ({ data: [assistantMessage(VALID_PLAN)] })) + const messages = vi.fn(async () => ({ data: [assistantMessage(VALID_PLAN)] })) const client = makeClient(messages) await fetchLatestPlanForSession(client, 'sess-1', undefined) expect(messages).toHaveBeenCalledWith({ sessionID: 'sess-1', limit: 20 }) }) test('honors a custom limit', async () => { - const messages = mock(async () => ({ data: [assistantMessage(VALID_PLAN)] })) + const messages = vi.fn(async () => ({ data: [assistantMessage(VALID_PLAN)] })) const client = makeClient(messages) await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj', { limit: 5 }) expect(messages).toHaveBeenCalledWith({ sessionID: 'sess-1', directory: '/tmp/proj', limit: 5 }) @@ -61,7 +61,7 @@ describe('fetchLatestPlanForSession', () => { test('picks the most recent marked plan when multiple assistant messages exist', async () => { const older = `${PLAN_START_MARKER}\nold plan\n${PLAN_END_MARKER}` const newer = `${PLAN_START_MARKER}\nnew plan\n${PLAN_END_MARKER}` - const messages = mock(async () => ({ + const messages = vi.fn(async () => ({ data: [ assistantMessage(older, 'msg-old'), assistantMessage('some interleaving chat', 'msg-chat'), @@ -74,34 +74,34 @@ describe('fetchLatestPlanForSession', () => { }) test('returns null and logs when the messages call errors', async () => { - const messages = mock(async () => ({ error: new Error('boom') })) + const messages = vi.fn(async () => ({ error: new Error('boom') })) const client = makeClient(messages) - const debug = mock(() => {}) + const debug = vi.fn(() => {}) const result = await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj', { debug }) expect(result).toBeNull() expect(debug).toHaveBeenCalled() }) test('returns null and logs when the messages call throws', async () => { - const messages = mock(async () => { throw new Error('network') }) + const messages = vi.fn(async () => { throw new Error('network') }) const client = makeClient(messages) - const debug = mock(() => {}) + const debug = vi.fn(() => {}) const result = await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj', { debug }) expect(result).toBeNull() expect(debug).toHaveBeenCalled() }) test('returns null when the session has no messages', async () => { - const messages = mock(async () => ({ data: [] })) + const messages = vi.fn(async () => ({ data: [] })) const client = makeClient(messages) - const debug = mock(() => {}) + const debug = vi.fn(() => {}) const result = await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj', { debug }) expect(result).toBeNull() expect(debug).toHaveBeenCalled() }) test('returns null when no assistant message contains plan markers', async () => { - const messages = mock(async () => ({ + const messages = vi.fn(async () => ({ data: [assistantMessage('Just chatting, no plan in here.', 'msg-1')], })) const client = makeClient(messages) @@ -110,18 +110,18 @@ describe('fetchLatestPlanForSession', () => { }) test('returns null when the latest plan is unterminated (start without end)', async () => { - const messages = mock(async () => ({ + const messages = vi.fn(async () => ({ data: [assistantMessage(`${PLAN_START_MARKER}\noops no end marker`, 'msg-1')], })) const client = makeClient(messages) - const debug = mock(() => {}) + const debug = vi.fn(() => {}) const result = await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj', { debug }) expect(result).toBeNull() expect(debug).toHaveBeenCalled() }) test('returns null when the latest plan is empty between markers', async () => { - const messages = mock(async () => ({ + const messages = vi.fn(async () => ({ data: [assistantMessage(`${PLAN_START_MARKER}\n\n${PLAN_END_MARKER}`, 'msg-1')], })) const client = makeClient(messages) @@ -130,7 +130,7 @@ describe('fetchLatestPlanForSession', () => { }) test('skips user messages when scanning for the latest plan', async () => { - const messages = mock(async () => ({ + const messages = vi.fn(async () => ({ data: [ assistantMessage(VALID_PLAN, 'msg-old'), { info: { role: 'user', id: 'msg-user' }, parts: [{ type: 'text', text: 'noise' }] }, @@ -142,9 +142,9 @@ describe('fetchLatestPlanForSession', () => { }) test('debug callback receives a string for the success path', async () => { - const messages = mock(async () => ({ data: [assistantMessage(VALID_PLAN, 'msg-123')] })) + const messages = vi.fn(async () => ({ data: [assistantMessage(VALID_PLAN, 'msg-123')] })) const client = makeClient(messages) - const debug = mock(() => {}) + const debug = vi.fn((..._args: unknown[]) => {}) await fetchLatestPlanForSession(client, 'sess-1', '/tmp/proj', { debug }) expect(debug).toHaveBeenCalled() const args = debug.mock.calls[0] diff --git a/test/utils/sandbox-ready.test.ts b/test/utils/sandbox-ready.test.ts index ceb5268bed..598cf264cb 100644 --- a/test/utils/sandbox-ready.test.ts +++ b/test/utils/sandbox-ready.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, afterEach } from 'bun:test' +import { describe, it, expect, beforeEach, afterEach } from 'vitest' import { Database } from 'bun:sqlite' import { tmpdir } from 'os' import { join } from 'path' diff --git a/test/utils/tui-execution-context-cache.test.ts b/test/utils/tui-execution-context-cache.test.ts index e68f6e51e2..a8502e3a61 100644 --- a/test/utils/tui-execution-context-cache.test.ts +++ b/test/utils/tui-execution-context-cache.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, vi } from 'bun:test' +import { describe, it, expect, vi } from 'vitest' import { createExecutionContextCache } from '../../src/utils/tui-execution-context-cache' import type { ExecutionPreferences } from '../../src/utils/tui-execution-preferences' import type { PluginConfig } from '../../src/types' diff --git a/test/watchdog.test.ts b/test/watchdog.test.ts index 7f8d1de679..a2399d5950 100644 --- a/test/watchdog.test.ts +++ b/test/watchdog.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'bun:test' +import { describe, it, expect } from 'vitest' import { createLoopWatchdog } from '../src/hooks/watchdog' import type { LoopState } from '../src/loop/state' diff --git a/test/workspace-recovery.test.ts b/test/workspace-recovery.test.ts index 797a714ea8..39a303bc2e 100644 --- a/test/workspace-recovery.test.ts +++ b/test/workspace-recovery.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from 'bun:test' +import { describe, it, expect } from 'vitest' import { isWorkspaceNotFoundError } from '../src/hooks/loop' describe('workspace recovery', () => { diff --git a/test/workspace/forge-adapter-e2e.test.ts b/test/workspace/forge-adapter-e2e.test.ts index 990e0334ba..ee6010abe0 100644 --- a/test/workspace/forge-adapter-e2e.test.ts +++ b/test/workspace/forge-adapter-e2e.test.ts @@ -11,7 +11,7 @@ describe('forge workspace adapter e2e', () => { const tmpDataDir = mkdtempSync(join(tmpdir(), 'forge-e2e-data-')) try { - execSync('git init && git commit --allow-empty -m "init"', { + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m "init"', { cwd: tmpRepo, encoding: 'utf-8', }) @@ -77,7 +77,7 @@ describe('forge workspace adapter e2e', () => { const tmpDataDir = mkdtempSync(join(tmpdir(), 'forge-e2e-data-')) try { - execSync('git init && git commit --allow-empty -m "init"', { + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m "init"', { cwd: tmpRepo, encoding: 'utf-8', }) diff --git a/test/workspace/forge-adapter.test.ts b/test/workspace/forge-adapter.test.ts index ff7b4f6549..36a6802d4a 100644 --- a/test/workspace/forge-adapter.test.ts +++ b/test/workspace/forge-adapter.test.ts @@ -108,7 +108,7 @@ describe('createForgeWorkspaceAdapter', () => { it('create invokes git worktree add and creates worktree directory', async () => { const tmpRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-repo-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) const adapter = createForgeWorkspaceAdapter({ dataDir: tmpDataDir, logger, @@ -130,7 +130,7 @@ describe('createForgeWorkspaceAdapter', () => { it('create uses info.extra.projectDirectory as the git cwd, ignoring deps', async () => { const realRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-projdir-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: realRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: realRepo, encoding: 'utf-8' }) const adapter = createForgeWorkspaceAdapter({ dataDir: tmpDataDir, logger }) const configured = adapter.configure({ id: 'ws-1', type: 'forge', name: '', branch: null, directory: null, @@ -182,7 +182,7 @@ describe('createForgeWorkspaceAdapter', () => { it('create ensures parent worktree directory exists before calling git', async () => { const tmpRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-repo2-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) const nestedDataDir = join(tmpDataDir, 'nested', 'deep') const adapter = createForgeWorkspaceAdapter({ dataDir: nestedDataDir, @@ -204,7 +204,7 @@ describe('createForgeWorkspaceAdapter', () => { it('create starts sandbox after creating the worktree', async () => { const tmpRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-repo-sandbox-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) const sandboxManager = { start: vi.fn().mockResolvedValue({ containerName: 'forge-sandbox-loop' }), stop: vi.fn().mockResolvedValue(undefined), @@ -228,7 +228,7 @@ describe('createForgeWorkspaceAdapter', () => { it('create cleans up worktree and sandbox when sandbox start fails', async () => { const tmpRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-repo-sandbox-fail-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) const sandboxManager = { start: vi.fn().mockRejectedValue(new Error('docker unavailable')), stop: vi.fn().mockResolvedValue(undefined), @@ -252,7 +252,7 @@ describe('createForgeWorkspaceAdapter', () => { it('remove runs git worktree remove and prune', async () => { const tmpRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-repo3-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) const adapter = createForgeWorkspaceAdapter({ dataDir: tmpDataDir, logger, @@ -276,7 +276,7 @@ describe('createForgeWorkspaceAdapter', () => { it('remove is idempotent: skips remove when directory does not exist', async () => { const tmpRepo = mkdtempSync(join(tmpdir(), 'forge-adapter-repo4-')) try { - execSync('git init && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) + execSync('git init && git config user.email t@t && git config user.name t && git commit --allow-empty -m init', { cwd: tmpRepo, encoding: 'utf-8' }) const adapter = createForgeWorkspaceAdapter({ dataDir: tmpDataDir, logger, diff --git a/test/worktree-log.test.ts b/test/worktree-log.test.ts index 09aa15f6bf..76c56c1412 100644 --- a/test/worktree-log.test.ts +++ b/test/worktree-log.test.ts @@ -1,4 +1,4 @@ -import { describe, test, expect, beforeEach, afterEach } from 'bun:test' +import { describe, test, expect, beforeEach, afterEach } from 'vitest' import { mkdirSync, rmSync, existsSync, readFileSync, writeFileSync } from 'fs' import { join, isAbsolute } from 'path' import type { PluginConfig } from '../src/types' diff --git a/vitest.config.ts b/vitest.config.ts index 44c230ea68..061bf485b6 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -5,86 +5,10 @@ export default defineConfig({ resolve: { alias: { 'bun:sqlite': resolve(__dirname, './test/__shims__/bun-sqlite.mjs'), - 'bun:test': resolve(__dirname, './test/__shims__/bun-test.mjs'), }, }, test: { - include: [ - 'test/constants/loop.test.ts', - 'test/deterministic-decomposer.test.ts', - 'test/hooks/audit-rotate-ordering.test.ts', - 'test/hooks/loop-section-audit-retry.test.ts', - 'test/hooks/loop-idle-gate.test.ts', - 'test/hooks/loop-event-gate.test.ts', - 'test/services/orphan-sweep.test.ts', - 'test/services/execution-restart.test.ts', - 'test/services/execution-in-flight-guard.test.ts', - 'test/services/execution.start-loop.test.ts', - 'test/services/parse-section-summary.test.ts', - 'test/utils/coder-decisions.test.ts', - 'test/utils/worktree-cleanup.test.ts', - 'test/utils/tui-client-workspaces.test.ts', - 'test/utils/workspace-status-registry.test.ts', - 'test/index/session-lookup.test.ts', - 'test/loop/finding-recurrence.test.ts', - 'test/loop/termination.test.ts', - 'test/loop/state-mapper.test.ts', - 'test/loop/prompts.test.ts', - 'test/loop/transitions.test.ts', - 'test/loop/in-flight-guard.test.ts', - 'test/loop/runtime.test.ts', - 'test/loop/start.test.ts', - 'test/loop/cancel.test.ts', - 'test/loop/token-usage.test.ts', - 'test/plan-execution.test.ts', - 'test/loop-status-tool.test.ts', - 'test/workspace/forge-worktree.test.ts', - 'test/workspace/forge-adapter.test.ts', - 'test/workspace/forge-adapter-e2e.test.ts', - 'test/workspace/classify-stale.test.ts', - 'test/workspace/sweep-stale.test.ts', - 'test/sandbox-docker.test.ts', - 'test/sandbox-manager.test.ts', - 'test/sandbox-tools.test.ts', - 'test/sandbox-path.test.ts', - 'test/sandbox/manager.test.ts', - 'test/sandbox/context.test.ts', - 'test/sandbox/reconcile.test.ts', - 'test/utils/sandbox-ready.test.ts', - 'test/loop-service.test.ts', - 'test/loop-service-notify.test.ts', - 'test/boot-sandbox-preserve.test.ts', - 'test/services/attach-loop.test.ts', - 'test/hooks/forge-session-attach.test.ts', - 'test/hooks/host-side-effects-unwarp.test.ts', - 'test/utils/tui-client-warp-flow.test.ts', - 'test/utils/tui-client-loop-inline-plan.test.ts', - 'test/services/execution-attach-cleanup.test.ts', - 'test/tui/execute-plan-panel-busy.test.ts', - 'test/tui/session-follow.test.ts', - 'test/hooks/plan-approval-dedupe.test.ts', - 'test/hooks/plan-approval-worktree-timing.test.ts', - 'test/plan-capture.test.ts', - 'test/utils/plan-from-messages.test.ts', - 'test/services/select-initial-worktree-session.test.ts', - 'test/plan-approval.test.ts', - 'test/api-model-preferences.test.ts', - 'test/tui-execution-preferences.test.ts', - 'test/utils/tui-execution-context-cache.test.ts', - 'test/utils/tui-client-variants.test.ts', - 'test/utils/tui-client-await-workspace-connected.test.ts', - 'test/utils/tui-client-select-session.test.ts', - 'test/loop-permission-ruleset.test.ts', - 'test/loop-runtime-audit-permissions.test.ts', - 'test/loop-format.test.ts', - 'test/loop-session-usage-repo.test.ts', - 'test/dashboard/data.test.ts', - 'test/dashboard/render.test.ts', - 'test/dashboard/server.test.ts', - 'test/storage-migrations.test.ts', - 'test/worktree-log.test.ts', - 'test/plugin.test.ts', - ], + include: ['test/**/*.test.ts'], globals: true, }, })