mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-10 09:19:42 +02:00
fix(cli-registry): codex launch defaults as registry data, ultra footer, schema doc defaults
- 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>
This commit is contained in:
@@ -291,6 +291,57 @@ describe('cross-field integrity', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('capabilities.launchDefaults', () => {
|
||||
/** Codex with its shipped launch defaults replaced by `launchDefaults` (or with them unchanged). */
|
||||
function codexWith(mutate: (entry: Record<string, unknown>) => void): boolean {
|
||||
const entry = baseEntry('codex');
|
||||
mutate(entry);
|
||||
return CliEntrySchema.safeParse(entry).success;
|
||||
}
|
||||
const setDefaults = (value: unknown) => (e: Record<string, unknown>) => {
|
||||
(e.capabilities as Record<string, unknown>).launchDefaults = value;
|
||||
};
|
||||
|
||||
it('ships on codex alone, keyed by launch param', () => {
|
||||
const declaring = STOCK_CLIS.filter((e) => e.capabilities.launchDefaults !== undefined).map((e) => e.id);
|
||||
expect(declaring).toEqual(['codex']);
|
||||
expect(codexWith(() => {})).toBe(true);
|
||||
});
|
||||
|
||||
it('rejects a param the entry never declared', () => {
|
||||
// Filled into the config object and then read by nothing: a silent no-op, like a
|
||||
// privilegedParams clamp naming the wrong param.
|
||||
expect(codexWith(setDefaults({ effort: 'codexReasoningEffort' }))).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects a settings key outside the closed list', () => {
|
||||
// An override must not be able to pour an arbitrary setting onto a command line.
|
||||
expect(codexWith(setDefaults({ model: 'claudeModel' }))).toBe(false);
|
||||
expect(codexWith(setDefaults({ model: 'codexmodel' }))).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects an empty map', () => {
|
||||
expect(codexWith(setDefaults({}))).toBe(false);
|
||||
});
|
||||
|
||||
it('refuses an entry with no legacyConfigField to fill', () => {
|
||||
// Without one the params are read off the request body itself, where `model` is
|
||||
// claude's per-session field, not this CLI's.
|
||||
expect(
|
||||
codexWith((e) => {
|
||||
delete (e.launch as Record<string, unknown>).legacyConfigField;
|
||||
})
|
||||
).toBe(false);
|
||||
// The same entry without launch defaults is fine: the refusal is about the pair.
|
||||
expect(
|
||||
codexWith((e) => {
|
||||
delete (e.launch as Record<string, unknown>).legacyConfigField;
|
||||
delete (e.capabilities as Record<string, unknown>).launchDefaults;
|
||||
})
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('the env allowlist cannot be widened by config', () => {
|
||||
it('requires a prefix to end with an underscore', () => {
|
||||
expectRejected((e) => {
|
||||
|
||||
Reference in New Issue
Block a user