+30
-2
@@ -9,6 +9,35 @@ const entrySchema = z
|
||||
.object({ package: z.string(), options: z.record(z.string(), z.json()).optional() })
|
||||
.catchall(z.json());
|
||||
type Entry = z.infer<typeof entrySchema>;
|
||||
type Options = NonNullable<Entry["options"]>;
|
||||
|
||||
// Every option the plugins read, empty so users can fill them in; plugins treat "" as unset.
|
||||
function skeleton(name: (typeof names)[number]): Options {
|
||||
if (name === "agents")
|
||||
return {
|
||||
agents: Object.fromEntries(
|
||||
["fast-lo", "fast-hi", "good-lo", "good-hi", "deep-lo", "deep-hi"].map((worker) => [
|
||||
worker,
|
||||
"",
|
||||
]),
|
||||
),
|
||||
};
|
||||
if (name === "optchat") return { compactionModel: "", dataDir: "" };
|
||||
return {};
|
||||
}
|
||||
const nested = z.record(z.string(), z.json());
|
||||
/** Adds missing keys from `defaults` without overwriting existing values. */
|
||||
function fill(target: Options, defaults: Options) {
|
||||
for (const [key, value] of Object.entries(defaults)) {
|
||||
const existing = nested.safeParse(target[key]);
|
||||
const missing = nested.safeParse(value);
|
||||
if (target[key] === undefined) target[key] = structuredClone(value);
|
||||
else if (existing.success && missing.success) {
|
||||
fill(existing.data, missing.data);
|
||||
target[key] = existing.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
const pluginSchema = z.union([z.string(), entrySchema]);
|
||||
const registrationSchema = z
|
||||
.union([z.string().transform((packageName) => ({ package: packageName })), entrySchema])
|
||||
@@ -105,10 +134,9 @@ export async function install(source: string, config: string, selection?: string
|
||||
(name === "agents" && monolith(entry.package)),
|
||||
);
|
||||
const options: NonNullable<Entry["options"]> = {};
|
||||
if (name === "agents" && !prior?.options)
|
||||
Object.assign(options, { mode: "gpt", provider: "openai", lunaPriority: true });
|
||||
Object.assign(options, prior?.options);
|
||||
delete options.playwright;
|
||||
fill(options, skeleton(name));
|
||||
const entry = entrySchema.parse({ ...prior, package: `${base}/${name}` });
|
||||
delete entry.options;
|
||||
if (Object.keys(options).length) entry.options = options;
|
||||
|
||||
Reference in New Issue
Block a user