@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.
Files changed (66) hide show
  1. package/README.md +31 -2
  2. package/cli/program.d.ts.map +1 -1
  3. package/cli/program.js +247 -0
  4. package/cli/program.js.map +1 -1
  5. package/lib/database/index.d.ts.map +1 -1
  6. package/lib/database/index.js +16 -2
  7. package/lib/database/index.js.map +1 -1
  8. package/lib/database/schemas.d.ts.map +1 -1
  9. package/lib/database/schemas.js +8 -0
  10. package/lib/database/schemas.js.map +1 -1
  11. package/lib/server.d.ts.map +1 -1
  12. package/lib/server.js +60 -0
  13. package/lib/server.js.map +1 -1
  14. package/lib/tools/consistency/index.d.ts +25 -0
  15. package/lib/tools/consistency/index.d.ts.map +1 -0
  16. package/lib/tools/consistency/index.js +88 -0
  17. package/lib/tools/consistency/index.js.map +1 -0
  18. package/lib/tools/consistency/patterns.d.ts +6 -0
  19. package/lib/tools/consistency/patterns.d.ts.map +1 -0
  20. package/lib/tools/consistency/patterns.js +39 -0
  21. package/lib/tools/consistency/patterns.js.map +1 -0
  22. package/lib/tools/consistency/rules/entity-duplicate.d.ts +3 -0
  23. package/lib/tools/consistency/rules/entity-duplicate.d.ts.map +1 -0
  24. package/lib/tools/consistency/rules/entity-duplicate.js +84 -0
  25. package/lib/tools/consistency/rules/entity-duplicate.js.map +1 -0
  26. package/lib/tools/consistency/rules/first-time-content.d.ts +3 -0
  27. package/lib/tools/consistency/rules/first-time-content.d.ts.map +1 -0
  28. package/lib/tools/consistency/rules/first-time-content.js +114 -0
  29. package/lib/tools/consistency/rules/first-time-content.js.map +1 -0
  30. package/lib/tools/consistency/rules/kink-firsts.d.ts +3 -0
  31. package/lib/tools/consistency/rules/kink-firsts.d.ts.map +1 -0
  32. package/lib/tools/consistency/rules/kink-firsts.js +81 -0
  33. package/lib/tools/consistency/rules/kink-firsts.js.map +1 -0
  34. package/lib/tools/consistency/rules/outfit-claims.d.ts +3 -0
  35. package/lib/tools/consistency/rules/outfit-claims.d.ts.map +1 -0
  36. package/lib/tools/consistency/rules/outfit-claims.js +175 -0
  37. package/lib/tools/consistency/rules/outfit-claims.js.map +1 -0
  38. package/lib/tools/consistency/rules/relation-jump.d.ts +3 -0
  39. package/lib/tools/consistency/rules/relation-jump.d.ts.map +1 -0
  40. package/lib/tools/consistency/rules/relation-jump.js +105 -0
  41. package/lib/tools/consistency/rules/relation-jump.js.map +1 -0
  42. package/lib/tools/consistency/types.d.ts +27 -0
  43. package/lib/tools/consistency/types.d.ts.map +1 -0
  44. package/lib/tools/consistency/types.js +2 -0
  45. package/lib/tools/consistency/types.js.map +1 -0
  46. package/lib/tools/graph-export.d.ts +47 -0
  47. package/lib/tools/graph-export.d.ts.map +1 -0
  48. package/lib/tools/graph-export.js +152 -0
  49. package/lib/tools/graph-export.js.map +1 -0
  50. package/lib/tools/history.d.ts +47 -0
  51. package/lib/tools/history.d.ts.map +1 -0
  52. package/lib/tools/history.js +134 -0
  53. package/lib/tools/history.js.map +1 -0
  54. package/lib/tools/review-apply.d.ts +30 -0
  55. package/lib/tools/review-apply.d.ts.map +1 -0
  56. package/lib/tools/review-apply.js +305 -0
  57. package/lib/tools/review-apply.js.map +1 -0
  58. package/lib/tools/review-generate.d.ts +22 -0
  59. package/lib/tools/review-generate.d.ts.map +1 -0
  60. package/lib/tools/review-generate.js +123 -0
  61. package/lib/tools/review-generate.js.map +1 -0
  62. package/lib/tools/review-status.d.ts +28 -0
  63. package/lib/tools/review-status.d.ts.map +1 -0
  64. package/lib/tools/review-status.js +60 -0
  65. package/lib/tools/review-status.js.map +1 -0
  66. 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":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Issue } from '../types.js';
2
+ export declare function checkRelationJump(dbPath: string, arc: string): Promise<Issue[]>;
3
+ //# sourceMappingURL=relation-jump.d.ts.map
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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"}