@velvetmonkey/vault-core 2.0.145 → 2.0.147

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/entities.js CHANGED
@@ -248,8 +248,12 @@ const FRONTMATTER_TYPE_MAP = {
248
248
  country: 'locations', region: 'locations',
249
249
  concept: 'concepts', idea: 'concepts', topic: 'concepts',
250
250
  };
251
- function mapFrontmatterType(type) {
252
- return FRONTMATTER_TYPE_MAP[type.toLowerCase()];
251
+ function mapFrontmatterType(type, customCategories) {
252
+ const lower = type.toLowerCase();
253
+ // Custom categories take priority — frontmatter type becomes the category name
254
+ if (customCategories?.[lower])
255
+ return lower;
256
+ return FRONTMATTER_TYPE_MAP[lower];
253
257
  }
254
258
  /**
255
259
  * Categorize an entity based on its name and optional frontmatter type
@@ -296,10 +300,10 @@ const FOLDER_CATEGORY_MAP = {
296
300
  'finance': 'finance',
297
301
  'hobbies': 'hobbies',
298
302
  };
299
- function categorizeEntity(name, techKeywords, frontmatterType, notePath) {
300
- // 0. Frontmatter type takes priority
303
+ function categorizeEntity(name, techKeywords, frontmatterType, notePath, customCategories) {
304
+ // 0. Frontmatter type takes priority (custom categories checked first)
301
305
  if (frontmatterType) {
302
- const mapped = mapFrontmatterType(frontmatterType);
306
+ const mapped = mapFrontmatterType(frontmatterType, customCategories);
303
307
  if (mapped)
304
308
  return mapped;
305
309
  }
@@ -442,6 +446,7 @@ async function scanDirectory(dirPath, basePath, excludeFolders) {
442
446
  export async function scanVaultEntities(vaultPath, options = {}) {
443
447
  const excludeFolders = options.excludeFolders ?? [];
444
448
  const techKeywords = options.techKeywords ?? DEFAULT_TECH_KEYWORDS;
449
+ const customCategories = options.customCategories;
445
450
  // Scan vault for all markdown files
446
451
  const allEntities = await scanDirectory(vaultPath, vaultPath, excludeFolders);
447
452
  // Filter out periodic notes, invalid entries, and stop-listed entities
@@ -494,7 +499,7 @@ export async function scanVaultEntities(vaultPath, options = {}) {
494
499
  },
495
500
  };
496
501
  for (const entity of uniqueEntities) {
497
- const category = categorizeEntity(entity.name, techKeywords, entity.frontmatterType, entity.relativePath);
502
+ const category = categorizeEntity(entity.name, techKeywords, entity.frontmatterType, entity.relativePath, customCategories);
498
503
  // Store as EntityWithAliases object
499
504
  const entityObj = {
500
505
  name: entity.name,
@@ -502,41 +507,40 @@ export async function scanVaultEntities(vaultPath, options = {}) {
502
507
  aliases: entity.aliases,
503
508
  description: entity.description,
504
509
  };
510
+ // Initialize custom category array if needed
511
+ if (!index[category]) {
512
+ index[category] = [];
513
+ }
505
514
  index[category].push(entityObj);
506
515
  }
507
- // Sort each category by name
516
+ // Sort each category by name (including custom categories)
508
517
  const sortByName = (a, b) => {
509
518
  const nameA = typeof a === 'string' ? a : a.name;
510
519
  const nameB = typeof b === 'string' ? b : b.name;
511
520
  return nameA.localeCompare(nameB);
512
521
  };
513
- const allCategories = [
514
- 'technologies', 'acronyms', 'people', 'projects', 'organizations',
515
- 'locations', 'concepts', 'animals', 'media', 'events', 'documents',
516
- 'vehicles', 'health', 'finance', 'food', 'hobbies', 'other',
517
- ];
518
- for (const cat of allCategories) {
522
+ const allCategoryKeys = Object.keys(index).filter(k => k !== '_metadata');
523
+ for (const cat of allCategoryKeys) {
519
524
  index[cat].sort(sortByName);
520
525
  }
521
526
  // Update metadata
522
- index._metadata.total_entities = allCategories.reduce((sum, cat) => sum + index[cat].length, 0);
527
+ index._metadata.total_entities = allCategoryKeys.reduce((sum, cat) => sum + index[cat].length, 0);
523
528
  return index;
524
529
  }
525
530
  /**
526
531
  * Get all entities as a flat array (for wikilink matching)
527
532
  * Handles both legacy string format and new EntityWithAliases format
528
533
  */
529
- /** All entity category keys (excludes _metadata) */
530
- const ALL_ENTITY_CATEGORIES = [
531
- 'technologies', 'acronyms', 'people', 'projects', 'organizations',
532
- 'locations', 'concepts', 'animals', 'media', 'events', 'documents',
533
- 'vehicles', 'health', 'finance', 'food', 'hobbies', 'periodical', 'other',
534
- ];
534
+ /** Get all category keys from an index (includes custom categories, excludes _metadata) */
535
+ function getIndexCategories(index) {
536
+ return Object.keys(index).filter(k => k !== '_metadata');
537
+ }
535
538
  export function getAllEntities(index) {
536
539
  const result = [];
537
- for (const cat of ALL_ENTITY_CATEGORIES) {
538
- if (index[cat])
539
- result.push(...index[cat]);
540
+ for (const cat of getIndexCategories(index)) {
541
+ const entities = index[cat];
542
+ if (Array.isArray(entities))
543
+ result.push(...entities);
540
544
  }
541
545
  return result;
542
546
  }
@@ -552,8 +556,7 @@ export function getAllEntities(index) {
552
556
  */
553
557
  export function getAllEntitiesWithTypes(index) {
554
558
  const result = [];
555
- const categories = ALL_ENTITY_CATEGORIES;
556
- for (const category of categories) {
559
+ for (const category of getIndexCategories(index)) {
557
560
  const entities = index[category];
558
561
  // Skip undefined or empty categories
559
562
  if (!entities || !Array.isArray(entities)) {
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@
4
4
  * Shared vault utilities for the Flywheel ecosystem.
5
5
  * Used by both Flywheel (read) and Flywheel Memory (write).
6
6
  */
7
- export type { EntityIndex, EntityCategory, EntityWithAliases, Entity, EntityWithType, ScanOptions, WikilinkOptions, WikilinkResult, ImplicitEntityConfig, ExtendedWikilinkOptions, ImplicitEntityMatch, ResolveAliasOptions, ProtectedZone, ProtectedZoneType, } from './types.js';
7
+ export type { EntityIndex, EntityCategory, DefaultEntityCategory, EntityWithAliases, Entity, EntityWithType, ScanOptions, WikilinkOptions, WikilinkResult, ImplicitEntityConfig, ExtendedWikilinkOptions, ImplicitEntityMatch, ResolveAliasOptions, ProtectedZone, ProtectedZoneType, } from './types.js';
8
+ export { DEFAULT_ENTITY_CATEGORIES, getIndexCategory, ensureIndexCategory, } from './types.js';
8
9
  export { COMMON_ENGLISH_WORDS } from './common-words.js';
9
10
  export { stem } from './stemmer.js';
10
11
  export { scanVaultEntities, getAllEntities, getAllEntitiesWithTypes, getEntityName, getEntityAliases, loadEntityCache, saveEntityCache, ENTITY_CACHE_VERSION, } from './entities.js';
package/dist/index.js CHANGED
@@ -4,6 +4,8 @@
4
4
  * Shared vault utilities for the Flywheel ecosystem.
5
5
  * Used by both Flywheel (read) and Flywheel Memory (write).
6
6
  */
7
+ // Type helpers and constants
8
+ export { DEFAULT_ENTITY_CATEGORIES, getIndexCategory, ensureIndexCategory, } from './types.js';
7
9
  // Common English words (frequency list for alias filtering)
8
10
  export { COMMON_ENGLISH_WORDS } from './common-words.js';
9
11
  // Porter Stemmer (for morphological entity matching)
package/dist/queries.js CHANGED
@@ -122,6 +122,10 @@ export function getEntityIndexFromDb(stateDb) {
122
122
  hubScore: entity.hubScore,
123
123
  description: entity.description,
124
124
  };
125
+ // Initialize custom category array if needed
126
+ if (!index[entity.category]) {
127
+ index[entity.category] = [];
128
+ }
125
129
  index[entity.category].push(entityObj);
126
130
  }
127
131
  return index;
package/dist/sqlite.js CHANGED
@@ -193,13 +193,8 @@ export function openStateDb(vaultPath) {
193
193
  replaceAllEntities: db.transaction((index) => {
194
194
  // Clear existing entities
195
195
  stateDb.clearEntities.run();
196
- // Insert all entities by category
197
- const categories = [
198
- 'technologies', 'acronyms', 'people', 'projects',
199
- 'organizations', 'locations', 'concepts', 'animals',
200
- 'media', 'events', 'documents', 'vehicles', 'health',
201
- 'finance', 'food', 'hobbies', 'other',
202
- ];
196
+ // Insert all entities by category (including custom categories)
197
+ const categories = Object.keys(index).filter(k => k !== '_metadata');
203
198
  let total = 0;
204
199
  for (const category of categories) {
205
200
  const entities = index[category];
package/dist/types.d.ts CHANGED
@@ -2,9 +2,15 @@
2
2
  * Types for vault-core shared utilities
3
3
  */
4
4
  /**
5
- * Categories for entity classification
5
+ * Built-in entity categories
6
6
  */
7
- export type EntityCategory = 'technologies' | 'acronyms' | 'people' | 'projects' | 'organizations' | 'locations' | 'concepts' | 'animals' | 'media' | 'events' | 'documents' | 'vehicles' | 'health' | 'finance' | 'food' | 'hobbies' | 'periodical' | 'other';
7
+ export type DefaultEntityCategory = 'technologies' | 'acronyms' | 'people' | 'projects' | 'organizations' | 'locations' | 'concepts' | 'animals' | 'media' | 'events' | 'documents' | 'vehicles' | 'health' | 'finance' | 'food' | 'hobbies' | 'periodical' | 'other';
8
+ /**
9
+ * Entity category — built-in defaults + user-defined custom categories.
10
+ * Custom categories are configured via FlywheelConfig.custom_categories
11
+ * and populated from frontmatter `type:` fields.
12
+ */
13
+ export type EntityCategory = DefaultEntityCategory | (string & Record<never, never>);
8
14
  /**
9
15
  * Entity with optional aliases from frontmatter
10
16
  */
@@ -32,9 +38,11 @@ export interface EntityWithType {
32
38
  entity: EntityWithAliases;
33
39
  category: EntityCategory;
34
40
  }
41
+ /** Built-in category keys (excludes _metadata) */
42
+ export declare const DEFAULT_ENTITY_CATEGORIES: DefaultEntityCategory[];
35
43
  /**
36
- * Entity index structure matching wikilink-cache.py output
37
- * Now supports both string[] (legacy) and EntityWithAliases[] (v2)
44
+ * Entity index structure built-in categories as typed properties,
45
+ * custom categories accessed dynamically via getIndexCategory().
38
46
  */
39
47
  export interface EntityIndex {
40
48
  technologies: Entity[];
@@ -55,6 +63,8 @@ export interface EntityIndex {
55
63
  hobbies: Entity[];
56
64
  periodical: Entity[];
57
65
  other: Entity[];
66
+ /** Dynamic custom categories */
67
+ [customCategory: string]: Entity[] | EntityIndex['_metadata'];
58
68
  _metadata: {
59
69
  total_entities: number;
60
70
  generated_at: string;
@@ -64,6 +74,10 @@ export interface EntityIndex {
64
74
  version?: number;
65
75
  };
66
76
  }
77
+ /** Get entities for a category (handles both built-in and custom) */
78
+ export declare function getIndexCategory(index: EntityIndex, category: string): Entity[];
79
+ /** Ensure a category array exists on the index */
80
+ export declare function ensureIndexCategory(index: EntityIndex, category: string): void;
67
81
  /**
68
82
  * A protected zone in content where wikilinks should not be applied
69
83
  */
@@ -88,6 +102,14 @@ export interface ScanOptions {
88
102
  * Tech keywords for categorization
89
103
  */
90
104
  techKeywords?: string[];
105
+ /**
106
+ * Custom entity categories from FlywheelConfig.
107
+ * Keys are frontmatter `type:` values; entities with matching types
108
+ * get that key as their category instead of the default classifier.
109
+ */
110
+ customCategories?: Record<string, {
111
+ type_boost?: number;
112
+ }>;
91
113
  }
92
114
  /**
93
115
  * Options for wikilink application
package/dist/types.js CHANGED
@@ -1,5 +1,22 @@
1
1
  /**
2
2
  * Types for vault-core shared utilities
3
3
  */
4
- export {};
4
+ /** Built-in category keys (excludes _metadata) */
5
+ export const DEFAULT_ENTITY_CATEGORIES = [
6
+ 'technologies', 'acronyms', 'people', 'projects', 'organizations',
7
+ 'locations', 'concepts', 'animals', 'media', 'events', 'documents',
8
+ 'vehicles', 'health', 'finance', 'food', 'hobbies', 'periodical', 'other',
9
+ ];
10
+ /** Get entities for a category (handles both built-in and custom) */
11
+ export function getIndexCategory(index, category) {
12
+ if (category === '_metadata')
13
+ return [];
14
+ return index[category] ?? [];
15
+ }
16
+ /** Ensure a category array exists on the index */
17
+ export function ensureIndexCategory(index, category) {
18
+ if (category !== '_metadata' && !index[category]) {
19
+ index[category] = [];
20
+ }
21
+ }
5
22
  //# sourceMappingURL=types.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velvetmonkey/vault-core",
3
- "version": "2.0.145",
3
+ "version": "2.0.147",
4
4
  "description": "Shared vault utilities for Flywheel ecosystem (entity scanning, wikilinks, protected zones)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",