-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdefaults.mjs
More file actions
94 lines (83 loc) · 3.11 KB
/
defaults.mjs
File metadata and controls
94 lines (83 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Persistent command-default helpers for the OpenCode companion.
//
// `/opencode:setup` can persist defaults in `state.config.defaults`.
// These helpers keep precedence rules centralized and testable:
// explicit runtime flags win, otherwise saved defaults apply.
import { parseModelString } from "./model.mjs";
const SUPPORTED_DEFAULT_AGENTS = new Set(["build", "plan"]);
/**
* @param {Record<string, unknown>|undefined|null} options
* @param {string} key
* @returns {boolean}
*/
export function hasOwnOption(options, key) {
return Object.prototype.hasOwnProperty.call(options ?? {}, key);
}
/**
* Normalize persisted defaults read from state. Invalid or missing values are
* ignored so a hand-edited state file cannot break every command invocation.
* @param {unknown} raw
* @returns {{ model: string | null, agent: string | null }}
*/
export function normalizeDefaults(raw) {
const defaults = raw && typeof raw === "object" ? raw : {};
const modelRaw = typeof defaults.model === "string" ? defaults.model.trim() : "";
const model = modelRaw && parseModelString(modelRaw) ? modelRaw : null;
const agentRaw = typeof defaults.agent === "string" ? defaults.agent.trim() : "";
const agent = SUPPORTED_DEFAULT_AGENTS.has(agentRaw) ? agentRaw : null;
return { model, agent };
}
/**
* Parse a `/opencode:setup --default-model` value. Returns null for "off".
* @param {unknown} value
* @returns {string | null}
*/
export function parseDefaultModelSetting(value) {
const raw = typeof value === "string" ? value.trim() : "";
if (raw === "off") return null;
if (!raw || !parseModelString(raw)) {
throw new Error(
`--default-model must be "off" or a provider/model-id value ` +
`(e.g. anthropic/claude-opus-4-6).`
);
}
return raw;
}
/**
* Parse a `/opencode:setup --default-agent` value. Returns null for "off".
* @param {unknown} value
* @returns {"build" | "plan" | null}
*/
export function parseDefaultAgentSetting(value) {
const raw = typeof value === "string" ? value.trim() : "";
if (raw === "off") return null;
if (!SUPPORTED_DEFAULT_AGENTS.has(raw)) {
throw new Error(`--default-agent must be "build", "plan", or "off".`);
}
return raw;
}
/**
* Apply a persisted model default when the user did not explicitly supply
* either `--model` or `--free`.
* @param {Record<string, unknown>} options
* @param {{ model?: string | null }} defaults
* @returns {Record<string, unknown>}
*/
export function applyDefaultModelOptions(options, defaults) {
if (hasOwnOption(options, "model") || options?.free) return options;
if (!defaults?.model) return options;
return { ...options, model: defaults.model };
}
/**
* Resolve the task agent using explicit CLI args first, then persisted
* defaults, then the existing write/read-only fallback.
* @param {Record<string, unknown>} options
* @param {{ agent?: string | null }} defaults
* @param {boolean} isWrite
* @returns {string}
*/
export function resolveTaskAgentName(options, defaults, isWrite) {
if (hasOwnOption(options, "agent")) return options.agent;
if (defaults?.agent) return defaults.agent;
return isWrite ? "build" : "plan";
}