@echoes-io/mcp-server 6.2.0 → 7.0.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/README.md +31 -2
- package/cli/program.d.ts.map +1 -1
- package/cli/program.js +247 -0
- package/cli/program.js.map +1 -1
- package/lib/database/index.d.ts.map +1 -1
- package/lib/database/index.js +16 -2
- package/lib/database/index.js.map +1 -1
- package/lib/database/schemas.d.ts.map +1 -1
- package/lib/database/schemas.js +8 -0
- package/lib/database/schemas.js.map +1 -1
- package/lib/server.d.ts.map +1 -1
- package/lib/server.js +60 -0
- package/lib/server.js.map +1 -1
- package/lib/tools/consistency/index.d.ts +25 -0
- package/lib/tools/consistency/index.d.ts.map +1 -0
- package/lib/tools/consistency/index.js +88 -0
- package/lib/tools/consistency/index.js.map +1 -0
- package/lib/tools/consistency/patterns.d.ts +6 -0
- package/lib/tools/consistency/patterns.d.ts.map +1 -0
- package/lib/tools/consistency/patterns.js +39 -0
- package/lib/tools/consistency/patterns.js.map +1 -0
- package/lib/tools/consistency/rules/entity-duplicate.d.ts +3 -0
- package/lib/tools/consistency/rules/entity-duplicate.d.ts.map +1 -0
- package/lib/tools/consistency/rules/entity-duplicate.js +84 -0
- package/lib/tools/consistency/rules/entity-duplicate.js.map +1 -0
- package/lib/tools/consistency/rules/first-time-content.d.ts +3 -0
- package/lib/tools/consistency/rules/first-time-content.d.ts.map +1 -0
- package/lib/tools/consistency/rules/first-time-content.js +114 -0
- package/lib/tools/consistency/rules/first-time-content.js.map +1 -0
- package/lib/tools/consistency/rules/kink-firsts.d.ts +3 -0
- package/lib/tools/consistency/rules/kink-firsts.d.ts.map +1 -0
- package/lib/tools/consistency/rules/kink-firsts.js +81 -0
- package/lib/tools/consistency/rules/kink-firsts.js.map +1 -0
- package/lib/tools/consistency/rules/outfit-claims.d.ts +3 -0
- package/lib/tools/consistency/rules/outfit-claims.d.ts.map +1 -0
- package/lib/tools/consistency/rules/outfit-claims.js +175 -0
- package/lib/tools/consistency/rules/outfit-claims.js.map +1 -0
- package/lib/tools/consistency/rules/relation-jump.d.ts +3 -0
- package/lib/tools/consistency/rules/relation-jump.d.ts.map +1 -0
- package/lib/tools/consistency/rules/relation-jump.js +105 -0
- package/lib/tools/consistency/rules/relation-jump.js.map +1 -0
- package/lib/tools/consistency/types.d.ts +27 -0
- package/lib/tools/consistency/types.d.ts.map +1 -0
- package/lib/tools/consistency/types.js +2 -0
- package/lib/tools/consistency/types.js.map +1 -0
- package/lib/tools/graph-export.d.ts +47 -0
- package/lib/tools/graph-export.d.ts.map +1 -0
- package/lib/tools/graph-export.js +152 -0
- package/lib/tools/graph-export.js.map +1 -0
- package/lib/tools/history.d.ts +47 -0
- package/lib/tools/history.d.ts.map +1 -0
- package/lib/tools/history.js +134 -0
- package/lib/tools/history.js.map +1 -0
- package/lib/tools/review-apply.d.ts +30 -0
- package/lib/tools/review-apply.d.ts.map +1 -0
- package/lib/tools/review-apply.js +305 -0
- package/lib/tools/review-apply.js.map +1 -0
- package/lib/tools/review-generate.d.ts +22 -0
- package/lib/tools/review-generate.d.ts.map +1 -0
- package/lib/tools/review-generate.js +123 -0
- package/lib/tools/review-generate.js.map +1 -0
- package/lib/tools/review-status.d.ts +28 -0
- package/lib/tools/review-status.d.ts.map +1 -0
- package/lib/tools/review-status.js +60 -0
- package/lib/tools/review-status.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { parseMarkdown } from '../../../utils.js';
|
|
4
|
+
// Common clothing items to look for
|
|
5
|
+
const CLOTHING_ITEMS = [
|
|
6
|
+
'gonna',
|
|
7
|
+
'minigonna',
|
|
8
|
+
'vestito',
|
|
9
|
+
'abito',
|
|
10
|
+
'top',
|
|
11
|
+
'camicia',
|
|
12
|
+
'camicetta',
|
|
13
|
+
'maglietta',
|
|
14
|
+
'reggiseno',
|
|
15
|
+
'mutandine',
|
|
16
|
+
'slip',
|
|
17
|
+
'tanga',
|
|
18
|
+
'autoreggenti',
|
|
19
|
+
'calze',
|
|
20
|
+
'tacchi',
|
|
21
|
+
'scarpe',
|
|
22
|
+
'sandali',
|
|
23
|
+
'giacca',
|
|
24
|
+
'blazer',
|
|
25
|
+
'pantaloni',
|
|
26
|
+
'jeans',
|
|
27
|
+
'shorts',
|
|
28
|
+
'bikini',
|
|
29
|
+
'costume',
|
|
30
|
+
'pigiama',
|
|
31
|
+
];
|
|
32
|
+
// Patterns to find "never worn" claims
|
|
33
|
+
const NEVER_WORN_PATTERNS = [
|
|
34
|
+
/non (l')?aveva(no)? mai (indossato|portato|messo)/gi,
|
|
35
|
+
/non (l')?avevo mai (indossato|portato|messo)/gi,
|
|
36
|
+
/mai (indossato|portato|messo) (prima|un[ao]?)/gi,
|
|
37
|
+
/(comprato|acquistato).{0,30}mai (indossato|portato|messo)/gi,
|
|
38
|
+
];
|
|
39
|
+
// Parse outfit field: "Ele: gonna nera, top bianco | Nic: camicia"
|
|
40
|
+
function parseOutfitField(outfit) {
|
|
41
|
+
const results = [];
|
|
42
|
+
// Split by | or newline for multiple characters
|
|
43
|
+
const parts = outfit
|
|
44
|
+
.split(/[|\n]/)
|
|
45
|
+
.map((p) => p.trim())
|
|
46
|
+
.filter(Boolean);
|
|
47
|
+
for (const part of parts) {
|
|
48
|
+
// Try to match "Character: outfit description"
|
|
49
|
+
const match = part.match(/^([A-Za-z]+):\s*(.+)$/);
|
|
50
|
+
if (match) {
|
|
51
|
+
const character = match[1].toLowerCase();
|
|
52
|
+
const description = match[2].toLowerCase();
|
|
53
|
+
const foundItems = CLOTHING_ITEMS.filter((item) => description.includes(item));
|
|
54
|
+
// Remove items that are substrings of other found items
|
|
55
|
+
const items = foundItems.filter((item) => !foundItems.some((otherItem) => otherItem !== item && otherItem.includes(item)));
|
|
56
|
+
if (items.length > 0) {
|
|
57
|
+
results.push({ character, items });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
// No character prefix, try to extract items anyway
|
|
62
|
+
const description = part.toLowerCase();
|
|
63
|
+
const foundItems = CLOTHING_ITEMS.filter((item) => description.includes(item));
|
|
64
|
+
// Remove items that are substrings of other found items
|
|
65
|
+
const items = foundItems.filter((item) => !foundItems.some((otherItem) => otherItem !== item && otherItem.includes(item)));
|
|
66
|
+
if (items.length > 0) {
|
|
67
|
+
results.push({ character: 'unknown', items });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return results;
|
|
72
|
+
}
|
|
73
|
+
// Extract clothing items mentioned in "never worn" context
|
|
74
|
+
function extractNeverWornItems(text) {
|
|
75
|
+
const lowerText = text.toLowerCase();
|
|
76
|
+
const foundItems = CLOTHING_ITEMS.filter((item) => lowerText.includes(item));
|
|
77
|
+
// Remove items that are substrings of other found items (e.g., "gonna" when "minigonna" is found)
|
|
78
|
+
return foundItems.filter((item) => !foundItems.some((otherItem) => otherItem !== item && otherItem.includes(item)));
|
|
79
|
+
}
|
|
80
|
+
function scanChapters(contentPath, arc) {
|
|
81
|
+
const outfits = [];
|
|
82
|
+
const claims = [];
|
|
83
|
+
function scanDir(dir) {
|
|
84
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
85
|
+
const fullPath = join(dir, entry.name);
|
|
86
|
+
if (entry.isDirectory()) {
|
|
87
|
+
scanDir(fullPath);
|
|
88
|
+
}
|
|
89
|
+
else if (entry.isFile() && entry.name.endsWith('.md')) {
|
|
90
|
+
try {
|
|
91
|
+
const raw = readFileSync(fullPath, 'utf-8');
|
|
92
|
+
const { metadata, content } = parseMarkdown(raw);
|
|
93
|
+
if (metadata.arc !== arc)
|
|
94
|
+
continue;
|
|
95
|
+
const ref = {
|
|
96
|
+
arc: metadata.arc,
|
|
97
|
+
episode: metadata.episode ?? 0,
|
|
98
|
+
chapter: metadata.chapter ?? 0,
|
|
99
|
+
};
|
|
100
|
+
// Parse outfit field
|
|
101
|
+
if (metadata.outfit) {
|
|
102
|
+
const parsed = parseOutfitField(metadata.outfit);
|
|
103
|
+
for (const { character, items } of parsed) {
|
|
104
|
+
outfits.push({ ref, character, items, raw: metadata.outfit });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Find "never worn" claims in content
|
|
108
|
+
for (const pattern of NEVER_WORN_PATTERNS) {
|
|
109
|
+
const matches = content.matchAll(pattern);
|
|
110
|
+
for (const match of matches) {
|
|
111
|
+
// Get surrounding context
|
|
112
|
+
const start = Math.max(0, (match.index ?? 0) - 100);
|
|
113
|
+
const end = Math.min(content.length, (match.index ?? 0) + match[0].length + 100);
|
|
114
|
+
const context = content.slice(start, end);
|
|
115
|
+
const items = extractNeverWornItems(context);
|
|
116
|
+
if (items.length > 0) {
|
|
117
|
+
claims.push({ ref, text: context.replace(/\s+/g, ' ').trim(), items });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// Skip unparseable files
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
scanDir(contentPath);
|
|
129
|
+
// Sort by episode, then chapter
|
|
130
|
+
const sortFn = (a, b) => {
|
|
131
|
+
if (a.ref.episode !== b.ref.episode)
|
|
132
|
+
return a.ref.episode - b.ref.episode;
|
|
133
|
+
return a.ref.chapter - b.ref.chapter;
|
|
134
|
+
};
|
|
135
|
+
outfits.sort(sortFn);
|
|
136
|
+
claims.sort(sortFn);
|
|
137
|
+
return { outfits, claims };
|
|
138
|
+
}
|
|
139
|
+
export async function checkOutfitClaims(contentPath, arc) {
|
|
140
|
+
const { outfits, claims } = scanChapters(contentPath, arc);
|
|
141
|
+
if (claims.length === 0)
|
|
142
|
+
return [];
|
|
143
|
+
const issues = [];
|
|
144
|
+
const seenIssues = new Set(); // To avoid duplicates
|
|
145
|
+
// For each "never worn" claim, check if the item appeared in earlier outfits
|
|
146
|
+
for (const claim of claims) {
|
|
147
|
+
for (const item of claim.items) {
|
|
148
|
+
// Find earlier outfits with this item
|
|
149
|
+
const earlierOutfits = outfits.filter((o) => o.items.includes(item) &&
|
|
150
|
+
(o.ref.episode < claim.ref.episode ||
|
|
151
|
+
(o.ref.episode === claim.ref.episode && o.ref.chapter < claim.ref.chapter)));
|
|
152
|
+
if (earlierOutfits.length > 0) {
|
|
153
|
+
const first = earlierOutfits[0];
|
|
154
|
+
const issueKey = `${claim.ref.arc}:${claim.ref.episode}:${claim.ref.chapter}:${item}`;
|
|
155
|
+
if (!seenIssues.has(issueKey)) {
|
|
156
|
+
seenIssues.add(issueKey);
|
|
157
|
+
issues.push({
|
|
158
|
+
type: 'OUTFIT_CONTRADICTION',
|
|
159
|
+
severity: 'warning',
|
|
160
|
+
message: `Claim "never worn ${item}" contradicts earlier outfit`,
|
|
161
|
+
current: claim.ref,
|
|
162
|
+
previous: first.ref,
|
|
163
|
+
details: {
|
|
164
|
+
item,
|
|
165
|
+
claimText: claim.text.slice(0, 100),
|
|
166
|
+
previousOutfit: first.raw,
|
|
167
|
+
},
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return issues;
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=outfit-claims.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outfit-claims.js","sourceRoot":"","sources":["outfit-claims.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,oCAAoC;AACpC,MAAM,cAAc,GAAG;IACrB,OAAO;IACP,WAAW;IACX,SAAS;IACT,OAAO;IACP,KAAK;IACL,SAAS;IACT,WAAW;IACX,WAAW;IACX,WAAW;IACX,WAAW;IACX,MAAM;IACN,OAAO;IACP,cAAc;IACd,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,WAAW;IACX,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,SAAS;CACV,CAAC;AAEF,uCAAuC;AACvC,MAAM,mBAAmB,GAAG;IAC1B,qDAAqD;IACrD,gDAAgD;IAChD,iDAAiD;IACjD,6DAA6D;CAC9D,CAAC;AAeF,mEAAmE;AACnE,SAAS,gBAAgB,CAAC,MAAc;IACtC,MAAM,OAAO,GAAkD,EAAE,CAAC;IAElE,gDAAgD;IAChD,MAAM,KAAK,GAAG,MAAM;SACjB,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,+CAA+C;QAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/E,wDAAwD;YACxD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAC7B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC1F,CAAC;YACF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,mDAAmD;YACnD,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/E,wDAAwD;YACxD,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,CAC7B,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC1F,CAAC;YACF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,2DAA2D;AAC3D,SAAS,qBAAqB,CAAC,IAAY;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAE7E,kGAAkG;IAClG,OAAO,UAAU,CAAC,MAAM,CACtB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC1F,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,WAAmB,EACnB,GAAW;IAEX,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,SAAS,OAAO,CAAC,GAAW;QAC1B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpB,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBAC5C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;oBAEjD,IAAI,QAAQ,CAAC,GAAG,KAAK,GAAG;wBAAE,SAAS;oBAEnC,MAAM,GAAG,GAAe;wBACtB,GAAG,EAAE,QAAQ,CAAC,GAAG;wBACjB,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,CAAC;wBAC9B,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,CAAC;qBAC/B,CAAC;oBAEF,qBAAqB;oBACrB,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;wBACpB,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;wBACjD,KAAK,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,MAAM,EAAE,CAAC;4BAC1C,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;wBAChE,CAAC;oBACH,CAAC;oBAED,sCAAsC;oBACtC,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;wBAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;wBAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;4BAC5B,0BAA0B;4BAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;4BACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;4BACjF,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;4BAE1C,MAAM,KAAK,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;4BAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gCACrB,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;4BACzE,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,yBAAyB;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,WAAW,CAAC,CAAC;IAErB,gCAAgC;IAChC,MAAM,MAAM,GAAG,CAAC,CAAsB,EAAE,CAAsB,EAAE,EAAE;QAChE,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,GAAG,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;QAC1E,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IACvC,CAAC,CAAC;IAEF,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEpB,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,WAAmB,EAAE,GAAW;IACtE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IAE3D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,MAAM,MAAM,GAAY,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC,CAAC,sBAAsB;IAE5D,6EAA6E;IAC7E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,sCAAsC;YACtC,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACtB,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO;oBAChC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAChF,CAAC;YAEF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAChC,MAAM,QAAQ,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBAEtF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC9B,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACzB,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,sBAAsB;wBAC5B,QAAQ,EAAE,SAAS;wBACnB,OAAO,EAAE,qBAAqB,IAAI,8BAA8B;wBAChE,OAAO,EAAE,KAAK,CAAC,GAAG;wBAClB,QAAQ,EAAE,KAAK,CAAC,GAAG;wBACnB,OAAO,EAAE;4BACP,IAAI;4BACJ,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;4BACnC,cAAc,EAAE,KAAK,CAAC,GAAG;yBAC1B;qBACF,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-jump.d.ts","sourceRoot":"","sources":["relation-jump.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAiCzC,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAgGrF"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { Database } from '../../../database/index.js';
|
|
2
|
+
// Parse chapter ID to get episode and chapter numbers
|
|
3
|
+
function parseChapterId(id) {
|
|
4
|
+
const parts = id.split(':');
|
|
5
|
+
return {
|
|
6
|
+
episode: Number.parseInt(parts[1], 10) || 0,
|
|
7
|
+
chapter: Number.parseInt(parts[2], 10) || 0,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
// Check if relation type changed drastically
|
|
11
|
+
function isDrasticTypeChange(from, to) {
|
|
12
|
+
const positive = ['LOVES', 'FRIENDS_WITH', 'KNOWS'];
|
|
13
|
+
const negative = ['HATES', 'ENEMIES_WITH'];
|
|
14
|
+
const fromPositive = positive.includes(from);
|
|
15
|
+
const fromNegative = negative.includes(from);
|
|
16
|
+
const toPositive = positive.includes(to);
|
|
17
|
+
const toNegative = negative.includes(to);
|
|
18
|
+
// Positive to negative or vice versa is drastic
|
|
19
|
+
return (fromPositive && toNegative) || (fromNegative && toPositive);
|
|
20
|
+
}
|
|
21
|
+
export async function checkRelationJump(dbPath, arc) {
|
|
22
|
+
const db = new Database(dbPath);
|
|
23
|
+
await db.connect();
|
|
24
|
+
const relations = await db.getRelations(arc);
|
|
25
|
+
db.close();
|
|
26
|
+
if (relations.length === 0)
|
|
27
|
+
return [];
|
|
28
|
+
const issues = [];
|
|
29
|
+
// Group relations by source+target pair
|
|
30
|
+
const pairs = new Map();
|
|
31
|
+
for (const rel of relations) {
|
|
32
|
+
const key = `${rel.source_entity}:${rel.target_entity}`;
|
|
33
|
+
for (const chapterId of rel.chapters) {
|
|
34
|
+
const { episode, chapter } = parseChapterId(chapterId);
|
|
35
|
+
if (!pairs.has(key)) {
|
|
36
|
+
pairs.set(key, []);
|
|
37
|
+
}
|
|
38
|
+
const pairArray = pairs.get(key);
|
|
39
|
+
if (pairArray) {
|
|
40
|
+
pairArray.push({
|
|
41
|
+
chapter: chapterId,
|
|
42
|
+
type: rel.type,
|
|
43
|
+
weight: rel.weight,
|
|
44
|
+
episode,
|
|
45
|
+
chapterNum: chapter,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Check each pair for drastic changes
|
|
51
|
+
for (const [key, changes] of pairs) {
|
|
52
|
+
if (changes.length < 2)
|
|
53
|
+
continue;
|
|
54
|
+
// Sort by episode, then chapter
|
|
55
|
+
changes.sort((a, b) => {
|
|
56
|
+
if (a.episode !== b.episode)
|
|
57
|
+
return a.episode - b.episode;
|
|
58
|
+
return a.chapterNum - b.chapterNum;
|
|
59
|
+
});
|
|
60
|
+
// Check consecutive changes
|
|
61
|
+
for (let i = 1; i < changes.length; i++) {
|
|
62
|
+
const prev = changes[i - 1];
|
|
63
|
+
const curr = changes[i];
|
|
64
|
+
// Check for drastic type change
|
|
65
|
+
if (isDrasticTypeChange(prev.type, curr.type)) {
|
|
66
|
+
const [source, target] = key.split(':').map((s) => s.split(':').pop());
|
|
67
|
+
issues.push({
|
|
68
|
+
type: 'RELATION_JUMP',
|
|
69
|
+
severity: 'warning',
|
|
70
|
+
message: `Relation ${source} → ${target} changed from ${prev.type} to ${curr.type}`,
|
|
71
|
+
current: { arc, episode: curr.episode, chapter: curr.chapterNum },
|
|
72
|
+
previous: { arc, episode: prev.episode, chapter: prev.chapterNum },
|
|
73
|
+
details: {
|
|
74
|
+
source,
|
|
75
|
+
target,
|
|
76
|
+
previousType: prev.type,
|
|
77
|
+
currentType: curr.type,
|
|
78
|
+
previousWeight: prev.weight,
|
|
79
|
+
currentWeight: curr.weight,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// Check for drastic weight drop (>0.5)
|
|
84
|
+
if (prev.type === curr.type && prev.weight - curr.weight > 0.5) {
|
|
85
|
+
const [source, target] = key.split(':').map((s) => s.split(':').pop());
|
|
86
|
+
issues.push({
|
|
87
|
+
type: 'RELATION_JUMP',
|
|
88
|
+
severity: 'info',
|
|
89
|
+
message: `Relation ${source} → ${target} weight dropped from ${prev.weight} to ${curr.weight}`,
|
|
90
|
+
current: { arc, episode: curr.episode, chapter: curr.chapterNum },
|
|
91
|
+
previous: { arc, episode: prev.episode, chapter: prev.chapterNum },
|
|
92
|
+
details: {
|
|
93
|
+
source,
|
|
94
|
+
target,
|
|
95
|
+
type: curr.type,
|
|
96
|
+
previousWeight: prev.weight,
|
|
97
|
+
currentWeight: curr.weight,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return issues;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=relation-jump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation-jump.js","sourceRoot":"","sources":["relation-jump.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type IssueSeverity = 'error' | 'warning' | 'info';
|
|
2
|
+
export type IssueType = 'KINK_FIRST_DUPLICATE' | 'OUTFIT_CONTRADICTION' | 'FIRST_TIME_DUPLICATE' | 'RELATION_JUMP' | 'ENTITY_DUPLICATE';
|
|
3
|
+
export interface ChapterRef {
|
|
4
|
+
arc: string;
|
|
5
|
+
episode: number;
|
|
6
|
+
chapter: number;
|
|
7
|
+
}
|
|
8
|
+
export interface Issue {
|
|
9
|
+
type: IssueType;
|
|
10
|
+
severity: IssueSeverity;
|
|
11
|
+
message: string;
|
|
12
|
+
current: ChapterRef;
|
|
13
|
+
previous?: ChapterRef;
|
|
14
|
+
details: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface CheckResult {
|
|
17
|
+
arc: string;
|
|
18
|
+
issues: Issue[];
|
|
19
|
+
summary: {
|
|
20
|
+
errors: number;
|
|
21
|
+
warnings: number;
|
|
22
|
+
info: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export type RuleName = 'kink-firsts' | 'outfit-claims' | 'first-time-content' | 'relation-jump' | 'entity-duplicate';
|
|
26
|
+
export type RuleFunction = (arc: string, dbPath: string) => Promise<Issue[]>;
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzD,MAAM,MAAM,SAAS,GACjB,sBAAsB,GACtB,sBAAsB,GACtB,sBAAsB,GACtB,eAAe,GACf,kBAAkB,CAAC;AAEvB,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,eAAe,GACf,oBAAoB,GACpB,eAAe,GACf,kBAAkB,CAAC;AAEvB,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import type { ToolConfig } from '../types.js';
|
|
3
|
+
export declare const graphExportConfig: ToolConfig;
|
|
4
|
+
export declare const graphExportSchema: z.ZodObject<{
|
|
5
|
+
arc: z.ZodString;
|
|
6
|
+
format: z.ZodEnum<{
|
|
7
|
+
json: "json";
|
|
8
|
+
mermaid: "mermaid";
|
|
9
|
+
dot: "dot";
|
|
10
|
+
}>;
|
|
11
|
+
entityTypes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
12
|
+
CHARACTER: "CHARACTER";
|
|
13
|
+
LOCATION: "LOCATION";
|
|
14
|
+
EVENT: "EVENT";
|
|
15
|
+
OBJECT: "OBJECT";
|
|
16
|
+
EMOTION: "EMOTION";
|
|
17
|
+
}>>>;
|
|
18
|
+
relationTypes: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
19
|
+
LOVES: "LOVES";
|
|
20
|
+
HATES: "HATES";
|
|
21
|
+
KNOWS: "KNOWS";
|
|
22
|
+
RELATED_TO: "RELATED_TO";
|
|
23
|
+
FRIENDS_WITH: "FRIENDS_WITH";
|
|
24
|
+
ENEMIES_WITH: "ENEMIES_WITH";
|
|
25
|
+
LOCATED_IN: "LOCATED_IN";
|
|
26
|
+
LIVES_IN: "LIVES_IN";
|
|
27
|
+
TRAVELS_TO: "TRAVELS_TO";
|
|
28
|
+
HAPPENS_BEFORE: "HAPPENS_BEFORE";
|
|
29
|
+
HAPPENS_AFTER: "HAPPENS_AFTER";
|
|
30
|
+
CAUSES: "CAUSES";
|
|
31
|
+
OWNS: "OWNS";
|
|
32
|
+
USES: "USES";
|
|
33
|
+
SEEKS: "SEEKS";
|
|
34
|
+
}>>>;
|
|
35
|
+
characters: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
|
+
dbPath: z.ZodDefault<z.ZodString>;
|
|
37
|
+
}, z.z.core.$strip>;
|
|
38
|
+
export type GraphExportInput = z.infer<typeof graphExportSchema>;
|
|
39
|
+
export declare function graphExport(input: GraphExportInput): Promise<{
|
|
40
|
+
format: "json" | "mermaid" | "dot";
|
|
41
|
+
content: string;
|
|
42
|
+
stats: {
|
|
43
|
+
nodes: number;
|
|
44
|
+
edges: number;
|
|
45
|
+
};
|
|
46
|
+
}>;
|
|
47
|
+
//# sourceMappingURL=graph-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-export.d.ts","sourceRoot":"","sources":["graph-export.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAKpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,iBAAiB,EAAE,UAW/B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA+B5B,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AA+HjE,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB;;;;;;;GAgCxD"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import { DEFAULT_DB_PATH } from '../constants.js';
|
|
3
|
+
import { Database } from '../database/index.js';
|
|
4
|
+
export const graphExportConfig = {
|
|
5
|
+
name: 'graph-export',
|
|
6
|
+
description: 'Export knowledge graph in various formats (Mermaid, JSON, DOT).',
|
|
7
|
+
arguments: {
|
|
8
|
+
arc: 'Arc name to export.',
|
|
9
|
+
format: 'Output format: mermaid, json, or dot.',
|
|
10
|
+
entityTypes: 'Filter by entity types (comma-separated).',
|
|
11
|
+
relationTypes: 'Filter by relation types (comma-separated).',
|
|
12
|
+
characters: 'Filter by specific character names (comma-separated).',
|
|
13
|
+
dbPath: `Database path (default: ${DEFAULT_DB_PATH}).`,
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
export const graphExportSchema = z.object({
|
|
17
|
+
arc: z.string().describe(graphExportConfig.arguments.arc),
|
|
18
|
+
format: z.enum(['mermaid', 'json', 'dot']).describe(graphExportConfig.arguments.format),
|
|
19
|
+
entityTypes: z
|
|
20
|
+
.array(z.enum(['CHARACTER', 'LOCATION', 'EVENT', 'OBJECT', 'EMOTION']))
|
|
21
|
+
.optional()
|
|
22
|
+
.describe(graphExportConfig.arguments.entityTypes),
|
|
23
|
+
relationTypes: z
|
|
24
|
+
.array(z.enum([
|
|
25
|
+
'LOVES',
|
|
26
|
+
'HATES',
|
|
27
|
+
'KNOWS',
|
|
28
|
+
'RELATED_TO',
|
|
29
|
+
'FRIENDS_WITH',
|
|
30
|
+
'ENEMIES_WITH',
|
|
31
|
+
'LOCATED_IN',
|
|
32
|
+
'LIVES_IN',
|
|
33
|
+
'TRAVELS_TO',
|
|
34
|
+
'HAPPENS_BEFORE',
|
|
35
|
+
'HAPPENS_AFTER',
|
|
36
|
+
'CAUSES',
|
|
37
|
+
'OWNS',
|
|
38
|
+
'USES',
|
|
39
|
+
'SEEKS',
|
|
40
|
+
]))
|
|
41
|
+
.optional()
|
|
42
|
+
.describe(graphExportConfig.arguments.relationTypes),
|
|
43
|
+
characters: z.array(z.string()).optional().describe(graphExportConfig.arguments.characters),
|
|
44
|
+
dbPath: z.string().default(DEFAULT_DB_PATH).describe(graphExportConfig.arguments.dbPath),
|
|
45
|
+
});
|
|
46
|
+
async function buildGraph(dbPath, arc) {
|
|
47
|
+
const db = new Database(dbPath);
|
|
48
|
+
await db.connect();
|
|
49
|
+
const entities = await db.getEntities(arc);
|
|
50
|
+
const relations = await db.getRelations(arc);
|
|
51
|
+
db.close();
|
|
52
|
+
const nodes = entities.map((entity) => ({
|
|
53
|
+
id: entity.name,
|
|
54
|
+
name: entity.name,
|
|
55
|
+
type: entity.type,
|
|
56
|
+
}));
|
|
57
|
+
const edges = relations.map((relation) => ({
|
|
58
|
+
source: relation.source_entity.split(':').pop() || '',
|
|
59
|
+
target: relation.target_entity.split(':').pop() || '',
|
|
60
|
+
type: relation.type,
|
|
61
|
+
weight: relation.weight,
|
|
62
|
+
}));
|
|
63
|
+
return { nodes, edges };
|
|
64
|
+
}
|
|
65
|
+
function filterGraph(graph, filters) {
|
|
66
|
+
let { nodes, edges } = graph;
|
|
67
|
+
// Filter nodes by entity types
|
|
68
|
+
if (filters.entityTypes) {
|
|
69
|
+
nodes = nodes.filter((node) => filters.entityTypes?.includes(node.type));
|
|
70
|
+
}
|
|
71
|
+
// Filter nodes by character names
|
|
72
|
+
if (filters.characters) {
|
|
73
|
+
nodes = nodes.filter((node) => filters.characters?.includes(node.name));
|
|
74
|
+
}
|
|
75
|
+
// Filter edges by relation types
|
|
76
|
+
if (filters.relationTypes) {
|
|
77
|
+
edges = edges.filter((edge) => filters.relationTypes?.includes(edge.type));
|
|
78
|
+
}
|
|
79
|
+
// Remove edges that reference filtered-out nodes
|
|
80
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
81
|
+
edges = edges.filter((edge) => nodeIds.has(edge.source) && nodeIds.has(edge.target));
|
|
82
|
+
return { nodes, edges };
|
|
83
|
+
}
|
|
84
|
+
function toMermaid(graph) {
|
|
85
|
+
const lines = ['graph LR'];
|
|
86
|
+
for (const edge of graph.edges) {
|
|
87
|
+
const source = edge.source.replace(/[^a-zA-Z0-9]/g, '_');
|
|
88
|
+
const target = edge.target.replace(/[^a-zA-Z0-9]/g, '_');
|
|
89
|
+
lines.push(` ${source} -->|${edge.type}| ${target}`);
|
|
90
|
+
}
|
|
91
|
+
return lines.join('\n');
|
|
92
|
+
}
|
|
93
|
+
function toJSON(graph) {
|
|
94
|
+
const result = {
|
|
95
|
+
nodes: graph.nodes.map((node) => ({
|
|
96
|
+
id: node.id,
|
|
97
|
+
name: node.name,
|
|
98
|
+
type: node.type,
|
|
99
|
+
group: node.type === 'CHARACTER' ? 1 : node.type === 'LOCATION' ? 2 : 3,
|
|
100
|
+
})),
|
|
101
|
+
links: graph.edges.map((edge) => ({
|
|
102
|
+
source: edge.source,
|
|
103
|
+
target: edge.target,
|
|
104
|
+
type: edge.type,
|
|
105
|
+
weight: edge.weight,
|
|
106
|
+
})),
|
|
107
|
+
};
|
|
108
|
+
return JSON.stringify(result, null, 2);
|
|
109
|
+
}
|
|
110
|
+
function toDOT(graph) {
|
|
111
|
+
const lines = ['digraph G {'];
|
|
112
|
+
// Add node definitions with types
|
|
113
|
+
for (const node of graph.nodes) {
|
|
114
|
+
const shape = node.type === 'CHARACTER' ? 'ellipse' : node.type === 'LOCATION' ? 'box' : 'diamond';
|
|
115
|
+
lines.push(` "${node.name}" [shape=${shape}];`);
|
|
116
|
+
}
|
|
117
|
+
// Add edges
|
|
118
|
+
for (const edge of graph.edges) {
|
|
119
|
+
lines.push(` "${edge.source}" -> "${edge.target}" [label="${edge.type}"];`);
|
|
120
|
+
}
|
|
121
|
+
lines.push('}');
|
|
122
|
+
return lines.join('\n');
|
|
123
|
+
}
|
|
124
|
+
export async function graphExport(input) {
|
|
125
|
+
const { arc, format, entityTypes, relationTypes, characters, dbPath } = graphExportSchema.parse(input);
|
|
126
|
+
// Build graph from database
|
|
127
|
+
let graph = await buildGraph(dbPath, arc);
|
|
128
|
+
// Apply filters
|
|
129
|
+
graph = filterGraph(graph, { entityTypes, relationTypes, characters });
|
|
130
|
+
// Generate output based on format
|
|
131
|
+
let content;
|
|
132
|
+
switch (format) {
|
|
133
|
+
case 'mermaid':
|
|
134
|
+
content = toMermaid(graph);
|
|
135
|
+
break;
|
|
136
|
+
case 'json':
|
|
137
|
+
content = toJSON(graph);
|
|
138
|
+
break;
|
|
139
|
+
case 'dot':
|
|
140
|
+
content = toDOT(graph);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
format,
|
|
145
|
+
content,
|
|
146
|
+
stats: {
|
|
147
|
+
nodes: graph.nodes.length,
|
|
148
|
+
edges: graph.edges.length,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=graph-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-export.js","sourceRoot":"","sources":["graph-export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import z from 'zod';
|
|
2
|
+
import type { ToolConfig } from '../types.js';
|
|
3
|
+
export declare const historyConfig: ToolConfig;
|
|
4
|
+
export declare const historySchema: z.ZodObject<{
|
|
5
|
+
arc: z.ZodString;
|
|
6
|
+
character: z.ZodOptional<z.ZodString>;
|
|
7
|
+
only: z.ZodOptional<z.ZodEnum<{
|
|
8
|
+
relations: "relations";
|
|
9
|
+
kinks: "kinks";
|
|
10
|
+
outfits: "outfits";
|
|
11
|
+
locations: "locations";
|
|
12
|
+
}>>;
|
|
13
|
+
search: z.ZodOptional<z.ZodString>;
|
|
14
|
+
dbPath: z.ZodDefault<z.ZodString>;
|
|
15
|
+
}, z.z.core.$strip>;
|
|
16
|
+
export type HistoryInput = z.infer<typeof historySchema>;
|
|
17
|
+
interface KinkEntry {
|
|
18
|
+
chapter: string;
|
|
19
|
+
kink: string;
|
|
20
|
+
isFirst: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface OutfitEntry {
|
|
23
|
+
chapter: string;
|
|
24
|
+
character: string;
|
|
25
|
+
outfit: string;
|
|
26
|
+
}
|
|
27
|
+
interface LocationEntry {
|
|
28
|
+
chapter: string;
|
|
29
|
+
location: string;
|
|
30
|
+
}
|
|
31
|
+
interface RelationEntry {
|
|
32
|
+
chapter: string;
|
|
33
|
+
source: string;
|
|
34
|
+
target: string;
|
|
35
|
+
type: string;
|
|
36
|
+
}
|
|
37
|
+
interface HistoryResult {
|
|
38
|
+
arc: string;
|
|
39
|
+
character?: string;
|
|
40
|
+
kinks: KinkEntry[];
|
|
41
|
+
outfits: OutfitEntry[];
|
|
42
|
+
locations: LocationEntry[];
|
|
43
|
+
relations: RelationEntry[];
|
|
44
|
+
}
|
|
45
|
+
export declare function history(input: HistoryInput): Promise<HistoryResult>;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["history.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAIpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,aAAa,EAAE,UAU3B,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;mBASxB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEzD,UAAU,SAAS;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,aAAa;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAwBD,wBAAsB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAwGzE"}
|