@actalk/inkos 0.3.1 → 0.3.4
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/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +14 -4
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/book.js +56 -11
- package/dist/commands/book.js.map +1 -1
- package/dist/commands/config.js +54 -3
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +47 -11
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/draft.d.ts.map +1 -1
- package/dist/commands/draft.js +4 -3
- package/dist/commands/draft.js.map +1 -1
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +25 -8
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +69 -25
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/radar.js +27 -14
- package/dist/commands/radar.js.map +1 -1
- package/dist/commands/review.js +109 -30
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/revise.d.ts.map +1 -1
- package/dist/commands/revise.js +13 -4
- package/dist/commands/revise.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +46 -13
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +32 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/write.d.ts.map +1 -1
- package/dist/commands/write.js +75 -25
- package/dist/commands/write.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils.d.ts +7 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +44 -6
- package/dist/utils.js.map +1 -1
- package/package.json +11 -13
- package/LICENSE +0 -21
package/dist/commands/init.js
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import { writeFile, mkdir } from "node:fs/promises";
|
|
3
|
-
import { join } from "node:path";
|
|
4
|
-
import { log, logError } from "../utils.js";
|
|
2
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import { join, basename } from "node:path";
|
|
4
|
+
import { log, logError, GLOBAL_ENV_PATH } from "../utils.js";
|
|
5
|
+
async function hasGlobalConfig() {
|
|
6
|
+
try {
|
|
7
|
+
const content = await readFile(GLOBAL_ENV_PATH, "utf-8");
|
|
8
|
+
return content.includes("INKOS_LLM_API_KEY=") && !content.includes("your-api-key-here");
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
5
14
|
export const initCommand = new Command("init")
|
|
6
|
-
.description("Initialize
|
|
7
|
-
.argument("[name]", "Project name
|
|
15
|
+
.description("Initialize an InkOS project (current directory by default)")
|
|
16
|
+
.argument("[name]", "Project name (creates subdirectory). Omit to init current directory.")
|
|
8
17
|
.action(async (name) => {
|
|
9
|
-
const projectDir = join(process.cwd(), name);
|
|
18
|
+
const projectDir = name ? join(process.cwd(), name) : process.cwd();
|
|
19
|
+
const projectName = name ?? basename(projectDir);
|
|
10
20
|
try {
|
|
11
21
|
await mkdir(projectDir, { recursive: true });
|
|
12
22
|
await mkdir(join(projectDir, "books"), { recursive: true });
|
|
13
23
|
await mkdir(join(projectDir, "radar"), { recursive: true });
|
|
14
24
|
const config = {
|
|
15
|
-
name,
|
|
25
|
+
name: projectName,
|
|
16
26
|
version: "0.1.0",
|
|
17
27
|
llm: {
|
|
18
28
|
provider: process.env.INKOS_LLM_PROVIDER ?? "openai",
|
|
19
29
|
baseUrl: process.env.INKOS_LLM_BASE_URL ?? "https://api.openai.com/v1",
|
|
20
|
-
apiKey: process.env.INKOS_LLM_API_KEY ?? "",
|
|
21
30
|
model: process.env.INKOS_LLM_MODEL ?? "gpt-4o",
|
|
22
31
|
},
|
|
23
32
|
notify: [],
|
|
@@ -31,26 +40,61 @@ export const initCommand = new Command("init")
|
|
|
31
40
|
},
|
|
32
41
|
};
|
|
33
42
|
await writeFile(join(projectDir, "inkos.json"), JSON.stringify(config, null, 2), "utf-8");
|
|
34
|
-
await
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
const global = await hasGlobalConfig();
|
|
44
|
+
if (global) {
|
|
45
|
+
await writeFile(join(projectDir, ".env"), [
|
|
46
|
+
"# Project-level LLM overrides (optional)",
|
|
47
|
+
"# Global config at ~/.inkos/.env will be used by default.",
|
|
48
|
+
"# Uncomment below to override for this project only:",
|
|
49
|
+
"# INKOS_LLM_PROVIDER=openai",
|
|
50
|
+
"# INKOS_LLM_BASE_URL=https://api.openai.com/v1",
|
|
51
|
+
"# INKOS_LLM_API_KEY=your-api-key-here",
|
|
52
|
+
"# INKOS_LLM_MODEL=gpt-4o",
|
|
53
|
+
].join("\n"), "utf-8");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
await writeFile(join(projectDir, ".env"), [
|
|
57
|
+
"# LLM Configuration",
|
|
58
|
+
"# Tip: Run 'inkos config set-global' to set once for all projects.",
|
|
59
|
+
"# Provider: openai (OpenAI / compatible proxy), anthropic (Anthropic native)",
|
|
60
|
+
"INKOS_LLM_PROVIDER=openai",
|
|
61
|
+
"INKOS_LLM_BASE_URL=https://api.openai.com/v1",
|
|
62
|
+
"INKOS_LLM_API_KEY=your-api-key-here",
|
|
63
|
+
"INKOS_LLM_MODEL=gpt-4o",
|
|
64
|
+
"",
|
|
65
|
+
"# Optional parameters (defaults shown):",
|
|
66
|
+
"# INKOS_LLM_TEMPERATURE=0.7",
|
|
67
|
+
"# INKOS_LLM_MAX_TOKENS=8192",
|
|
68
|
+
"# INKOS_LLM_THINKING_BUDGET=0 # Anthropic extended thinking budget",
|
|
69
|
+
"# INKOS_LLM_API_FORMAT=chat # chat (default) or responses (OpenAI Responses API)",
|
|
70
|
+
"",
|
|
71
|
+
"# Anthropic example:",
|
|
72
|
+
"# INKOS_LLM_PROVIDER=anthropic",
|
|
73
|
+
"# INKOS_LLM_BASE_URL=https://api.anthropic.com",
|
|
74
|
+
"# INKOS_LLM_MODEL=claude-sonnet-4-5-20250514",
|
|
75
|
+
].join("\n"), "utf-8");
|
|
76
|
+
}
|
|
47
77
|
await writeFile(join(projectDir, ".gitignore"), [".env", "node_modules/", ".DS_Store"].join("\n"), "utf-8");
|
|
48
78
|
log(`Project initialized at ${projectDir}`);
|
|
49
79
|
log("");
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
80
|
+
if (global) {
|
|
81
|
+
log("Global LLM config detected. Ready to go!");
|
|
82
|
+
log("");
|
|
83
|
+
log("Next steps:");
|
|
84
|
+
if (name)
|
|
85
|
+
log(` cd ${name}`);
|
|
86
|
+
log(" inkos book create --title '我的小说' --genre xuanhuan --platform tomato");
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
log("Next steps:");
|
|
90
|
+
if (name)
|
|
91
|
+
log(` cd ${name}`);
|
|
92
|
+
log(" # Option 1: Set global config (recommended, one-time):");
|
|
93
|
+
log(" inkos config set-global --provider openai --base-url https://api.openai.com/v1 --api-key sk-xxx --model gpt-4o");
|
|
94
|
+
log(" # Option 2: Edit .env for this project only");
|
|
95
|
+
log("");
|
|
96
|
+
log(" inkos book create --title '我的小说' --genre xuanhuan --platform tomato");
|
|
97
|
+
}
|
|
54
98
|
log(" inkos write next <book-id>");
|
|
55
99
|
}
|
|
56
100
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7D,KAAK,UAAU,eAAe;IAC5B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QACzD,OAAO,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IAC1F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,4DAA4D,CAAC;KACzE,QAAQ,CAAC,QAAQ,EAAE,sEAAsE,CAAC;KAC1F,MAAM,CAAC,KAAK,EAAE,IAAa,EAAE,EAAE;IAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IACpE,MAAM,WAAW,GAAG,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5D,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5D,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,OAAO;YAChB,GAAG,EAAE;gBACH,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,QAAQ;gBACpD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,2BAA2B;gBACtE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,QAAQ;aAC/C;YACD,MAAM,EAAE,EAAE;YACV,MAAM,EAAE;gBACN,QAAQ,EAAE;oBACR,SAAS,EAAE,WAAW;oBACtB,SAAS,EAAE,YAAY;oBACvB,SAAS,EAAE,YAAY;iBACxB;gBACD,kBAAkB,EAAE,CAAC;aACtB;SACF,CAAC;QAEF,MAAM,SAAS,CACb,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAC/B,OAAO,CACR,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;QAEvC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,SAAS,CACb,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EACxB;gBACE,0CAA0C;gBAC1C,2DAA2D;gBAC3D,sDAAsD;gBACtD,6BAA6B;gBAC7B,gDAAgD;gBAChD,uCAAuC;gBACvC,0BAA0B;aAC3B,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ,OAAO,CACR,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,CACb,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EACxB;gBACE,qBAAqB;gBACrB,oEAAoE;gBACpE,8EAA8E;gBAC9E,2BAA2B;gBAC3B,8CAA8C;gBAC9C,qCAAqC;gBACrC,wBAAwB;gBACxB,EAAE;gBACF,yCAAyC;gBACzC,6BAA6B;gBAC7B,6BAA6B;gBAC7B,6EAA6E;gBAC7E,8FAA8F;gBAC9F,EAAE;gBACF,sBAAsB;gBACtB,gCAAgC;gBAChC,gDAAgD;gBAChD,8CAA8C;aAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ,OAAO,CACR,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,CACb,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,EAC9B,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EACjD,OAAO,CACR,CAAC;QAEF,GAAG,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QAC5C,GAAG,CAAC,EAAE,CAAC,CAAC;QACR,IAAI,MAAM,EAAE,CAAC;YACX,GAAG,CAAC,0CAA0C,CAAC,CAAC;YAChD,GAAG,CAAC,EAAE,CAAC,CAAC;YACR,GAAG,CAAC,aAAa,CAAC,CAAC;YACnB,IAAI,IAAI;gBAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YAC9B,GAAG,CAAC,uEAAuE,CAAC,CAAC;QAC/E,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,aAAa,CAAC,CAAC;YACnB,IAAI,IAAI;gBAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;YAC9B,GAAG,CAAC,0DAA0D,CAAC,CAAC;YAChE,GAAG,CAAC,kHAAkH,CAAC,CAAC;YACxH,GAAG,CAAC,+CAA+C,CAAC,CAAC;YACrD,GAAG,CAAC,EAAE,CAAC,CAAC;YACR,GAAG,CAAC,uEAAuE,CAAC,CAAC;QAC/E,CAAC;QACD,GAAG,CAAC,8BAA8B,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,QAAQ,CAAC,iCAAiC,CAAC,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/commands/radar.js
CHANGED
|
@@ -8,7 +8,8 @@ export const radarCommand = new Command("radar")
|
|
|
8
8
|
radarCommand
|
|
9
9
|
.command("scan")
|
|
10
10
|
.description("Scan market for opportunities")
|
|
11
|
-
.
|
|
11
|
+
.option("--json", "Output JSON")
|
|
12
|
+
.action(async (opts) => {
|
|
12
13
|
try {
|
|
13
14
|
const config = await loadConfig();
|
|
14
15
|
const client = createClient(config);
|
|
@@ -18,26 +19,38 @@ radarCommand
|
|
|
18
19
|
model: config.llm.model,
|
|
19
20
|
projectRoot: root,
|
|
20
21
|
});
|
|
21
|
-
|
|
22
|
+
if (!opts.json)
|
|
23
|
+
log("Scanning market...");
|
|
22
24
|
const result = await pipeline.runRadar();
|
|
23
|
-
log(`\nMarket Summary:\n${result.marketSummary}\n`);
|
|
24
|
-
log("Recommendations:");
|
|
25
|
-
for (const rec of result.recommendations) {
|
|
26
|
-
log(` [${(rec.confidence * 100).toFixed(0)}%] ${rec.platform}/${rec.genre}`);
|
|
27
|
-
log(` Concept: ${rec.concept}`);
|
|
28
|
-
log(` Reasoning: ${rec.reasoning}`);
|
|
29
|
-
log(` Benchmarks: ${rec.benchmarkTitles.join(", ")}`);
|
|
30
|
-
log("");
|
|
31
|
-
}
|
|
32
25
|
// Save radar result
|
|
33
26
|
const radarDir = join(root, "radar");
|
|
34
27
|
await mkdir(radarDir, { recursive: true });
|
|
35
28
|
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
const filePath = join(radarDir, `scan-${timestamp}.json`);
|
|
30
|
+
await writeFile(filePath, JSON.stringify(result, null, 2), "utf-8");
|
|
31
|
+
if (opts.json) {
|
|
32
|
+
log(JSON.stringify({ ...result, savedTo: filePath }, null, 2));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
log(`\nMarket Summary:\n${result.marketSummary}\n`);
|
|
36
|
+
log("Recommendations:");
|
|
37
|
+
for (const rec of result.recommendations) {
|
|
38
|
+
log(` [${(rec.confidence * 100).toFixed(0)}%] ${rec.platform}/${rec.genre}`);
|
|
39
|
+
log(` Concept: ${rec.concept}`);
|
|
40
|
+
log(` Reasoning: ${rec.reasoning}`);
|
|
41
|
+
log(` Benchmarks: ${rec.benchmarkTitles.join(", ")}`);
|
|
42
|
+
log("");
|
|
43
|
+
}
|
|
44
|
+
log(`Radar result saved to radar/scan-${timestamp}.json`);
|
|
45
|
+
}
|
|
38
46
|
}
|
|
39
47
|
catch (e) {
|
|
40
|
-
|
|
48
|
+
if (opts.json) {
|
|
49
|
+
log(JSON.stringify({ error: String(e) }));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
logError(`Radar scan failed: ${e}`);
|
|
53
|
+
}
|
|
41
54
|
process.exit(1);
|
|
42
55
|
}
|
|
43
56
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radar.js","sourceRoot":"","sources":["../../src/commands/radar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,qBAAqB,CAAC,CAAC;AAEtC,YAAY;KACT,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,KAAK,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"radar.js","sourceRoot":"","sources":["../../src/commands/radar.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/review.js
CHANGED
|
@@ -1,54 +1,101 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { StateManager } from "@actalk/inkos-core";
|
|
3
|
-
import { findProjectRoot, log, logError } from "../utils.js";
|
|
3
|
+
import { findProjectRoot, resolveBookId, log, logError } from "../utils.js";
|
|
4
4
|
export const reviewCommand = new Command("review")
|
|
5
5
|
.description("Review and approve chapters");
|
|
6
6
|
reviewCommand
|
|
7
7
|
.command("list")
|
|
8
8
|
.description("List chapters pending review")
|
|
9
9
|
.argument("[book-id]", "Book ID (optional, lists all books if omitted)")
|
|
10
|
-
.
|
|
10
|
+
.option("--json", "Output JSON")
|
|
11
|
+
.action(async (bookId, opts) => {
|
|
11
12
|
try {
|
|
12
13
|
const root = findProjectRoot();
|
|
13
14
|
const state = new StateManager(root);
|
|
14
15
|
const bookIds = bookId ? [bookId] : await state.listBooks();
|
|
16
|
+
const allPending = [];
|
|
15
17
|
for (const id of bookIds) {
|
|
16
18
|
const index = await state.loadChapterIndex(id);
|
|
17
19
|
const pending = index.filter((ch) => ch.status === "ready-for-review" || ch.status === "audit-failed");
|
|
18
20
|
if (pending.length === 0)
|
|
19
21
|
continue;
|
|
20
22
|
const book = await state.loadBookConfig(id);
|
|
21
|
-
|
|
23
|
+
if (!opts.json) {
|
|
24
|
+
log(`\n${book.title} (${id}):`);
|
|
25
|
+
}
|
|
22
26
|
for (const ch of pending) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
allPending.push({
|
|
28
|
+
bookId: id,
|
|
29
|
+
title: book.title,
|
|
30
|
+
chapter: ch.number,
|
|
31
|
+
chapterTitle: ch.title,
|
|
32
|
+
wordCount: ch.wordCount,
|
|
33
|
+
status: ch.status,
|
|
34
|
+
issues: ch.auditIssues,
|
|
35
|
+
});
|
|
36
|
+
if (!opts.json) {
|
|
37
|
+
log(` Ch.${ch.number} "${ch.title}" | ${ch.wordCount}字 | ${ch.status}`);
|
|
38
|
+
if (ch.auditIssues.length > 0) {
|
|
39
|
+
for (const issue of ch.auditIssues) {
|
|
40
|
+
log(` - ${issue}`);
|
|
41
|
+
}
|
|
27
42
|
}
|
|
28
43
|
}
|
|
29
44
|
}
|
|
30
45
|
}
|
|
46
|
+
if (opts.json) {
|
|
47
|
+
log(JSON.stringify({ pending: allPending }, null, 2));
|
|
48
|
+
}
|
|
49
|
+
else if (allPending.length === 0) {
|
|
50
|
+
log("No chapters pending review.");
|
|
51
|
+
}
|
|
31
52
|
}
|
|
32
53
|
catch (e) {
|
|
33
|
-
|
|
54
|
+
if (opts.json) {
|
|
55
|
+
log(JSON.stringify({ error: String(e) }));
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
logError(`Failed to list reviews: ${e}`);
|
|
59
|
+
}
|
|
34
60
|
process.exit(1);
|
|
35
61
|
}
|
|
36
62
|
});
|
|
63
|
+
/**
|
|
64
|
+
* Parse "[book-id] <chapter>" style arguments from variadic args.
|
|
65
|
+
* Supports: "3" (auto-detect book) or "my-book 3"
|
|
66
|
+
*/
|
|
67
|
+
function parseBookAndChapter(args) {
|
|
68
|
+
if (args.length === 1) {
|
|
69
|
+
const num = parseInt(args[0], 10);
|
|
70
|
+
if (isNaN(num)) {
|
|
71
|
+
throw new Error(`Expected chapter number, got "${args[0]}"`);
|
|
72
|
+
}
|
|
73
|
+
return { bookIdArg: undefined, chapterNum: num };
|
|
74
|
+
}
|
|
75
|
+
if (args.length === 2) {
|
|
76
|
+
const num = parseInt(args[1], 10);
|
|
77
|
+
if (isNaN(num)) {
|
|
78
|
+
throw new Error(`Expected chapter number as second argument, got "${args[1]}"`);
|
|
79
|
+
}
|
|
80
|
+
return { bookIdArg: args[0], chapterNum: num };
|
|
81
|
+
}
|
|
82
|
+
throw new Error("Usage: inkos review approve [book-id] <chapter>");
|
|
83
|
+
}
|
|
37
84
|
reviewCommand
|
|
38
85
|
.command("approve")
|
|
39
|
-
.description("Approve a chapter")
|
|
40
|
-
.argument("<
|
|
41
|
-
.
|
|
42
|
-
.action(async (
|
|
86
|
+
.description("Approve a chapter: approve [book-id] <chapter>")
|
|
87
|
+
.argument("<args...>", "Book ID (optional) and chapter number")
|
|
88
|
+
.option("--json", "Output JSON")
|
|
89
|
+
.action(async (args, opts) => {
|
|
43
90
|
try {
|
|
44
91
|
const root = findProjectRoot();
|
|
92
|
+
const { bookIdArg, chapterNum } = parseBookAndChapter(args);
|
|
93
|
+
const bookId = await resolveBookId(bookIdArg, root);
|
|
45
94
|
const state = new StateManager(root);
|
|
46
|
-
const chapterNum = parseInt(chapterStr, 10);
|
|
47
95
|
const index = [...(await state.loadChapterIndex(bookId))];
|
|
48
96
|
const idx = index.findIndex((ch) => ch.number === chapterNum);
|
|
49
97
|
if (idx === -1) {
|
|
50
|
-
|
|
51
|
-
process.exit(1);
|
|
98
|
+
throw new Error(`Chapter ${chapterNum} not found in "${bookId}"`);
|
|
52
99
|
}
|
|
53
100
|
index[idx] = {
|
|
54
101
|
...index[idx],
|
|
@@ -56,20 +103,32 @@ reviewCommand
|
|
|
56
103
|
updatedAt: new Date().toISOString(),
|
|
57
104
|
};
|
|
58
105
|
await state.saveChapterIndex(bookId, index);
|
|
59
|
-
|
|
106
|
+
if (opts.json) {
|
|
107
|
+
log(JSON.stringify({ bookId, chapter: chapterNum, status: "approved" }));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
log(`Chapter ${chapterNum} approved.`);
|
|
111
|
+
}
|
|
60
112
|
}
|
|
61
113
|
catch (e) {
|
|
62
|
-
|
|
114
|
+
if (opts.json) {
|
|
115
|
+
log(JSON.stringify({ error: String(e) }));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
logError(`Failed to approve: ${e}`);
|
|
119
|
+
}
|
|
63
120
|
process.exit(1);
|
|
64
121
|
}
|
|
65
122
|
});
|
|
66
123
|
reviewCommand
|
|
67
124
|
.command("approve-all")
|
|
68
125
|
.description("Approve all pending chapters for a book")
|
|
69
|
-
.argument("
|
|
70
|
-
.
|
|
126
|
+
.argument("[book-id]", "Book ID (auto-detected if only one book)")
|
|
127
|
+
.option("--json", "Output JSON")
|
|
128
|
+
.action(async (bookIdArg, opts) => {
|
|
71
129
|
try {
|
|
72
130
|
const root = findProjectRoot();
|
|
131
|
+
const bookId = await resolveBookId(bookIdArg, root);
|
|
73
132
|
const state = new StateManager(root);
|
|
74
133
|
const index = [...(await state.loadChapterIndex(bookId))];
|
|
75
134
|
let count = 0;
|
|
@@ -82,29 +141,39 @@ reviewCommand
|
|
|
82
141
|
return ch;
|
|
83
142
|
});
|
|
84
143
|
await state.saveChapterIndex(bookId, updated);
|
|
85
|
-
|
|
144
|
+
if (opts.json) {
|
|
145
|
+
log(JSON.stringify({ bookId, approvedCount: count }));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
log(`${count} chapter(s) approved.`);
|
|
149
|
+
}
|
|
86
150
|
}
|
|
87
151
|
catch (e) {
|
|
88
|
-
|
|
152
|
+
if (opts.json) {
|
|
153
|
+
log(JSON.stringify({ error: String(e) }));
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
logError(`Failed to approve: ${e}`);
|
|
157
|
+
}
|
|
89
158
|
process.exit(1);
|
|
90
159
|
}
|
|
91
160
|
});
|
|
92
161
|
reviewCommand
|
|
93
162
|
.command("reject")
|
|
94
|
-
.description("Reject a chapter")
|
|
95
|
-
.argument("<
|
|
96
|
-
.argument("<chapter>", "Chapter number")
|
|
163
|
+
.description("Reject a chapter: reject [book-id] <chapter>")
|
|
164
|
+
.argument("<args...>", "Book ID (optional) and chapter number")
|
|
97
165
|
.option("--reason <reason>", "Rejection reason")
|
|
98
|
-
.
|
|
166
|
+
.option("--json", "Output JSON")
|
|
167
|
+
.action(async (args, opts) => {
|
|
99
168
|
try {
|
|
100
169
|
const root = findProjectRoot();
|
|
170
|
+
const { bookIdArg, chapterNum } = parseBookAndChapter(args);
|
|
171
|
+
const bookId = await resolveBookId(bookIdArg, root);
|
|
101
172
|
const state = new StateManager(root);
|
|
102
|
-
const chapterNum = parseInt(chapterStr, 10);
|
|
103
173
|
const index = [...(await state.loadChapterIndex(bookId))];
|
|
104
174
|
const idx = index.findIndex((ch) => ch.number === chapterNum);
|
|
105
175
|
if (idx === -1) {
|
|
106
|
-
|
|
107
|
-
process.exit(1);
|
|
176
|
+
throw new Error(`Chapter ${chapterNum} not found in "${bookId}"`);
|
|
108
177
|
}
|
|
109
178
|
index[idx] = {
|
|
110
179
|
...index[idx],
|
|
@@ -113,10 +182,20 @@ reviewCommand
|
|
|
113
182
|
updatedAt: new Date().toISOString(),
|
|
114
183
|
};
|
|
115
184
|
await state.saveChapterIndex(bookId, index);
|
|
116
|
-
|
|
185
|
+
if (opts.json) {
|
|
186
|
+
log(JSON.stringify({ bookId, chapter: chapterNum, status: "rejected" }));
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
log(`Chapter ${chapterNum} rejected.`);
|
|
190
|
+
}
|
|
117
191
|
}
|
|
118
192
|
catch (e) {
|
|
119
|
-
|
|
193
|
+
if (opts.json) {
|
|
194
|
+
log(JSON.stringify({ error: String(e) }));
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
logError(`Failed to reject: ${e}`);
|
|
198
|
+
}
|
|
120
199
|
process.exit(1);
|
|
121
200
|
}
|
|
122
201
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revise.d.ts","sourceRoot":"","sources":["../../src/commands/revise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"revise.d.ts","sourceRoot":"","sources":["../../src/commands/revise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAqDtB,CAAC"}
|
package/dist/commands/revise.js
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { PipelineRunner } from "@actalk/inkos-core";
|
|
3
|
-
import { loadConfig, createClient, findProjectRoot, log, logError } from "../utils.js";
|
|
3
|
+
import { loadConfig, createClient, findProjectRoot, resolveBookId, log, logError } from "../utils.js";
|
|
4
4
|
export const reviseCommand = new Command("revise")
|
|
5
5
|
.description("Revise a chapter based on audit issues")
|
|
6
|
-
.argument("
|
|
6
|
+
.argument("[book-id]", "Book ID (auto-detected if only one book)")
|
|
7
7
|
.argument("[chapter]", "Chapter number (defaults to latest)")
|
|
8
8
|
.option("--mode <mode>", "Revise mode: polish, rewrite, rework", "rewrite")
|
|
9
9
|
.option("--json", "Output JSON")
|
|
10
|
-
.action(async (
|
|
10
|
+
.action(async (bookIdArg, chapterStr, opts) => {
|
|
11
11
|
try {
|
|
12
12
|
const config = await loadConfig();
|
|
13
13
|
const client = createClient(config);
|
|
14
14
|
const root = findProjectRoot();
|
|
15
|
+
let bookId;
|
|
16
|
+
let chapterNumber;
|
|
17
|
+
if (bookIdArg && /^\d+$/.test(bookIdArg)) {
|
|
18
|
+
bookId = await resolveBookId(undefined, root);
|
|
19
|
+
chapterNumber = parseInt(bookIdArg, 10);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
bookId = await resolveBookId(bookIdArg, root);
|
|
23
|
+
chapterNumber = chapterStr ? parseInt(chapterStr, 10) : undefined;
|
|
24
|
+
}
|
|
15
25
|
const pipeline = new PipelineRunner({
|
|
16
26
|
client,
|
|
17
27
|
model: config.llm.model,
|
|
18
28
|
projectRoot: root,
|
|
19
29
|
});
|
|
20
|
-
const chapterNumber = chapterStr ? parseInt(chapterStr, 10) : undefined;
|
|
21
30
|
const mode = opts.mode;
|
|
22
31
|
if (!opts.json)
|
|
23
32
|
log(`Revising "${bookId}"${chapterNumber ? ` chapter ${chapterNumber}` : " (latest)"} [mode: ${mode}]...`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revise.js","sourceRoot":"","sources":["../../src/commands/revise.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAmB,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"revise.js","sourceRoot":"","sources":["../../src/commands/revise.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SA8EtB,CAAC"}
|
package/dist/commands/status.js
CHANGED
|
@@ -3,14 +3,23 @@ import { StateManager } from "@actalk/inkos-core";
|
|
|
3
3
|
import { findProjectRoot, log, logError } from "../utils.js";
|
|
4
4
|
export const statusCommand = new Command("status")
|
|
5
5
|
.description("Show project status")
|
|
6
|
-
.
|
|
6
|
+
.argument("[book-id]", "Book ID (optional, shows all if omitted)")
|
|
7
|
+
.option("--json", "Output JSON")
|
|
8
|
+
.action(async (bookIdArg, opts) => {
|
|
7
9
|
try {
|
|
8
10
|
const root = findProjectRoot();
|
|
9
11
|
const state = new StateManager(root);
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const allBookIds = await state.listBooks();
|
|
13
|
+
const bookIds = bookIdArg ? [bookIdArg] : allBookIds;
|
|
14
|
+
if (bookIdArg && !allBookIds.includes(bookIdArg)) {
|
|
15
|
+
throw new Error(`Book "${bookIdArg}" not found. Available: ${allBookIds.join(", ") || "(none)"}`);
|
|
16
|
+
}
|
|
17
|
+
const booksData = [];
|
|
18
|
+
if (!opts.json) {
|
|
19
|
+
log(`InkOS Project: ${root}`);
|
|
20
|
+
log(`Books: ${allBookIds.length}`);
|
|
21
|
+
log("");
|
|
22
|
+
}
|
|
14
23
|
for (const id of bookIds) {
|
|
15
24
|
const book = await state.loadBookConfig(id);
|
|
16
25
|
const index = await state.loadChapterIndex(id);
|
|
@@ -18,19 +27,43 @@ export const statusCommand = new Command("status")
|
|
|
18
27
|
const approved = index.filter((ch) => ch.status === "approved").length;
|
|
19
28
|
const pending = index.filter((ch) => ch.status === "ready-for-review").length;
|
|
20
29
|
const failed = index.filter((ch) => ch.status === "audit-failed").length;
|
|
21
|
-
log(` ${book.title} (${id})`);
|
|
22
|
-
log(` Status: ${book.status}`);
|
|
23
|
-
log(` Platform: ${book.platform} | Genre: ${book.genre}`);
|
|
24
30
|
const totalWords = index.reduce((sum, ch) => sum + ch.wordCount, 0);
|
|
25
31
|
const avgWords = index.length > 0 ? Math.round(totalWords / index.length) : 0;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
booksData.push({
|
|
33
|
+
id,
|
|
34
|
+
title: book.title,
|
|
35
|
+
status: book.status,
|
|
36
|
+
genre: book.genre,
|
|
37
|
+
platform: book.platform,
|
|
38
|
+
chapters: nextChapter - 1,
|
|
39
|
+
targetChapters: book.targetChapters,
|
|
40
|
+
totalWords,
|
|
41
|
+
avgWordsPerChapter: avgWords,
|
|
42
|
+
approved,
|
|
43
|
+
pending,
|
|
44
|
+
failed,
|
|
45
|
+
});
|
|
46
|
+
if (!opts.json) {
|
|
47
|
+
log(` ${book.title} (${id})`);
|
|
48
|
+
log(` Status: ${book.status}`);
|
|
49
|
+
log(` Platform: ${book.platform} | Genre: ${book.genre}`);
|
|
50
|
+
log(` Chapters: ${nextChapter - 1} / ${book.targetChapters}`);
|
|
51
|
+
log(` Words: ${totalWords.toLocaleString()} (avg ${avgWords}/ch)`);
|
|
52
|
+
log(` Approved: ${approved} | Pending: ${pending} | Failed: ${failed}`);
|
|
53
|
+
log("");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (opts.json) {
|
|
57
|
+
log(JSON.stringify({ project: root, books: booksData }, null, 2));
|
|
30
58
|
}
|
|
31
59
|
}
|
|
32
60
|
catch (e) {
|
|
33
|
-
|
|
61
|
+
if (opts.json) {
|
|
62
|
+
log(JSON.stringify({ error: String(e) }));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
logError(`Failed to get status: ${e}`);
|
|
66
|
+
}
|
|
34
67
|
process.exit(1);
|
|
35
68
|
}
|
|
36
69
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,qBAAqB,CAAC;KAClC,MAAM,CAAC,KAAK,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,qBAAqB,CAAC;KAClC,QAAQ,CAAC,WAAW,EAAE,0CAA0C,CAAC;KACjE,MAAM,CAAC,QAAQ,EAAE,aAAa,CAAC;KAC/B,MAAM,CAAC,KAAK,EAAE,SAA6B,EAAE,IAAI,EAAE,EAAE;IACpD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;QAErC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QAErD,IAAI,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CACb,SAAS,SAAS,2BAA2B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,CACjF,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,EAAE,CAAC;QAErB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;YAC9B,GAAG,CAAC,UAAU,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;YACnC,GAAG,CAAC,EAAE,CAAC,CAAC;QACV,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YAC/C,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;YAEzD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,MAAM,CAAC;YACvE,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAC1B,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,kBAAkB,CACzC,CAAC,MAAM,CAAC;YACT,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CACzB,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,KAAK,cAAc,CACrC,CAAC,MAAM,CAAC;YACT,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACpE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAE9E,SAAS,CAAC,IAAI,CAAC;gBACb,EAAE;gBACF,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,QAAQ,EAAE,WAAW,GAAG,CAAC;gBACzB,cAAc,EAAE,IAAI,CAAC,cAAc;gBACnC,UAAU;gBACV,kBAAkB,EAAE,QAAQ;gBAC5B,QAAQ;gBACR,OAAO;gBACP,MAAM;aACP,CAAC,CAAC;YAEH,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,IAAI,CAAC,KAAK,KAAK,EAAE,GAAG,CAAC,CAAC;gBAC/B,GAAG,CAAC,eAAe,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;gBAClC,GAAG,CAAC,iBAAiB,IAAI,CAAC,QAAQ,aAAa,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC7D,GAAG,CAAC,iBAAiB,WAAW,GAAG,CAAC,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;gBACjE,GAAG,CAAC,cAAc,UAAU,CAAC,cAAc,EAAE,SAAS,QAAQ,MAAM,CAAC,CAAC;gBACtE,GAAG,CAAC,iBAAiB,QAAQ,eAAe,OAAO,cAAc,MAAM,EAAE,CAAC,CAAC;gBAC3E,GAAG,CAAC,EAAE,CAAC,CAAC;YACV,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACpE,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,yBAAyB,CAAC,EAAE,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|