revise.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { Command } from "commander";
  2. import { DEFAULT_REVISE_MODE, PipelineRunner, type ReviseMode } from "@actalk/inkos-core";
  3. import { loadConfig, buildPipelineConfig, findProjectRoot, resolveBookId, log, logError } from "../utils.js";
  4. export const reviseCommand = new Command("revise")
  5. .description("Revise a chapter based on audit issues")
  6. .argument("[book-id]", "Book ID (auto-detected if only one book)")
  7. .argument("[chapter]", "Chapter number (defaults to latest)")
  8. .option("--mode <mode>", "Revise mode: spot-fix, polish, rewrite, rework, anti-detect", DEFAULT_REVISE_MODE)
  9. .option("--json", "Output JSON")
  10. .action(async (bookIdArg: string | undefined, chapterStr: string | undefined, opts) => {
  11. try {
  12. const config = await loadConfig();
  13. const root = findProjectRoot();
  14. let bookId: string;
  15. let chapterNumber: number | undefined;
  16. if (bookIdArg && /^\d+$/.test(bookIdArg)) {
  17. bookId = await resolveBookId(undefined, root);
  18. chapterNumber = parseInt(bookIdArg, 10);
  19. } else {
  20. bookId = await resolveBookId(bookIdArg, root);
  21. chapterNumber = chapterStr ? parseInt(chapterStr, 10) : undefined;
  22. }
  23. const pipeline = new PipelineRunner(buildPipelineConfig(config, root));
  24. const mode = opts.mode as ReviseMode;
  25. if (!opts.json) log(`Revising "${bookId}"${chapterNumber ? ` chapter ${chapterNumber}` : " (latest)"} [mode: ${mode}]...`);
  26. const result = await pipeline.reviseDraft(bookId, chapterNumber, mode);
  27. if (opts.json) {
  28. log(JSON.stringify(result, null, 2));
  29. } else if (!result.applied) {
  30. log(` Chapter ${result.chapterNumber}: kept original draft`);
  31. if (result.skippedReason) log(` Reason: ${result.skippedReason}`);
  32. } else {
  33. log(` Chapter ${result.chapterNumber} revised`);
  34. log(` Words: ${result.wordCount}`);
  35. log(` Status: ${result.status}`);
  36. log(" Fixed:");
  37. for (const fix of result.fixedIssues) {
  38. log(` - ${fix}`);
  39. }
  40. }
  41. } catch (e) {
  42. if (opts.json) {
  43. log(JSON.stringify({ error: String(e) }));
  44. } else {
  45. logError(`Revise failed: ${e}`);
  46. }
  47. process.exit(1);
  48. }
  49. });