From e59f2d622125afa357b5520b75cd489445444276 Mon Sep 17 00:00:00 2001 From: sebastian Date: Wed, 30 Sep 2026 13:48:25 +0200 Subject: [PATCH] fix: make lint pass on Biome 2.x The config used the Biome 1.x `linter.preset` key, which Biome 2.5 rejects as unknown, so `pnpm lint` (and CI) failed at config parse. Recommended rules are on by default in Biome 2.x, so the key is simply removed. Also apply the project's own format/import order to the files that had drifted, so `biome check` is clean. Co-authored-by: CommandCodeBot --- biome.json | 3 +-- src/__tests__/mod.test.ts | 38 ++++++++++++++++++++++------------ src/__tests__/protocol.test.ts | 34 +++++++++++++++--------------- src/client.ts | 4 +--- src/index.ts | 21 +++++++++++-------- src/protocol.ts | 6 ++++-- 6 files changed, 60 insertions(+), 46 deletions(-) diff --git a/biome.json b/biome.json index 9269cec..ba7021f 100644 --- a/biome.json +++ b/biome.json @@ -17,7 +17,6 @@ } }, "linter": { - "enabled": true, - "preset": "recommended" + "enabled": true } } diff --git a/src/__tests__/mod.test.ts b/src/__tests__/mod.test.ts index bbf99da..fde8c66 100644 --- a/src/__tests__/mod.test.ts +++ b/src/__tests__/mod.test.ts @@ -1,16 +1,16 @@ // jev-nudge mod tests — the wiring: dormant without a key, the request it sends, the // continue it returns, the per-run bookkeeping, and that Jev failures never change a stop. +import {describe, expect, it} from 'vitest'; +import type {JevFetch} from '../client.js'; +import {createJevNudgeMod} from '../index.js'; +import {NUDGE_REASON, SYSTEM_ONE_PATH} from '../protocol.js'; import type { AgentState, ModApi, ModFlagDefinition, ModHooks, } from '../types.js'; -import {describe, expect, it} from 'vitest'; -import type {JevFetch} from '../client.js'; -import {createJevNudgeMod} from '../index.js'; -import {NUDGE_REASON, SYSTEM_ONE_PATH} from '../protocol.js'; interface FakeHost { readonly cmd: ModApi; @@ -123,9 +123,11 @@ async function stop( describe('jev-nudge mod', () => { it('registers only its flags without a key, and says so', () => { const host = fakeCmd(); - createJevNudgeMod({env: {}, storedKey: noStoredKey, fetch: fakeFetch(() => answers(1)).fetch})( - host.cmd, - ); + createJevNudgeMod({ + env: {}, + storedKey: noStoredKey, + fetch: fakeFetch(() => answers(1)).fetch, + })(host.cmd); expect([...host.flags.keys()]).toEqual([ 'jev-nudge-threshold', 'jev-nudge-max', @@ -223,8 +225,11 @@ describe('jev-nudge mod', () => { it('only judges natural end_turn stops', async () => { const host = fakeCmd(); const {fetch, captured} = fakeFetch(() => answers(1)); - createJevNudgeMod({env: {CMD_API_KEY: 'ck'}, - storedKey: noStoredKey, fetch})(host.cmd); + createJevNudgeMod({ + env: {CMD_API_KEY: 'ck'}, + storedKey: noStoredKey, + fetch, + })(host.cmd); expect(await stop(host, {stopReason: 'max_tokens'})).toBeUndefined(); expect(captured.requests).toEqual([]); }); @@ -234,7 +239,7 @@ describe('jev-nudge mod', () => { const host = fakeCmd(); createJevNudgeMod({ env: {CMD_API_KEY: 'ck'}, - storedKey: noStoredKey, + storedKey: noStoredKey, fetch: fakeFetch(() => failure).fetch, })(host.cmd); expect(await stop(host)).toBeUndefined(); @@ -247,8 +252,11 @@ describe('jev-nudge mod', () => { const host = fakeCmd(); host.flagValues.set('jev-nudge-max', '2'); const {fetch, captured} = fakeFetch(() => answers(0.9, 0.1, 0.9)); - createJevNudgeMod({env: {CMD_API_KEY: 'ck'}, - storedKey: noStoredKey, fetch})(host.cmd); + createJevNudgeMod({ + env: {CMD_API_KEY: 'ck'}, + storedKey: noStoredKey, + fetch, + })(host.cmd); const hooks = host.hooks[0]; if (!hooks?.afterToolCall || !hooks.onTurnStart) throw new Error('hooks missing'); @@ -309,7 +317,11 @@ describe('jev-nudge mod', () => { host.flagValues.set('jev-nudge-model', 'jev-2'); host.flagValues.set('jev-nudge-threshold', '0.95'); const {fetch, captured} = fakeFetch(() => answers(0.9)); - createJevNudgeMod({env: {CMD_API_KEY: 'ck'}, storedKey: noStoredKey, fetch})(host.cmd); + createJevNudgeMod({ + env: {CMD_API_KEY: 'ck'}, + storedKey: noStoredKey, + fetch, + })(host.cmd); expect(await stop(host)).toBeUndefined(); expect(captured.requests[0]?.url).toBe( diff --git a/src/__tests__/protocol.test.ts b/src/__tests__/protocol.test.ts index ec139b6..7f9de2d 100644 --- a/src/__tests__/protocol.test.ts +++ b/src/__tests__/protocol.test.ts @@ -1,21 +1,21 @@ // jev-nudge protocol tests — the pure half: key resolution, the state Jev sees, the // questions asked, and how probabilities become a stop-hook decision. -import type {AgentMessage} from '../types.js'; import {describe, expect, it} from 'vitest'; import { buildNudgeState, + COMMAND_CODE_BASE_URL, DEFAULT_MAX_NUDGES, DEFAULT_THRESHOLD, decideNudge, - COMMAND_CODE_BASE_URL, + JEV_MODEL, jevResponseSchema, nudgeQuestions, parseMaxNudges, parseThreshold, - JEV_MODEL, resolveJevConfig, } from '../protocol.js'; +import type {AgentMessage} from '../types.js'; describe('resolveJevConfig', () => { it('is dormant without a key', () => { @@ -37,8 +37,10 @@ describe('resolveJevConfig', () => { model: JEV_MODEL, }); expect( - resolveJevConfig({env: {COMMAND_CODE_API_KEY: 'cli'}, storedKey: 'stored'}) - ?.apiKey, + resolveJevConfig({ + env: {COMMAND_CODE_API_KEY: 'cli'}, + storedKey: 'stored', + })?.apiKey, ).toBe('cli'); expect(resolveJevConfig({env: {}, storedKey: 'stored'})?.apiKey).toBe( 'stored', @@ -132,19 +134,17 @@ describe('buildNudgeState', () => { describe('nudgeQuestions', () => { it('asks the progress guard only once a nudge already happened', () => { + expect(Object.keys(nudgeQuestions({hasPreviousNudge: false}))).toEqual([ + 'nudge', + 'waiting', + ]); + expect(Object.keys(nudgeQuestions({hasPreviousNudge: true}))).toEqual([ + 'nudge', + 'waiting', + 'progress', + ]); expect( - Object.keys( - nudgeQuestions({hasPreviousNudge: false}), - ), - ).toEqual(['nudge', 'waiting']); - expect( - Object.keys( - nudgeQuestions({hasPreviousNudge: true}), - ), - ).toEqual(['nudge', 'waiting', 'progress']); - expect( - nudgeQuestions({hasPreviousNudge: false}).nudge - .instructions, + nudgeQuestions({hasPreviousNudge: false}).nudge.instructions, ).toContain('gentle nudge'); }); diff --git a/src/client.ts b/src/client.ts index 3483053..333142a 100644 --- a/src/client.ts +++ b/src/client.ts @@ -58,9 +58,7 @@ export async function askJev(params: AskJevParams): Promise { `jev ${response.status}${text ? `: ${text.slice(0, 200)}` : ''}`, ); } - const parsed = jevResponseSchema.safeParse( - await response.json(), - ); + const parsed = jevResponseSchema.safeParse(await response.json()); if (!parsed.success) { throw new Error( `jev returned an unexpected shape: ${parsed.error.message}`, diff --git a/src/index.ts b/src/index.ts index f084e0c..a1510b6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,21 +21,21 @@ import {readFileSync} from 'node:fs'; import {homedir} from 'node:os'; import {join} from 'node:path'; -import type {ModApi} from './types.js'; import {askJev, type JevFetch} from './client.js'; import { buildNudgeState, + CMD_KEY_ENV, DEFAULT_THRESHOLD, decideNudge, JEV_NUDGE_MOD_NAME, NUDGE_REASON, nudgeQuestions, + type PreviousNudge, parseMaxNudges, parseThreshold, - type PreviousNudge, resolveJevConfig, - CMD_KEY_ENV, } from './protocol.js'; +import type {ModApi} from './types.js'; // A stop decision is on the critical path between "model finished" and "prompt comes back"; // a gut-check model should answer well inside this, and past it the run just stops. @@ -77,13 +77,11 @@ export function createJevNudgeMod( }); cmd.addFlag('jev-nudge-base-url', { type: 'string', - description: - 'API root for Jev (default: https://api.commandcode.ai)', + description: 'API root for Jev (default: https://api.commandcode.ai)', }); cmd.addFlag('jev-nudge-model', { type: 'string', - description: - 'Model id sent to the endpoint (default: typesafe/jev)', + description: 'Model id sent to the endpoint (default: typesafe/jev)', }); cmd.addFlag('jev-nudge-verbose', { @@ -164,7 +162,8 @@ export function createJevNudgeMod( } catch (error) { // Best-effort: the stop decision must never depend on a network call succeeding, // but a failing call is said out loud so "no nudge" is never a mystery. - const message = error instanceof Error ? error.message : String(error); + const message = + error instanceof Error ? error.message : String(error); dlog(`[${JEV_NUDGE_MOD_NAME}] ${message}`); cmd.ui.notify( `${JEV_NUDGE_MOD_NAME}: Jev call failed (${message}), letting the run stop`, @@ -185,7 +184,11 @@ export function createJevNudgeMod( run = { nudges: [ ...previousNudges, - {turnNumber, toolCallsAfter: 0, assistantTextAtNudge: lastAssistantText}, + { + turnNumber, + toolCallsAfter: 0, + assistantTextAtNudge: lastAssistantText, + }, ], toolCallsSinceNudge: 0, }; diff --git a/src/protocol.ts b/src/protocol.ts index e89308e..8fd66b2 100644 --- a/src/protocol.ts +++ b/src/protocol.ts @@ -7,8 +7,8 @@ // probabilities instead of generating text, so the "should the agent keep going?" judgment // comes back as numbers this file can threshold, with no prose to parse. -import type {AgentMessage} from './types.js'; import {z} from 'zod'; +import type {AgentMessage} from './types.js'; export const JEV_NUDGE_MOD_NAME = 'jev-nudge'; @@ -244,7 +244,9 @@ export interface NudgeAnswers { // System One returns `{model, answers, usage}` with each yes/no answered as `{type: 'noul', // noul}`; the schema hands back plain numbers so nothing downstream sees the wire shape. -const probability = z.object({noul: z.number()}).transform(answer => answer.noul); +const probability = z + .object({noul: z.number()}) + .transform(answer => answer.noul); export const jevResponseSchema = z.object({ model: z.string().optional(),