@kienmatu/inkos 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/LICENSE +661 -0
  2. package/dist/book-backup.d.ts +33 -0
  3. package/dist/book-backup.d.ts.map +1 -0
  4. package/dist/book-backup.js +74 -0
  5. package/dist/book-backup.js.map +1 -0
  6. package/dist/commands/agent.d.ts +3 -0
  7. package/dist/commands/agent.d.ts.map +1 -0
  8. package/dist/commands/agent.js +71 -0
  9. package/dist/commands/agent.js.map +1 -0
  10. package/dist/commands/analytics.d.ts +3 -0
  11. package/dist/commands/analytics.d.ts.map +1 -0
  12. package/dist/commands/analytics.js +74 -0
  13. package/dist/commands/analytics.js.map +1 -0
  14. package/dist/commands/audit.d.ts +3 -0
  15. package/dist/commands/audit.d.ts.map +1 -0
  16. package/dist/commands/audit.js +81 -0
  17. package/dist/commands/audit.js.map +1 -0
  18. package/dist/commands/auto.d.ts +3 -0
  19. package/dist/commands/auto.d.ts.map +1 -0
  20. package/dist/commands/auto.js +136 -0
  21. package/dist/commands/auto.js.map +1 -0
  22. package/dist/commands/book.d.ts +3 -0
  23. package/dist/commands/book.d.ts.map +1 -0
  24. package/dist/commands/book.js +324 -0
  25. package/dist/commands/book.js.map +1 -0
  26. package/dist/commands/chapter.d.ts +3 -0
  27. package/dist/commands/chapter.d.ts.map +1 -0
  28. package/dist/commands/chapter.js +103 -0
  29. package/dist/commands/chapter.js.map +1 -0
  30. package/dist/commands/compose.d.ts +3 -0
  31. package/dist/commands/compose.d.ts.map +1 -0
  32. package/dist/commands/compose.js +46 -0
  33. package/dist/commands/compose.js.map +1 -0
  34. package/dist/commands/config.d.ts +3 -0
  35. package/dist/commands/config.d.ts.map +1 -0
  36. package/dist/commands/config.js +321 -0
  37. package/dist/commands/config.js.map +1 -0
  38. package/dist/commands/consolidate.d.ts +3 -0
  39. package/dist/commands/consolidate.d.ts.map +1 -0
  40. package/dist/commands/consolidate.js +50 -0
  41. package/dist/commands/consolidate.js.map +1 -0
  42. package/dist/commands/daemon.d.ts +4 -0
  43. package/dist/commands/daemon.d.ts.map +1 -0
  44. package/dist/commands/daemon.js +118 -0
  45. package/dist/commands/daemon.js.map +1 -0
  46. package/dist/commands/detect.d.ts +3 -0
  47. package/dist/commands/detect.d.ts.map +1 -0
  48. package/dist/commands/detect.js +104 -0
  49. package/dist/commands/detect.js.map +1 -0
  50. package/dist/commands/doctor.d.ts +8 -0
  51. package/dist/commands/doctor.d.ts.map +1 -0
  52. package/dist/commands/doctor.js +356 -0
  53. package/dist/commands/doctor.js.map +1 -0
  54. package/dist/commands/draft.d.ts +3 -0
  55. package/dist/commands/draft.d.ts.map +1 -0
  56. package/dist/commands/draft.js +42 -0
  57. package/dist/commands/draft.js.map +1 -0
  58. package/dist/commands/eval.d.ts +3 -0
  59. package/dist/commands/eval.d.ts.map +1 -0
  60. package/dist/commands/eval.js +57 -0
  61. package/dist/commands/eval.js.map +1 -0
  62. package/dist/commands/export.d.ts +3 -0
  63. package/dist/commands/export.d.ts.map +1 -0
  64. package/dist/commands/export.js +46 -0
  65. package/dist/commands/export.js.map +1 -0
  66. package/dist/commands/fanfic.d.ts +3 -0
  67. package/dist/commands/fanfic.d.ts.map +1 -0
  68. package/dist/commands/fanfic.js +177 -0
  69. package/dist/commands/fanfic.js.map +1 -0
  70. package/dist/commands/forecast.d.ts +12 -0
  71. package/dist/commands/forecast.d.ts.map +1 -0
  72. package/dist/commands/forecast.js +156 -0
  73. package/dist/commands/forecast.js.map +1 -0
  74. package/dist/commands/genre.d.ts +11 -0
  75. package/dist/commands/genre.d.ts.map +1 -0
  76. package/dist/commands/genre.js +186 -0
  77. package/dist/commands/genre.js.map +1 -0
  78. package/dist/commands/import.d.ts +3 -0
  79. package/dist/commands/import.d.ts.map +1 -0
  80. package/dist/commands/import.js +110 -0
  81. package/dist/commands/import.js.map +1 -0
  82. package/dist/commands/init.d.ts +3 -0
  83. package/dist/commands/init.d.ts.map +1 -0
  84. package/dist/commands/init.js +63 -0
  85. package/dist/commands/init.js.map +1 -0
  86. package/dist/commands/interact.d.ts +6 -0
  87. package/dist/commands/interact.d.ts.map +1 -0
  88. package/dist/commands/interact.js +95 -0
  89. package/dist/commands/interact.js.map +1 -0
  90. package/dist/commands/plan.d.ts +3 -0
  91. package/dist/commands/plan.d.ts.map +1 -0
  92. package/dist/commands/plan.js +50 -0
  93. package/dist/commands/plan.js.map +1 -0
  94. package/dist/commands/radar.d.ts +3 -0
  95. package/dist/commands/radar.d.ts.map +1 -0
  96. package/dist/commands/radar.js +52 -0
  97. package/dist/commands/radar.js.map +1 -0
  98. package/dist/commands/review.d.ts +3 -0
  99. package/dist/commands/review.d.ts.map +1 -0
  100. package/dist/commands/review.js +229 -0
  101. package/dist/commands/review.js.map +1 -0
  102. package/dist/commands/revise.d.ts +3 -0
  103. package/dist/commands/revise.d.ts.map +1 -0
  104. package/dist/commands/revise.js +91 -0
  105. package/dist/commands/revise.js.map +1 -0
  106. package/dist/commands/short-fiction.d.ts +4 -0
  107. package/dist/commands/short-fiction.d.ts.map +1 -0
  108. package/dist/commands/short-fiction.js +220 -0
  109. package/dist/commands/short-fiction.js.map +1 -0
  110. package/dist/commands/status.d.ts +3 -0
  111. package/dist/commands/status.d.ts.map +1 -0
  112. package/dist/commands/status.js +123 -0
  113. package/dist/commands/status.js.map +1 -0
  114. package/dist/commands/studio.d.ts +21 -0
  115. package/dist/commands/studio.d.ts.map +1 -0
  116. package/dist/commands/studio.js +151 -0
  117. package/dist/commands/studio.js.map +1 -0
  118. package/dist/commands/style.d.ts +3 -0
  119. package/dist/commands/style.d.ts.map +1 -0
  120. package/dist/commands/style.js +95 -0
  121. package/dist/commands/style.js.map +1 -0
  122. package/dist/commands/translate.d.ts +3 -0
  123. package/dist/commands/translate.d.ts.map +1 -0
  124. package/dist/commands/translate.js +111 -0
  125. package/dist/commands/translate.js.map +1 -0
  126. package/dist/commands/tui.d.ts +6 -0
  127. package/dist/commands/tui.d.ts.map +1 -0
  128. package/dist/commands/tui.js +14 -0
  129. package/dist/commands/tui.js.map +1 -0
  130. package/dist/commands/update.d.ts +3 -0
  131. package/dist/commands/update.d.ts.map +1 -0
  132. package/dist/commands/update.js +40 -0
  133. package/dist/commands/update.js.map +1 -0
  134. package/dist/commands/write.d.ts +3 -0
  135. package/dist/commands/write.d.ts.map +1 -0
  136. package/dist/commands/write.js +371 -0
  137. package/dist/commands/write.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +4 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/localization.d.ts +103 -0
  143. package/dist/localization.d.ts.map +1 -0
  144. package/dist/localization.js +377 -0
  145. package/dist/localization.js.map +1 -0
  146. package/dist/notify-helper.d.ts +17 -0
  147. package/dist/notify-helper.d.ts.map +1 -0
  148. package/dist/notify-helper.js +27 -0
  149. package/dist/notify-helper.js.map +1 -0
  150. package/dist/program.d.ts +10 -0
  151. package/dist/program.d.ts.map +1 -0
  152. package/dist/program.js +97 -0
  153. package/dist/program.js.map +1 -0
  154. package/dist/progress-text.d.ts +26 -0
  155. package/dist/progress-text.d.ts.map +1 -0
  156. package/dist/progress-text.js +35 -0
  157. package/dist/progress-text.js.map +1 -0
  158. package/dist/project-bootstrap.d.ts +8 -0
  159. package/dist/project-bootstrap.d.ts.map +1 -0
  160. package/dist/project-bootstrap.js +139 -0
  161. package/dist/project-bootstrap.js.map +1 -0
  162. package/dist/runtime-requirements.d.ts +24 -0
  163. package/dist/runtime-requirements.d.ts.map +1 -0
  164. package/dist/runtime-requirements.js +89 -0
  165. package/dist/runtime-requirements.js.map +1 -0
  166. package/dist/tui/__tests__/markdown.test.d.ts +2 -0
  167. package/dist/tui/__tests__/markdown.test.d.ts.map +1 -0
  168. package/dist/tui/__tests__/markdown.test.js +58 -0
  169. package/dist/tui/__tests__/markdown.test.js.map +1 -0
  170. package/dist/tui/activity-state.d.ts +9 -0
  171. package/dist/tui/activity-state.d.ts.map +1 -0
  172. package/dist/tui/activity-state.js +6 -0
  173. package/dist/tui/activity-state.js.map +1 -0
  174. package/dist/tui/agent-input.d.ts +118 -0
  175. package/dist/tui/agent-input.d.ts.map +1 -0
  176. package/dist/tui/agent-input.js +255 -0
  177. package/dist/tui/agent-input.js.map +1 -0
  178. package/dist/tui/ansi.d.ts +40 -0
  179. package/dist/tui/ansi.d.ts.map +1 -0
  180. package/dist/tui/ansi.js +62 -0
  181. package/dist/tui/ansi.js.map +1 -0
  182. package/dist/tui/app.d.ts +13 -0
  183. package/dist/tui/app.d.ts.map +1 -0
  184. package/dist/tui/app.js +109 -0
  185. package/dist/tui/app.js.map +1 -0
  186. package/dist/tui/chat-depth.d.ts +9 -0
  187. package/dist/tui/chat-depth.d.ts.map +1 -0
  188. package/dist/tui/chat-depth.js +14 -0
  189. package/dist/tui/chat-depth.js.map +1 -0
  190. package/dist/tui/chat-draft.d.ts +4 -0
  191. package/dist/tui/chat-draft.d.ts.map +1 -0
  192. package/dist/tui/chat-draft.js +28 -0
  193. package/dist/tui/chat-draft.js.map +1 -0
  194. package/dist/tui/composer-caret.d.ts +10 -0
  195. package/dist/tui/composer-caret.d.ts.map +1 -0
  196. package/dist/tui/composer-caret.js +13 -0
  197. package/dist/tui/composer-caret.js.map +1 -0
  198. package/dist/tui/composer-display.d.ts +7 -0
  199. package/dist/tui/composer-display.d.ts.map +1 -0
  200. package/dist/tui/composer-display.js +17 -0
  201. package/dist/tui/composer-display.js.map +1 -0
  202. package/dist/tui/dashboard-model.d.ts +46 -0
  203. package/dist/tui/dashboard-model.d.ts.map +1 -0
  204. package/dist/tui/dashboard-model.js +105 -0
  205. package/dist/tui/dashboard-model.js.map +1 -0
  206. package/dist/tui/dashboard.d.ts +38 -0
  207. package/dist/tui/dashboard.d.ts.map +1 -0
  208. package/dist/tui/dashboard.js +357 -0
  209. package/dist/tui/dashboard.js.map +1 -0
  210. package/dist/tui/effects.d.ts +61 -0
  211. package/dist/tui/effects.d.ts.map +1 -0
  212. package/dist/tui/effects.js +451 -0
  213. package/dist/tui/effects.js.map +1 -0
  214. package/dist/tui/i18n.d.ts +63 -0
  215. package/dist/tui/i18n.d.ts.map +1 -0
  216. package/dist/tui/i18n.js +205 -0
  217. package/dist/tui/i18n.js.map +1 -0
  218. package/dist/tui/input-history.d.ts +12 -0
  219. package/dist/tui/input-history.d.ts.map +1 -0
  220. package/dist/tui/input-history.js +47 -0
  221. package/dist/tui/input-history.js.map +1 -0
  222. package/dist/tui/local-commands.d.ts +12 -0
  223. package/dist/tui/local-commands.d.ts.map +1 -0
  224. package/dist/tui/local-commands.js +50 -0
  225. package/dist/tui/local-commands.js.map +1 -0
  226. package/dist/tui/markdown.d.ts +2 -0
  227. package/dist/tui/markdown.d.ts.map +1 -0
  228. package/dist/tui/markdown.js +60 -0
  229. package/dist/tui/markdown.js.map +1 -0
  230. package/dist/tui/session-store.d.ts +2 -0
  231. package/dist/tui/session-store.d.ts.map +1 -0
  232. package/dist/tui/session-store.js +2 -0
  233. package/dist/tui/session-store.js.map +1 -0
  234. package/dist/tui/setup.d.ts +53 -0
  235. package/dist/tui/setup.d.ts.map +1 -0
  236. package/dist/tui/setup.js +313 -0
  237. package/dist/tui/setup.js.map +1 -0
  238. package/dist/tui/slash-autocomplete.d.ts +8 -0
  239. package/dist/tui/slash-autocomplete.d.ts.map +1 -0
  240. package/dist/tui/slash-autocomplete.js +48 -0
  241. package/dist/tui/slash-autocomplete.js.map +1 -0
  242. package/dist/tui/theme.d.ts +28 -0
  243. package/dist/tui/theme.d.ts.map +1 -0
  244. package/dist/tui/theme.js +53 -0
  245. package/dist/tui/theme.js.map +1 -0
  246. package/dist/utils.d.ts +32 -0
  247. package/dist/utils.d.ts.map +1 -0
  248. package/dist/utils.js +165 -0
  249. package/dist/utils.js.map +1 -0
  250. package/package.json +72 -0
