mirror of
https://github.com/Narcooo/inkos.git
synced 2026-09-24 15:29:47 +08:00
feat: add version migration check to doctor command
Detects books using legacy pre-v0.6 format (no story/state/ directory) and advises running write next to auto-migrate. Addresses #95
This commit is contained in:
@@ -117,6 +117,36 @@ export const doctorCommand = new Command("doctor")
|
||||
checks.push({ name: "Books", ok: true, detail: "0 books" });
|
||||
}
|
||||
|
||||
// 5b. Check version migration status
|
||||
{
|
||||
const { existsSync } = await import("node:fs");
|
||||
const hasStructuredState = existsSync(join(root, "books"));
|
||||
if (hasStructuredState) {
|
||||
const { StateManager } = await import("@actalk/inkos-core");
|
||||
const sm = new StateManager(root);
|
||||
const bookIds = await sm.listBooks();
|
||||
let legacyCount = 0;
|
||||
for (const bid of bookIds) {
|
||||
const stateDir = join(sm.bookDir(bid), "story", "state");
|
||||
const hasNewState = existsSync(stateDir);
|
||||
if (!hasNewState) legacyCount++;
|
||||
}
|
||||
if (legacyCount > 0) {
|
||||
checks.push({
|
||||
name: "Version Migration",
|
||||
ok: false,
|
||||
detail: `${legacyCount} book(s) using legacy format (pre-v0.6). Run 'inkos write next' on each to auto-migrate, or re-init with 'inkos init'.`,
|
||||
});
|
||||
} else if (bookIds.length > 0) {
|
||||
checks.push({
|
||||
name: "Version Migration",
|
||||
ok: true,
|
||||
detail: "All books use current format",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 6. API connectivity test
|
||||
try {
|
||||
const { createLLMClient, chatCompletion, LLMConfigSchema, isApiKeyOptionalForEndpoint } = await import("@actalk/inkos-core");
|
||||
|
||||
@@ -430,11 +430,11 @@ describe("StateManager", () => {
|
||||
await writeFile(join(chapDir, "0001_ch1.md"), "# Chapter 1\nContent 1", "utf-8");
|
||||
await writeFile(join(chapDir, "0002_ch2.md"), "# Chapter 2\nContent 2", "utf-8");
|
||||
await writeFile(join(chapDir, "0003_ch3.md"), "# Chapter 3\nContent 3", "utf-8");
|
||||
const fullIndex = [
|
||||
{ number: 1, title: "Ch1", status: "approved", wordCount: 100, createdAt: "", updatedAt: "", auditIssues: [] },
|
||||
{ number: 2, title: "Ch2", status: "approved", wordCount: 100, createdAt: "", updatedAt: "", auditIssues: [] },
|
||||
{ number: 3, title: "Ch3", status: "approved", wordCount: 100, createdAt: "", updatedAt: "", auditIssues: [] },
|
||||
];
|
||||
const mkEntry = (n: number) => ({
|
||||
number: n, title: `Ch${n}`, status: "approved" as const, wordCount: 100,
|
||||
createdAt: "", updatedAt: "", auditIssues: [] as string[], lengthWarnings: [] as string[],
|
||||
});
|
||||
const fullIndex = [mkEntry(1), mkEntry(2), mkEntry(3)];
|
||||
await manager.saveChapterIndex(rwBookId, fullIndex);
|
||||
|
||||
// Snapshot state at chapter 1 (before chapter 2)
|
||||
|
||||
Reference in New Issue
Block a user