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 |
|
| `.baoyu-skills/baoyu-imagine/EXTEND.md` | Project directory |
|
||||||
| `$HOME/.baoyu-skills/baoyu-imagine/EXTEND.md` | User home |
|
| `$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
|
**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`
|
Schema: `references/config/preferences-schema.md`
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {
|
||||||
getWorkerCount,
|
getWorkerCount,
|
||||||
isRetryableGenerationError,
|
isRetryableGenerationError,
|
||||||
loadBatchTasks,
|
loadBatchTasks,
|
||||||
|
loadExtendConfig,
|
||||||
mergeConfig,
|
mergeConfig,
|
||||||
normalizeOutputImagePath,
|
normalizeOutputImagePath,
|
||||||
parseArgs,
|
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", () => {
|
test("mergeConfig only fills values missing from CLI args", () => {
|
||||||
const merged = mergeConfig(
|
const merged = mergeConfig(
|
||||||
makeArgs({
|
makeArgs({
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import path from "node:path";
|
||||||
import process from "node:process";
|
import process from "node:process";
|
||||||
import { homedir } from "node:os";
|
import { homedir } from "node:os";
|
||||||
import { fileURLToPath } from "node:url";
|
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 {
|
import type {
|
||||||
BatchFile,
|
BatchFile,
|
||||||
BatchTaskInput,
|
BatchTaskInput,
|
||||||
|
|
@ -471,14 +471,49 @@ export function parseSimpleYaml(yaml: string): Partial<ExtendConfig> {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadExtendConfig(): Promise<Partial<ExtendConfig>> {
|
type ExtendConfigPathPair = {
|
||||||
const home = homedir();
|
current: string;
|
||||||
const cwd = process.cwd();
|
legacy: string;
|
||||||
|
};
|
||||||
|
|
||||||
const paths = [
|
function getExtendConfigPathPairs(cwd: string, home: string): ExtendConfigPathPair[] {
|
||||||
path.join(cwd, ".baoyu-skills", "baoyu-imagine", "EXTEND.md"),
|
return [
|
||||||
path.join(home, ".baoyu-skills", "baoyu-imagine", "EXTEND.md"),
|
{
|
||||||
|
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) {
|
for (const p of paths) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue