@echoes-io/mcp-server 4.1.1 → 6.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 (108) hide show
  1. package/README.md +120 -185
  2. package/cli/index.d.ts +1 -0
  3. package/cli/index.d.ts.map +1 -0
  4. package/cli/index.js +3 -185
  5. package/cli/index.js.map +1 -0
  6. package/cli/program.d.ts +3 -0
  7. package/cli/program.d.ts.map +1 -0
  8. package/cli/program.js +150 -0
  9. package/cli/program.js.map +1 -0
  10. package/lib/constants.d.ts +8 -0
  11. package/lib/constants.d.ts.map +1 -0
  12. package/lib/constants.js +12 -0
  13. package/lib/constants.js.map +1 -0
  14. package/lib/database/index.d.ts +34 -0
  15. package/lib/database/index.d.ts.map +1 -0
  16. package/lib/database/index.js +266 -0
  17. package/lib/database/index.js.map +1 -0
  18. package/lib/database/schemas.d.ts +55 -0
  19. package/lib/database/schemas.d.ts.map +1 -0
  20. package/lib/database/schemas.js +70 -0
  21. package/lib/database/schemas.js.map +1 -0
  22. package/lib/indexer/embeddings.d.ts +6 -0
  23. package/lib/indexer/embeddings.d.ts.map +1 -0
  24. package/lib/indexer/embeddings.js +51 -0
  25. package/lib/indexer/embeddings.js.map +1 -0
  26. package/lib/indexer/extractor.d.ts +81 -0
  27. package/lib/indexer/extractor.d.ts.map +1 -0
  28. package/lib/indexer/extractor.js +68 -0
  29. package/lib/indexer/extractor.js.map +1 -0
  30. package/lib/indexer/scanner.d.ts +8 -0
  31. package/lib/indexer/scanner.d.ts.map +1 -0
  32. package/lib/indexer/scanner.js +73 -0
  33. package/lib/indexer/scanner.js.map +1 -0
  34. package/lib/prompts/index.d.ts +13 -0
  35. package/lib/prompts/index.d.ts.map +1 -0
  36. package/lib/prompts/index.js +153 -0
  37. package/lib/prompts/index.js.map +1 -0
  38. package/lib/server.d.ts +13 -0
  39. package/lib/server.d.ts.map +1 -0
  40. package/lib/server.js +90 -0
  41. package/lib/server.js.map +1 -0
  42. package/lib/tools/index.d.ts +19 -0
  43. package/lib/tools/index.d.ts.map +1 -0
  44. package/lib/tools/index.js +128 -0
  45. package/lib/tools/index.js.map +1 -0
  46. package/lib/tools/search.d.ts +86 -0
  47. package/lib/tools/search.d.ts.map +1 -0
  48. package/lib/tools/search.js +95 -0
  49. package/lib/tools/search.js.map +1 -0
  50. package/lib/tools/stats.d.ts +18 -0
  51. package/lib/tools/stats.d.ts.map +1 -0
  52. package/lib/tools/stats.js +62 -0
  53. package/lib/tools/stats.js.map +1 -0
  54. package/{src → lib}/tools/words-count.d.ts +6 -3
  55. package/lib/tools/words-count.d.ts.map +1 -0
  56. package/lib/tools/words-count.js +31 -0
  57. package/lib/tools/words-count.js.map +1 -0
  58. package/{src/types/frontmatter.d.ts → lib/types.d.ts} +11 -17
  59. package/lib/types.d.ts.map +1 -0
  60. package/lib/types.js +2 -0
  61. package/lib/types.js.map +1 -0
  62. package/lib/utils.d.ts +19 -0
  63. package/lib/utils.d.ts.map +1 -0
  64. package/lib/utils.js +40 -0
  65. package/lib/utils.js.map +1 -0
  66. package/package.json +59 -62
  67. package/src/database/index.d.ts +0 -6
  68. package/src/database/index.js +0 -26
  69. package/src/database/relations.d.ts +0 -744
  70. package/src/database/relations.js +0 -52
  71. package/src/database/schema.d.ts +0 -733
  72. package/src/database/schema.js +0 -69
  73. package/src/database/vector.d.ts +0 -25
  74. package/src/database/vector.js +0 -98
  75. package/src/index.d.ts +0 -5
  76. package/src/index.js +0 -5
  77. package/src/rag/character-ner.d.ts +0 -36
  78. package/src/rag/character-ner.js +0 -416
  79. package/src/rag/database-sync.d.ts +0 -38
  80. package/src/rag/database-sync.js +0 -158
  81. package/src/rag/embeddings.d.ts +0 -74
  82. package/src/rag/embeddings.js +0 -164
  83. package/src/rag/graph-rag.d.ts +0 -69
  84. package/src/rag/graph-rag.js +0 -311
  85. package/src/rag/hybrid-rag.d.ts +0 -109
  86. package/src/rag/hybrid-rag.js +0 -255
  87. package/src/rag/index.d.ts +0 -16
  88. package/src/rag/index.js +0 -33
  89. package/src/server.d.ts +0 -43
  90. package/src/server.js +0 -177
  91. package/src/tools/index-rag.d.ts +0 -19
  92. package/src/tools/index-rag.js +0 -85
  93. package/src/tools/index-tracker.d.ts +0 -17
  94. package/src/tools/index-tracker.js +0 -89
  95. package/src/tools/index.d.ts +0 -5
  96. package/src/tools/index.js +0 -5
  97. package/src/tools/rag-context.d.ts +0 -34
  98. package/src/tools/rag-context.js +0 -51
  99. package/src/tools/rag-search.d.ts +0 -35
  100. package/src/tools/rag-search.js +0 -60
  101. package/src/tools/words-count.js +0 -28
  102. package/src/types/frontmatter.js +0 -1
  103. package/src/utils/index.d.ts +0 -1
  104. package/src/utils/index.js +0 -1
  105. package/src/utils/markdown.d.ts +0 -6
  106. package/src/utils/markdown.js +0 -36
  107. package/src/utils/timeline-detection.d.ts +0 -13
  108. package/src/utils/timeline-detection.js +0 -76
@@ -0,0 +1,128 @@
1
+ import z from 'zod';
2
+ import { DEFAULT_DB_PATH } from '../constants.js';
3
+ import { Database } from '../database/index.js';
4
+ import { generateEmbedding } from '../indexer/embeddings.js';
5
+ import { extractEntities } from '../indexer/extractor.js';
6
+ import { scanTimeline } from '../indexer/scanner.js';
7
+ export const indexConfig = {
8
+ name: 'index',
9
+ description: 'Index timeline content into the database for semantic search.',
10
+ arguments: {
11
+ contentPath: 'Path to the content directory.',
12
+ arc: 'Filter by arc name (optional).',
13
+ force: 'Force re-indexing of all chapters.',
14
+ dbPath: `Database path (default: ${DEFAULT_DB_PATH}).`,
15
+ },
16
+ };
17
+ export const indexSchema = z.object({
18
+ contentPath: z.string().describe(indexConfig.arguments.contentPath),
19
+ arc: z.string().optional().describe(indexConfig.arguments.arc),
20
+ force: z.boolean().optional().describe(indexConfig.arguments.force),
21
+ dbPath: z.string().default(DEFAULT_DB_PATH).describe(indexConfig.arguments.dbPath),
22
+ });
23
+ export async function index(input) {
24
+ const { contentPath, arc, force = false, dbPath } = indexSchema.parse(input);
25
+ const db = new Database(dbPath);
26
+ await db.connect();
27
+ // 1. Scan filesystem
28
+ const { chapters: scanned } = scanTimeline(contentPath, arc);
29
+ // 2. Get existing hashes for incremental indexing
30
+ const existingHashes = await db.getChapterHashes();
31
+ // 3. Determine what needs indexing
32
+ const toIndex = scanned.filter((ch) => force || existingHashes.get(ch.file_path) !== ch.file_hash);
33
+ const skipped = scanned.length - toIndex.length;
34
+ // 4. Collect all entities and relations
35
+ const allEntities = new Map();
36
+ const allRelations = new Map();
37
+ // 5. Process chapters
38
+ for (const chapter of toIndex) {
39
+ // Generate embedding
40
+ const vector = await generateEmbedding(chapter.content, db.embeddingModel);
41
+ // Extract entities and relations
42
+ const { entities, relations } = await extractEntities(chapter.content);
43
+ // Build chapter record
44
+ const chapterRecord = {
45
+ ...chapter,
46
+ vector,
47
+ entities: entities.map((e) => `${chapter.arc}:${e.type}:${e.name}`),
48
+ indexed_at: Date.now(),
49
+ };
50
+ await db.upsertChapters([chapterRecord]);
51
+ // Aggregate entities
52
+ for (const entity of entities) {
53
+ const entityId = `${chapter.arc}:${entity.type}:${entity.name}`;
54
+ const existing = allEntities.get(entityId);
55
+ if (existing) {
56
+ existing.chapters.push(chapter.id);
57
+ existing.chapter_count++;
58
+ // Merge aliases
59
+ for (const alias of entity.aliases) {
60
+ if (!existing.aliases.includes(alias)) {
61
+ existing.aliases.push(alias);
62
+ }
63
+ }
64
+ }
65
+ else {
66
+ allEntities.set(entityId, {
67
+ id: entityId,
68
+ arc: chapter.arc,
69
+ name: entity.name,
70
+ type: entity.type,
71
+ description: entity.description,
72
+ aliases: entity.aliases,
73
+ vector: [], // Will be filled later
74
+ chapters: [chapter.id],
75
+ chapter_count: 1,
76
+ first_appearance: chapter.id,
77
+ indexed_at: Date.now(),
78
+ });
79
+ }
80
+ }
81
+ // Aggregate relations
82
+ for (const relation of relations) {
83
+ const relationId = `${chapter.arc}:${relation.source}:${relation.type}:${relation.target}`;
84
+ const existing = allRelations.get(relationId);
85
+ if (existing) {
86
+ if (!existing.chapters.includes(chapter.id)) {
87
+ existing.chapters.push(chapter.id);
88
+ }
89
+ }
90
+ else {
91
+ allRelations.set(relationId, {
92
+ id: relationId,
93
+ arc: chapter.arc,
94
+ source_entity: `${chapter.arc}:CHARACTER:${relation.source}`,
95
+ target_entity: `${chapter.arc}:CHARACTER:${relation.target}`,
96
+ type: relation.type,
97
+ description: relation.description,
98
+ weight: 0.5,
99
+ chapters: [chapter.id],
100
+ indexed_at: Date.now(),
101
+ });
102
+ }
103
+ }
104
+ }
105
+ // 6. Generate embeddings for entities and save
106
+ for (const entity of allEntities.values()) {
107
+ entity.vector = await generateEmbedding(`${entity.name}: ${entity.description}`, db.embeddingModel);
108
+ }
109
+ if (allEntities.size > 0) {
110
+ await db.upsertEntities([...allEntities.values()]);
111
+ }
112
+ if (allRelations.size > 0) {
113
+ await db.upsertRelations([...allRelations.values()]);
114
+ }
115
+ // 7. Delete removed chapters
116
+ const currentPaths = new Set(scanned.map((c) => c.file_path));
117
+ const toDelete = [...existingHashes.keys()].filter((p) => !currentPaths.has(p));
118
+ await db.deleteChaptersByPaths(toDelete);
119
+ db.close();
120
+ return {
121
+ indexed: toIndex.length,
122
+ skipped,
123
+ deleted: toDelete.length,
124
+ entities: allEntities.size,
125
+ relations: allRelations.size,
126
+ };
127
+ }
128
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import z from 'zod';
2
+ import type { ToolConfig } from '../types.js';
3
+ export declare const searchConfig: ToolConfig;
4
+ export declare const searchSchema: z.ZodObject<{
5
+ query: z.ZodString;
6
+ type: z.ZodDefault<z.ZodEnum<{
7
+ entities: "entities";
8
+ chapters: "chapters";
9
+ relations: "relations";
10
+ }>>;
11
+ arc: z.ZodOptional<z.ZodString>;
12
+ entityType: z.ZodOptional<z.ZodString>;
13
+ relationType: z.ZodOptional<z.ZodString>;
14
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
15
+ dbPath: z.ZodDefault<z.ZodString>;
16
+ }, z.z.core.$strip>;
17
+ export type SearchInput = {
18
+ query: string;
19
+ type?: 'chapters' | 'entities' | 'relations';
20
+ arc?: string;
21
+ entityType?: string;
22
+ relationType?: string;
23
+ limit?: number;
24
+ dbPath?: string;
25
+ };
26
+ export interface ChapterResult {
27
+ id: string;
28
+ arc: string;
29
+ episode: number;
30
+ chapter: number;
31
+ pov: string;
32
+ title: string;
33
+ location: string;
34
+ content: string;
35
+ word_count: number;
36
+ score: number;
37
+ }
38
+ export interface EntityResult {
39
+ id: string;
40
+ arc: string;
41
+ name: string;
42
+ type: string;
43
+ description: string;
44
+ aliases: string[];
45
+ chapter_count: number;
46
+ score: number;
47
+ }
48
+ export interface RelationResult {
49
+ id: string;
50
+ arc: string;
51
+ source_entity: string;
52
+ target_entity: string;
53
+ type: string;
54
+ description: string;
55
+ chapters: string[];
56
+ }
57
+ export type SearchOutput = {
58
+ type: 'chapters';
59
+ results: ChapterResult[];
60
+ } | {
61
+ type: 'entities';
62
+ results: EntityResult[];
63
+ } | {
64
+ type: 'relations';
65
+ results: RelationResult[];
66
+ };
67
+ export declare function search(input: SearchInput & {
68
+ type: 'chapters';
69
+ }): Promise<{
70
+ type: 'chapters';
71
+ results: ChapterResult[];
72
+ }>;
73
+ export declare function search(input: SearchInput & {
74
+ type: 'entities';
75
+ }): Promise<{
76
+ type: 'entities';
77
+ results: EntityResult[];
78
+ }>;
79
+ export declare function search(input: SearchInput & {
80
+ type: 'relations';
81
+ }): Promise<{
82
+ type: 'relations';
83
+ results: RelationResult[];
84
+ }>;
85
+ export declare function search(input: SearchInput): Promise<SearchOutput>;
86
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["search.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAMpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,YAAY,EAAE,UAY1B,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;mBAWvB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC;AAGrD,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACxC,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,CAAC;AAC3D,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACxC,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CAAC;AAC1D,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACzC,OAAO,CAAC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAAC;AAC7D,wBAAsB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC"}
@@ -0,0 +1,95 @@
1
+ import z from 'zod';
2
+ import { DEFAULT_DB_PATH } from '../constants.js';
3
+ import { Database } from '../database/index.js';
4
+ import { generateEmbedding } from '../indexer/embeddings.js';
5
+ export const searchConfig = {
6
+ name: 'search',
7
+ description: 'Search indexed content using semantic similarity or filters.',
8
+ arguments: {
9
+ query: 'Search query text.',
10
+ type: 'Search type: chapters (default), entities, or relations.',
11
+ arc: 'Filter by arc name (optional).',
12
+ entityType: 'Filter entities by type: CHARACTER, LOCATION, EVENT, OBJECT, EMOTION.',
13
+ relationType: 'Filter relations by type.',
14
+ limit: 'Maximum number of results (default: 10).',
15
+ dbPath: `Database path (default: ${DEFAULT_DB_PATH}).`,
16
+ },
17
+ };
18
+ export const searchSchema = z.object({
19
+ query: z.string().describe(searchConfig.arguments.query),
20
+ type: z
21
+ .enum(['chapters', 'entities', 'relations'])
22
+ .default('chapters')
23
+ .describe(searchConfig.arguments.type),
24
+ arc: z.string().optional().describe(searchConfig.arguments.arc),
25
+ entityType: z.string().optional().describe(searchConfig.arguments.entityType),
26
+ relationType: z.string().optional().describe(searchConfig.arguments.relationType),
27
+ limit: z.number().optional().default(10).describe(searchConfig.arguments.limit),
28
+ dbPath: z.string().default(DEFAULT_DB_PATH).describe(searchConfig.arguments.dbPath),
29
+ });
30
+ export async function search(input) {
31
+ const { query, type, arc, entityType, relationType, limit, dbPath } = searchSchema.parse(input);
32
+ const db = new Database(dbPath);
33
+ await db.connect();
34
+ if (type === 'chapters') {
35
+ const vector = await generateEmbedding(query, db.embeddingModel);
36
+ const chapters = await db.searchChapters(vector, limit, arc);
37
+ db.close();
38
+ return {
39
+ type: 'chapters',
40
+ results: chapters.map((c) => ({
41
+ id: c.id,
42
+ arc: c.arc,
43
+ episode: c.episode,
44
+ chapter: c.chapter,
45
+ pov: c.pov,
46
+ title: c.title,
47
+ location: c.location,
48
+ content: c.content.slice(0, 500) + (c.content.length > 500 ? '...' : ''),
49
+ word_count: c.word_count,
50
+ /* v8 ignore next */
51
+ score: 1 - (c._distance ?? 0),
52
+ })),
53
+ };
54
+ }
55
+ if (type === 'entities') {
56
+ const vector = await generateEmbedding(query, db.embeddingModel);
57
+ const entities = await db.searchEntities(vector, limit, arc, entityType);
58
+ db.close();
59
+ return {
60
+ type: 'entities',
61
+ results: entities.map((e) => ({
62
+ id: e.id,
63
+ arc: e.arc,
64
+ name: e.name,
65
+ type: e.type,
66
+ description: e.description,
67
+ aliases: e.aliases,
68
+ chapter_count: e.chapter_count,
69
+ /* v8 ignore next */
70
+ score: 1 - (e._distance ?? 0),
71
+ })),
72
+ };
73
+ }
74
+ // type === 'relations'
75
+ const relations = await db.getRelations(arc, relationType);
76
+ db.close();
77
+ // Filter relations by query (simple text match on source/target/description)
78
+ const queryLower = query.toLowerCase();
79
+ const filtered = relations.filter((r) => r.source_entity.toLowerCase().includes(queryLower) ||
80
+ r.target_entity.toLowerCase().includes(queryLower) ||
81
+ r.description.toLowerCase().includes(queryLower));
82
+ return {
83
+ type: 'relations',
84
+ results: filtered.slice(0, limit).map((r) => ({
85
+ id: r.id,
86
+ arc: r.arc,
87
+ source_entity: r.source_entity,
88
+ target_entity: r.target_entity,
89
+ type: r.type,
90
+ description: r.description,
91
+ chapters: r.chapters,
92
+ })),
93
+ };
94
+ }
95
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import z from 'zod';
2
+ import type { ToolConfig } from '../types.js';
3
+ export declare const statsConfig: ToolConfig;
4
+ export declare const statsSchema: z.ZodObject<{
5
+ arc: z.ZodOptional<z.ZodString>;
6
+ pov: z.ZodOptional<z.ZodString>;
7
+ dbPath: z.ZodDefault<z.ZodString>;
8
+ }, z.z.core.$strip>;
9
+ export type StatsInput = z.infer<typeof statsSchema>;
10
+ export interface StatsOutput {
11
+ totalChapters: number;
12
+ totalWords: number;
13
+ arcs: string[];
14
+ povs: Record<string, number>;
15
+ averageWordsPerChapter: number;
16
+ }
17
+ export declare function stats(input: StatsInput): Promise<StatsOutput>;
18
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["stats.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAIpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,WAAW,EAAE,UAQzB,CAAC;AAEF,eAAO,MAAM,WAAW;;;;mBAItB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAOD,wBAAsB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA8CnE"}
@@ -0,0 +1,62 @@
1
+ import z from 'zod';
2
+ import { DEFAULT_DB_PATH } from '../constants.js';
3
+ import { Database } from '../database/index.js';
4
+ export const statsConfig = {
5
+ name: 'stats',
6
+ description: 'Get aggregate statistics for indexed timeline content.',
7
+ arguments: {
8
+ arc: 'Filter by arc name(s), comma-separated (optional).',
9
+ pov: 'Filter by POV character(s), comma-separated (optional).',
10
+ dbPath: `Database path (default: ${DEFAULT_DB_PATH}).`,
11
+ },
12
+ };
13
+ export const statsSchema = z.object({
14
+ arc: z.string().optional().describe(statsConfig.arguments.arc),
15
+ pov: z.string().optional().describe(statsConfig.arguments.pov),
16
+ dbPath: z.string().default(DEFAULT_DB_PATH).describe(statsConfig.arguments.dbPath),
17
+ });
18
+ function parseFilter(value) {
19
+ if (!value)
20
+ return undefined;
21
+ return value.split(',').map((v) => v.trim().toLowerCase());
22
+ }
23
+ export async function stats(input) {
24
+ const { arc, pov, dbPath } = statsSchema.parse(input);
25
+ const arcFilter = parseFilter(arc);
26
+ const povFilter = parseFilter(pov);
27
+ const db = new Database(dbPath);
28
+ let chapters = await db.getChapters();
29
+ db.close();
30
+ if (chapters.length === 0) {
31
+ throw new Error('No indexed chapters found. Run "index" first.');
32
+ }
33
+ // Normalize POV to lowercase for comparison
34
+ chapters = chapters.map((c) => ({ ...c, pov: c.pov.toLowerCase() }));
35
+ if (arcFilter) {
36
+ chapters = chapters.filter((c) => arcFilter.includes(c.arc.toLowerCase()));
37
+ if (chapters.length === 0) {
38
+ throw new Error(`No chapters found for arc "${arc}".`);
39
+ }
40
+ }
41
+ if (povFilter) {
42
+ chapters = chapters.filter((c) => povFilter.includes(c.pov));
43
+ if (chapters.length === 0) {
44
+ throw new Error(`No chapters found for POV "${pov}".`);
45
+ }
46
+ }
47
+ const arcs = [...new Set(chapters.map((c) => c.arc))].sort();
48
+ const povs = {};
49
+ let totalWords = 0;
50
+ for (const chapter of chapters) {
51
+ totalWords += chapter.word_count;
52
+ povs[chapter.pov] = (povs[chapter.pov] || 0) + 1;
53
+ }
54
+ return {
55
+ totalChapters: chapters.length,
56
+ totalWords,
57
+ arcs,
58
+ povs,
59
+ averageWordsPerChapter: Math.round(totalWords / chapters.length),
60
+ };
61
+ }
62
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["stats.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,10 @@
1
- import { z } from 'zod';
1
+ import z from 'zod';
2
+ import type { ToolConfig } from '../types.js';
3
+ export declare const wordsCountConfig: ToolConfig;
2
4
  export declare const wordsCountSchema: z.ZodObject<{
3
5
  filePath: z.ZodString;
4
6
  detailed: z.ZodOptional<z.ZodBoolean>;
5
- }, z.core.$strip>;
7
+ }, z.z.core.$strip>;
6
8
  export type WordsCountInput = z.infer<typeof wordsCountSchema>;
