feat(baoyu-imagine): auto-migrate legacy baoyu-image-gen EXTEND.md config path
This commit is contained in:
parent
7a0ffd9533
commit
b6bf8ecd06
|
|
@ -55,6 +55,8 @@ if (Test-Path "$HOME/.baoyu-skills/baoyu-imagine/EXTEND.md") { "user" }
|
|||
| `.baoyu-skills/baoyu-imagine/EXTEND.md` | Project directory |
|
||||
| `$HOME/.baoyu-skills/baoyu-imagine/EXTEND.md` | User home |
|
||||
|
||||
Legacy compatibility: if `.baoyu-skills/baoyu-image-gen/EXTEND.md` exists and the new path does not, runtime renames it to `baoyu-imagine`. If both files exist, runtime leaves them unchanged and uses the new path.
|
||||
|
||||
**EXTEND.md Supports**: Default provider | Default quality | Default aspect ratio | Default image size | Default models | Batch worker cap | Provider-specific batch limits
|
||||
|
||||
Schema: `references/config/preferences-schema.md`
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import {
|
|||
getWorkerCount,
|
||||
isRetryableGenerationError,
|
||||
loadBatchTasks,
|
||||
loadExtendConfig,
|
||||
mergeConfig,
|
||||
normalizeOutputImagePath,
|
||||
parseArgs,
|
||||
|
|
@ -170,6 +171,61 @@ batch:
|
|||
});
|
||||
});
|
||||
|
||||
test("loadExtendConfig renames legacy EXTEND.md when the new path is missing", async () => {
|
||||
const root = await makeTempDir("baoyu-imagine-extend-");
|
||||
const cwd = path.join(root, "project");
|
||||
const home = path.join(root, "home");
|
||||
const legacyPath = path.join(cwd, ".baoyu-skills", "baoyu-image-gen", "EXTEND.md");
|
||||
const currentPath = path.join(cwd, ".baoyu-skills", "baoyu-imagine", "EXTEND.md");
|
||||
|
||||
await fs.mkdir(path.dirname(legacyPath), { recursive: true });
|
||||
await fs.mkdir(home, { recursive: true });
|
||||
await fs.writeFile(legacyPath, `---
|
||||
default_provider: google
|
||||
default_quality: 2k
|
||||
---
|
||||
`);
|
||||
|
||||
const config = await loadExtendConfig(cwd, home);
|
||||
|
||||
assert.equal(config.default_provider, "google");
|
||||
assert.equal(config.default_quality, "2k");
|
||||
await fs.access(currentPath);
|
||||
await assert.rejects(() => fs.access(legacyPath));
|
||||
});
|
||||
|
||||
test("loadExtendConfig leaves legacy EXTEND.md untouched when both paths exist", async () => {
|
||||
const root = await makeTempDir("baoyu-imagine-extend-dual-");
|
||||
const cwd = path.join(root, "project");
|
||||
const home = path.join(root, "home");
|
||||
const legacyPath = path.join(cwd, ".baoyu-skills", "baoyu-image-gen", "EXTEND.md");
|
||||
const currentPath = path.join(cwd, ".baoyu-skills", "baoyu-imagine", "EXTEND.md");
|
||||
|
||||
await fs.mkdir(path.dirname(legacyPath), { recursive: true });
|
||||
await fs.mkdir(path.dirname(currentPath), { recursive: true });
|
||||
await fs.mkdir(home, { recursive: true });
|
||||
await fs.writeFile(legacyPath, `---
|
||||
default_provider: google
|
||||
---
|
||||
`);
|
||||
await fs.writeFile(currentPath, `---
|
||||
default_provider: openai
|
||||
---
|
||||
`);
|
||||
|
||||
const config = await loadExtendConfig(cwd, home);
|
||||
|
||||
assert.equal(config.default_provider, "openai");
|
||||
assert.equal(await fs.readFile(legacyPath, "utf8"), `---
|
||||
default_provider: google
|
||||
---
|
||||
`);
|
||||
assert.equal(await fs.readFile(currentPath, "utf8"), `---
|
||||
default_provider: openai
|
||||
---
|
||||
`);
|
||||
});
|
||||
|
||||
test("mergeConfig only fills values missing from CLI args", () => {
|
||||
const merged = mergeConfig(
|
||||
makeArgs({
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import path from "node:path";
|
|||
import process from "node:process";
|
||||
import { homedir } from "node:os";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
||||
import { access, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
||||
import type {
|
||||
BatchFile,
|
||||
BatchTaskInput,
|
||||
|
|
@ -471,14 +471,49 @@ export function parseSimpleYaml(yaml: string): Partial<ExtendConfig> {
|
|||
return config;
|
||||
}
|
||||
|
||||
async function loadExtendConfig(): Promise<Partial<ExtendConfig>> {
|
||||
const home = homedir();
|
||||
const cwd = process.cwd();
|
||||
type ExtendConfigPathPair = {
|
||||
current: string;
|
||||
legacy: string;
|
||||
};
|
||||
|
||||
const paths = [
|
||||
path.join(cwd, ".baoyu-skills", "baoyu-imagine", "EXTEND.md"),
|
||||
path.join(home, ".baoyu-skills", "baoyu-imagine", "EXTEND.md"),
|
||||
function getExtendConfigPathPairs(cwd: string, home: string): ExtendConfigPathPair[] {
|
||||
return [
|
||||
{
|
||||
current: path.join(cwd, ".baoyu-skills", "baoyu-imagine", "EXTEND.md"),
|
||||
legacy: path.join(cwd, ".baoyu-skills", "baoyu-image-gen", "EXTEND.md"),
|
||||
},
|
||||
{
|
||||
current: path.join(home, ".baoyu-skills", "baoyu-imagine", "EXTEND.md"),
|
||||
legacy: path.join(home, ".baoyu-skills", "baoyu-image-gen", "EXTEND.md"),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
async function exists(filePath: string): Promise<boolean> {
|
||||
try {
|
||||
await access(filePath);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function migrateLegacyExtendConfig(cwd: string, home: string): Promise<void> {
|
||||
for (const { current, legacy } of getExtendConfigPathPairs(cwd, home)) {
|
||||
const [hasCurrent, hasLegacy] = await Promise.all([exists(current), exists(legacy)]);
|
||||
if (hasCurrent || !hasLegacy) continue;
|
||||
await mkdir(path.dirname(current), { recursive: true });
|
||||
await rename(legacy, current);
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadExtendConfig(
|
||||
cwd = process.cwd(),
|
||||
home = homedir(),
|
||||
): Promise<Partial<ExtendConfig>> {
|
||||
await migrateLegacyExtendConfig(cwd, home);
|
||||
|
||||
const paths = getExtendConfigPathPairs(cwd, home).map(({ current }) => current);
|
||||
|
||||
for (const p of paths) {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue