@actalk/inkos-core 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 (89) hide show
  1. package/dist/__tests__/models.test.d.ts +2 -0
  2. package/dist/__tests__/models.test.d.ts.map +1 -0
  3. package/dist/__tests__/models.test.js +328 -0
  4. package/dist/__tests__/models.test.js.map +1 -0
  5. package/dist/__tests__/state-manager.test.d.ts +2 -0
  6. package/dist/__tests__/state-manager.test.d.ts.map +1 -0
  7. package/dist/__tests__/state-manager.test.js +264 -0
  8. package/dist/__tests__/state-manager.test.js.map +1 -0
  9. package/dist/__tests__/writer-parser.test.d.ts +2 -0
  10. package/dist/__tests__/writer-parser.test.d.ts.map +1 -0
  11. package/dist/__tests__/writer-parser.test.js +183 -0
  12. package/dist/__tests__/writer-parser.test.js.map +1 -0
  13. package/dist/agents/architect.d.ts +16 -0
  14. package/dist/agents/architect.d.ts.map +1 -0
  15. package/dist/agents/architect.js +85 -0
  16. package/dist/agents/architect.js.map +1 -0
  17. package/dist/agents/base.d.ts +18 -0
  18. package/dist/agents/base.d.ts.map +1 -0
  19. package/dist/agents/base.js +11 -0
  20. package/dist/agents/base.js.map +1 -0
  21. package/dist/agents/continuity.d.ts +19 -0
  22. package/dist/agents/continuity.d.ts.map +1 -0
  23. package/dist/agents/continuity.js +114 -0
  24. package/dist/agents/continuity.js.map +1 -0
  25. package/dist/agents/radar.d.ts +21 -0
  26. package/dist/agents/radar.d.ts.map +1 -0
  27. package/dist/agents/radar.js +60 -0
  28. package/dist/agents/radar.js.map +1 -0
  29. package/dist/agents/reviser.d.ts +17 -0
  30. package/dist/agents/reviser.d.ts.map +1 -0
  31. package/dist/agents/reviser.js +99 -0
  32. package/dist/agents/reviser.js.map +1 -0
  33. package/dist/agents/writer.d.ts +30 -0
  34. package/dist/agents/writer.d.ts.map +1 -0
  35. package/dist/agents/writer.js +284 -0
  36. package/dist/agents/writer.js.map +1 -0
  37. package/dist/index.d.ts +19 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +24 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/llm/provider.d.ts +20 -0
  42. package/dist/llm/provider.d.ts.map +1 -0
  43. package/dist/llm/provider.js +41 -0
  44. package/dist/llm/provider.js.map +1 -0
  45. package/dist/models/book.d.ts +40 -0
  46. package/dist/models/book.d.ts.map +1 -0
  47. package/dist/models/book.js +32 -0
  48. package/dist/models/book.js.map +1 -0
  49. package/dist/models/chapter.d.ts +33 -0
  50. package/dist/models/chapter.d.ts.map +1 -0
  51. package/dist/models/chapter.js +25 -0
  52. package/dist/models/chapter.js.map +1 -0
  53. package/dist/models/project.d.ts +189 -0
  54. package/dist/models/project.d.ts.map +1 -0
  55. package/dist/models/project.js +44 -0
  56. package/dist/models/project.js.map +1 -0
  57. package/dist/models/state.d.ts +48 -0
  58. package/dist/models/state.d.ts.map +1 -0
  59. package/dist/models/state.js +6 -0
  60. package/dist/models/state.js.map +1 -0
  61. package/dist/notify/dispatcher.d.ts +7 -0
  62. package/dist/notify/dispatcher.d.ts.map +1 -0
  63. package/dist/notify/dispatcher.js +27 -0
  64. package/dist/notify/dispatcher.js.map +1 -0
  65. package/dist/notify/feishu.d.ts +5 -0
  66. package/dist/notify/feishu.d.ts.map +1 -0
  67. package/dist/notify/feishu.js +26 -0
  68. package/dist/notify/feishu.js.map +1 -0
  69. package/dist/notify/telegram.d.ts +6 -0
  70. package/dist/notify/telegram.d.ts.map +1 -0
  71. package/dist/notify/telegram.js +17 -0
  72. package/dist/notify/telegram.js.map +1 -0
  73. package/dist/notify/wechat-work.d.ts +5 -0
  74. package/dist/notify/wechat-work.d.ts.map +1 -0
  75. package/dist/notify/wechat-work.js +15 -0
  76. package/dist/notify/wechat-work.js.map +1 -0
  77. package/dist/pipeline/runner.d.ts +30 -0
  78. package/dist/pipeline/runner.d.ts.map +1 -0
  79. package/dist/pipeline/runner.js +141 -0
  80. package/dist/pipeline/runner.js.map +1 -0
  81. package/dist/pipeline/scheduler.d.ts +24 -0
  82. package/dist/pipeline/scheduler.d.ts.map +1 -0
  83. package/dist/pipeline/scheduler.js +102 -0
  84. package/dist/pipeline/scheduler.js.map +1 -0
  85. package/dist/state/manager.d.ts +20 -0
  86. package/dist/state/manager.d.ts.map +1 -0
  87. package/dist/state/manager.js +128 -0
  88. package/dist/state/manager.js.map +1 -0
  89. package/package.json +35 -0
