mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-12 10:19:42 +02:00
- Codex footer model detection (c28): the modelDetect.screenLine effort alternation is now built from CODEX_REASONING_EFFORTS plus 'default', so 'ultra' (offered by the codexReasoningEffort App Setting and codex's own /model picker) is read and the launch enum and the footer reader cannot drift again. Still one capture group, 125 characters, no new quantifier. New session-display-model case loops every effort level, ultra included. - No CLI-id branching for launch defaults (c27): the two mode === 'codex' branches the synced codex model/effort defaults added to the create and quick-start routes are replaced by a registry capability, capabilities.launchDefaults (launch param -> settings key, values from a closed enum), declared on the codex entry only. The resolver moved from web/codex-launch-defaults.ts to web/launch-defaults.ts as applyLaunchDefaults(mode, configs, customEndpoint), filling the entry's legacyConfigField object through legacyConfigAliases, still re-validating with SettingsUpdateSchema and never overwriting a caller's value. The route exclusions are unchanged (create: not remote; quick-start: not remote, not Docker, not a custom model endpoint), and quick-start still derives the session model from a bag without ompConfig, as before. schema.ts refuses an undeclared param, an unknown settings key, an empty map, and launchDefaults on an entry with no legacyConfigField. - The no-id-branching guard now carries an exact occurrence count per allowlisted key, so a new copy of an already approved expression fails instead of riding the old approval, with a synthetic anti-vacuity case. - SettingsUpdateSchema JSDoc (c21/c29): 'classic' is the tabArrangement default and 'compact' the headerStatsStyle default, matching the resolvers and the pre-paint script; state/case/ledger are marked opt-in. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
50 lines
2.5 KiB
TypeScript
50 lines
2.5 KiB
TypeScript
/**
|
|
* @fileoverview Launch-time defaults from synced App Settings, driven by registry data.
|
|
*
|
|
* A CLI entry declares `capabilities.launchDefaults` (launch param -> settings key; today
|
|
* only codex, `{ model: 'codexModel', reasoningEffort: 'codexReasoningEffort' }`), and
|
|
* `applyLaunchDefaults()` fills those settings into the entry's `launch.legacyConfigField`
|
|
* object, setting ONLY the fields the caller left unset. Persisted values are re-validated
|
|
* with `SettingsUpdateSchema`, so a hand-edited settings.json can never smuggle an
|
|
* unchecked value onto the command line.
|
|
*
|
|
* Scope is the caller's decision: the create and quick-start routes apply it to local
|
|
* launches only, never to remote, Docker or custom-endpoint launches. Nothing here writes
|
|
* a CLI's own config files.
|
|
*/
|
|
|
|
import { getCli } from '../config/cli-registry/registry.js';
|
|
import { SettingsUpdateSchema } from './schemas.js';
|
|
import { readJsonConfig, SETTINGS_PATH } from './route-helpers.js';
|
|
|
|
/**
|
|
* Return `configs` with the launch defaults of `mode`'s registry entry filled into its
|
|
* legacy config object (e.g. `codexConfig`). Every other field of `configs` is passed
|
|
* through untouched, and `configs` itself comes back unchanged (same object) when the entry
|
|
* declares no defaults, `customEndpoint` is set, or no setting names a value.
|
|
*/
|
|
export async function applyLaunchDefaults<T extends object>(
|
|
mode: string,
|
|
configs: T,
|
|
customEndpoint = false
|
|
): Promise<T> {
|
|
const entry = getCli(mode);
|
|
const declared = entry?.capabilities.launchDefaults;
|
|
const field = entry?.launch.legacyConfigField;
|
|
if (customEndpoint || !declared || field === undefined) return configs;
|
|
|
|
const settings = await readJsonConfig<Record<string, unknown>>(SETTINGS_PATH, 'CLI launch defaults', {});
|
|
const aliases = entry.launch.legacyConfigAliases ?? {};
|
|
const current = (configs as Record<string, unknown>)[field] as Record<string, unknown> | undefined;
|
|
const defaults: Record<string, unknown> = {};
|
|
for (const [param, settingKey] of Object.entries(declared)) {
|
|
const parsed = SettingsUpdateSchema.shape[settingKey].safeParse(settings[settingKey]);
|
|
// '' is the settings' "leave it to the CLI" value, the same as unset.
|
|
const value = parsed.success ? parsed.data || undefined : undefined;
|
|
const wireKey = aliases[param] ?? param;
|
|
if (value !== undefined && (current?.[wireKey] ?? undefined) === undefined) defaults[wireKey] = value;
|
|
}
|
|
if (Object.keys(defaults).length === 0) return configs;
|
|
return { ...configs, [field]: { ...current, ...defaults } };
|
|
}
|