@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.
- package/LICENSE +661 -0
- package/dist/book-backup.d.ts +33 -0
- package/dist/book-backup.d.ts.map +1 -0
- package/dist/book-backup.js +74 -0
- package/dist/book-backup.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +71 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/analytics.d.ts +3 -0
- package/dist/commands/analytics.d.ts.map +1 -0
- package/dist/commands/analytics.js +74 -0
- package/dist/commands/analytics.js.map +1 -0
- package/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +81 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/auto.d.ts +3 -0
- package/dist/commands/auto.d.ts.map +1 -0
- package/dist/commands/auto.js +136 -0
- package/dist/commands/auto.js.map +1 -0
- package/dist/commands/book.d.ts +3 -0
- package/dist/commands/book.d.ts.map +1 -0
- package/dist/commands/book.js +324 -0
- package/dist/commands/book.js.map +1 -0
- package/dist/commands/chapter.d.ts +3 -0
- package/dist/commands/chapter.d.ts.map +1 -0
- package/dist/commands/chapter.js +103 -0
- package/dist/commands/chapter.js.map +1 -0
- package/dist/commands/compose.d.ts +3 -0
- package/dist/commands/compose.d.ts.map +1 -0
- package/dist/commands/compose.js +46 -0
- package/dist/commands/compose.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +321 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/consolidate.d.ts +3 -0
- package/dist/commands/consolidate.d.ts.map +1 -0
- package/dist/commands/consolidate.js +50 -0
- package/dist/commands/consolidate.js.map +1 -0
- package/dist/commands/daemon.d.ts +4 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +118 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/detect.d.ts +3 -0
- package/dist/commands/detect.d.ts.map +1 -0
- package/dist/commands/detect.js +104 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +356 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/draft.d.ts +3 -0
- package/dist/commands/draft.d.ts.map +1 -0
- package/dist/commands/draft.js +42 -0
- package/dist/commands/draft.js.map +1 -0
- package/dist/commands/eval.d.ts +3 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +57 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/export.d.ts +3 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +46 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/fanfic.d.ts +3 -0
- package/dist/commands/fanfic.d.ts.map +1 -0
- package/dist/commands/fanfic.js +177 -0
- package/dist/commands/fanfic.js.map +1 -0
- package/dist/commands/forecast.d.ts +12 -0
- package/dist/commands/forecast.d.ts.map +1 -0
- package/dist/commands/forecast.js +156 -0
- package/dist/commands/forecast.js.map +1 -0
- package/dist/commands/genre.d.ts +11 -0
- package/dist/commands/genre.d.ts.map +1 -0
- package/dist/commands/genre.js +186 -0
- package/dist/commands/genre.js.map +1 -0
- package/dist/commands/import.d.ts +3 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +110 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +63 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/interact.d.ts +6 -0
- package/dist/commands/interact.d.ts.map +1 -0
- package/dist/commands/interact.js +95 -0
- package/dist/commands/interact.js.map +1 -0
- package/dist/commands/plan.d.ts +3 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +50 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/radar.d.ts +3 -0
- package/dist/commands/radar.d.ts.map +1 -0
- package/dist/commands/radar.js +52 -0
- package/dist/commands/radar.js.map +1 -0
- package/dist/commands/review.d.ts +3 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +229 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/revise.d.ts +3 -0
- package/dist/commands/revise.d.ts.map +1 -0
- package/dist/commands/revise.js +91 -0
- package/dist/commands/revise.js.map +1 -0
- package/dist/commands/short-fiction.d.ts +4 -0
- package/dist/commands/short-fiction.d.ts.map +1 -0
- package/dist/commands/short-fiction.js +220 -0
- package/dist/commands/short-fiction.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +123 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/studio.d.ts +21 -0
- package/dist/commands/studio.d.ts.map +1 -0
- package/dist/commands/studio.js +151 -0
- package/dist/commands/studio.js.map +1 -0
- package/dist/commands/style.d.ts +3 -0
- package/dist/commands/style.d.ts.map +1 -0
- package/dist/commands/style.js +95 -0
- package/dist/commands/style.js.map +1 -0
- package/dist/commands/translate.d.ts +3 -0
- package/dist/commands/translate.d.ts.map +1 -0
- package/dist/commands/translate.js +111 -0
- package/dist/commands/translate.js.map +1 -0
- package/dist/commands/tui.d.ts +6 -0
- package/dist/commands/tui.d.ts.map +1 -0
- package/dist/commands/tui.js +14 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +40 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/write.d.ts +3 -0
- package/dist/commands/write.d.ts.map +1 -0
- package/dist/commands/write.js +371 -0
- package/dist/commands/write.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/localization.d.ts +103 -0
- package/dist/localization.d.ts.map +1 -0
- package/dist/localization.js +377 -0
- package/dist/localization.js.map +1 -0
- package/dist/notify-helper.d.ts +17 -0
- package/dist/notify-helper.d.ts.map +1 -0
- package/dist/notify-helper.js +27 -0
- package/dist/notify-helper.js.map +1 -0
- package/dist/program.d.ts +10 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +97 -0
- package/dist/program.js.map +1 -0
- package/dist/progress-text.d.ts +26 -0
- package/dist/progress-text.d.ts.map +1 -0
- package/dist/progress-text.js +35 -0
- package/dist/progress-text.js.map +1 -0
- package/dist/project-bootstrap.d.ts +8 -0
- package/dist/project-bootstrap.d.ts.map +1 -0
- package/dist/project-bootstrap.js +139 -0
- package/dist/project-bootstrap.js.map +1 -0
- package/dist/runtime-requirements.d.ts +24 -0
- package/dist/runtime-requirements.d.ts.map +1 -0
- package/dist/runtime-requirements.js +89 -0
- package/dist/runtime-requirements.js.map +1 -0
- package/dist/tui/__tests__/markdown.test.d.ts +2 -0
- package/dist/tui/__tests__/markdown.test.d.ts.map +1 -0
- package/dist/tui/__tests__/markdown.test.js +58 -0
- package/dist/tui/__tests__/markdown.test.js.map +1 -0
- package/dist/tui/activity-state.d.ts +9 -0
- package/dist/tui/activity-state.d.ts.map +1 -0
- package/dist/tui/activity-state.js +6 -0
- package/dist/tui/activity-state.js.map +1 -0
- package/dist/tui/agent-input.d.ts +118 -0
- package/dist/tui/agent-input.d.ts.map +1 -0
- package/dist/tui/agent-input.js +255 -0
- package/dist/tui/agent-input.js.map +1 -0
- package/dist/tui/ansi.d.ts +40 -0
- package/dist/tui/ansi.d.ts.map +1 -0
- package/dist/tui/ansi.js +62 -0
- package/dist/tui/ansi.js.map +1 -0
- package/dist/tui/app.d.ts +13 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +109 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/chat-depth.d.ts +9 -0
- package/dist/tui/chat-depth.d.ts.map +1 -0
- package/dist/tui/chat-depth.js +14 -0
- package/dist/tui/chat-depth.js.map +1 -0
- package/dist/tui/chat-draft.d.ts +4 -0
- package/dist/tui/chat-draft.d.ts.map +1 -0
- package/dist/tui/chat-draft.js +28 -0
- package/dist/tui/chat-draft.js.map +1 -0
- package/dist/tui/composer-caret.d.ts +10 -0
- package/dist/tui/composer-caret.d.ts.map +1 -0
- package/dist/tui/composer-caret.js +13 -0
- package/dist/tui/composer-caret.js.map +1 -0
- package/dist/tui/composer-display.d.ts +7 -0
- package/dist/tui/composer-display.d.ts.map +1 -0
- package/dist/tui/composer-display.js +17 -0
- package/dist/tui/composer-display.js.map +1 -0
- package/dist/tui/dashboard-model.d.ts +46 -0
- package/dist/tui/dashboard-model.d.ts.map +1 -0
- package/dist/tui/dashboard-model.js +105 -0
- package/dist/tui/dashboard-model.js.map +1 -0
- package/dist/tui/dashboard.d.ts +38 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js +357 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/effects.d.ts +61 -0
- package/dist/tui/effects.d.ts.map +1 -0
- package/dist/tui/effects.js +451 -0
- package/dist/tui/effects.js.map +1 -0
- package/dist/tui/i18n.d.ts +63 -0
- package/dist/tui/i18n.d.ts.map +1 -0
- package/dist/tui/i18n.js +205 -0
- package/dist/tui/i18n.js.map +1 -0
- package/dist/tui/input-history.d.ts +12 -0
- package/dist/tui/input-history.d.ts.map +1 -0
- package/dist/tui/input-history.js +47 -0
- package/dist/tui/input-history.js.map +1 -0
- package/dist/tui/local-commands.d.ts +12 -0
- package/dist/tui/local-commands.d.ts.map +1 -0
- package/dist/tui/local-commands.js +50 -0
- package/dist/tui/local-commands.js.map +1 -0
- package/dist/tui/markdown.d.ts +2 -0
- package/dist/tui/markdown.d.ts.map +1 -0
- package/dist/tui/markdown.js +60 -0
- package/dist/tui/markdown.js.map +1 -0
- package/dist/tui/session-store.d.ts +2 -0
- package/dist/tui/session-store.d.ts.map +1 -0
- package/dist/tui/session-store.js +2 -0
- package/dist/tui/session-store.js.map +1 -0
- package/dist/tui/setup.d.ts +53 -0
- package/dist/tui/setup.d.ts.map +1 -0
- package/dist/tui/setup.js +313 -0
- package/dist/tui/setup.js.map +1 -0
- package/dist/tui/slash-autocomplete.d.ts +8 -0
- package/dist/tui/slash-autocomplete.d.ts.map +1 -0
- package/dist/tui/slash-autocomplete.js +48 -0
- package/dist/tui/slash-autocomplete.js.map +1 -0
- package/dist/tui/theme.d.ts +28 -0
- package/dist/tui/theme.d.ts.map +1 -0
- package/dist/tui/theme.js +53 -0
- package/dist/tui/theme.js.map +1 -0
- package/dist/utils.d.ts +32 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +165 -0
- package/dist/utils.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface BookBackupInfo {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly createdAt: string;
|
|
4
|
+
}
|
|
5
|
+
export interface CreateBookBackupOptions {
|
|
6
|
+
/** Injectable clock so tests do not depend on real time. */
|
|
7
|
+
readonly now?: () => Date;
|
|
8
|
+
/** Appended to the backup id, e.g. "pre-restore". */
|
|
9
|
+
readonly suffix?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface CreateBookBackupResult {
|
|
12
|
+
readonly bookId: string;
|
|
13
|
+
readonly backupId: string;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
}
|
|
16
|
+
export interface RestoreBookBackupOptions {
|
|
17
|
+
readonly now?: () => Date;
|
|
18
|
+
}
|
|
19
|
+
export interface RestoreBookBackupResult {
|
|
20
|
+
readonly bookId: string;
|
|
21
|
+
readonly restoredFrom: string;
|
|
22
|
+
/** Auto-backup of the pre-restore state; null when the book directory did not exist. */
|
|
23
|
+
readonly preRestoreBackupId: string | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Whole-book backups live OUTSIDE books/ (at .inkos/backups/<bookId>/<backupId>/),
|
|
27
|
+
* so a backup never recursively contains other backups.
|
|
28
|
+
*/
|
|
29
|
+
export declare function bookBackupsDir(root: string, bookId: string): string;
|
|
30
|
+
export declare function createBookBackup(root: string, bookId: string, options?: CreateBookBackupOptions): Promise<CreateBookBackupResult>;
|
|
31
|
+
export declare function listBookBackups(root: string, bookId: string): Promise<ReadonlyArray<BookBackupInfo>>;
|
|
32
|
+
export declare function restoreBookBackup(root: string, bookId: string, backupId: string, options?: RestoreBookBackupOptions): Promise<RestoreBookBackupResult>;
|
|
33
|
+
//# sourceMappingURL=book-backup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"book-backup.d.ts","sourceRoot":"","sources":["../src/book-backup.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAoBjC;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAmBxC;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CA4BlC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { access, cp, mkdir, readdir, rm, stat } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Whole-book backups live OUTSIDE books/ (at .inkos/backups/<bookId>/<backupId>/),
|
|
5
|
+
* so a backup never recursively contains other backups.
|
|
6
|
+
*/
|
|
7
|
+
export function bookBackupsDir(root, bookId) {
|
|
8
|
+
return join(root, ".inkos", "backups", bookId);
|
|
9
|
+
}
|
|
10
|
+
export async function createBookBackup(root, bookId, options = {}) {
|
|
11
|
+
const bookDir = join(root, "books", bookId);
|
|
12
|
+
const bookInfo = await stat(bookDir).catch(() => null);
|
|
13
|
+
if (!bookInfo?.isDirectory()) {
|
|
14
|
+
throw new Error(`Book "${bookId}" not found at books/${bookId}/.`);
|
|
15
|
+
}
|
|
16
|
+
const backupsDir = bookBackupsDir(root, bookId);
|
|
17
|
+
await mkdir(backupsDir, { recursive: true });
|
|
18
|
+
const clock = options.now ?? (() => new Date());
|
|
19
|
+
const base = options.suffix ? `${formatStamp(clock())}-${options.suffix}` : formatStamp(clock());
|
|
20
|
+
let backupId = base;
|
|
21
|
+
for (let attempt = 2; await pathExists(join(backupsDir, backupId)); attempt += 1) {
|
|
22
|
+
backupId = `${base}-${attempt}`;
|
|
23
|
+
}
|
|
24
|
+
const backupPath = join(backupsDir, backupId);
|
|
25
|
+
await cp(bookDir, backupPath, { recursive: true });
|
|
26
|
+
return { bookId, backupId, path: backupPath };
|
|
27
|
+
}
|
|
28
|
+
export async function listBookBackups(root, bookId) {
|
|
29
|
+
const backupsDir = bookBackupsDir(root, bookId);
|
|
30
|
+
const entries = await readdir(backupsDir, { withFileTypes: true }).catch((error) => {
|
|
31
|
+
if (error.code === "ENOENT") {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
});
|
|
36
|
+
const backups = await Promise.all(entries
|
|
37
|
+
.filter((entry) => entry.isDirectory())
|
|
38
|
+
.map(async (entry) => {
|
|
39
|
+
const info = await stat(join(backupsDir, entry.name));
|
|
40
|
+
return { id: entry.name, createdAt: info.mtime.toISOString() };
|
|
41
|
+
}));
|
|
42
|
+
// Backup ids start with a UTC timestamp, so a descending id sort is newest-first.
|
|
43
|
+
return backups.sort((a, b) => b.id.localeCompare(a.id));
|
|
44
|
+
}
|
|
45
|
+
export async function restoreBookBackup(root, bookId, backupId, options = {}) {
|
|
46
|
+
// backupId comes from CLI input and is joined into a path — keep it a single
|
|
47
|
+
// safe path component.
|
|
48
|
+
if (!/^[A-Za-z0-9._-]+$/.test(backupId) || backupId === "." || backupId === "..") {
|
|
49
|
+
throw new Error(`Invalid backup id "${backupId}": a backup id must be a single directory name.`);
|
|
50
|
+
}
|
|
51
|
+
const backupPath = join(bookBackupsDir(root, bookId), backupId);
|
|
52
|
+
const backupInfo = await stat(backupPath).catch(() => null);
|
|
53
|
+
if (!backupInfo?.isDirectory()) {
|
|
54
|
+
throw new Error(`Backup "${backupId}" not found for book "${bookId}". `
|
|
55
|
+
+ `List available backups with: inkos book backup ${bookId} --list`);
|
|
56
|
+
}
|
|
57
|
+
const bookDir = join(root, "books", bookId);
|
|
58
|
+
const bookExists = await stat(bookDir).then((info) => info.isDirectory()).catch(() => false);
|
|
59
|
+
let preRestoreBackupId = null;
|
|
60
|
+
if (bookExists) {
|
|
61
|
+
const preRestore = await createBookBackup(root, bookId, { now: options.now, suffix: "pre-restore" });
|
|
62
|
+
preRestoreBackupId = preRestore.backupId;
|
|
63
|
+
}
|
|
64
|
+
await rm(bookDir, { recursive: true, force: true });
|
|
65
|
+
await cp(backupPath, bookDir, { recursive: true });
|
|
66
|
+
return { bookId, restoredFrom: backupId, preRestoreBackupId };
|
|
67
|
+
}
|
|
68
|
+
function formatStamp(date) {
|
|
69
|
+
return date.toISOString().slice(0, 19).replace(/[-:]/g, "").replace("T", "-");
|
|
70
|
+
}
|
|
71
|
+
async function pathExists(path) {
|
|
72
|
+
return access(path).then(() => true).catch(() => false);
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=book-backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"book-backup.js","sourceRoot":"","sources":["../src/book-backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,YAAY,SAsErB,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { PipelineRunner, runAgentSession, toWritingLanguage } from "@kienmatu/inkos-core";
|
|
3
|
+
import { buildPipelineConfig, loadConfig, createClient, findProjectRoot, resolveBookId, resolveContext, log, logError } from "../utils.js";
|
|
4
|
+
export const agentCommand = new Command("agent")
|
|
5
|
+
.description("Natural language agent mode (LLM orchestrates via tool-use)")
|
|
6
|
+
.argument("<instruction>", "Natural language instruction")
|
|
7
|
+
.option("--book <bookId>", "Bind this request to an existing book")
|
|
8
|
+
.option("--session <sessionId>", "Reuse an agent session id")
|
|
9
|
+
.option("--context <text>", "Additional context (natural language)")
|
|
10
|
+
.option("--context-file <path>", "Read additional context from file")
|
|
11
|
+
.option("--json", "Output JSON (suppress progress messages)")
|
|
12
|
+
.option("--quiet", "Suppress non-JSON console output")
|
|
13
|
+
.action(async (instruction, opts) => {
|
|
14
|
+
try {
|
|
15
|
+
const config = await loadConfig();
|
|
16
|
+
const client = createClient(config);
|
|
17
|
+
const root = findProjectRoot();
|
|
18
|
+
const context = await resolveContext(opts);
|
|
19
|
+
const fullInstruction = context
|
|
20
|
+
? `${instruction}\n\n补充信息:${context}`
|
|
21
|
+
: instruction;
|
|
22
|
+
const bookId = opts.book ? await resolveBookId(opts.book, root) : null;
|
|
23
|
+
const trimmed = fullInstruction.trim();
|
|
24
|
+
const actionSource = trimmed.startsWith("/") ? "slash" : "free-text";
|
|
25
|
+
const requestedIntent = bookId && trimmed === "/write"
|
|
26
|
+
? "write_next"
|
|
27
|
+
: !bookId && trimmed === "/create"
|
|
28
|
+
? "create_book"
|
|
29
|
+
: undefined;
|
|
30
|
+
const sessionKind = bookId
|
|
31
|
+
? "book"
|
|
32
|
+
: requestedIntent === "create_book"
|
|
33
|
+
? "book-create"
|
|
34
|
+
: "chat";
|
|
35
|
+
const sessionId = opts.session?.trim() || `cli-agent-${Date.now().toString(36)}`;
|
|
36
|
+
const pipeline = new PipelineRunner(buildPipelineConfig(config, root, {
|
|
37
|
+
externalContext: context,
|
|
38
|
+
quiet: opts.quiet || opts.json,
|
|
39
|
+
}));
|
|
40
|
+
const result = await runAgentSession({
|
|
41
|
+
sessionId,
|
|
42
|
+
bookId,
|
|
43
|
+
sessionKind,
|
|
44
|
+
actionSource,
|
|
45
|
+
requestedIntent,
|
|
46
|
+
language: toWritingLanguage(config.language),
|
|
47
|
+
pipeline,
|
|
48
|
+
projectRoot: root,
|
|
49
|
+
model: client._piModel
|
|
50
|
+
? client._piModel
|
|
51
|
+
: { provider: config.llm.provider ?? "openai", modelId: config.llm.model },
|
|
52
|
+
apiKey: client._apiKey,
|
|
53
|
+
}, fullInstruction);
|
|
54
|
+
if (opts.json) {
|
|
55
|
+
log(JSON.stringify({ result }));
|
|
56
|
+
}
|
|
57
|
+
else if (!opts.quiet && result.responseText.trim()) {
|
|
58
|
+
log(result.responseText);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
if (opts.json) {
|
|
63
|
+
log(JSON.stringify({ error: String(e) }));
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
logError(`Agent failed: ${e}`);
|
|
67
|
+
}
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/commands/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/commands/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,gBAAgB,SAwEzB,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { StateManager, computeAnalytics } from "@kienmatu/inkos-core";
|
|
3
|
+
import { loadConfig, findProjectRoot, resolveBookId, log, logError } from "../utils.js";
|
|
4
|
+
export const analyticsCommand = new Command("analytics")
|
|
5
|
+
.alias("stats")
|
|
6
|
+
.description("Show analytics and token stats for a book")
|
|
7
|
+
.argument("[book-id]", "Book ID (auto-detected if only one book)")
|
|
8
|
+
.option("--json", "Output JSON")
|
|
9
|
+
.action(async (bookIdArg, opts) => {
|
|
10
|
+
try {
|
|
11
|
+
await loadConfig();
|
|
12
|
+
const root = findProjectRoot();
|
|
13
|
+
const bookId = await resolveBookId(bookIdArg, root);
|
|
14
|
+
const state = new StateManager(root);
|
|
15
|
+
const chapters = await state.loadChapterIndex(bookId);
|
|
16
|
+
const analytics = computeAnalytics(bookId, chapters);
|
|
17
|
+
if (opts.json) {
|
|
18
|
+
log(JSON.stringify(analytics, null, 2));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
log(`Analytics for "${bookId}":`);
|
|
22
|
+
log("");
|
|
23
|
+
log(` Total chapters: ${analytics.totalChapters}`);
|
|
24
|
+
log(` Total words: ${analytics.totalWords.toLocaleString()}`);
|
|
25
|
+
log(` Avg words/chapter: ${analytics.avgWordsPerChapter.toLocaleString()}`);
|
|
26
|
+
log(` Audit pass rate: ${analytics.auditPassRate}%`);
|
|
27
|
+
log("");
|
|
28
|
+
if (Object.keys(analytics.statusDistribution).length > 0) {
|
|
29
|
+
log(" Status distribution:");
|
|
30
|
+
for (const [status, count] of Object.entries(analytics.statusDistribution)) {
|
|
31
|
+
log(` ${status}: ${count}`);
|
|
32
|
+
}
|
|
33
|
+
log("");
|
|
34
|
+
}
|
|
35
|
+
if (analytics.tokenStats) {
|
|
36
|
+
log(" Token usage:");
|
|
37
|
+
log(` Total tokens: ${analytics.tokenStats.totalTokens.toLocaleString()}`);
|
|
38
|
+
log(` Prompt tokens: ${analytics.tokenStats.totalPromptTokens.toLocaleString()}`);
|
|
39
|
+
log(` Completion tokens: ${analytics.tokenStats.totalCompletionTokens.toLocaleString()}`);
|
|
40
|
+
log(` Avg tokens/chapter: ${analytics.tokenStats.avgTokensPerChapter.toLocaleString()}`);
|
|
41
|
+
if (analytics.tokenStats.recentTrend.length > 0) {
|
|
42
|
+
log(" Recent trend:");
|
|
43
|
+
for (const { chapter, totalTokens } of analytics.tokenStats.recentTrend) {
|
|
44
|
+
log(` Ch.${chapter}: ${totalTokens.toLocaleString()} tokens`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
log("");
|
|
48
|
+
}
|
|
49
|
+
if (analytics.topIssueCategories.length > 0) {
|
|
50
|
+
log(" Most common issue categories:");
|
|
51
|
+
for (const { category, count } of analytics.topIssueCategories) {
|
|
52
|
+
log(` ${category}: ${count}`);
|
|
53
|
+
}
|
|
54
|
+
log("");
|
|
55
|
+
}
|
|
56
|
+
if (analytics.chaptersWithMostIssues.length > 0) {
|
|
57
|
+
log(" Chapters with most issues:");
|
|
58
|
+
for (const { chapter, issueCount } of analytics.chaptersWithMostIssues) {
|
|
59
|
+
log(` Ch.${chapter}: ${issueCount} issues`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
if (opts.json) {
|
|
66
|
+
log(JSON.stringify({ error: String(e) }));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
logError(`Analytics failed: ${e}`);
|
|
70
|
+
}
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/commands/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,YAAY,SA4ErB,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { PipelineRunner, StateManager } from "@kienmatu/inkos-core";
|
|
3
|
+
import { loadConfig, buildPipelineConfig, findProjectRoot, resolveBookId, log, logError } from "../utils.js";
|
|
4
|
+
import { formatNotifyAuditBody, formatNotifyCommandTitle, formatNotifyFailureBody, resolveCliLanguage, } from "../localization.js";
|
|
5
|
+
import { sendCommandNotification } from "../notify-helper.js";
|
|
6
|
+
export const auditCommand = new Command("audit")
|
|
7
|
+
.description("Audit a chapter for continuity issues")
|
|
8
|
+
.argument("[book-id]", "Book ID (auto-detected if only one book)")
|
|
9
|
+
.argument("[chapter]", "Chapter number (defaults to latest)")
|
|
10
|
+
.option("--json", "Output JSON")
|
|
11
|
+
.option("--notify", "Send a notification to configured notify channels when the command finishes")
|
|
12
|
+
.action(async (bookIdArg, chapterStr, opts) => {
|
|
13
|
+
let notifyLanguage = "zh";
|
|
14
|
+
let notifyBookName;
|
|
15
|
+
try {
|
|
16
|
+
const config = await loadConfig();
|
|
17
|
+
const root = findProjectRoot();
|
|
18
|
+
// If first arg looks like a number, treat it as chapter (auto-detect book)
|
|
19
|
+
let bookId;
|
|
20
|
+
let chapterNumber;
|
|
21
|
+
if (bookIdArg && /^\d+$/.test(bookIdArg)) {
|
|
22
|
+
bookId = await resolveBookId(undefined, root);
|
|
23
|
+
chapterNumber = parseInt(bookIdArg, 10);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
bookId = await resolveBookId(bookIdArg, root);
|
|
27
|
+
chapterNumber = chapterStr ? parseInt(chapterStr, 10) : undefined;
|
|
28
|
+
}
|
|
29
|
+
const state = new StateManager(root);
|
|
30
|
+
const book = await state.loadBookConfig(bookId);
|
|
31
|
+
const language = resolveCliLanguage(book.language);
|
|
32
|
+
notifyLanguage = language;
|
|
33
|
+
notifyBookName = book.title ?? bookId;
|
|
34
|
+
const pipeline = new PipelineRunner(buildPipelineConfig(config, root));
|
|
35
|
+
if (!opts.json)
|
|
36
|
+
log(`Auditing "${bookId}"${chapterNumber ? ` chapter ${chapterNumber}` : " (latest)"}...`);
|
|
37
|
+
const result = await pipeline.auditDraft(bookId, chapterNumber);
|
|
38
|
+
if (opts.json) {
|
|
39
|
+
log(JSON.stringify(result, null, 2));
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
log(` Chapter ${result.chapterNumber}: ${result.passed ? "PASSED" : "FAILED"}`);
|
|
43
|
+
log(` Summary: ${result.summary}`);
|
|
44
|
+
if (result.issues.length > 0) {
|
|
45
|
+
log(" Issues:");
|
|
46
|
+
for (const issue of result.issues) {
|
|
47
|
+
log(` [${issue.severity}] ${issue.category}: ${issue.description}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Unlike write commands, the pipeline sends no notification for
|
|
52
|
+
// auditDraft, so --notify always sends the completion notification here.
|
|
53
|
+
if (opts.notify) {
|
|
54
|
+
await sendCommandNotification({
|
|
55
|
+
title: formatNotifyCommandTitle(language, "audit", notifyBookName, true),
|
|
56
|
+
body: formatNotifyAuditBody(language, {
|
|
57
|
+
chapterNumber: result.chapterNumber,
|
|
58
|
+
passed: result.passed,
|
|
59
|
+
issueCount: result.issues.length,
|
|
60
|
+
summary: result.summary,
|
|
61
|
+
}),
|
|
62
|
+
}, config);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
if (opts.notify) {
|
|
67
|
+
await sendCommandNotification({
|
|
68
|
+
title: formatNotifyCommandTitle(notifyLanguage, "audit", notifyBookName, false),
|
|
69
|
+
body: formatNotifyFailureBody(notifyLanguage, e),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (opts.json) {
|
|
73
|
+
log(JSON.stringify({ error: String(e) }));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
logError(`Audit failed: ${e}`);
|
|
77
|
+
}
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.d.ts","sourceRoot":"","sources":["../../src/commands/auto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAiBpC,eAAO,MAAM,WAAW,SAuIpB,CAAC"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { PipelineRunner, StateManager } from "@kienmatu/inkos-core";
|
|
3
|
+
import { loadConfig, buildPipelineConfig, findProjectRoot, getLegacyMigrationHint, resolveBookId, log, logError } from "../utils.js";
|
|
4
|
+
import { formatAutoWriteAlreadyComplete, formatAutoWriteStart, formatNotifyBatchWriteBody, formatNotifyCommandTitle, formatNotifyFailureBody, formatWriteNextComplete, formatWriteNextProgress, formatWriteNextResultLines, resolveCliLanguage, } from "../localization.js";
|
|
5
|
+
import { sendCommandNotification } from "../notify-helper.js";
|
|
6
|
+
export const autoCommand = new Command("auto")
|
|
7
|
+
.description("Auto-write chapters until the book reaches a target chapter number: auto [book-id] <target-chapter>")
|
|
8
|
+
.argument("<args...>", "Book ID (optional, auto-detected if only one book) and target chapter number")
|
|
9
|
+
.option("--words <n>", "Words per chapter (overrides book config)")
|
|
10
|
+
.option("--json", "Output JSON")
|
|
11
|
+
.option("-q, --quiet", "Suppress console output")
|
|
12
|
+
.option("--notify", "Send a notification to configured notify channels when the command finishes")
|
|
13
|
+
.action(async (args, opts) => {
|
|
14
|
+
let notifyLanguage = "zh";
|
|
15
|
+
let notifyBookName;
|
|
16
|
+
try {
|
|
17
|
+
const root = findProjectRoot();
|
|
18
|
+
let bookId;
|
|
19
|
+
let targetChapter;
|
|
20
|
+
if (args.length === 1) {
|
|
21
|
+
targetChapter = parseInt(args[0], 10);
|
|
22
|
+
if (isNaN(targetChapter))
|
|
23
|
+
throw new Error(`Expected target chapter number, got "${args[0]}"`);
|
|
24
|
+
bookId = await resolveBookId(undefined, root);
|
|
25
|
+
}
|
|
26
|
+
else if (args.length === 2) {
|
|
27
|
+
targetChapter = parseInt(args[1], 10);
|
|
28
|
+
if (isNaN(targetChapter))
|
|
29
|
+
throw new Error(`Expected target chapter number, got "${args[1]}"`);
|
|
30
|
+
bookId = await resolveBookId(args[0], root);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
throw new Error("Usage: inkos auto [book-id] <target-chapter>");
|
|
34
|
+
}
|
|
35
|
+
if (targetChapter < 1) {
|
|
36
|
+
throw new Error(`Target chapter must be >= 1, got ${targetChapter}`);
|
|
37
|
+
}
|
|
38
|
+
const state = new StateManager(root);
|
|
39
|
+
const book = await state.loadBookConfig(bookId);
|
|
40
|
+
const language = resolveCliLanguage(book.language);
|
|
41
|
+
notifyLanguage = language;
|
|
42
|
+
notifyBookName = book.title ?? bookId;
|
|
43
|
+
const migrationHint = await getLegacyMigrationHint(root, bookId);
|
|
44
|
+
if (migrationHint && !opts.json) {
|
|
45
|
+
log(`[migration] ${migrationHint}`);
|
|
46
|
+
}
|
|
47
|
+
const startChapter = await state.getNextChapterNumber(bookId);
|
|
48
|
+
if (startChapter > targetChapter) {
|
|
49
|
+
if (opts.json) {
|
|
50
|
+
log(JSON.stringify([], null, 2));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
log(formatAutoWriteAlreadyComplete(language, bookId, startChapter - 1, targetChapter));
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const config = await loadConfig();
|
|
58
|
+
// `inkos auto` is unattended batch writing, so the audit→revise loop must
|
|
59
|
+
// run inline: force "auto" regardless of book/project reviewMode settings.
|
|
60
|
+
const pipeline = new PipelineRunner(buildPipelineConfig(config, root, {
|
|
61
|
+
quiet: opts.quiet,
|
|
62
|
+
chapterReviewMode: "auto",
|
|
63
|
+
}));
|
|
64
|
+
if (!opts.json)
|
|
65
|
+
log(formatAutoWriteStart(language, bookId, startChapter, targetChapter));
|
|
66
|
+
const wordCount = opts.words ? parseInt(opts.words, 10) : undefined;
|
|
67
|
+
const results = [];
|
|
68
|
+
for (let chapter = startChapter; chapter <= targetChapter; chapter++) {
|
|
69
|
+
if (!opts.json)
|
|
70
|
+
log(formatWriteNextProgress(language, chapter, targetChapter, bookId));
|
|
71
|
+
let result;
|
|
72
|
+
try {
|
|
73
|
+
result = await pipeline.writeNextChapter(bookId, wordCount);
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
throw new Error(`Chapter ${chapter} failed, stopping auto-write (${results.length} chapter(s) completed this run): ${e instanceof Error ? e.message : String(e)}`, { cause: e });
|
|
77
|
+
}
|
|
78
|
+
results.push(result);
|
|
79
|
+
if (!opts.json) {
|
|
80
|
+
for (const line of formatWriteNextResultLines(language, {
|
|
81
|
+
chapterNumber: result.chapterNumber,
|
|
82
|
+
title: result.title,
|
|
83
|
+
wordCount: result.wordCount,
|
|
84
|
+
auditPassed: result.auditResult.passed,
|
|
85
|
+
revised: result.revised,
|
|
86
|
+
status: result.status,
|
|
87
|
+
issues: result.auditResult.issues,
|
|
88
|
+
})) {
|
|
89
|
+
log(line);
|
|
90
|
+
}
|
|
91
|
+
log("");
|
|
92
|
+
}
|
|
93
|
+
if (result.status === "state-degraded") {
|
|
94
|
+
throw new Error(`Chapter ${result.chapterNumber} finished in state-degraded status, stopping auto-write. Run "inkos write repair-state ${bookId} ${result.chapterNumber}" first, then re-run inkos auto.`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (opts.json) {
|
|
98
|
+
log(JSON.stringify(results, null, 2));
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
log(formatWriteNextComplete(language));
|
|
102
|
+
}
|
|
103
|
+
// The pipeline itself already sends one notification per completed
|
|
104
|
+
// chapter whenever notify channels are configured (runner.ts, end of
|
|
105
|
+
// writeNextChapter). A single-chapter run would therefore duplicate that
|
|
106
|
+
// exact notification — only send a command-level batch summary when this
|
|
107
|
+
// run wrote more than one chapter.
|
|
108
|
+
if (opts.notify && results.length > 1) {
|
|
109
|
+
await sendCommandNotification({
|
|
110
|
+
title: formatNotifyCommandTitle(language, "auto", notifyBookName, true),
|
|
111
|
+
body: formatNotifyBatchWriteBody(language, results.map((r) => ({
|
|
112
|
+
chapterNumber: r.chapterNumber,
|
|
113
|
+
title: r.title,
|
|
114
|
+
wordCount: r.wordCount,
|
|
115
|
+
auditPassed: r.auditResult.passed,
|
|
116
|
+
}))),
|
|
117
|
+
}, config);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
if (opts.notify) {
|
|
122
|
+
await sendCommandNotification({
|
|
123
|
+
title: formatNotifyCommandTitle(notifyLanguage, "auto", notifyBookName, false),
|
|
124
|
+
body: formatNotifyFailureBody(notifyLanguage, e),
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
if (opts.json) {
|
|
128
|
+
log(JSON.stringify({ error: String(e) }));
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
logError(`Auto-write failed: ${e}`);
|
|
132
|
+
}
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=auto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto.js","sourceRoot":"","sources":["../../src/commands/auto.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"book.d.ts","sourceRoot":"","sources":["../../src/commands/book.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,eAAO,MAAM,WAAW,SACM,CAAC"}
|