@@ -0,0 +1,104 @@
1
+ import { Command } from "commander";
2
+ import { StateManager, detectChapter, loadDetectionHistory, analyzeDetectionInsights, } from "@kienmatu/inkos-core";
3
+ import { loadConfig, findProjectRoot, resolveBookId, log, logError } from "../utils.js";
4
+ import { readFile, readdir } from "node:fs/promises";
5
+ import { join } from "node:path";
6
+ export const detectCommand = new Command("detect")
7
+ .description("Run AIGC detection on chapters")
8
+ .argument("[book-id]", "Book ID (auto-detected if only one book)")
9
+ .argument("[chapter]", "Chapter number (defaults to latest)")
10
+ .option("--all", "Detect all chapters")
11
+ .option("--stats", "Show detection statistics")
12
+ .option("--json", "Output JSON")
13
+ .action(async (bookIdArg, chapterStr, opts) => {
14
+ try {
15
+ const config = await loadConfig();
16
+ const root = findProjectRoot();
17
+ if (!config.detection?.enabled) {
18
+ logError("AIGC detection is not enabled. Add detection config to inkos.json.");
19
+ process.exit(1);
20
+ }
21
+ // If first arg looks like a number, treat it as chapter
22
+ let bookId;
23
+ let chapterNumber;
24
+ if (bookIdArg && /^\d+$/.test(bookIdArg)) {
25
+ bookId = await resolveBookId(undefined, root);
26
+ chapterNumber = parseInt(bookIdArg, 10);
27
+ }
28
+ else {
29
+ bookId = await resolveBookId(bookIdArg, root);
30
+ chapterNumber = chapterStr ? parseInt(chapterStr, 10) : undefined;
31
+ }
32
+ const state = new StateManager(root);
33
+ const bookDir = state.bookDir(bookId);
34
+ if (opts.stats) {
35
+ const history = await loadDetectionHistory(bookDir);
36
+ const stats = analyzeDetectionInsights(history);
37
+ if (opts.json) {
38
+ log(JSON.stringify(stats, null, 2));
39
+ }
40
+ else {
41
+ log(`Detection Statistics:`);
42
+ log(` Total detections: ${stats.totalDetections}`);
43
+ log(` Total rewrites: ${stats.totalRewrites}`);
44
+ log(` Avg original score: ${stats.avgOriginalScore.toFixed(3)}`);
45
+ log(` Avg final score: ${stats.avgFinalScore.toFixed(3)}`);
46
+ log(` Avg score reduction: ${stats.avgScoreReduction.toFixed(3)}`);
47
+ log(` Pass rate: ${(stats.passRate * 100).toFixed(0)}%`);
48
+ if (stats.chapterBreakdown.length > 0) {
49
+ log(` Chapters:`);
50
+ for (const ch of stats.chapterBreakdown) {
51
+ log(` Ch.${ch.chapterNumber}: ${ch.originalScore.toFixed(3)} → ${ch.finalScore.toFixed(3)} (${ch.rewriteAttempts} rewrites)`);
52
+ }
53
+ }
54
+ }
55
+ return;
56
+ }
57
+ const detectionConfig = config.detection;
58
+ if (opts.all) {
59
+ const index = await state.loadChapterIndex(bookId);
60
+ for (const ch of index) {
61
+ const content = await readChapterContent(bookDir, ch.number);
62
+ const result = await detectChapter(detectionConfig, content, ch.number);
63
+ printResult(result, opts.json);
64
+ }
65
+ }
66
+ else {
67
+ const targetChapter = chapterNumber ?? (await state.getNextChapterNumber(bookId)) - 1;
68
+ if (targetChapter < 1) {
69
+ logError("No chapters to detect.");
70
+ process.exit(1);
71
+ }
72
+ const content = await readChapterContent(bookDir, targetChapter);
73
+ const result = await detectChapter(detectionConfig, content, targetChapter);
74
+ printResult(result, opts.json);
75
+ }
76
+ }
77
+ catch (e) {
78
+ logError(`Detection failed: ${e}`);
79
+ process.exit(1);
80
+ }
81
+ });
82
+ function printResult(result, json) {
83
+ if (json) {
84
+ log(JSON.stringify(result, null, 2));
85
+ }
86
+ else {
87
+ const icon = result.passed ? "✅" : "⚠️";
88
+ log(` ${icon} Chapter ${result.chapterNumber}: score=${result.detection.score.toFixed(3)} (${result.detection.provider}) ${result.passed ? "PASS" : "FAIL"}`);
89
+ }
90
+ }
91
+ async function readChapterContent(bookDir, chapterNumber) {
92
+ const chaptersDir = join(bookDir, "chapters");
93
+ const files = await readdir(chaptersDir);
94
+ const paddedNum = String(chapterNumber).padStart(4, "0");
95
+ const chapterFile = files.find((f) => f.startsWith(paddedNum) && f.endsWith(".md"));
96
+ if (!chapterFile) {
97
+ throw new Error(`Chapter ${chapterNumber} file not found`);
98
+ }
99
+ const raw = await readFile(join(chaptersDir, chapterFile), "utf-8");
100
+ const lines = raw.split("\n");
101
+ const contentStart = lines.findIndex((l, i) => i > 0 && l.trim().length > 0);
102
+ return contentStart >= 0 ? lines.slice(contentStart).join("\n") : raw;
103
+ }
104
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/commands/detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { Command } from "commander";
2
+ export declare function buildDoctorModelCandidates(preferredModel: string | undefined, discoveredModels: Array<{
3
+ id: string;
4
+ name: string;
5
+ }>): string[];
6
+ export declare function resolveDoctorModelsBaseUrl(service: string | undefined, baseUrl: string, resolveServiceModelsBaseUrl: (service: string) => string | undefined): string;
7
+ export declare const doctorCommand: Command;
8
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+CpC,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,gBAAgB,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,MAAM,EAAE,CAoBV;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,EACf,2BAA2B,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GACnE,MAAM,CAKR;AAqBD,eAAO,MAAM,aAAa,SAsStB,CAAC"}
@@ -0,0 +1,356 @@
1
+ import { Command } from "commander";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { findProjectRoot, log, GLOBAL_ENV_PATH } from "../utils.js";
5
+ import { fetchWithProxy } from "@kienmatu/inkos-core";
6
+ import { ensureNodeRuntimePinFiles, evaluateNodeRuntimeSupport, inspectNodeRuntimePinFiles, } from "../runtime-requirements.js";
7
+ import { formatDoctorHintBaseUrl, formatDoctorHintInvalidApiKey, formatDoctorHintModelName, formatDoctorHintOpenAiProbeExhausted, formatDoctorHintQuota, formatDoctorHintStreamRequirement, resolveCliLanguage, } from "../localization.js";
8
+ function buildDoctorProbePlans(preferredApiFormat, preferredStream) {
9
+ const plans = [];
10
+ const seen = new Set();
11
+ const push = (apiFormat, stream) => {
12
+ const key = `${apiFormat}:${stream ? "1" : "0"}`;
13
+ if (seen.has(key))
14
+ return;
15
+ seen.add(key);
16
+ plans.push({ apiFormat, stream });
17
+ };
18
+ if (preferredApiFormat) {
19
+ push(preferredApiFormat, preferredStream ?? false);
20
+ push(preferredApiFormat, !(preferredStream ?? false));
21
+ }
22
+ const alternate = preferredApiFormat === "responses" ? "chat" : "responses";
23
+ push(alternate, false);
24
+ push(alternate, true);
25
+ push("chat", false);
26
+ push("chat", true);
27
+ push("responses", false);
28
+ push("responses", true);
29
+ return plans;
30
+ }
31
+ export function buildDoctorModelCandidates(preferredModel, discoveredModels) {
32
+ const seen = new Set();
33
+ const candidates = [];
34
+ const push = (value) => {
35
+ if (!value || value.trim().length === 0)
36
+ return;
37
+ const model = value.trim();
38
+ if (seen.has(model))
39
+ return;
40
+ seen.add(model);
41
+ candidates.push(model);
42
+ };
43
+ push(preferredModel);
44
+ for (const model of discoveredModels)
45
+ push(model.id);
46
+ push("gpt-5.4");
47
+ push("gpt-4o");
48
+ push("claude-sonnet-4-6");
49
+ push("MiniMax-M2.7");
50
+ push("kimi-k2.5");
51
+ push("gemini-2.5-flash");
52
+ return candidates;
53
+ }
54
+ export function resolveDoctorModelsBaseUrl(service, baseUrl, resolveServiceModelsBaseUrl) {
55
+ if (!service || service.length === 0) {
56
+ return baseUrl;
57
+ }
58
+ return resolveServiceModelsBaseUrl(service) ?? baseUrl;
59
+ }
60
+ async function fetchDoctorModels(modelsBaseUrl, apiKey, proxyUrl) {
61
+ const modelsUrl = modelsBaseUrl.replace(/\/$/, "") + "/models";
62
+ try {
63
+ const res = await fetchWithProxy(modelsUrl, {
64
+ headers: { Authorization: `Bearer ${apiKey}` },
65
+ signal: AbortSignal.timeout(10_000),
66
+ }, proxyUrl);
67
+ if (!res.ok)
68
+ return [];
69
+ const json = await res.json();
70
+ return (json.data ?? []).map((model) => ({ id: model.id, name: model.id }));
71
+ }
72
+ catch {
73
+ return [];
74
+ }
75
+ }
76
+ export const doctorCommand = new Command("doctor")
77
+ .description("Check environment and project health")
78
+ .option("--repair-node-runtime", "Write .nvmrc and .node-version pinned to Node 22 for this project")
79
+ .action(async (opts) => {
80
+ const checks = [];
81
+ const root = findProjectRoot();
82
+ // doctor is not scoped to a book, so the language comes from the environment
83
+ // (INKOS_LOCALE -> LC_ALL/LC_MESSAGES/LANG, default zh).
84
+ const language = resolveCliLanguage();
85
+ if (opts.repairNodeRuntime) {
86
+ const repair = await ensureNodeRuntimePinFiles(root);
87
+ checks.push({
88
+ name: "Node runtime pin files repaired",
89
+ ok: true,
90
+ detail: repair.updated
91
+ ? `Wrote ${repair.written.join(", ")} -> Node 22`
92
+ : "Already pinned to Node 22",
93
+ });
94
+ }
95
+ // 1. Check Node.js version
96
+ const nodeVersion = process.version;
97
+ checks.push({
98
+ name: "Node.js >= 22",
99
+ ...evaluateNodeRuntimeSupport({ nodeVersion }),
100
+ });
101
+ checks.push({
102
+ name: "Node runtime pin files",
103
+ ...await inspectNodeRuntimePinFiles(root),
104
+ });
105
+ // 2. Check inkos.json exists
106
+ try {
107
+ await readFile(join(root, "inkos.json"), "utf-8");
108
+ checks.push({ name: "inkos.json", ok: true, detail: "Found" });
109
+ }
110
+ catch {
111
+ checks.push({ name: "inkos.json", ok: false, detail: "Not found. Run 'inkos init'" });
112
+ }
113
+ // 3. Check .env exists
114
+ try {
115
+ await readFile(join(root, ".env"), "utf-8");
116
+ checks.push({ name: ".env", ok: true, detail: "Found" });
117
+ }
118
+ catch {
119
+ checks.push({ name: ".env", ok: false, detail: "Not found" });
120
+ }
121
+ // 4. Check global config
122
+ {
123
+ let hasGlobal = false;
124
+ try {
125
+ const globalContent = await readFile(GLOBAL_ENV_PATH, "utf-8");
126
+ hasGlobal = globalContent.includes("INKOS_LLM_API_KEY=") && !globalContent.includes("your-api-key-here");
127
+ }
128
+ catch { /* no global config */ }
129
+ checks.push({
130
+ name: "Global Config",
131
+ ok: hasGlobal,
132
+ detail: hasGlobal ? `Found (${GLOBAL_ENV_PATH})` : "Not set. Run 'inkos config set-global'",
133
+ });
134
+ }
135
+ // 5. Check effective LLM config (Studio project base + env/CLI overlay, or legacy env)
136
+ {
137
+ const { loadConfigWithDiagnostics } = await import("../utils.js");
138
+ const { isApiKeyOptionalForEndpoint } = await import("@kienmatu/inkos-core");
139
+ let configResult;
140
+ try {
141
+ configResult = await loadConfigWithDiagnostics({ requireApiKey: false });
142
+ checks.push({
143
+ name: "LLM Config Mode",
144
+ ok: true,
145
+ detail: `${configResult.diagnostics.configMode} (service=${configResult.diagnostics.serviceSource}, model=${configResult.diagnostics.modelSource}, key=${configResult.diagnostics.apiKeySource})`,
146
+ });
147
+ for (const warning of configResult.diagnostics.warnings) {
148
+ checks.push({ name: " Config Hint", ok: true, detail: warning });
149
+ }
150
+ }
151
+ catch {
152
+ // The API connectivity check below will report the concrete config failure.
153
+ }
154
+ const provider = configResult?.llm.provider;
155
+ const baseUrl = configResult?.llm.baseUrl;
156
+ const apiKey = configResult?.llm.apiKey;
157
+ const apiKeyOptional = isApiKeyOptionalForEndpoint({ provider, baseUrl });
158
+ const hasKey = apiKeyOptional || (!!apiKey && apiKey.length > 10 && apiKey !== "your-api-key-here");
159
+ checks.push({
160
+ name: "LLM API Key",
161
+ ok: hasKey,
162
+ detail: apiKeyOptional
163
+ ? "Optional for local/self-hosted endpoint"
164
+ : hasKey
165
+ ? "Configured"
166
+ : "Missing — save a Studio service key or set env for CLI/daemon/deploy",
167
+ });
168
+ }
169
+ // 5. Check books directory
170
+ try {
171
+ const { StateManager } = await import("@kienmatu/inkos-core");
172
+ const state = new StateManager(root);
173
+ const books = await state.listBooks();
174
+ checks.push({
175
+ name: "Books",
176
+ ok: true,
177
+ detail: `${books.length} book(s) found`,
178
+ });
179
+ }
180
+ catch {
181
+ checks.push({ name: "Books", ok: true, detail: "0 books" });
182
+ }
183
+ // 5b. Check version migration status
184
+ {
185
+ const { existsSync } = await import("node:fs");
186
+ const hasStructuredState = existsSync(join(root, "books"));
187
+ if (hasStructuredState) {
188
+ const { StateManager } = await import("@kienmatu/inkos-core");
189
+ const sm = new StateManager(root);
190
+ const bookIds = await sm.listBooks();
191
+ let legacyCount = 0;
192
+ for (const bid of bookIds) {
193
+ const stateDir = join(sm.bookDir(bid), "story", "state");
194
+ const hasNewState = existsSync(stateDir);
195
+ if (!hasNewState)
196
+ legacyCount++;
197
+ }
198
+ if (legacyCount > 0) {
199
+ checks.push({
200
+ name: "Version Migration",
201
+ ok: false,
202
+ 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'.`,
203
+ });
204
+ }
205
+ else if (bookIds.length > 0) {
206
+ checks.push({
207
+ name: "Version Migration",
208
+ ok: true,
209
+ detail: "All books use current format",
210
+ });
211
+ }
212
+ }
213
+ }
214
+ // 6. API connectivity test
215
+ try {
216
+ const { createLLMClient, chatCompletion, LLMConfigSchema, isApiKeyOptionalForEndpoint, resolveServiceModelsBaseUrl } = await import("@kienmatu/inkos-core");
217
+ const { loadConfig } = await import("../utils.js");
218
+ let llmConfig;
219
+ try {
220
+ const config = await loadConfig();
221
+ llmConfig = config.llm;
222
+ }
223
+ catch {
224
+ // No project config — try building from global env
225
+ const { config: loadDotenv } = await import("dotenv");
226
+ loadDotenv({ path: GLOBAL_ENV_PATH });
227
+ const env = process.env;
228
+ const apiKeyOptional = isApiKeyOptionalForEndpoint({
229
+ provider: env.INKOS_LLM_PROVIDER,
230
+ baseUrl: env.INKOS_LLM_BASE_URL,
231
+ });
232
+ if ((env.INKOS_LLM_API_KEY || apiKeyOptional) && env.INKOS_LLM_BASE_URL && env.INKOS_LLM_MODEL) {
233
+ llmConfig = LLMConfigSchema.parse({
234
+ provider: env.INKOS_LLM_PROVIDER ?? "custom",
235
+ baseUrl: env.INKOS_LLM_BASE_URL,
236
+ apiKey: env.INKOS_LLM_API_KEY ?? "",
237
+ model: env.INKOS_LLM_MODEL,
238
+ });
239
+ }
240
+ }
241
+ if (!llmConfig) {
242
+ checks.push({
243
+ name: "API Connectivity",
244
+ ok: false,
245
+ detail: "No LLM config available (no project config or global .env)",
246
+ });
247
+ checks.push({
248
+ name: " Hint",
249
+ ok: false,
250
+ detail: "Run `inkos setup`, `inkos config set-global`, or add LLM settings to the project .env file.",
251
+ });
252
+ }
253
+ else {
254
+ checks.push({
255
+ name: "LLM Config",
256
+ ok: true,
257
+ detail: `provider=${llmConfig.provider} model=${llmConfig.model} stream=${llmConfig.stream ?? true} baseUrl=${llmConfig.baseUrl}`,
258
+ });
259
+ log("\n [..] Testing API connectivity...");
260
+ let connected = false;
261
+ let detectedDetail = "";
262
+ let lastError = "Unknown error";
263
+ const modelsBaseUrl = resolveDoctorModelsBaseUrl(typeof llmConfig.service === "string" ? llmConfig.service : undefined, llmConfig.baseUrl, resolveServiceModelsBaseUrl);
264
+ const discoveredModels = (llmConfig.apiKey && modelsBaseUrl)
265
+ ? await fetchDoctorModels(modelsBaseUrl, llmConfig.apiKey, llmConfig.proxyUrl)
266
+ : [];
267
+ const modelCandidates = (llmConfig.provider === "openai" || discoveredModels.length > 0)
268
+ ? buildDoctorModelCandidates(llmConfig.model, discoveredModels)
269
+ : [llmConfig.model];
270
+ const plans = llmConfig.provider === "openai"
271
+ ? buildDoctorProbePlans(llmConfig.apiFormat, llmConfig.stream)
272
+ : [{ apiFormat: (llmConfig.apiFormat ?? "chat"), stream: llmConfig.stream ?? true }];
273
+ for (const model of modelCandidates) {
274
+ for (const plan of plans) {
275
+ try {
276
+ const client = createLLMClient({
277
+ ...llmConfig,
278
+ model,
279
+ apiFormat: plan.apiFormat,
280
+ stream: plan.stream,
281
+ });
282
+ const response = await chatCompletion(client, model, [
283
+ { role: "user", content: "Say OK" },
284
+ ], { maxTokens: 16 });
285
+ connected = true;
286
+ detectedDetail = `OK (model: ${model}, apiFormat=${plan.apiFormat}, stream=${plan.stream}, tokens: ${response.usage.totalTokens})`;
287
+ break;
288
+ }
289
+ catch (error) {
290
+ lastError = error instanceof Error ? error.message : String(error);
291
+ }
292
+ }
293
+ if (connected) {
294
+ break;
295
+ }
296
+ }
297
+ checks.push({
298
+ name: "API Connectivity",
299
+ ok: connected,
300
+ detail: connected ? detectedDetail : lastError.split("\n")[0],
301
+ });
302
+ if (!connected && /\b(?:401|403|429)\b|unauthorized|forbidden|quota|balance|insufficient|exceeded|额度|余额|配额/i.test(lastError)) {
303
+ checks.push({
304
+ name: " Hint",
305
+ ok: false,
306
+ detail: formatDoctorHintQuota(language),
307
+ });
308
+ }
309
+ if (!connected && llmConfig.provider === "openai") {
310
+ checks.push({
311
+ name: " Hint",
312
+ ok: false,
313
+ detail: formatDoctorHintOpenAiProbeExhausted(language),
314
+ });
315
+ }
316
+ }
317
+ }
318
+ catch (e) {
319
+ const errMsg = String(e);
320
+ const hints = [];
321
+ if (errMsg.includes("Connection error") || errMsg.includes("ECONNREFUSED") || errMsg.includes("fetch failed")) {
322
+ hints.push(formatDoctorHintBaseUrl(language));
323
+ }
324
+ if (errMsg.includes("400")) {
325
+ hints.push(formatDoctorHintStreamRequirement(language));
326
+ hints.push(formatDoctorHintModelName(language));
327
+ }
328
+ if (errMsg.includes("401")) {
329
+ hints.push(formatDoctorHintInvalidApiKey(language));
330
+ }
331
+ checks.push({
332
+ name: "API Connectivity",
333
+ ok: false,
334
+ detail: errMsg.split("\n")[0],
335
+ });
336
+ if (hints.length > 0) {
337
+ for (const hint of hints) {
338
+ checks.push({ name: " Hint", ok: false, detail: hint });
339
+ }
340
+ }
341
+ }
342
+ // Output
343
+ log("\nInkOS Doctor\n");
344
+ for (const check of checks) {
345
+ const icon = check.ok ? "[OK]" : "[!!]";
346
+ log(` ${icon} ${check.name}: ${check.detail}`);
347
+ }
348
+ const failed = checks.filter((c) => !c.ok);
349
+ if (failed.length > 0) {
350
+ log(`\n${failed.length} issue(s) found.`);
351
+ }
352
+ else {
353
+ log("\nAll checks passed.");
354
+ }
355
+ });
356
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const draftCommand: Command;
3
+ //# sourceMappingURL=draft.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/commands/draft.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,YAAY,SAsCrB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { Command } from "commander";
2
+ import { PipelineRunner } from "@kienmatu/inkos-core";
3
+ import { loadConfig, buildPipelineConfig, findProjectRoot, resolveContext, resolveBookId, log, logError } from "../utils.js";
4
+ export const draftCommand = new Command("draft")
5
+ .description("Write a draft chapter (no audit/revise)")
6
+ .argument("[book-id]", "Book ID (auto-detected if only one book)")
7
+ .option("--words <n>", "Words per chapter (overrides book config)")
8
+ .option("--context <text>", "Creative guidance (natural language)")
9
+ .option("--context-file <path>", "Read guidance from file")
10
+ .option("--json", "Output JSON")
11
+ .option("-q, --quiet", "Suppress console output")
12
+ .action(async (bookIdArg, opts) => {
13
+ try {
14
+ const config = await loadConfig();
15
+ const root = findProjectRoot();
16
+ const bookId = await resolveBookId(bookIdArg, root);
17
+ const context = await resolveContext(opts);
18
+ const pipeline = new PipelineRunner(buildPipelineConfig(config, root, { quiet: opts.quiet }));
19
+ const wordCount = opts.words ? parseInt(opts.words, 10) : undefined;
20
+ if (!opts.json)
21
+ log(`Writing draft for "${bookId}"...`);
22
+ const result = await pipeline.writeDraft(bookId, context, wordCount);
23
+ if (opts.json) {
24
+ log(JSON.stringify(result, null, 2));
25
+ }
26
+ else {
27
+ log(` Chapter ${result.chapterNumber}: ${result.title}`);
28
+ log(` Words: ${result.wordCount}`);
29
+ log(` File: ${result.filePath}`);
30
+ }
31
+ }
32
+ catch (e) {
33
+ if (opts.json) {
34
+ log(JSON.stringify({ error: String(e) }));
35
+ }
36
+ else {
37
+ logError(`Failed to write draft: ${e}`);
38
+ }
39
+ process.exit(1);
40
+ }
41
+ });
42
+ //# sourceMappingURL=draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/commands/draft.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7H,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,yCAAyC,CAAC;KACtD,QAAQ,CAAC,WAAW,EAAE,0CAA0C,CAAC;KACjE,MAAM,CAAC,aAAa,EAAE,2CAA2C,CAAC;KAClE,MAAM,CAAC,kBAAkB,EAAE,sCAAsC,CAAC;KAClE,MAAM,CAAC,uBAAuB,EAAE,yBAAyB,CAAC;KAC1D,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;KAC/B,MAAM,CAAC,aAAa,EAAE,yBAAyB,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,SAA6B,EAAE,IAAI,EAAE,EAAE;IACpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAE3C,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAE9F,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEpE,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,GAAG,CAAC,sBAAsB,MAAM,MAAM,CAAC,CAAC;QAExD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;QAErE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,aAAa,MAAM,CAAC,aAAa,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAC1D,GAAG,CAAC,YAAY,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;YACpC,GAAG,CAAC,WAAW,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const evalCommand: Command;
3
+ //# sourceMappingURL=eval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.d.ts","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,WAAW,SAmDpB,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { Command } from "commander";
2
+ import { StateManager, evaluateBookQuality, } from "@kienmatu/inkos-core";
3
+ import { findProjectRoot, resolveBookId, log, logError } from "../utils.js";
4
+ export const evalCommand = new Command("eval")
5
+ .description("Evaluate writing quality for a book — outputs structured quality report")
6
+ .argument("[book-id]", "Book ID (auto-detected if only one book)")
7
+ .option("--json", "Output JSON only")
8
+ .option("--chapters <range>", "Chapter range (e.g. 1-10, 5-20)")
9
+ .action(async (bookIdArg, opts) => {
10
+ try {
11
+ const root = findProjectRoot();
12
+ const bookId = await resolveBookId(bookIdArg, root);
13
+ const state = new StateManager(root);
14
+ const result = await evaluateBookQuality({ state, bookId, chapters: opts.chapters });
15
+ if (opts.json) {
16
+ log(JSON.stringify(result, null, 2));
17
+ }
18
+ else {
19
+ log(`\nQuality Report: "${bookId}"\n`);
20
+ log(` Quality Score: ${result.qualityScore}/100`);
21
+ log(` Chapters: ${result.totalChapters}`);
22
+ log(` Words: ${result.totalWords.toLocaleString()}`);
23
+ log("");
24
+ log(" Dimensions:");
25
+ log(` Audit pass rate: ${result.auditPassRate}%`);
26
+ log(` AI tell density: ${result.avgAiTellDensity.toFixed(2)} / 1k chars`);
27
+ log(` Paragraph warnings: ${result.avgParagraphWarnings.toFixed(1)} avg/chapter`);
28
+ log(` Hook resolve rate: ${result.hookResolveRate}%`);
29
+ log(` Duplicate titles: ${result.duplicateTitles}`);
30
+ log("");
31
+ log(" Quality Trend:");
32
+ for (const { chapter, score } of result.qualityTrend) {
33
+ const bar = "█".repeat(Math.round(score / 5)) + "░".repeat(20 - Math.round(score / 5));
34
+ log(` Ch.${String(chapter).padStart(3)} ${bar} ${score}`);
35
+ }
36
+ log("");
37
+ // Drift detection: compare first half vs second half
38
+ if (result.qualityTrend.length >= 6) {
39
+ const mid = Math.floor(result.qualityTrend.length / 2);
40
+ const firstHalf = result.qualityTrend.slice(0, mid).reduce((s, c) => s + c.score, 0) / mid;
41
+ const secondHalf = result.qualityTrend.slice(mid).reduce((s, c) => s + c.score, 0) / (result.qualityTrend.length - mid);
42
+ const drift = Math.round(secondHalf - firstHalf);
43
+ log(` Quality Drift: ${drift > 0 ? "+" : ""}${drift} (${drift >= 0 ? "stable/improving" : "DEGRADING"})`);
44
+ }
45
+ }
46
+ }
47
+ catch (e) {
48
+ if (opts.json) {
49
+ log(JSON.stringify({ error: String(e) }));
50
+ }
51
+ else {
52
+ logError(`Eval failed: ${e}`);
53
+ }
54
+ process.exit(1);
55
+ }
56
+ });
57
+ //# sourceMappingURL=eval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.js","sourceRoot":"","sources":["../../src/commands/eval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const exportCommand: Command;
3
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,aAAa,SAuCtB,CAAC"}