7
9
  export interface WordsCountOutput {
8
10
  words: number;
@@ -12,4 +14,5 @@ export interface WordsCountOutput {
12
14
  sentences?: number;
13
15
  paragraphs?: number;
14
16
  }
15
- export declare function wordsCount(input: WordsCountInput): Promise<WordsCountOutput>;
17
+ export declare function wordsCount(input: WordsCountInput): WordsCountOutput;
18
+ //# sourceMappingURL=words-count.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"words-count.d.ts","sourceRoot":"","sources":["words-count.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,eAAO,MAAM,gBAAgB,EAAE,UAO9B,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;mBAG3B,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAkBnE"}
@@ -0,0 +1,31 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import z from 'zod';
3
+ import { parseChapter } from '../utils.js';
4
+ export const wordsCountConfig = {
5
+ name: 'words-count',
6
+ description: 'Counts the number of words in a given text file.',
7
+ arguments: {
8
+ filePath: 'Path to the text file to be analyzed.',
9
+ detailed: 'Include detailed statistics.',
10
+ },
11
+ };
12
+ export const wordsCountSchema = z.object({
13
+ filePath: z.string().describe(wordsCountConfig.arguments.filePath),
14
+ detailed: z.boolean().optional().describe(wordsCountConfig.arguments.detailed),
15
+ });
16
+ export function wordsCount(input) {
17
+ const { filePath, detailed = false } = wordsCountSchema.parse(input);
18
+ const { stats } = parseChapter(readFileSync(filePath, 'utf-8'));
19
+ const result = {
20
+ words: stats.wordCount,
21
+ characters: stats.charCountWithSpaces,
22
+ charactersNoSpaces: stats.charCount,
23
+ readingTimeMinutes: stats.readingTimeMinutes,
24
+ };
25
+ if (detailed) {
26
+ result.sentences = stats.sentenceCount;
27
+ result.paragraphs = stats.paragraphCount;
28
+ }
29
+ return result;
30
+ }
31
+ //# sourceMappingURL=words-count.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"words-count.js","sourceRoot":"","sources":["words-count.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,CAAC,MAAM,KAAK,CAAC;AAGpB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,CAAC,MAAM,gBAAgB,GAAe;IAC1C,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE,kDAAkD;IAC/D,SAAS,EAAE;QACT,QAAQ,EAAE,uCAAuC;QACjD,QAAQ,EAAE,8BAA8B;KACzC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC;IAClE,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,QAAQ,CAAC;CAC/E,CAAC,CAAC;AAaH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAErE,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAqB;QAC/B,KAAK,EAAE,KAAK,CAAC,SAAS;QACtB,UAAU,EAAE,KAAK,CAAC,mBAAmB;QACrC,kBAAkB,EAAE,KAAK,CAAC,SAAS;QACnC,kBAAkB,EAAE,KAAK,CAAC,kBAAkB;KAC7C,CAAC;IAEF,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,SAAS,GAAG,KAAK,CAAC,aAAa,CAAC;QACvC,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC,cAAc,CAAC;IAC3C,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,6 +1,13 @@
1
- /**
2
- * Frontmatter metadata from YAML headers
3
- */
1
+ export interface Package {
2
+ name: string;
3
+ description: string;
4
+ version: string;
5
+ }
6
+ export interface ToolConfig {
7
+ name: string;
8
+ description: string;
9
+ arguments: Record<string, string>;
10
+ }
4
11
  export interface ChapterMetadata {
5
12
  pov: string;
6
13
  title: string;
@@ -15,21 +22,8 @@ export interface ChapterMetadata {
15
22
  outfit?: string;
16
23
  kink?: string;
17
24
  }
18
- /**
19
- * Text statistics calculated from content
20
- */
21
- export interface TextStats {
22
- words: number;
23
- characters: number;
24
- charactersNoSpaces: number;
25
- paragraphs: number;
26
- sentences: number;
27
- readingTimeMinutes: number;
28
- }
29
- /**
30
- * Result of parsing a markdown file
31
- */
32
25
  export interface ParsedMarkdown {
33
26
  metadata: ChapterMetadata;
34
27
  content: string;
35
28
  }
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/lib/types.js ADDED
@@ -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":""}
package/lib/utils.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { ChapterMetadata, Package, ParsedMarkdown } from './types.js';
2
+ export declare function getPackageConfig(): Package;
3
+ export interface TextStats {
4
+ wordCount: number;
5
+ charCount: number;
6
+ charCountWithSpaces: number;
7
+ paragraphCount: number;
8
+ sentenceCount: number;
9
+ readingTimeMinutes: number;
10
+ }
11
+ export interface ParsedChapter {
12
+ metadata: ChapterMetadata;
13
+ content: string;
14
+ plainText: string;
15
+ stats: TextStats;
16
+ }
17
+ export declare function parseMarkdown(markdown: string): ParsedMarkdown;
18
+ export declare function parseChapter(markdown: string): ParsedChapter;
19
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE3E,wBAAgB,gBAAgB,IAAI,OAAO,CAG1C;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAW9D;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAuB5D"}
package/lib/utils.js ADDED
@@ -0,0 +1,40 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import matter from 'gray-matter';
4
+ import removeMd from 'remove-markdown';
5
+ export function getPackageConfig() {
6
+ const packagePath = join(import.meta.dirname, '..', 'package.json');
7
+ return JSON.parse(readFileSync(packagePath, 'utf8'));
8
+ }
9
+ export function parseMarkdown(markdown) {
10
+ const { data, content } = matter(markdown);
11
+ if (data.date instanceof Date) {
12
+ data.date = data.date.toISOString().split('T')[0];
13
+ }
14
+ return {
15
+ metadata: data,
16
+ content: content.trim(),
17
+ };
18
+ }
19
+ export function parseChapter(markdown) {
20
+ const { metadata, content } = parseMarkdown(markdown);
21
+ // Strip markdown to plain text
22
+ const withoutHeaders = content.replace(/^#{1,6}\s+.*$/gm, '');
23
+ const plainText = removeMd(withoutHeaders);
24
+ // Compute all stats
25
+ const wordCount = plainText.split(/\s+/).filter((w) => w.length > 0).length;
26
+ return {
27
+ metadata,
28
+ content,
29
+ plainText,
30
+ stats: {
31
+ wordCount,
32
+ charCount: plainText.replace(/\s/g, '').length,
33
+ charCountWithSpaces: plainText.length,
34
+ paragraphCount: plainText.split(/\n\s*\n/).filter((p) => p.trim().length > 0).length,
35
+ sentenceCount: plainText.split(/[.!?]+/).filter((s) => s.trim().length > 0).length,
36
+ readingTimeMinutes: Math.ceil(wordCount / 200),
37
+ },
38
+ };
39
+ }
40
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AAIvC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAY,CAAC;AAClE,CAAC;AAkBD,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,IAAI,CAAC,IAAI,YAAY,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,IAAuB;QACjC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEtD,+BAA+B;IAC/B,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC;IAE3C,oBAAoB;IACpB,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAE5E,OAAO;QACL,QAAQ;QACR,OAAO;QACP,SAAS;QACT,KAAK,EAAE;YACL,SAAS;YACT,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM;YAC9C,mBAAmB,EAAE,SAAS,CAAC,MAAM;YACrC,cAAc,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM;YACpF,aAAa,EAAE,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM;YAClF,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;SAC/C;KACF,CAAC;AACJ,CAAC"}