From ae2e382bfdea460caa66b1fca7ecae528f2acb0b Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:42:56 +0000 Subject: [PATCH] Fix: Correctly detect agent platform for locks - Updated `src/utils.mjs` to detect 'claude' platform via `CLAUDE_API_KEY`, `ANTHROPIC_API_KEY`, or `CLAUDE_SESSION_ID`. - Updated `scripts/agent/scheduler-utils.mjs` `getSafeEnv` to preserve `JULES_`, `CODEX_`, `CLAUDE_`, `ANTHROPIC_`, and `GOOSE_` environment variables when spawning child processes. - Updated `scripts/agent/run-scheduler-cycle.mjs` to use `detectPlatform()` as a fallback for `AGENT_PLATFORM` instead of hardcoding `'codex'`, ensuring the correct platform is used for lock creation. - Added unit tests for `detectPlatform` in `test/utils.test.mjs`. This resolves the issue where lock cards displayed "Unknown" or incorrect platforms. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- scripts/agent/run-scheduler-cycle.mjs | 4 +- scripts/agent/scheduler-utils.mjs | 7 +++- src/utils.mjs | 1 + test/utils.test.mjs | 60 ++++++++++++++++++++++++++- 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/scripts/agent/run-scheduler-cycle.mjs b/scripts/agent/run-scheduler-cycle.mjs index 5358a49..7a9b873 100644 --- a/scripts/agent/run-scheduler-cycle.mjs +++ b/scripts/agent/run-scheduler-cycle.mjs @@ -25,6 +25,8 @@ import { summarizeLockFailureReasons, } from './scheduler-lock.mjs'; +import { detectPlatform } from '../../src/utils.mjs'; + const VALID_CADENCES = new Set(['daily', 'weekly']); const ALL_EXCLUDED_REASON = 'All roster tasks currently claimed by other agents'; const FAILURE_CATEGORY = { @@ -35,7 +37,7 @@ const FAILURE_CATEGORY = { }; function parseArgs(argv) { - const args = { cadence: null, platform: process.env.AGENT_PLATFORM || 'codex', model: process.env.AGENT_MODEL || null }; + const args = { cadence: null, platform: process.env.AGENT_PLATFORM || detectPlatform() || 'unknown', model: process.env.AGENT_MODEL || null }; for (let i = 0; i < argv.length; i += 1) { const value = argv[i]; if (!value.startsWith('--') && !args.cadence) { diff --git a/scripts/agent/scheduler-utils.mjs b/scripts/agent/scheduler-utils.mjs index 5403122..cfef0d9 100644 --- a/scripts/agent/scheduler-utils.mjs +++ b/scripts/agent/scheduler-utils.mjs @@ -20,7 +20,12 @@ export function getSafeEnv() { key.startsWith('NOSTR_') || key.startsWith('TORCH_') || key.startsWith('SCHEDULER_') || - key.startsWith('AGENT_')) { + key.startsWith('AGENT_') || + key.startsWith('JULES_') || + key.startsWith('CODEX_') || + key.startsWith('CLAUDE_') || + key.startsWith('ANTHROPIC_') || + key.startsWith('GOOSE_')) { safeEnv[key] = process.env[key]; } } diff --git a/src/utils.mjs b/src/utils.mjs index e091fa6..3c198fd 100644 --- a/src/utils.mjs +++ b/src/utils.mjs @@ -34,6 +34,7 @@ export function detectPlatform() { if (process.env.JULES_API_KEY || process.env.JULES_SESSION_ID) return 'jules'; if (process.env.CODEX_API_KEY || process.env.CODEX_SESSION_ID) return 'codex'; if (process.env.GOOSE_API_KEY || process.env.GOOSE_SESSION_ID) return 'goose'; + if (process.env.CLAUDE_API_KEY || process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_SESSION_ID) return 'claude'; return null; } diff --git a/test/utils.test.mjs b/test/utils.test.mjs index 29f3526..0ce8d5a 100644 --- a/test/utils.test.mjs +++ b/test/utils.test.mjs @@ -2,7 +2,7 @@ import { describe, it, after } from 'node:test'; import assert from 'node:assert'; import fs from 'node:fs'; import path from 'node:path'; -import { getIsoWeekStr, todayDateStr, nowUnix, ensureDir } from '../src/utils.mjs'; +import { getIsoWeekStr, todayDateStr, nowUnix, ensureDir, detectPlatform } from '../src/utils.mjs'; describe('Date Utilities', () => { describe('todayDateStr', () => { @@ -59,6 +59,64 @@ describe('Date Utilities', () => { }); }); +describe('Platform Utilities', () => { + describe('detectPlatform', () => { + const originalEnv = { ...process.env }; + + // Helper to clear relevant env vars + const clearEnv = () => { + delete process.env.JULES_SESSION_ID; + delete process.env.JULES_API_KEY; + delete process.env.CODEX_SESSION_ID; + delete process.env.CODEX_API_KEY; + delete process.env.GOOSE_SESSION_ID; + delete process.env.GOOSE_API_KEY; + delete process.env.CLAUDE_SESSION_ID; + delete process.env.CLAUDE_API_KEY; + delete process.env.ANTHROPIC_API_KEY; + }; + + after(() => { + process.env = originalEnv; + }); + + it('detects jules', () => { + clearEnv(); + process.env.JULES_SESSION_ID = 'test'; + assert.strictEqual(detectPlatform(), 'jules'); + }); + + it('detects codex', () => { + clearEnv(); + process.env.CODEX_API_KEY = 'test'; + assert.strictEqual(detectPlatform(), 'codex'); + }); + + it('detects goose', () => { + clearEnv(); + process.env.GOOSE_SESSION_ID = 'test'; + assert.strictEqual(detectPlatform(), 'goose'); + }); + + it('detects claude via CLAUDE_API_KEY', () => { + clearEnv(); + process.env.CLAUDE_API_KEY = 'test'; + assert.strictEqual(detectPlatform(), 'claude'); + }); + + it('detects claude via ANTHROPIC_API_KEY', () => { + clearEnv(); + process.env.ANTHROPIC_API_KEY = 'test'; + assert.strictEqual(detectPlatform(), 'claude'); + }); + + it('returns null if no platform detected', () => { + clearEnv(); + assert.strictEqual(detectPlatform(), null); + }); + }); +}); + describe('File Utilities', () => { describe('ensureDir', () => { const tempBase = fs.mkdtempSync(path.join(process.cwd(), 'test-utils-'));