diff --git a/bun.lock b/bun.lock index 1282995..2ee3463 100644 --- a/bun.lock +++ b/bun.lock @@ -5,7 +5,7 @@ "": { "name": "local", "dependencies": { - "@mattstack/rt-client": "^0.3.0", + "@mattstack/rt-client": "^0.10.1", "@mattstack/tui-kit": "file:../tui-kit", "react": "19.2.8", "react-dom": "19.2.8", @@ -38,7 +38,7 @@ "@mattstack/glance": ["@mattstack/glance@0.19.0", "", { "dependencies": { "@gitbeaker/rest": "^43.8.0", "@octokit/core": "^7.0.7", "@octokit/graphql": "^9.0.4", "@octokit/plugin-paginate-rest": "^15.0.0", "@octokit/plugin-retry": "^8.1.1", "@octokit/plugin-throttling": "^11.0.5", "@octokit/request-error": "^7.1.1" } }, "sha512-H+QMuyC3IZ3SXl8TpdjIKVhZvx+vP2ltVdt88CDz8e6YFponB2fplyOrHXLvGFITN1EnnEM6DQyYTcQ06F+7fg=="], - "@mattstack/rt-client": ["@mattstack/rt-client@0.3.0", "", { "dependencies": { "jsonc-parser": "^3.3.1" }, "peerDependencies": { "@mattstack/glance": ">=0.13.0" } }, "sha512-o1X3/mde98vOFd89FvmaSf2K1d5V7BbW3rl/j94wlkaf9/+smtNbeDsVL4bCImLn5ktosVOhXPdvZrMqZISL1Q=="], + "@mattstack/rt-client": ["@mattstack/rt-client@0.10.1", "", { "dependencies": { "jsonc-parser": "^3.3.1" }, "peerDependencies": { "@mattstack/glance": ">=0.13.0" } }, "sha512-RndroXypLyHHeJ8RVO9RFt2/DB0im1moG4SUElETTHKgLdpLwPsiMFohEcdH9cIe72JLzt/i9wA1mC/66lq7Ng=="], "@mattstack/tui-kit": ["@mattstack/tui-kit@file:../tui-kit", { "dependencies": { "@soribashi/core": "file:../soribashi/packages/core", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1" }, "devDependencies": { "@types/node": "^26.2.0", "@types/react": "^19", "@types/react-dom": "^19", "@types/react-test-renderer": "^19.1.0", "@vitejs/plugin-react": "^6", "@vitest/browser-playwright": "^4.1.10", "playwright": "^1.59.1", "react": "^19.2", "react-dom": "^19.2", "react-test-renderer": "^19.2.8", "typescript": "^7", "vitest": "^4", "vitest-browser-react": "^2" }, "peerDependencies": { "react": "^19.0.0", "react-dom": "^19.0.0" } }], diff --git a/package.json b/package.json index 2d474d2..8c04ec1 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "deploy": "bun run scripts/deploy.ts" }, "dependencies": { - "@mattstack/rt-client": "^0.3.0", + "@mattstack/rt-client": "^0.10.1", "@mattstack/tui-kit": "file:../tui-kit", "react": "19.2.8", "react-dom": "19.2.8" diff --git a/src/api/dev-mode.test.ts b/src/api/dev-mode.test.ts index af3f745..accf2ed 100644 --- a/src/api/dev-mode.test.ts +++ b/src/api/dev-mode.test.ts @@ -1,4 +1,8 @@ import { test, expect, beforeEach } from "bun:test"; +import { mkdtempSync } from "fs"; +import { tmpdir } from "os"; +import { join } from "path"; +import { setSetting } from "@mattstack/rt-client"; import { isDevMode, resetDevModeCache } from "./dev-mode.ts"; beforeEach(() => resetDevModeCache()); @@ -18,3 +22,26 @@ test("unset value is production (fail closed)", () => { test("a throwing read is production (fail closed)", () => { expect(isDevMode({ read: () => { throw new Error("no daemon"); } })).toBe(false); }); + +// The real getSetting path (no injected read), which the cases above bypass. +// Regression guard for the rt-client bump: `mattstack.mode` must be a registered +// key, or getSetting throws unknownKey and the gate is stuck fail-closed to prod. +test("real rt-client path reads mattstack.mode from the store", () => { + const origHome = process.env.HOME; + process.env.HOME = mkdtempSync(join(tmpdir(), "devmode-real-")); + try { + resetDevModeCache(); + expect(isDevMode()).toBe(false); // unset -> prod + + setSetting("mattstack.mode", "prod", "machine"); + resetDevModeCache(); + expect(isDevMode()).toBe(false); + + setSetting("mattstack.mode", "dev", "machine"); + resetDevModeCache(); + expect(isDevMode()).toBe(true); + } finally { + process.env.HOME = origHome; + resetDevModeCache(); + } +});