@@ -0,0 +1,141 @@
1
+ import { ArchitectAgent } from "../agents/architect.js";
2
+ import { WriterAgent } from "../agents/writer.js";
3
+ import { ContinuityAuditor } from "../agents/continuity.js";
4
+ import { ReviserAgent } from "../agents/reviser.js";
5
+ import { RadarAgent } from "../agents/radar.js";
6
+ import { StateManager } from "../state/manager.js";
7
+ import { dispatchNotification } from "../notify/dispatcher.js";
8
+ import { writeFile } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ export class PipelineRunner {
11
+ state;
12
+ config;
13
+ constructor(config) {
14
+ this.config = config;
15
+ this.state = new StateManager(config.projectRoot);
16
+ }
17
+ agentCtx(bookId) {
18
+ return {
19
+ client: this.config.client,
20
+ model: this.config.model,
21
+ projectRoot: this.config.projectRoot,
22
+ bookId,
23
+ };
24
+ }
25
+ async runRadar() {
26
+ const radar = new RadarAgent(this.agentCtx());
27
+ return radar.scan(["tomato", "feilu"]);
28
+ }
29
+ async initBook(book) {
30
+ const architect = new ArchitectAgent(this.agentCtx(book.id));
31
+ const bookDir = this.state.bookDir(book.id);
32
+ await this.state.saveBookConfig(book.id, book);
33
+ const foundation = await architect.generateFoundation(book);
34
+ await architect.writeFoundationFiles(bookDir, foundation);
35
+ await this.state.saveChapterIndex(book.id, []);
36
+ }
37
+ async writeNextChapter(bookId) {
38
+ const releaseLock = await this.state.acquireBookLock(bookId);
39
+ try {
40
+ return await this._writeNextChapterLocked(bookId);
41
+ }
42
+ finally {
43
+ await releaseLock();
44
+ }
45
+ }
46
+ async _writeNextChapterLocked(bookId) {
47
+ const book = await this.state.loadBookConfig(bookId);
48
+ const bookDir = this.state.bookDir(bookId);
49
+ const chapterNumber = await this.state.getNextChapterNumber(bookId);
50
+ // 1. Write chapter
51
+ const writer = new WriterAgent(this.agentCtx(bookId));
52
+ const output = await writer.writeChapter({
53
+ book,
54
+ bookDir,
55
+ chapterNumber,
56
+ });
57
+ // 2. Audit chapter
58
+ const auditor = new ContinuityAuditor(this.agentCtx(bookId));
59
+ let auditResult = await auditor.auditChapter(bookDir, output.content, chapterNumber);
60
+ let finalContent = output.content;
61
+ let finalWordCount = output.wordCount;
62
+ let revised = false;
63
+ // 3. If audit fails, try auto-revise once
64
+ if (!auditResult.passed) {
65
+ const criticalIssues = auditResult.issues.filter((i) => i.severity === "critical");
66
+ if (criticalIssues.length > 0) {
67
+ const reviser = new ReviserAgent(this.agentCtx(bookId));
68
+ const reviseOutput = await reviser.reviseChapter(bookDir, output.content, chapterNumber, auditResult.issues);
69
+ if (reviseOutput.revisedContent.length > 0) {
70
+ finalContent = reviseOutput.revisedContent;
71
+ finalWordCount = reviseOutput.wordCount;
72
+ revised = true;
73
+ // Re-audit the revised content
74
+ auditResult = await auditor.auditChapter(bookDir, finalContent, chapterNumber);
75
+ // Update state files from revision
76
+ const storyDir = join(bookDir, "story");
77
+ if (reviseOutput.updatedState !== "(状态卡未更新)") {
78
+ await writeFile(join(storyDir, "current_state.md"), reviseOutput.updatedState, "utf-8");
79
+ }
80
+ if (reviseOutput.updatedLedger !== "(账本未更新)") {
81
+ await writeFile(join(storyDir, "particle_ledger.md"), reviseOutput.updatedLedger, "utf-8");
82
+ }
83
+ if (reviseOutput.updatedHooks !== "(伏笔池未更新)") {
84
+ await writeFile(join(storyDir, "pending_hooks.md"), reviseOutput.updatedHooks, "utf-8");
85
+ }
86
+ }
87
+ }
88
+ }
89
+ // 4. Save chapter (original or revised)
90
+ const chaptersDir = join(bookDir, "chapters");
91
+ const paddedNum = String(chapterNumber).padStart(4, "0");
92
+ const title = revised ? output.title : output.title;
93
+ const filename = `${paddedNum}_${title.replace(/[/\\?%*:|"<>]/g, "").replace(/\s+/g, "_").slice(0, 50)}.md`;
94
+ await writeFile(join(chaptersDir, filename), `# 第${chapterNumber}章 ${title}\n\n${finalContent}`, "utf-8");
95
+ // Save original state files if not revised
96
+ if (!revised) {
97
+ await writer.saveChapter(bookDir, output);
98
+ }
99
+ // 5. Update chapter index
100
+ const existingIndex = await this.state.loadChapterIndex(bookId);
101
+ const now = new Date().toISOString();
102
+ const newEntry = {
103
+ number: chapterNumber,
104
+ title: output.title,
105
+ status: auditResult.passed ? "ready-for-review" : "audit-failed",
106
+ wordCount: finalWordCount,
107
+ createdAt: now,
108
+ updatedAt: now,
109
+ auditIssues: auditResult.issues.map((i) => `[${i.severity}] ${i.description}`),
110
+ };
111
+ await this.state.saveChapterIndex(bookId, [...existingIndex, newEntry]);
112
+ // 5.5 Snapshot state for rollback support
113
+ await this.state.snapshotState(bookId, chapterNumber);
114
+ // 6. Send notification
115
+ if (this.config.notifyChannels && this.config.notifyChannels.length > 0) {
116
+ const statusEmoji = auditResult.passed ? "✅" : "⚠️";
117
+ await dispatchNotification(this.config.notifyChannels, {
118
+ title: `${statusEmoji} ${book.title} 第${chapterNumber}章`,
119
+ body: [
120
+ `**${output.title}** | ${finalWordCount}字`,
121
+ revised ? "📝 已自动修正" : "",
122
+ `审稿: ${auditResult.passed ? "通过" : "需人工审核"}`,
123
+ ...auditResult.issues
124
+ .filter((i) => i.severity !== "info")
125
+ .map((i) => `- [${i.severity}] ${i.description}`),
126
+ ]
127
+ .filter(Boolean)
128
+ .join("\n"),
129
+ });
130
+ }
131
+ return {
132
+ chapterNumber,
133
+ title: output.title,
134
+ wordCount: finalWordCount,
135
+ auditResult,
136
+ revised,
137
+ status: auditResult.passed ? "approved" : "needs-review",
138
+ };
139
+ }
140
+ }
141
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/pipeline/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { PipelineConfig } from "./runner.js";
2
+ export interface SchedulerConfig extends PipelineConfig {
3
+ readonly radarCron: string;
4
+ readonly writeCron: string;
5
+ readonly auditCron: string;
6
+ readonly maxConcurrentBooks: number;
7
+ readonly onChapterComplete?: (bookId: string, chapter: number, status: string) => void;
8
+ readonly onError?: (bookId: string, error: Error) => void;
9
+ }
10
+ export declare class Scheduler {
11
+ private readonly pipeline;
12
+ private readonly state;
13
+ private readonly config;
14
+ private tasks;
15
+ private running;
16
+ constructor(config: SchedulerConfig);
17
+ start(): Promise<void>;
18
+ stop(): void;
19
+ get isRunning(): boolean;
20
+ private runWriteCycle;
21
+ private runRadarScan;
22
+ private cronToMs;
23
+ }
24
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/pipeline/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3D;AAQD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,eAAe;IAM7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC5B,IAAI,IAAI,IAAI;IAQZ,IAAI,SAAS,IAAI,OAAO,CAEvB;YAEa,aAAa;YA2Bb,YAAY;IAQ1B,OAAO,CAAC,QAAQ;CAiBjB"}
@@ -0,0 +1,102 @@
1
+ import { PipelineRunner } from "./runner.js";
2
+ import { StateManager } from "../state/manager.js";
3
+ export class Scheduler {
4
+ pipeline;
5
+ state;
6
+ config;
7
+ tasks = [];
8
+ running = false;
9
+ constructor(config) {
10
+ this.config = config;
11
+ this.pipeline = new PipelineRunner(config);
12
+ this.state = new StateManager(config.projectRoot);
13
+ }
14
+ async start() {
15
+ if (this.running)
16
+ return;
17
+ this.running = true;
18
+ // Run write cycle immediately on start, then schedule
19
+ await this.runWriteCycle();
20
+ // Schedule recurring write cycle (default: every 2 hours)
21
+ const writeCycleMs = this.cronToMs(this.config.writeCron);
22
+ const writeTask = {
23
+ name: "write-cycle",
24
+ intervalMs: writeCycleMs,
25
+ };
26
+ writeTask.timer = setInterval(() => {
27
+ this.runWriteCycle().catch((e) => {
28
+ this.config.onError?.("scheduler", e);
29
+ });
30
+ }, writeCycleMs);
31
+ this.tasks.push(writeTask);
32
+ // Schedule radar scan (default: daily)
33
+ const radarMs = this.cronToMs(this.config.radarCron);
34
+ const radarTask = {
35
+ name: "radar-scan",
36
+ intervalMs: radarMs,
37
+ };
38
+ radarTask.timer = setInterval(() => {
39
+ this.runRadarScan().catch((e) => {
40
+ this.config.onError?.("radar", e);
41
+ });
42
+ }, radarMs);
43
+ this.tasks.push(radarTask);
44
+ }
45
+ stop() {
46
+ this.running = false;
47
+ for (const task of this.tasks) {
48
+ if (task.timer)
49
+ clearInterval(task.timer);
50
+ }
51
+ this.tasks = [];
52
+ }
53
+ get isRunning() {
54
+ return this.running;
55
+ }
56
+ async runWriteCycle() {
57
+ const bookIds = await this.state.listBooks();
58
+ const activeBooks = [];
59
+ for (const id of bookIds) {
60
+ const config = await this.state.loadBookConfig(id);
61
+ if (config.status === "active" || config.status === "outlining") {
62
+ activeBooks.push({ id, config });
63
+ }
64
+ }
65
+ const booksToWrite = activeBooks.slice(0, this.config.maxConcurrentBooks);
66
+ for (const book of booksToWrite) {
67
+ try {
68
+ const result = await this.pipeline.writeNextChapter(book.id);
69
+ this.config.onChapterComplete?.(book.id, result.chapterNumber, result.status);
70
+ }
71
+ catch (e) {
72
+ this.config.onError?.(book.id, e);
73
+ }
74
+ }
75
+ }
76
+ async runRadarScan() {
77
+ try {
78
+ await this.pipeline.runRadar();
79
+ }
80
+ catch (e) {
81
+ this.config.onError?.("radar", e);
82
+ }
83
+ }
84
+ cronToMs(cron) {
85
+ // Simple cron-to-interval mapping for common patterns
86
+ // "0 9 * * *" = daily = 24h
87
+ // "0 14 * * *" = daily = 24h
88
+ // "0 */2 * * *" = every 2h
89
+ const parts = cron.split(" ");
90
+ if (parts.length >= 5) {
91
+ const hour = parts[1];
92
+ if (hour.startsWith("*/")) {
93
+ const interval = parseInt(hour.slice(2), 10);
94
+ return interval * 60 * 60 * 1000;
95
+ }
96
+ // Default: treat as daily
97
+ return 24 * 60 * 60 * 1000;
98
+ }
99
+ return 24 * 60 * 60 * 1000;
100
+ }
101
+ }
102
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/pipeline/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { BookConfig } from "../models/book.js";
2
+ import type { ChapterMeta } from "../models/chapter.js";
3
+ export declare class StateManager {
4
+ private readonly projectRoot;
5
+ constructor(projectRoot: string);
6
+ acquireBookLock(bookId: string): Promise<() => Promise<void>>;
7
+ get booksDir(): string;
8
+ bookDir(bookId: string): string;
9
+ loadProjectConfig(): Promise<Record<string, unknown>>;
10
+ saveProjectConfig(config: Record<string, unknown>): Promise<void>;
11
+ loadBookConfig(bookId: string): Promise<BookConfig>;
12
+ saveBookConfig(bookId: string, config: BookConfig): Promise<void>;
13
+ listBooks(): Promise<ReadonlyArray<string>>;
14
+ getNextChapterNumber(bookId: string): Promise<number>;
15
+ loadChapterIndex(bookId: string): Promise<ReadonlyArray<ChapterMeta>>;
16
+ saveChapterIndex(bookId: string, index: ReadonlyArray<ChapterMeta>): Promise<void>;
17
+ snapshotState(bookId: string, chapterNumber: number): Promise<void>;
18
+ restoreState(bookId: string, chapterNumber: number): Promise<boolean>;
19
+ }
20
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAE1C,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAsBnE,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAIzB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAMrD,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjE,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAMnD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjE,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAmB3C,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOrD,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IAUrE,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC;IAUV,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBnE,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAiB5E"}
@@ -0,0 +1,128 @@
1
+ import { readFile, writeFile, mkdir, readdir, stat, unlink } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ export class StateManager {
4
+ projectRoot;
5
+ constructor(projectRoot) {
6
+ this.projectRoot = projectRoot;
7
+ }
8
+ async acquireBookLock(bookId) {
9
+ const lockPath = join(this.bookDir(bookId), ".write.lock");
10
+ try {
11
+ await stat(lockPath);
12
+ const lockData = await readFile(lockPath, "utf-8");
13
+ throw new Error(`Book "${bookId}" is locked by another process (${lockData}). ` +
14
+ `If this is stale, delete ${lockPath}`);
15
+ }
16
+ catch (e) {
17
+ if (e instanceof Error && e.message.includes("is locked"))
18
+ throw e;
19
+ }
20
+ await writeFile(lockPath, `pid:${process.pid} ts:${Date.now()}`, "utf-8");
21
+ return async () => {
22
+ try {
23
+ await unlink(lockPath);
24
+ }
25
+ catch {
26
+ // ignore
27
+ }
28
+ };
29
+ }
30
+ get booksDir() {
31
+ return join(this.projectRoot, "books");
32
+ }
33
+ bookDir(bookId) {
34
+ return join(this.booksDir, bookId);
35
+ }
36
+ async loadProjectConfig() {
37
+ const configPath = join(this.projectRoot, "inkos.json");
38
+ const raw = await readFile(configPath, "utf-8");
39
+ return JSON.parse(raw);
40
+ }
41
+ async saveProjectConfig(config) {
42
+ const configPath = join(this.projectRoot, "inkos.json");
43
+ await writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
44
+ }
45
+ async loadBookConfig(bookId) {
46
+ const configPath = join(this.bookDir(bookId), "book.json");
47
+ const raw = await readFile(configPath, "utf-8");
48
+ return JSON.parse(raw);
49
+ }
50
+ async saveBookConfig(bookId, config) {
51
+ const dir = this.bookDir(bookId);
52
+ await mkdir(dir, { recursive: true });
53
+ await writeFile(join(dir, "book.json"), JSON.stringify(config, null, 2), "utf-8");
54
+ }
55
+ async listBooks() {
56
+ try {
57
+ const entries = await readdir(this.booksDir);
58
+ const bookIds = [];
59
+ for (const entry of entries) {
60
+ const bookJsonPath = join(this.booksDir, entry, "book.json");
61
+ try {
62
+ await stat(bookJsonPath);
63
+ bookIds.push(entry);
64
+ }
65
+ catch {
66
+ // not a book directory
67
+ }
68
+ }
69
+ return bookIds;
70
+ }
71
+ catch {
72
+ return [];
73
+ }
74
+ }
75
+ async getNextChapterNumber(bookId) {
76
+ const index = await this.loadChapterIndex(bookId);
77
+ if (index.length === 0)
78
+ return 1;
79
+ const maxNum = Math.max(...index.map((ch) => ch.number));
80
+ return maxNum + 1;
81
+ }
82
+ async loadChapterIndex(bookId) {
83
+ const indexPath = join(this.bookDir(bookId), "chapters", "index.json");
84
+ try {
85
+ const raw = await readFile(indexPath, "utf-8");
86
+ return JSON.parse(raw);
87
+ }
88
+ catch {
89
+ return [];
90
+ }
91
+ }
92
+ async saveChapterIndex(bookId, index) {
93
+ const chaptersDir = join(this.bookDir(bookId), "chapters");
94
+ await mkdir(chaptersDir, { recursive: true });
95
+ await writeFile(join(chaptersDir, "index.json"), JSON.stringify(index, null, 2), "utf-8");
96
+ }
97
+ async snapshotState(bookId, chapterNumber) {
98
+ const storyDir = join(this.bookDir(bookId), "story");
99
+ const snapshotDir = join(storyDir, "snapshots", String(chapterNumber));
100
+ await mkdir(snapshotDir, { recursive: true });
101
+ const files = ["current_state.md", "particle_ledger.md", "pending_hooks.md"];
102
+ await Promise.all(files.map(async (f) => {
103
+ try {
104
+ const content = await readFile(join(storyDir, f), "utf-8");
105
+ await writeFile(join(snapshotDir, f), content, "utf-8");
106
+ }
107
+ catch {
108
+ // file doesn't exist yet
109
+ }
110
+ }));
111
+ }
112
+ async restoreState(bookId, chapterNumber) {
113
+ const storyDir = join(this.bookDir(bookId), "story");
114
+ const snapshotDir = join(storyDir, "snapshots", String(chapterNumber));
115
+ const files = ["current_state.md", "particle_ledger.md", "pending_hooks.md"];
116
+ try {
117
+ await Promise.all(files.map(async (f) => {
118
+ const content = await readFile(join(snapshotDir, f), "utf-8");
119
+ await writeFile(join(storyDir, f), content, "utf-8");
120
+ }));
121
+ return true;
122
+ }
123
+ catch {
124
+ return false;
125
+ }
126
+ }
127
+ }
128
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/state/manager.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@actalk/inkos-core",
3
+ "version": "0.1.0",
4
+ "description": "InkOS core: models, agents, pipeline, LLM integration",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": ["dist"],
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/Narcooo/inkos.git",
19
+ "directory": "packages/core"
20
+ },
21
+ "scripts": {
22
+ "build": "tsc",
23
+ "dev": "tsc --watch",
24
+ "test": "vitest run",
25
+ "typecheck": "tsc --noEmit"
26
+ },
27
+ "dependencies": {
28
+ "openai": "^4.80.0",
29
+ "zod": "^3.24.0"
30
+ },
31
+ "devDependencies": {
32
+ "typescript": "^5.8.0",
33
+ "vitest": "^3.0.0"
34
+ }
35
+ }