@galda/cli 0.10.51 → 0.10.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/engine/claude-models.mjs +13 -0
- package/engine/codex-models.mjs +42 -0
- package/engine/server.mjs +19 -6
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Claude Code accepts these stable aliases and resolves them to the current
|
|
2
|
+
// model versions for the active account and provider.
|
|
3
|
+
export const CLAUDE_MODELS = Object.freeze([
|
|
4
|
+
'sonnet',
|
|
5
|
+
'fable',
|
|
6
|
+
'best',
|
|
7
|
+
'opus',
|
|
8
|
+
'haiku',
|
|
9
|
+
'default',
|
|
10
|
+
'sonnet[1m]',
|
|
11
|
+
'opus[1m]',
|
|
12
|
+
'opusplan',
|
|
13
|
+
]);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
export const FALLBACK_CODEX_MODELS = [
|
|
6
|
+
'gpt-5.6-sol',
|
|
7
|
+
'gpt-5.6-terra',
|
|
8
|
+
'gpt-5.6-luna',
|
|
9
|
+
'gpt-5.5',
|
|
10
|
+
'gpt-5.4',
|
|
11
|
+
'gpt-5.4-mini',
|
|
12
|
+
'gpt-5.3-codex-spark',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
export function parseCodexModelCache(raw, fallback = FALLBACK_CODEX_MODELS) {
|
|
16
|
+
try {
|
|
17
|
+
const parsed = JSON.parse(String(raw));
|
|
18
|
+
const models = Array.isArray(parsed?.models)
|
|
19
|
+
? parsed.models
|
|
20
|
+
.filter((model) => model?.visibility === 'list' && typeof model.slug === 'string')
|
|
21
|
+
.map((model) => model.slug.trim())
|
|
22
|
+
.filter(Boolean)
|
|
23
|
+
: [];
|
|
24
|
+
return models.length ? [...new Set(models)] : fallback.slice();
|
|
25
|
+
} catch {
|
|
26
|
+
return fallback.slice();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Codex refreshes this cache itself. Reading it gives Galda the account's real
|
|
31
|
+
// picker catalog without launching Codex, making a network request, or running
|
|
32
|
+
// an installer. Older CLIs and first-run installs simply use the fallback.
|
|
33
|
+
export function loadCodexModels({ cacheFile, readFile = readFileSync } = {}) {
|
|
34
|
+
const file = cacheFile
|
|
35
|
+
|| process.env.MANAGER_CODEX_MODELS_FILE
|
|
36
|
+
|| join(process.env.CODEX_HOME || join(homedir(), '.codex'), 'models_cache.json');
|
|
37
|
+
try {
|
|
38
|
+
return parseCodexModelCache(readFile(file, 'utf8'));
|
|
39
|
+
} catch {
|
|
40
|
+
return FALLBACK_CODEX_MODELS.slice();
|
|
41
|
+
}
|
|
42
|
+
}
|
package/engine/server.mjs
CHANGED
|
@@ -20,10 +20,12 @@ import { resolve, dirname, join, basename } from 'node:path';
|
|
|
20
20
|
import { homedir } from 'node:os';
|
|
21
21
|
import { fileURLToPath } from 'node:url';
|
|
22
22
|
import { pathToFileURL } from 'node:url';
|
|
23
|
-
import { needsProjectFolder, folderLabel, chooseFolderScript, parseChosenFolder, buildFolderQuestion, resolveFolderAnswer, classifyFolderTarget, buildFolderInitConfirm, isFolderInitConfirmed, needsReviewPreference, buildReviewPreferenceQuestion, resolveReviewPreferenceAnswer, routeQuestionAnswer, notUnderstoodNote, parseRelocalizedQuestion, classifyAuthProbe, authBannerText, makeSigninChallenge, parseClaimResponse } from './lib.mjs';
|
|
23
|
+
import { needsProjectFolder, folderLabel, chooseFolderScript, parseChosenFolder, buildFolderQuestion, resolveFolderAnswer, classifyFolderTarget, buildFolderInitConfirm, isFolderInitConfirmed, needsReviewPreference, buildReviewPreferenceQuestion, resolveReviewPreferenceAnswer, routeQuestionAnswer, notUnderstoodNote, parseRelocalizedQuestion, classifyAuthProbe, authBannerText, makeSigninChallenge, parseClaimResponse, isCommandOnPath } from './lib.mjs';
|
|
24
24
|
import { parseStreamEvents, parseCodexEvents, buildCodexArgs, parsePlan, refinePlanTasks, canEditGoal, canDeleteGoal, shouldAskClarification, workerExitReason, isForcedStop, taskStatusAfterVerify, workerResultText, taskCountsAsComplete, resolveWantsPR, resolveGoalSource, buildGoalSummary, buildGoalProofMd, buildGoalPrBody, buildReviewSummaryPrompt, parseReviewSummary, buildReviewRuleSection, nextGoalStatus, isPrMerged, isPrApproved, reviewToDoneStatus, advanceReviewGoal, revertReviewGoal, approveGoal, dismissGoal, rejectGoal, reopenGoal, permissionModeFor, isPlanReview, nextAfterPlanApprove, GOAL_MODES, parseSkillFrontmatter, collectSkills, retestGoal, cancelRetestGoal, computeRetestOutcome, revertGoal, planRevertActions, archiveGoal, unarchiveGoal, undismissGoal, parseNumstat, truncateDiffText, sumUsage, resolveEntryUrl, parseGitLog, diffNewCommits, replayQueueLog, reconcileOrphanGoals, reorderQueue, sortQueueByPriority, TASK_PRIORITIES, validateWorkflowColumns, DEFAULT_WORKFLOW_COLUMNS, validateReviewDefinition, DEFAULT_REVIEW_DEFINITION, resolveTestGate, buildEphemeralSeedLog, buildEphemeralSeedProjects, trimTaskActivityForState, buildAskContext, WORKER_TOOLS, workerPrompt, verifyCfAccessJwt, resolveIdentity, goalVisibleTo, clampParallelLimit, canStartMore, nextRunnableTasks, goalsConflict, detectConflicts, pickFoldTarget, hasTestRelevantChanges, parseFailingTestNames, classifyTestGate, isInconclusiveTestRun, countInfraFlakes, classifyRunFailures, classifyVerifyGate, buildExecutionPlan, buildContextHandoffSummary, buildFailurePostmortem, appendFailureMemory, latestFailurePolicy, classifyChangeRisk, checkRunBudget, usageBudgetTokens, isRateLimited, nextResumeDelay, checkFreeTierLimit, resolveEntitlement, resolveCachedEntitlement, FREE_TIER_LIMITS, QUEUED_GOAL_STATUSES, verifyLicenseToken, licenseTokenPayload, shouldRefreshLicense, shouldEmitSetupCompleted, pickAnalyticsUid, shouldEmitFreeExhausted, detectRequestLanguage, isNothingVerifiable, classifyComposerIntentHeuristic, detectPauseIntent, buildIntentPrompt, parseIntentResponse, buildBoardSnapshot, validateBoardSnapshot, boardIsEmpty, decideBoardPull, resolveConnectedAgents, pickAvailableAgent, pickUtilityAgent, utilityModel, liveTakeoverDecision, shouldOpenBrowserOnBoot, goalTaskTitle, buildGoalTask, RUN_DECL_FILE, parseRunDeclaration, SHOT_DIR, collectShotNames, parseGoalAddress, REPLY_OUTCOMES, REPLY_INTENTS, buildReplyIntentPrompt, parseReplyIntent, buildGoalMessage, serializeGoalMessage, parseGoalMessages } from './lib.mjs';
|
|
25
25
|
import { createSerialQueue } from './lib.mjs';
|
|
26
26
|
import { collectProjectRules } from './lib.mjs';
|
|
27
|
+
import { FALLBACK_CODEX_MODELS, loadCodexModels } from './codex-models.mjs';
|
|
28
|
+
import { CLAUDE_MODELS } from './claude-models.mjs';
|
|
27
29
|
import { openPR } from './pr.mjs';
|
|
28
30
|
import { runVerification, exerciseUi } from './verify.mjs';
|
|
29
31
|
|
|
@@ -71,8 +73,8 @@ const WORKER_TIMEOUT_MS = Number(process.env.MANAGER_WORKER_TIMEOUT_MS) || 15 *
|
|
|
71
73
|
// review card showed a truncated report and called it evidence. Keep a cap —
|
|
72
74
|
// this lands in persisted state — but one that fits a real answer.
|
|
73
75
|
const RESULT_MAX = 20000;
|
|
74
|
-
const MODELS =
|
|
75
|
-
|
|
76
|
+
const MODELS = CLAUDE_MODELS;
|
|
77
|
+
let CODEX_MODELS = FALLBACK_CODEX_MODELS.slice();
|
|
76
78
|
const WORKER_AGENTS = ['claude-code', 'codex'];
|
|
77
79
|
const CLAUDE_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'];
|
|
78
80
|
const CODEX_EFFORTS = ['low', 'medium', 'high', 'xhigh'];
|
|
@@ -647,14 +649,25 @@ let _syncDirtyAgain = false; // a save landed mid-push → coalesce into
|
|
|
647
649
|
// Which worker agent CLIs are installed on this machine — the launcher
|
|
648
650
|
// (bin/manager-for-ai.mjs) detects them (codex via a PATH lookup, never executed)
|
|
649
651
|
// and passes the set here. Galda offers only these, so a Codex-only machine gets
|
|
650
|
-
// a working board and a claude-only one never shows Codex.
|
|
651
|
-
//
|
|
652
|
-
|
|
652
|
+
// a working board and a claude-only one never shows Codex.
|
|
653
|
+
// The packaged launcher sets MANAGER_AVAILABLE_AGENTS after its safe CLI probe.
|
|
654
|
+
// Direct starts (launchd, `npm start`, development) bypass that launcher, so do
|
|
655
|
+
// the same non-executing PATH lookup here instead of silently becoming
|
|
656
|
+
// Claude-only. Never invoke an agent, npx, or an installer during detection.
|
|
657
|
+
const configuredAgents = process.env.MANAGER_AVAILABLE_AGENTS;
|
|
658
|
+
const detectedAgents = configuredAgents === undefined
|
|
659
|
+
? [
|
|
660
|
+
isCommandOnPath('claude', { pathEnv: process.env.PATH || '', sep: process.platform === 'win32' ? ';' : ':', pathExt: process.env.PATHEXT || '' }) && 'claude-code',
|
|
661
|
+
isCommandOnPath('codex', { pathEnv: process.env.PATH || '', sep: process.platform === 'win32' ? ';' : ':', pathExt: process.env.PATHEXT || '' }) && 'codex',
|
|
662
|
+
].filter(Boolean).join(',')
|
|
663
|
+
: configuredAgents;
|
|
664
|
+
const envAgents = (detectedAgents || 'claude-code')
|
|
653
665
|
.split(',').map((a) => a.trim()).filter(Boolean);
|
|
654
666
|
const AVAILABLE_AGENTS = resolveConnectedAgents({
|
|
655
667
|
claude: envAgents.includes('claude-code'),
|
|
656
668
|
codex: envAgents.includes('codex'),
|
|
657
669
|
});
|
|
670
|
+
if (AVAILABLE_AGENTS.includes('codex')) CODEX_MODELS = loadCodexModels();
|
|
658
671
|
|
|
659
672
|
// ---- state ---------------------------------------------------------------
|
|
660
673
|
// Restarts must not lose pending work: tasks that never started stay
|
package/package.json
CHANGED