ai-prompt-guide-mcp 1.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/LICENSE +21 -0
- package/README.md +271 -0
- package/dist/__tests__/config-loading.test.d.ts +5 -0
- package/dist/__tests__/config-loading.test.d.ts.map +1 -0
- package/dist/__tests__/config-loading.test.js +127 -0
- package/dist/__tests__/config-loading.test.js.map +1 -0
- package/dist/__tests__/config-logging.test.d.ts +5 -0
- package/dist/__tests__/config-logging.test.d.ts.map +1 -0
- package/dist/__tests__/config-logging.test.js +146 -0
- package/dist/__tests__/config-logging.test.js.map +1 -0
- package/dist/__tests__/config-path-resolution.test.d.ts +5 -0
- package/dist/__tests__/config-path-resolution.test.d.ts.map +1 -0
- package/dist/__tests__/config-path-resolution.test.js +88 -0
- package/dist/__tests__/config-path-resolution.test.js.map +1 -0
- package/dist/__tests__/config-path-validation.test.d.ts +6 -0
- package/dist/__tests__/config-path-validation.test.d.ts.map +1 -0
- package/dist/__tests__/config-path-validation.test.js +203 -0
- package/dist/__tests__/config-path-validation.test.js.map +1 -0
- package/dist/__tests__/config-precedence.test.d.ts +5 -0
- package/dist/__tests__/config-precedence.test.d.ts.map +1 -0
- package/dist/__tests__/config-precedence.test.js +200 -0
- package/dist/__tests__/config-precedence.test.js.map +1 -0
- package/dist/__tests__/config-types.test.d.ts +5 -0
- package/dist/__tests__/config-types.test.d.ts.map +1 -0
- package/dist/__tests__/config-types.test.js +189 -0
- package/dist/__tests__/config-types.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +5 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +229 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/config.d.ts +87 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +498 -0
- package/dist/config.js.map +1 -0
- package/dist/constants/defaults.d.ts +78 -0
- package/dist/constants/defaults.d.ts.map +1 -0
- package/dist/constants/defaults.js +78 -0
- package/dist/constants/defaults.js.map +1 -0
- package/dist/document-cache.d.ts +485 -0
- package/dist/document-cache.d.ts.map +1 -0
- package/dist/document-cache.hierarchical.test.d.ts +2 -0
- package/dist/document-cache.hierarchical.test.d.ts.map +1 -0
- package/dist/document-cache.hierarchical.test.js +243 -0
- package/dist/document-cache.hierarchical.test.js.map +1 -0
- package/dist/document-cache.js +965 -0
- package/dist/document-cache.js.map +1 -0
- package/dist/document-cache.test.d.ts +8 -0
- package/dist/document-cache.test.d.ts.map +1 -0
- package/dist/document-cache.test.js +624 -0
- package/dist/document-cache.test.js.map +1 -0
- package/dist/document-manager.d.ts +252 -0
- package/dist/document-manager.d.ts.map +1 -0
- package/dist/document-manager.js +760 -0
- package/dist/document-manager.js.map +1 -0
- package/dist/document-manager.race-condition.test.d.ts +8 -0
- package/dist/document-manager.race-condition.test.d.ts.map +1 -0
- package/dist/document-manager.race-condition.test.js +139 -0
- package/dist/document-manager.race-condition.test.js.map +1 -0
- package/dist/fingerprint-index.d.ts +177 -0
- package/dist/fingerprint-index.d.ts.map +1 -0
- package/dist/fingerprint-index.js +374 -0
- package/dist/fingerprint-index.js.map +1 -0
- package/dist/fingerprint-index.test.d.ts +15 -0
- package/dist/fingerprint-index.test.d.ts.map +1 -0
- package/dist/fingerprint-index.test.js +482 -0
- package/dist/fingerprint-index.test.js.map +1 -0
- package/dist/fsio.d.ts +76 -0
- package/dist/fsio.d.ts.map +1 -0
- package/dist/fsio.js +506 -0
- package/dist/fsio.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown-tools.test.d.ts +5 -0
- package/dist/markdown-tools.test.d.ts.map +1 -0
- package/dist/markdown-tools.test.js +200 -0
- package/dist/markdown-tools.test.js.map +1 -0
- package/dist/parse.d.ts +19 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +144 -0
- package/dist/parse.js.map +1 -0
- package/dist/prompts/__tests__/prompt-loader.test.d.ts +5 -0
- package/dist/prompts/__tests__/prompt-loader.test.d.ts.map +1 -0
- package/dist/prompts/__tests__/prompt-loader.test.js +300 -0
- package/dist/prompts/__tests__/prompt-loader.test.js.map +1 -0
- package/dist/prompts/prompt-loader.d.ts +58 -0
- package/dist/prompts/prompt-loader.d.ts.map +1 -0
- package/dist/prompts/prompt-loader.js +215 -0
- package/dist/prompts/prompt-loader.js.map +1 -0
- package/dist/prompts/prompt-validator.d.ts +30 -0
- package/dist/prompts/prompt-validator.d.ts.map +1 -0
- package/dist/prompts/prompt-validator.js +65 -0
- package/dist/prompts/prompt-validator.js.map +1 -0
- package/dist/prompts/types.d.ts +46 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +14 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/prompts/workflow-prompts.d.ts +42 -0
- package/dist/prompts/workflow-prompts.d.ts.map +1 -0
- package/dist/prompts/workflow-prompts.js +61 -0
- package/dist/prompts/workflow-prompts.js.map +1 -0
- package/dist/sections.d.ts +67 -0
- package/dist/sections.d.ts.map +1 -0
- package/dist/sections.hierarchical.test.d.ts +8 -0
- package/dist/sections.hierarchical.test.d.ts.map +1 -0
- package/dist/sections.hierarchical.test.js +397 -0
- package/dist/sections.hierarchical.test.js.map +1 -0
- package/dist/sections.js +1229 -0
- package/dist/sections.js.map +1 -0
- package/dist/server/default-dependencies.d.ts +134 -0
- package/dist/server/default-dependencies.d.ts.map +1 -0
- package/dist/server/default-dependencies.js +176 -0
- package/dist/server/default-dependencies.js.map +1 -0
- package/dist/server/dependencies.d.ts +161 -0
- package/dist/server/dependencies.d.ts.map +1 -0
- package/dist/server/dependencies.js +50 -0
- package/dist/server/dependencies.js.map +1 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/middleware/error-handling.d.ts +52 -0
- package/dist/server/middleware/error-handling.d.ts.map +1 -0
- package/dist/server/middleware/error-handling.js +76 -0
- package/dist/server/middleware/error-handling.js.map +1 -0
- package/dist/server/middleware/index.d.ts +7 -0
- package/dist/server/middleware/index.d.ts.map +1 -0
- package/dist/server/middleware/index.js +7 -0
- package/dist/server/middleware/index.js.map +1 -0
- package/dist/server/middleware/logging.d.ts +29 -0
- package/dist/server/middleware/logging.d.ts.map +1 -0
- package/dist/server/middleware/logging.js +49 -0
- package/dist/server/middleware/logging.js.map +1 -0
- package/dist/server/middleware/session-management.d.ts +38 -0
- package/dist/server/middleware/session-management.d.ts.map +1 -0
- package/dist/server/middleware/session-management.js +66 -0
- package/dist/server/middleware/session-management.js.map +1 -0
- package/dist/server/request-handlers/index.d.ts +5 -0
- package/dist/server/request-handlers/index.d.ts.map +1 -0
- package/dist/server/request-handlers/index.js +5 -0
- package/dist/server/request-handlers/index.js.map +1 -0
- package/dist/server/request-handlers/prompt-handlers.d.ts +13 -0
- package/dist/server/request-handlers/prompt-handlers.d.ts.map +1 -0
- package/dist/server/request-handlers/prompt-handlers.js +80 -0
- package/dist/server/request-handlers/prompt-handlers.js.map +1 -0
- package/dist/server/request-handlers/tool-handlers.d.ts +11 -0
- package/dist/server/request-handlers/tool-handlers.d.ts.map +1 -0
- package/dist/server/request-handlers/tool-handlers.js +85 -0
- package/dist/server/request-handlers/tool-handlers.js.map +1 -0
- package/dist/server/server-factory.d.ts +68 -0
- package/dist/server/server-factory.d.ts.map +1 -0
- package/dist/server/server-factory.js +135 -0
- package/dist/server/server-factory.js.map +1 -0
- package/dist/server/transport/stdio-transport.d.ts +9 -0
- package/dist/server/transport/stdio-transport.d.ts.map +1 -0
- package/dist/server/transport/stdio-transport.js +11 -0
- package/dist/server/transport/stdio-transport.js.map +1 -0
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +7 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/session-store.d.ts +74 -0
- package/dist/session/session-store.d.ts.map +1 -0
- package/dist/session/session-store.js +150 -0
- package/dist/session/session-store.js.map +1 -0
- package/dist/session/types.d.ts +96 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +9 -0
- package/dist/session/types.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.d.ts +12 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.js +306 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.d.ts +6 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.js +205 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.lru.test.d.ts +6 -0
- package/dist/shared/__tests__/addressing-system.lru.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.lru.test.js +159 -0
- package/dist/shared/__tests__/addressing-system.lru.test.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.d.ts +14 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.js +249 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.js.map +1 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.d.ts +9 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.d.ts.map +1 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.js +419 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.js.map +1 -0
- package/dist/shared/__tests__/document-analysis.test.d.ts +8 -0
- package/dist/shared/__tests__/document-analysis.test.d.ts.map +1 -0
- package/dist/shared/__tests__/document-analysis.test.js +904 -0
- package/dist/shared/__tests__/document-analysis.test.js.map +1 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.d.ts +9 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.d.ts.map +1 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.js +317 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.js.map +1 -0
- package/dist/shared/__tests__/link-utils.test.d.ts +5 -0
- package/dist/shared/__tests__/link-utils.test.d.ts.map +1 -0
- package/dist/shared/__tests__/link-utils.test.js +560 -0
- package/dist/shared/__tests__/link-utils.test.js.map +1 -0
- package/dist/shared/__tests__/link-validation.test.d.ts +5 -0
- package/dist/shared/__tests__/link-validation.test.d.ts.map +1 -0
- package/dist/shared/__tests__/link-validation.test.js +473 -0
- package/dist/shared/__tests__/link-validation.test.js.map +1 -0
- package/dist/shared/__tests__/reference-extractor.test.d.ts +8 -0
- package/dist/shared/__tests__/reference-extractor.test.d.ts.map +1 -0
- package/dist/shared/__tests__/reference-extractor.test.js +260 -0
- package/dist/shared/__tests__/reference-extractor.test.js.map +1 -0
- package/dist/shared/__tests__/reference-loader.test.d.ts +8 -0
- package/dist/shared/__tests__/reference-loader.test.d.ts.map +1 -0
- package/dist/shared/__tests__/reference-loader.test.js +622 -0
- package/dist/shared/__tests__/reference-loader.test.js.map +1 -0
- package/dist/shared/__tests__/section-operations.append.test.d.ts +8 -0
- package/dist/shared/__tests__/section-operations.append.test.d.ts.map +1 -0
- package/dist/shared/__tests__/section-operations.append.test.js +150 -0
- package/dist/shared/__tests__/section-operations.append.test.js.map +1 -0
- package/dist/shared/__tests__/section-operations.test.d.ts +7 -0
- package/dist/shared/__tests__/section-operations.test.d.ts.map +1 -0
- package/dist/shared/__tests__/section-operations.test.js +118 -0
- package/dist/shared/__tests__/section-operations.test.js.map +1 -0
- package/dist/shared/__tests__/slug-utils.test.d.ts +5 -0
- package/dist/shared/__tests__/slug-utils.test.d.ts.map +1 -0
- package/dist/shared/__tests__/slug-utils.test.js +542 -0
- package/dist/shared/__tests__/slug-utils.test.js.map +1 -0
- package/dist/shared/__tests__/task-operations.test.d.ts +9 -0
- package/dist/shared/__tests__/task-operations.test.d.ts.map +1 -0
- package/dist/shared/__tests__/task-operations.test.js +257 -0
- package/dist/shared/__tests__/task-operations.test.js.map +1 -0
- package/dist/shared/__tests__/task-validation.test.d.ts +6 -0
- package/dist/shared/__tests__/task-validation.test.d.ts.map +1 -0
- package/dist/shared/__tests__/task-validation.test.js +129 -0
- package/dist/shared/__tests__/task-validation.test.js.map +1 -0
- package/dist/shared/__tests__/task-view-utilities.test.d.ts +5 -0
- package/dist/shared/__tests__/task-view-utilities.test.d.ts.map +1 -0
- package/dist/shared/__tests__/task-view-utilities.test.js +312 -0
- package/dist/shared/__tests__/task-view-utilities.test.js.map +1 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.d.ts +7 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.d.ts.map +1 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.js +169 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.js.map +1 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.d.ts +7 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.d.ts.map +1 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.js +204 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.js.map +1 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.d.ts +8 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.d.ts.map +1 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.js +722 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.js.map +1 -0
- package/dist/shared/addressing-system.d.ts +799 -0
- package/dist/shared/addressing-system.d.ts.map +1 -0
- package/dist/shared/addressing-system.js +1074 -0
- package/dist/shared/addressing-system.js.map +1 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.d.ts +8 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.d.ts.map +1 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.js +601 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.js.map +1 -0
- package/dist/shared/document-analysis/index.d.ts +67 -0
- package/dist/shared/document-analysis/index.d.ts.map +1 -0
- package/dist/shared/document-analysis/index.js +166 -0
- package/dist/shared/document-analysis/index.js.map +1 -0
- package/dist/shared/document-analysis/keyword-utils.d.ts +405 -0
- package/dist/shared/document-analysis/keyword-utils.d.ts.map +1 -0
- package/dist/shared/document-analysis/keyword-utils.js +1147 -0
- package/dist/shared/document-analysis/keyword-utils.js.map +1 -0
- package/dist/shared/document-analysis/reference-validation.d.ts +27 -0
- package/dist/shared/document-analysis/reference-validation.d.ts.map +1 -0
- package/dist/shared/document-analysis/reference-validation.js +173 -0
- package/dist/shared/document-analysis/reference-validation.js.map +1 -0
- package/dist/shared/document-analysis/related-docs.d.ts +27 -0
- package/dist/shared/document-analysis/related-docs.d.ts.map +1 -0
- package/dist/shared/document-analysis/related-docs.js +459 -0
- package/dist/shared/document-analysis/related-docs.js.map +1 -0
- package/dist/shared/document-analysis/types.d.ts +89 -0
- package/dist/shared/document-analysis/types.d.ts.map +1 -0
- package/dist/shared/document-analysis/types.js +41 -0
- package/dist/shared/document-analysis/types.js.map +1 -0
- package/dist/shared/document-analysis.d.ts +15 -0
- package/dist/shared/document-analysis.d.ts.map +1 -0
- package/dist/shared/document-analysis.js +16 -0
- package/dist/shared/document-analysis.js.map +1 -0
- package/dist/shared/document-manager-factory.d.ts +32 -0
- package/dist/shared/document-manager-factory.d.ts.map +1 -0
- package/dist/shared/document-manager-factory.js +75 -0
- package/dist/shared/document-manager-factory.js.map +1 -0
- package/dist/shared/index.d.ts +5 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +7 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/link-analysis.d.ts +84 -0
- package/dist/shared/link-analysis.d.ts.map +1 -0
- package/dist/shared/link-analysis.js +213 -0
- package/dist/shared/link-analysis.js.map +1 -0
- package/dist/shared/link-context.d.ts +23 -0
- package/dist/shared/link-context.d.ts.map +1 -0
- package/dist/shared/link-context.js +172 -0
- package/dist/shared/link-context.js.map +1 -0
- package/dist/shared/link-utils.d.ts +33 -0
- package/dist/shared/link-utils.d.ts.map +1 -0
- package/dist/shared/link-utils.js +301 -0
- package/dist/shared/link-utils.js.map +1 -0
- package/dist/shared/link-validation.d.ts +79 -0
- package/dist/shared/link-validation.d.ts.map +1 -0
- package/dist/shared/link-validation.js +340 -0
- package/dist/shared/link-validation.js.map +1 -0
- package/dist/shared/namespace-analysis.d.ts +10 -0
- package/dist/shared/namespace-analysis.d.ts.map +1 -0
- package/dist/shared/namespace-analysis.js +100 -0
- package/dist/shared/namespace-analysis.js.map +1 -0
- package/dist/shared/namespace-constants.d.ts +69 -0
- package/dist/shared/namespace-constants.d.ts.map +1 -0
- package/dist/shared/namespace-constants.js +97 -0
- package/dist/shared/namespace-constants.js.map +1 -0
- package/dist/shared/path-utilities.d.ts +13 -0
- package/dist/shared/path-utilities.d.ts.map +1 -0
- package/dist/shared/path-utilities.js +39 -0
- package/dist/shared/path-utilities.js.map +1 -0
- package/dist/shared/reference-extractor.d.ts +121 -0
- package/dist/shared/reference-extractor.d.ts.map +1 -0
- package/dist/shared/reference-extractor.js +195 -0
- package/dist/shared/reference-extractor.js.map +1 -0
- package/dist/shared/reference-loader.d.ts +163 -0
- package/dist/shared/reference-loader.d.ts.map +1 -0
- package/dist/shared/reference-loader.js +265 -0
- package/dist/shared/reference-loader.js.map +1 -0
- package/dist/shared/section-operations.d.ts +14 -0
- package/dist/shared/section-operations.d.ts.map +1 -0
- package/dist/shared/section-operations.js +115 -0
- package/dist/shared/section-operations.js.map +1 -0
- package/dist/shared/slug-utils.d.ts +109 -0
- package/dist/shared/slug-utils.d.ts.map +1 -0
- package/dist/shared/slug-utils.js +302 -0
- package/dist/shared/slug-utils.js.map +1 -0
- package/dist/shared/task-operations.d.ts +152 -0
- package/dist/shared/task-operations.d.ts.map +1 -0
- package/dist/shared/task-operations.js +416 -0
- package/dist/shared/task-operations.js.map +1 -0
- package/dist/shared/task-utilities.d.ts +63 -0
- package/dist/shared/task-utilities.d.ts.map +1 -0
- package/dist/shared/task-utilities.js +86 -0
- package/dist/shared/task-utilities.js.map +1 -0
- package/dist/shared/task-validation.d.ts +50 -0
- package/dist/shared/task-validation.d.ts.map +1 -0
- package/dist/shared/task-validation.js +97 -0
- package/dist/shared/task-validation.js.map +1 -0
- package/dist/shared/task-view-utilities.d.ts +109 -0
- package/dist/shared/task-view-utilities.d.ts.map +1 -0
- package/dist/shared/task-view-utilities.js +255 -0
- package/dist/shared/task-view-utilities.js.map +1 -0
- package/dist/shared/utilities.d.ts +14 -0
- package/dist/shared/utilities.d.ts.map +1 -0
- package/dist/shared/utilities.js +23 -0
- package/dist/shared/utilities.js.map +1 -0
- package/dist/shared/utilities.test.d.ts +5 -0
- package/dist/shared/utilities.test.d.ts.map +1 -0
- package/dist/shared/utilities.test.js +422 -0
- package/dist/shared/utilities.test.js.map +1 -0
- package/dist/shared/validation-utils.d.ts +57 -0
- package/dist/shared/validation-utils.d.ts.map +1 -0
- package/dist/shared/validation-utils.js +63 -0
- package/dist/shared/validation-utils.js.map +1 -0
- package/dist/shared/workflow-prompt-utilities.d.ts +64 -0
- package/dist/shared/workflow-prompt-utilities.d.ts.map +1 -0
- package/dist/shared/workflow-prompt-utilities.js +163 -0
- package/dist/shared/workflow-prompt-utilities.js.map +1 -0
- package/dist/slug.d.ts +9 -0
- package/dist/slug.d.ts.map +1 -0
- package/dist/slug.js +40 -0
- package/dist/slug.js.map +1 -0
- package/dist/template-loader.d.ts +6 -0
- package/dist/template-loader.d.ts.map +1 -0
- package/dist/template-loader.js +8 -0
- package/dist/template-loader.js.map +1 -0
- package/dist/tools/__tests__/create-document-self-reference.test.d.ts +2 -0
- package/dist/tools/__tests__/create-document-self-reference.test.d.ts.map +1 -0
- package/dist/tools/__tests__/create-document-self-reference.test.js +124 -0
- package/dist/tools/__tests__/create-document-self-reference.test.js.map +1 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.d.ts +16 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.d.ts.map +1 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.js +655 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.js.map +1 -0
- package/dist/tools/__tests__/create-document.test.d.ts +2 -0
- package/dist/tools/__tests__/create-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/create-document.test.js +255 -0
- package/dist/tools/__tests__/create-document.test.js.map +1 -0
- package/dist/tools/__tests__/delete-document.test.d.ts +7 -0
- package/dist/tools/__tests__/delete-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/delete-document.test.js +311 -0
- package/dist/tools/__tests__/delete-document.test.js.map +1 -0
- package/dist/tools/__tests__/edit-document.test.d.ts +2 -0
- package/dist/tools/__tests__/edit-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/edit-document.test.js +644 -0
- package/dist/tools/__tests__/edit-document.test.js.map +1 -0
- package/dist/tools/__tests__/error-scenarios.test.d.ts +5 -0
- package/dist/tools/__tests__/error-scenarios.test.d.ts.map +1 -0
- package/dist/tools/__tests__/error-scenarios.test.js +105 -0
- package/dist/tools/__tests__/error-scenarios.test.js.map +1 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.d.ts +99 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.d.ts.map +1 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.js +457 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.js.map +1 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.d.ts +103 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.d.ts.map +1 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.js +247 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.js.map +1 -0
- package/dist/tools/__tests__/move-document.test.d.ts +12 -0
- package/dist/tools/__tests__/move-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/move-document.test.js +214 -0
- package/dist/tools/__tests__/move-document.test.js.map +1 -0
- package/dist/tools/__tests__/move.test.d.ts +13 -0
- package/dist/tools/__tests__/move.test.d.ts.map +1 -0
- package/dist/tools/__tests__/move.test.js +939 -0
- package/dist/tools/__tests__/move.test.js.map +1 -0
- package/dist/tools/__tests__/section.integration.improved.test.d.ts +5 -0
- package/dist/tools/__tests__/section.integration.improved.test.d.ts.map +1 -0
- package/dist/tools/__tests__/section.integration.improved.test.js +199 -0
- package/dist/tools/__tests__/section.integration.improved.test.js.map +1 -0
- package/dist/tools/__tests__/section.integration.test.d.ts +5 -0
- package/dist/tools/__tests__/section.integration.test.d.ts.map +1 -0
- package/dist/tools/__tests__/section.integration.test.js +637 -0
- package/dist/tools/__tests__/section.integration.test.js.map +1 -0
- package/dist/tools/__tests__/setup/test-environment.d.ts +111 -0
- package/dist/tools/__tests__/setup/test-environment.d.ts.map +1 -0
- package/dist/tools/__tests__/setup/test-environment.js +322 -0
- package/dist/tools/__tests__/setup/test-environment.js.map +1 -0
- package/dist/tools/__tests__/suggestion-generator.test.d.ts +8 -0
- package/dist/tools/__tests__/suggestion-generator.test.d.ts.map +1 -0
- package/dist/tools/__tests__/suggestion-generator.test.js +508 -0
- package/dist/tools/__tests__/suggestion-generator.test.js.map +1 -0
- package/dist/tools/__tests__/task-consistency.test.d.ts +11 -0
- package/dist/tools/__tests__/task-consistency.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task-consistency.test.js +93 -0
- package/dist/tools/__tests__/task-consistency.test.js.map +1 -0
- package/dist/tools/__tests__/task-status-parsing.test.d.ts +15 -0
- package/dist/tools/__tests__/task-status-parsing.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task-status-parsing.test.js +126 -0
- package/dist/tools/__tests__/task-status-parsing.test.js.map +1 -0
- package/dist/tools/__tests__/view-section-boundary.test.d.ts +2 -0
- package/dist/tools/__tests__/view-section-boundary.test.d.ts.map +1 -0
- package/dist/tools/__tests__/view-section-boundary.test.js +132 -0
- package/dist/tools/__tests__/view-section-boundary.test.js.map +1 -0
- package/dist/tools/__tests__/write-operations-integration.test.d.ts +8 -0
- package/dist/tools/__tests__/write-operations-integration.test.d.ts.map +1 -0
- package/dist/tools/__tests__/write-operations-integration.test.js +136 -0
- package/dist/tools/__tests__/write-operations-integration.test.js.map +1 -0
- package/dist/tools/browse/content-analyzer.d.ts +27 -0
- package/dist/tools/browse/content-analyzer.d.ts.map +1 -0
- package/dist/tools/browse/content-analyzer.js +150 -0
- package/dist/tools/browse/content-analyzer.js.map +1 -0
- package/dist/tools/browse/dependency-analyzer.d.ts +63 -0
- package/dist/tools/browse/dependency-analyzer.d.ts.map +1 -0
- package/dist/tools/browse/dependency-analyzer.js +261 -0
- package/dist/tools/browse/dependency-analyzer.js.map +1 -0
- package/dist/tools/browse/folder-navigator.d.ts +35 -0
- package/dist/tools/browse/folder-navigator.d.ts.map +1 -0
- package/dist/tools/browse/folder-navigator.js +154 -0
- package/dist/tools/browse/folder-navigator.js.map +1 -0
- package/dist/tools/browse/index.d.ts +10 -0
- package/dist/tools/browse/index.d.ts.map +1 -0
- package/dist/tools/browse/index.js +14 -0
- package/dist/tools/browse/index.js.map +1 -0
- package/dist/tools/browse/relationship-classifier.d.ts +9 -0
- package/dist/tools/browse/relationship-classifier.d.ts.map +1 -0
- package/dist/tools/browse/relationship-classifier.js +38 -0
- package/dist/tools/browse/relationship-classifier.js.map +1 -0
- package/dist/tools/browse/search-engine.d.ts +69 -0
- package/dist/tools/browse/search-engine.d.ts.map +1 -0
- package/dist/tools/browse/search-engine.js +197 -0
- package/dist/tools/browse/search-engine.js.map +1 -0
- package/dist/tools/create/__tests__/file-creator.test.d.ts +6 -0
- package/dist/tools/create/__tests__/file-creator.test.d.ts.map +1 -0
- package/dist/tools/create/__tests__/file-creator.test.js +138 -0
- package/dist/tools/create/__tests__/file-creator.test.js.map +1 -0
- package/dist/tools/create/__tests__/template-processor.test.d.ts +6 -0
- package/dist/tools/create/__tests__/template-processor.test.d.ts.map +1 -0
- package/dist/tools/create/__tests__/template-processor.test.js +130 -0
- package/dist/tools/create/__tests__/template-processor.test.js.map +1 -0
- package/dist/tools/create/file-creator.d.ts +35 -0
- package/dist/tools/create/file-creator.d.ts.map +1 -0
- package/dist/tools/create/file-creator.js +103 -0
- package/dist/tools/create/file-creator.js.map +1 -0
- package/dist/tools/create/index.d.ts +6 -0
- package/dist/tools/create/index.d.ts.map +1 -0
- package/dist/tools/create/index.js +7 -0
- package/dist/tools/create/index.js.map +1 -0
- package/dist/tools/create/pipeline.d.ts +39 -0
- package/dist/tools/create/pipeline.d.ts.map +1 -0
- package/dist/tools/create/pipeline.js +112 -0
- package/dist/tools/create/pipeline.js.map +1 -0
- package/dist/tools/create/suggestion-generator.d.ts +47 -0
- package/dist/tools/create/suggestion-generator.d.ts.map +1 -0
- package/dist/tools/create/suggestion-generator.js +51 -0
- package/dist/tools/create/suggestion-generator.js.map +1 -0
- package/dist/tools/create/template-processor.d.ts +27 -0
- package/dist/tools/create/template-processor.d.ts.map +1 -0
- package/dist/tools/create/template-processor.js +74 -0
- package/dist/tools/create/template-processor.js.map +1 -0
- package/dist/tools/create/validation-processor.d.ts +48 -0
- package/dist/tools/create/validation-processor.d.ts.map +1 -0
- package/dist/tools/create/validation-processor.js +107 -0
- package/dist/tools/create/validation-processor.js.map +1 -0
- package/dist/tools/executor.d.ts +19 -0
- package/dist/tools/executor.d.ts.map +1 -0
- package/dist/tools/executor.js +53 -0
- package/dist/tools/executor.js.map +1 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.js +319 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.js +440 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.d.ts +14 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.js +851 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.d.ts +6 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.js +157 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task.test.d.ts +14 -0
- package/dist/tools/implementations/__tests__/complete-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task.test.js +867 -0
- package/dist/tools/implementations/__tests__/complete-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/continue-task.test.d.ts +11 -0
- package/dist/tools/implementations/__tests__/continue-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/continue-task.test.js +845 -0
- package/dist/tools/implementations/__tests__/continue-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.js +495 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/get-guide.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/get-guide.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/get-guide.test.js +242 -0
- package/dist/tools/implementations/__tests__/get-guide.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.js +232 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/search-documents.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/search-documents.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/search-documents.test.js +336 -0
- package/dist/tools/implementations/__tests__/search-documents.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.js +177 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.d.ts +11 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.js +846 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/start-task.test.d.ts +11 -0
- package/dist/tools/implementations/__tests__/start-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/start-task.test.js +828 -0
- package/dist/tools/implementations/__tests__/start-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.js +199 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.js +720 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.js +200 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/task.test.js +578 -0
- package/dist/tools/implementations/__tests__/task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.d.ts +13 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.js +1404 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.js +235 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.d.ts +9 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.js +160 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-task.test.d.ts +12 -0
- package/dist/tools/implementations/__tests__/view-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-task.test.js +1158 -0
- package/dist/tools/implementations/__tests__/view-task.test.js.map +1 -0
- package/dist/tools/implementations/browse-documents.d.ts +36 -0
- package/dist/tools/implementations/browse-documents.d.ts.map +1 -0
- package/dist/tools/implementations/browse-documents.js +123 -0
- package/dist/tools/implementations/browse-documents.js.map +1 -0
- package/dist/tools/implementations/complete-coordinator-task.d.ts +53 -0
- package/dist/tools/implementations/complete-coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/complete-coordinator-task.js +159 -0
- package/dist/tools/implementations/complete-coordinator-task.js.map +1 -0
- package/dist/tools/implementations/complete-subagent-task.d.ts +47 -0
- package/dist/tools/implementations/complete-subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/complete-subagent-task.js +141 -0
- package/dist/tools/implementations/complete-subagent-task.js.map +1 -0
- package/dist/tools/implementations/complete-task.d.ts +32 -0
- package/dist/tools/implementations/complete-task.d.ts.map +1 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.js +363 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/complete-task.js +122 -0
- package/dist/tools/implementations/complete-task.js.map +1 -0
- package/dist/tools/implementations/continue-task.d.ts +48 -0
- package/dist/tools/implementations/continue-task.d.ts.map +1 -0
- package/dist/tools/implementations/continue-task.js +167 -0
- package/dist/tools/implementations/continue-task.js.map +1 -0
- package/dist/tools/implementations/coordinator-task.d.ts +72 -0
- package/dist/tools/implementations/coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/coordinator-task.js +169 -0
- package/dist/tools/implementations/coordinator-task.js.map +1 -0
- package/dist/tools/implementations/create-document.d.ts +12 -0
- package/dist/tools/implementations/create-document.d.ts.map +1 -0
- package/dist/tools/implementations/create-document.js +15 -0
- package/dist/tools/implementations/create-document.js.map +1 -0
- package/dist/tools/implementations/delete-document.d.ts +16 -0
- package/dist/tools/implementations/delete-document.d.ts.map +1 -0
- package/dist/tools/implementations/delete-document.js +70 -0
- package/dist/tools/implementations/delete-document.js.map +1 -0
- package/dist/tools/implementations/edit-document.d.ts +8 -0
- package/dist/tools/implementations/edit-document.d.ts.map +1 -0
- package/dist/tools/implementations/edit-document.js +118 -0
- package/dist/tools/implementations/edit-document.js.map +1 -0
- package/dist/tools/implementations/get-guide.d.ts +13 -0
- package/dist/tools/implementations/get-guide.d.ts.map +1 -0
- package/dist/tools/implementations/get-guide.js +64 -0
- package/dist/tools/implementations/get-guide.js.map +1 -0
- package/dist/tools/implementations/get-workflow.d.ts +12 -0
- package/dist/tools/implementations/get-workflow.d.ts.map +1 -0
- package/dist/tools/implementations/get-workflow.js +71 -0
- package/dist/tools/implementations/get-workflow.js.map +1 -0
- package/dist/tools/implementations/index.d.ts +24 -0
- package/dist/tools/implementations/index.d.ts.map +1 -0
- package/dist/tools/implementations/index.js +24 -0
- package/dist/tools/implementations/index.js.map +1 -0
- package/dist/tools/implementations/manage-document.d.ts +8 -0
- package/dist/tools/implementations/manage-document.d.ts.map +1 -0
- package/dist/tools/implementations/manage-document.js +180 -0
- package/dist/tools/implementations/manage-document.js.map +1 -0
- package/dist/tools/implementations/move-document.d.ts +12 -0
- package/dist/tools/implementations/move-document.d.ts.map +1 -0
- package/dist/tools/implementations/move-document.js +72 -0
- package/dist/tools/implementations/move-document.js.map +1 -0
- package/dist/tools/implementations/move.d.ts +24 -0
- package/dist/tools/implementations/move.d.ts.map +1 -0
- package/dist/tools/implementations/move.js +167 -0
- package/dist/tools/implementations/move.js.map +1 -0
- package/dist/tools/implementations/search-documents.d.ts +39 -0
- package/dist/tools/implementations/search-documents.d.ts.map +1 -0
- package/dist/tools/implementations/search-documents.js +246 -0
- package/dist/tools/implementations/search-documents.js.map +1 -0
- package/dist/tools/implementations/section.d.ts +42 -0
- package/dist/tools/implementations/section.d.ts.map +1 -0
- package/dist/tools/implementations/section.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/section.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/section.hierarchical.test.js +299 -0
- package/dist/tools/implementations/section.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/section.js +244 -0
- package/dist/tools/implementations/section.js.map +1 -0
- package/dist/tools/implementations/section.test.d.ts +5 -0
- package/dist/tools/implementations/section.test.d.ts.map +1 -0
- package/dist/tools/implementations/section.test.js +371 -0
- package/dist/tools/implementations/section.test.js.map +1 -0
- package/dist/tools/implementations/start-coordinator-task.d.ts +44 -0
- package/dist/tools/implementations/start-coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/start-coordinator-task.js +125 -0
- package/dist/tools/implementations/start-coordinator-task.js.map +1 -0
- package/dist/tools/implementations/start-subagent-task.d.ts +53 -0
- package/dist/tools/implementations/start-subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/start-subagent-task.js +179 -0
- package/dist/tools/implementations/start-subagent-task.js.map +1 -0
- package/dist/tools/implementations/start-task.d.ts +48 -0
- package/dist/tools/implementations/start-task.d.ts.map +1 -0
- package/dist/tools/implementations/start-task.js +216 -0
- package/dist/tools/implementations/start-task.js.map +1 -0
- package/dist/tools/implementations/subagent-task.d.ts +98 -0
- package/dist/tools/implementations/subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/subagent-task.js +277 -0
- package/dist/tools/implementations/subagent-task.js.map +1 -0
- package/dist/tools/implementations/task.d.ts +97 -0
- package/dist/tools/implementations/task.d.ts.map +1 -0
- package/dist/tools/implementations/task.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/task.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/task.hierarchical.test.js +333 -0
- package/dist/tools/implementations/task.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/task.js +235 -0
- package/dist/tools/implementations/task.js.map +1 -0
- package/dist/tools/implementations/view-coordinator-task.d.ts +61 -0
- package/dist/tools/implementations/view-coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/view-coordinator-task.js +295 -0
- package/dist/tools/implementations/view-coordinator-task.js.map +1 -0
- package/dist/tools/implementations/view-document.d.ts +84 -0
- package/dist/tools/implementations/view-document.d.ts.map +1 -0
- package/dist/tools/implementations/view-document.js +287 -0
- package/dist/tools/implementations/view-document.js.map +1 -0
- package/dist/tools/implementations/view-section.d.ts +28 -0
- package/dist/tools/implementations/view-section.d.ts.map +1 -0
- package/dist/tools/implementations/view-section.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/view-section.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/view-section.hierarchical.test.js +318 -0
- package/dist/tools/implementations/view-section.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/view-section.js +167 -0
- package/dist/tools/implementations/view-section.js.map +1 -0
- package/dist/tools/implementations/view-subagent-task.d.ts +46 -0
- package/dist/tools/implementations/view-subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/view-subagent-task.js +283 -0
- package/dist/tools/implementations/view-subagent-task.js.map +1 -0
- package/dist/tools/implementations/view-task.d.ts +43 -0
- package/dist/tools/implementations/view-task.d.ts.map +1 -0
- package/dist/tools/implementations/view-task.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/view-task.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/view-task.hierarchical.test.js +420 -0
- package/dist/tools/implementations/view-task.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/view-task.js +280 -0
- package/dist/tools/implementations/view-task.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +10 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +132 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.d.ts +8 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.d.ts.map +1 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.js +216 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.js.map +1 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.d.ts +8 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.d.ts.map +1 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.js +229 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.js.map +1 -0
- package/dist/tools/schemas/browse-documents-schemas.d.ts +47 -0
- package/dist/tools/schemas/browse-documents-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/browse-documents-schemas.js +48 -0
- package/dist/tools/schemas/browse-documents-schemas.js.map +1 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.d.ts +41 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.js +42 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.d.ts +38 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.js +41 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/complete-task-schemas.d.ts +33 -0
- package/dist/tools/schemas/complete-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/complete-task-schemas.js +36 -0
- package/dist/tools/schemas/complete-task-schemas.js.map +1 -0
- package/dist/tools/schemas/continue-task-schemas.d.ts +27 -0
- package/dist/tools/schemas/continue-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/continue-task-schemas.js +28 -0
- package/dist/tools/schemas/continue-task-schemas.js.map +1 -0
- package/dist/tools/schemas/coordinator-task-schemas.d.ts +87 -0
- package/dist/tools/schemas/coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/coordinator-task-schemas.js +80 -0
- package/dist/tools/schemas/coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/create-document-schemas.d.ts +61 -0
- package/dist/tools/schemas/create-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/create-document-schemas.js +143 -0
- package/dist/tools/schemas/create-document-schemas.js.map +1 -0
- package/dist/tools/schemas/delete-document-schemas.d.ts +24 -0
- package/dist/tools/schemas/delete-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/delete-document-schemas.js +25 -0
- package/dist/tools/schemas/delete-document-schemas.js.map +1 -0
- package/dist/tools/schemas/edit-document-schemas.d.ts +27 -0
- package/dist/tools/schemas/edit-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/edit-document-schemas.js +28 -0
- package/dist/tools/schemas/edit-document-schemas.js.map +1 -0
- package/dist/tools/schemas/get-guide-schemas.d.ts +35 -0
- package/dist/tools/schemas/get-guide-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/get-guide-schemas.js +66 -0
- package/dist/tools/schemas/get-guide-schemas.js.map +1 -0
- package/dist/tools/schemas/get-workflow-schemas.d.ts +35 -0
- package/dist/tools/schemas/get-workflow-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/get-workflow-schemas.js +67 -0
- package/dist/tools/schemas/get-workflow-schemas.js.map +1 -0
- package/dist/tools/schemas/manage-document-schemas.d.ts +59 -0
- package/dist/tools/schemas/manage-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/manage-document-schemas.js +83 -0
- package/dist/tools/schemas/manage-document-schemas.js.map +1 -0
- package/dist/tools/schemas/move-document-schemas.d.ts +25 -0
- package/dist/tools/schemas/move-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/move-document-schemas.js +26 -0
- package/dist/tools/schemas/move-document-schemas.js.map +1 -0
- package/dist/tools/schemas/move-schemas.d.ts +43 -0
- package/dist/tools/schemas/move-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/move-schemas.js +43 -0
- package/dist/tools/schemas/move-schemas.js.map +1 -0
- package/dist/tools/schemas/search-documents-schemas.d.ts +77 -0
- package/dist/tools/schemas/search-documents-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/search-documents-schemas.js +78 -0
- package/dist/tools/schemas/search-documents-schemas.js.map +1 -0
- package/dist/tools/schemas/section-schemas.d.ts +361 -0
- package/dist/tools/schemas/section-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/section-schemas.js +182 -0
- package/dist/tools/schemas/section-schemas.js.map +1 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.d.ts +30 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.js +31 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/start-subagent-task-schemas.d.ts +29 -0
- package/dist/tools/schemas/start-subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/start-subagent-task-schemas.js +40 -0
- package/dist/tools/schemas/start-subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/start-task-schemas.d.ts +23 -0
- package/dist/tools/schemas/start-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/start-task-schemas.js +39 -0
- package/dist/tools/schemas/start-task-schemas.js.map +1 -0
- package/dist/tools/schemas/subagent-task-schemas.d.ts +93 -0
- package/dist/tools/schemas/subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/subagent-task-schemas.js +81 -0
- package/dist/tools/schemas/subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/task-schemas.d.ts +88 -0
- package/dist/tools/schemas/task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/task-schemas.js +80 -0
- package/dist/tools/schemas/task-schemas.js.map +1 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.d.ts +27 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.js +46 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/view-document-schemas.d.ts +152 -0
- package/dist/tools/schemas/view-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-document-schemas.js +70 -0
- package/dist/tools/schemas/view-document-schemas.js.map +1 -0
- package/dist/tools/schemas/view-section-schemas.d.ts +31 -0
- package/dist/tools/schemas/view-section-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-section-schemas.js +56 -0
- package/dist/tools/schemas/view-section-schemas.js.map +1 -0
- package/dist/tools/schemas/view-subagent-task-schemas.d.ts +31 -0
- package/dist/tools/schemas/view-subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-subagent-task-schemas.js +65 -0
- package/dist/tools/schemas/view-subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/view-task-schemas.d.ts +31 -0
- package/dist/tools/schemas/view-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-task-schemas.js +62 -0
- package/dist/tools/schemas/view-task-schemas.js.map +1 -0
- package/dist/tools/types.d.ts +98 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +9 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools-manager.d.ts +8 -0
- package/dist/tools-manager.d.ts.map +1 -0
- package/dist/tools-manager.js +9 -0
- package/dist/tools-manager.js.map +1 -0
- package/dist/types/core.d.ts +71 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +5 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/linking.d.ts +97 -0
- package/dist/types/linking.d.ts.map +1 -0
- package/dist/types/linking.js +5 -0
- package/dist/types/linking.js.map +1 -0
- package/dist/utils/__tests__/path-handler.archive.test.d.ts +8 -0
- package/dist/utils/__tests__/path-handler.archive.test.d.ts.map +1 -0
- package/dist/utils/__tests__/path-handler.archive.test.js +163 -0
- package/dist/utils/__tests__/path-handler.archive.test.js.map +1 -0
- package/dist/utils/error-formatter.d.ts +32 -0
- package/dist/utils/error-formatter.d.ts.map +1 -0
- package/dist/utils/error-formatter.js +79 -0
- package/dist/utils/error-formatter.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +154 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path-handler.d.ts +52 -0
- package/dist/utils/path-handler.d.ts.map +1 -0
- package/dist/utils/path-handler.js +129 -0
- package/dist/utils/path-handler.js.map +1 -0
- package/dist/utils/security-audit-logger.d.ts +64 -0
- package/dist/utils/security-audit-logger.d.ts.map +1 -0
- package/dist/utils/security-audit-logger.js +56 -0
- package/dist/utils/security-audit-logger.js.map +1 -0
- package/dist/utils/virtual-path-resolver.d.ts +126 -0
- package/dist/utils/virtual-path-resolver.d.ts.map +1 -0
- package/dist/utils/virtual-path-resolver.js +171 -0
- package/dist/utils/virtual-path-resolver.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,1147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced keyword extraction and weighting utilities for document analysis
|
|
3
|
+
*
|
|
4
|
+
* This module provides sophisticated keyword extraction with weighted scoring
|
|
5
|
+
* from multiple content sources including frontmatter, titles, headings,
|
|
6
|
+
* emphasized text, and content body. Integrates with the existing fingerprint
|
|
7
|
+
* system while providing enhanced relevance scoring capabilities.
|
|
8
|
+
*
|
|
9
|
+
* Note: Some exports may appear unused by dead code detection but are part
|
|
10
|
+
* of the Stage 4+ enhanced discovery system implementation. Functions like
|
|
11
|
+
* extractKeywordsWithFingerprint and DEFAULT_KEYWORD_WEIGHTS are intended
|
|
12
|
+
* for future stages of the document discovery improvement plan.
|
|
13
|
+
*/
|
|
14
|
+
import { getGlobalLogger } from '../../utils/logger.js';
|
|
15
|
+
const logger = getGlobalLogger();
|
|
16
|
+
/**
|
|
17
|
+
* Default keyword weighting configuration
|
|
18
|
+
*
|
|
19
|
+
* Balanced weighting that prioritizes explicit frontmatter keywords
|
|
20
|
+
* while giving appropriate weight to structural elements.
|
|
21
|
+
*/
|
|
22
|
+
export const DEFAULT_KEYWORD_WEIGHTS = {
|
|
23
|
+
frontmatter: 5.0, // Authoritative - explicit user-defined keywords
|
|
24
|
+
title: 3.0, // Highest structural weight
|
|
25
|
+
headings: 2.0, // High structural weight
|
|
26
|
+
emphasis: 1.5, // Medium weight for highlighted content
|
|
27
|
+
content: 1.0 // Base weight for general content
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Extract keywords with enhanced weighting from document content
|
|
31
|
+
*
|
|
32
|
+
* Performs comprehensive keyword extraction from multiple content sources
|
|
33
|
+
* with appropriate weighting. Treats explicit frontmatter keywords as
|
|
34
|
+
* authoritative when present, falls back to content analysis otherwise.
|
|
35
|
+
*
|
|
36
|
+
* @param title - Document title
|
|
37
|
+
* @param content - Full document content (including frontmatter)
|
|
38
|
+
* @param weights - Custom weighting configuration (optional)
|
|
39
|
+
*
|
|
40
|
+
* @returns Enhanced keyword extraction result with weighted keywords
|
|
41
|
+
*
|
|
42
|
+
* @example Basic usage
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const result = extractWeightedKeywords(
|
|
45
|
+
* 'User Authentication API',
|
|
46
|
+
* '---\nkeywords: [auth, api, security]\n---\n# Overview\nThis **important** API handles user login...'
|
|
47
|
+
* );
|
|
48
|
+
* console.log(result.hasExplicitKeywords); // true
|
|
49
|
+
* console.log(result.weightedKeywords); // [{keyword: 'auth', weight: 5.0, sources: ['frontmatter']}, ...]
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example Custom weighting
|
|
53
|
+
* ```typescript
|
|
54
|
+
* const customWeights = { ...DEFAULT_KEYWORD_WEIGHTS, title: 4.0 };
|
|
55
|
+
* const result = extractWeightedKeywords(title, content, customWeights);
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export function extractWeightedKeywords(title, content, weights = DEFAULT_KEYWORD_WEIGHTS) {
|
|
59
|
+
try {
|
|
60
|
+
// Input validation with graceful handling
|
|
61
|
+
const safeTitle = title ?? '';
|
|
62
|
+
const safeContent = content ?? '';
|
|
63
|
+
if (safeTitle.trim().length === 0 && safeContent.trim().length === 0) {
|
|
64
|
+
logger.warn('Empty title and content provided for keyword extraction');
|
|
65
|
+
return {
|
|
66
|
+
weightedKeywords: [],
|
|
67
|
+
keywords: [],
|
|
68
|
+
hasExplicitKeywords: false,
|
|
69
|
+
totalWeight: 0
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Parse content sources
|
|
73
|
+
const sources = parseContentSources(safeTitle, safeContent);
|
|
74
|
+
// Check for explicit frontmatter keywords first
|
|
75
|
+
const explicitKeywords = extractExplicitKeywords(sources.frontmatter);
|
|
76
|
+
if (explicitKeywords.length > 0) {
|
|
77
|
+
logger.debug('Found explicit frontmatter keywords', { keywords: explicitKeywords });
|
|
78
|
+
// Use explicit keywords with highest weight
|
|
79
|
+
const weightedKeywords = explicitKeywords.map(keyword => ({
|
|
80
|
+
keyword: keyword.toLowerCase().trim(),
|
|
81
|
+
weight: weights.frontmatter,
|
|
82
|
+
sources: ['frontmatter']
|
|
83
|
+
}));
|
|
84
|
+
return {
|
|
85
|
+
weightedKeywords,
|
|
86
|
+
keywords: explicitKeywords.map(k => k.toLowerCase().trim()),
|
|
87
|
+
hasExplicitKeywords: true,
|
|
88
|
+
totalWeight: explicitKeywords.length * weights.frontmatter
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
// Fall back to content analysis
|
|
92
|
+
const weightedKeywords = extractFromContentSources(sources, weights);
|
|
93
|
+
const keywords = weightedKeywords.map(wk => wk.keyword);
|
|
94
|
+
const totalWeight = weightedKeywords.reduce((sum, wk) => sum + wk.weight, 0);
|
|
95
|
+
logger.debug('Extracted keywords from content analysis', {
|
|
96
|
+
keywordCount: keywords.length,
|
|
97
|
+
totalWeight: Math.round(totalWeight * 100) / 100,
|
|
98
|
+
hasExplicitKeywords: false
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
weightedKeywords,
|
|
102
|
+
keywords,
|
|
103
|
+
hasExplicitKeywords: false,
|
|
104
|
+
totalWeight
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
logger.warn('Enhanced keyword extraction failed, returning empty result', { error });
|
|
109
|
+
return {
|
|
110
|
+
weightedKeywords: [],
|
|
111
|
+
keywords: [],
|
|
112
|
+
hasExplicitKeywords: false,
|
|
113
|
+
totalWeight: 0
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Default feature flags - conservative defaults
|
|
119
|
+
*/
|
|
120
|
+
export const DEFAULT_SCORING_FEATURES = {
|
|
121
|
+
enableLinkGraphBoost: false // Start disabled until proven stable
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Enhanced keyword extraction with fingerprint integration
|
|
125
|
+
*
|
|
126
|
+
* Provides enhanced keyword extraction that integrates with existing
|
|
127
|
+
* fingerprint data while offering enhanced weighting when full content
|
|
128
|
+
* analysis is available.
|
|
129
|
+
*
|
|
130
|
+
* @param title - Document title
|
|
131
|
+
* @param content - Full document content (optional for fingerprint-only mode)
|
|
132
|
+
* @param fingerprint - Existing fingerprint data (optional)
|
|
133
|
+
* @param weights - Custom weighting configuration (optional)
|
|
134
|
+
*
|
|
135
|
+
* @returns Enhanced keyword extraction result
|
|
136
|
+
*
|
|
137
|
+
* @example Fingerprint integration
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const result = extractKeywordsWithFingerprint(
|
|
140
|
+
* 'API Documentation',
|
|
141
|
+
* null, // No content available
|
|
142
|
+
* { keywords: ['api', 'docs'], namespace: 'api', lastModified: new Date(), contentHash: 'abc123' }
|
|
143
|
+
* );
|
|
144
|
+
* // Falls back to fingerprint keywords with base weight
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export function extractKeywordsWithFingerprint(title, content, fingerprint, weights = DEFAULT_KEYWORD_WEIGHTS) {
|
|
148
|
+
try {
|
|
149
|
+
// If we have content, prefer enhanced extraction
|
|
150
|
+
if (content != null && content.trim().length > 0) {
|
|
151
|
+
return extractWeightedKeywords(title, content, weights);
|
|
152
|
+
}
|
|
153
|
+
// Fall back to fingerprint data if available
|
|
154
|
+
if (fingerprint != null && fingerprint.keywords.length > 0) {
|
|
155
|
+
logger.debug('Using fingerprint keywords as fallback', {
|
|
156
|
+
keywordCount: fingerprint.keywords.length
|
|
157
|
+
});
|
|
158
|
+
const weightedKeywords = fingerprint.keywords.map(keyword => ({
|
|
159
|
+
keyword: keyword.toLowerCase().trim(),
|
|
160
|
+
weight: weights.content, // Use base weight for fingerprint keywords
|
|
161
|
+
sources: ['fingerprint']
|
|
162
|
+
}));
|
|
163
|
+
return {
|
|
164
|
+
weightedKeywords,
|
|
165
|
+
keywords: fingerprint.keywords.map(k => k.toLowerCase().trim()),
|
|
166
|
+
hasExplicitKeywords: false,
|
|
167
|
+
totalWeight: fingerprint.keywords.length * weights.content
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
// Final fallback to title-only extraction
|
|
171
|
+
logger.debug('Falling back to title-only keyword extraction');
|
|
172
|
+
return extractWeightedKeywords(title, '', weights);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
logger.warn('Fingerprint-integrated keyword extraction failed', { error });
|
|
176
|
+
return {
|
|
177
|
+
weightedKeywords: [],
|
|
178
|
+
keywords: [],
|
|
179
|
+
hasExplicitKeywords: false,
|
|
180
|
+
totalWeight: 0
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Calculate enhanced multi-factor relevance score with detailed breakdown
|
|
186
|
+
*
|
|
187
|
+
* Implements the complete multi-factor relevance algorithm with:
|
|
188
|
+
* - Keyword overlap (primary factor)
|
|
189
|
+
* - Title similarity boost
|
|
190
|
+
* - Namespace affinity boost
|
|
191
|
+
* - Recency boost
|
|
192
|
+
* - Link graph boost (feature-gated)
|
|
193
|
+
*
|
|
194
|
+
* Final relevance = sum of all factors, capped at 1.0 maximum
|
|
195
|
+
*
|
|
196
|
+
* @param sourceKeywords - Weighted keywords from source document
|
|
197
|
+
* @param sourceTitle - Source document title
|
|
198
|
+
* @param sourceNamespace - Source document namespace
|
|
199
|
+
* @param sourceContent - Source document content (for link graph analysis)
|
|
200
|
+
* @param targetTitle - Target document title
|
|
201
|
+
* @param targetContent - Target document content
|
|
202
|
+
* @param targetNamespace - Target document namespace
|
|
203
|
+
* @param targetLastModified - Target document last modified date
|
|
204
|
+
* @param targetPath - Target document path (for link graph analysis)
|
|
205
|
+
* @param targetFingerprint - Target document fingerprint (optional)
|
|
206
|
+
* @param features - Feature flags controlling optional factors
|
|
207
|
+
*
|
|
208
|
+
* @returns Multi-factor relevance score between 0 and 1
|
|
209
|
+
*
|
|
210
|
+
* @example Multi-factor relevance calculation
|
|
211
|
+
* ```typescript
|
|
212
|
+
* const sourceKeywords = [
|
|
213
|
+
* { keyword: 'api', weight: 3.0, sources: ['title'] },
|
|
214
|
+
* { keyword: 'auth', weight: 5.0, sources: ['frontmatter'] }
|
|
215
|
+
* ];
|
|
216
|
+
* const relevance = calculateWeightedRelevance(
|
|
217
|
+
* sourceKeywords,
|
|
218
|
+
* 'User Authentication',
|
|
219
|
+
* 'api/guides',
|
|
220
|
+
* 'This covers auth @/api/specs/auth.md',
|
|
221
|
+
* 'Authentication API',
|
|
222
|
+
* 'API for user authentication...',
|
|
223
|
+
* 'api/specs',
|
|
224
|
+
* new Date(),
|
|
225
|
+
* '/api/specs/auth.md'
|
|
226
|
+
* );
|
|
227
|
+
* // Returns combined score: keyword overlap + title similarity + namespace affinity + recency + link boost
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
export function calculateWeightedRelevance(sourceKeywords, sourceTitle, sourceNamespace, sourceContent, targetTitle, targetContent, targetNamespace, targetLastModified, targetPath, targetFingerprint, features = DEFAULT_SCORING_FEATURES) {
|
|
231
|
+
try {
|
|
232
|
+
if (sourceKeywords.length === 0) {
|
|
233
|
+
return 0;
|
|
234
|
+
}
|
|
235
|
+
// Calculate individual relevance factors
|
|
236
|
+
const factors = {
|
|
237
|
+
keywordOverlap: 0,
|
|
238
|
+
titleSimilarity: 0,
|
|
239
|
+
namespaceAffinity: 0,
|
|
240
|
+
recencyBoost: 0,
|
|
241
|
+
linkGraphBoost: 0
|
|
242
|
+
};
|
|
243
|
+
// 1. Keyword overlap (primary factor, 0.0-1.0)
|
|
244
|
+
factors.keywordOverlap = calculateKeywordOverlapScore(sourceKeywords, targetTitle, targetContent, targetFingerprint);
|
|
245
|
+
// 2. Title similarity boost (0.0-0.3)
|
|
246
|
+
factors.titleSimilarity = calculateTitleSimilarity(sourceTitle, targetTitle);
|
|
247
|
+
// 3. Namespace affinity boost (0.0-0.2)
|
|
248
|
+
factors.namespaceAffinity = calculateNamespaceAffinity(sourceNamespace, targetNamespace);
|
|
249
|
+
// 4. Recency boost (0.0-0.1)
|
|
250
|
+
factors.recencyBoost = calculateRecencyBoost(targetLastModified);
|
|
251
|
+
// 5. Link graph boost (0.0-0.3, feature-gated)
|
|
252
|
+
factors.linkGraphBoost = calculateLinkGraphBoost(sourceContent, targetPath, features);
|
|
253
|
+
// Calculate final relevance as sum of all factors
|
|
254
|
+
const totalRelevance = factors.keywordOverlap +
|
|
255
|
+
factors.titleSimilarity +
|
|
256
|
+
factors.namespaceAffinity +
|
|
257
|
+
factors.recencyBoost +
|
|
258
|
+
factors.linkGraphBoost;
|
|
259
|
+
// Cap at 1.0 maximum as specified
|
|
260
|
+
const cappedRelevance = Math.min(1.0, totalRelevance);
|
|
261
|
+
// Debug logging to show factor breakdown
|
|
262
|
+
logger.debug('Multi-factor relevance calculated', {
|
|
263
|
+
targetPath,
|
|
264
|
+
factors: {
|
|
265
|
+
keywordOverlap: Math.round(factors.keywordOverlap * 100) / 100,
|
|
266
|
+
titleSimilarity: Math.round(factors.titleSimilarity * 100) / 100,
|
|
267
|
+
namespaceAffinity: Math.round(factors.namespaceAffinity * 100) / 100,
|
|
268
|
+
recencyBoost: Math.round(factors.recencyBoost * 100) / 100,
|
|
269
|
+
linkGraphBoost: Math.round(factors.linkGraphBoost * 100) / 100
|
|
270
|
+
},
|
|
271
|
+
totalRelevance: Math.round(totalRelevance * 100) / 100,
|
|
272
|
+
cappedRelevance: Math.round(cappedRelevance * 100) / 100
|
|
273
|
+
});
|
|
274
|
+
return cappedRelevance;
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
logger.warn('Multi-factor relevance calculation failed', { error, targetPath });
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Calculate enhanced multi-factor relevance with detailed factor breakdown
|
|
283
|
+
*
|
|
284
|
+
* Extended version of calculateWeightedRelevance that returns both the final score
|
|
285
|
+
* and detailed factor breakdown for explanation generation.
|
|
286
|
+
*
|
|
287
|
+
* @param sourceKeywords - Weighted keywords from source document
|
|
288
|
+
* @param sourceTitle - Source document title
|
|
289
|
+
* @param sourceNamespace - Source document namespace
|
|
290
|
+
* @param sourceContent - Source document content (for link graph analysis)
|
|
291
|
+
* @param targetTitle - Target document title
|
|
292
|
+
* @param targetContent - Target document content
|
|
293
|
+
* @param targetNamespace - Target document namespace
|
|
294
|
+
* @param targetLastModified - Target document last modified date
|
|
295
|
+
* @param targetPath - Target document path (for link graph analysis)
|
|
296
|
+
* @param targetFingerprint - Target document fingerprint (optional)
|
|
297
|
+
* @param features - Feature flags controlling optional factors
|
|
298
|
+
*
|
|
299
|
+
* @returns Enhanced result with relevance score and factor breakdown
|
|
300
|
+
*
|
|
301
|
+
* @example Enhanced relevance calculation with breakdown
|
|
302
|
+
* ```typescript
|
|
303
|
+
* const result = calculateWeightedRelevanceWithBreakdown(
|
|
304
|
+
* sourceKeywords,
|
|
305
|
+
* 'User Authentication',
|
|
306
|
+
* 'api/guides',
|
|
307
|
+
* 'auth content',
|
|
308
|
+
* 'Auth API',
|
|
309
|
+
* 'API content',
|
|
310
|
+
* 'api/specs',
|
|
311
|
+
* new Date(),
|
|
312
|
+
* '/api/specs/auth.md'
|
|
313
|
+
* );
|
|
314
|
+
* console.log(`Relevance: ${result.relevance}`);
|
|
315
|
+
* console.log(`Primary factors: ${result.primaryFactors.map(f => f.description).join(', ')}`);
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
export function calculateWeightedRelevanceWithBreakdown(sourceKeywords, sourceTitle, sourceNamespace, sourceContent, targetTitle, targetContent, targetNamespace, targetLastModified, targetPath, targetFingerprint, features = DEFAULT_SCORING_FEATURES) {
|
|
319
|
+
try {
|
|
320
|
+
if (sourceKeywords.length === 0) {
|
|
321
|
+
return {
|
|
322
|
+
relevance: 0,
|
|
323
|
+
factors: {
|
|
324
|
+
keywordOverlap: 0,
|
|
325
|
+
titleSimilarity: 0,
|
|
326
|
+
namespaceAffinity: 0,
|
|
327
|
+
recencyBoost: 0,
|
|
328
|
+
linkGraphBoost: 0
|
|
329
|
+
},
|
|
330
|
+
primaryFactors: []
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
// Calculate individual relevance factors
|
|
334
|
+
const factors = {
|
|
335
|
+
keywordOverlap: 0,
|
|
336
|
+
titleSimilarity: 0,
|
|
337
|
+
namespaceAffinity: 0,
|
|
338
|
+
recencyBoost: 0,
|
|
339
|
+
linkGraphBoost: 0
|
|
340
|
+
};
|
|
341
|
+
// 1. Keyword overlap (primary factor, 0.0-1.0)
|
|
342
|
+
factors.keywordOverlap = calculateKeywordOverlapScore(sourceKeywords, targetTitle, targetContent, targetFingerprint);
|
|
343
|
+
// 2. Title similarity boost (0.0-0.3)
|
|
344
|
+
factors.titleSimilarity = calculateTitleSimilarity(sourceTitle, targetTitle);
|
|
345
|
+
// 3. Namespace affinity boost (0.0-0.2)
|
|
346
|
+
factors.namespaceAffinity = calculateNamespaceAffinity(sourceNamespace, targetNamespace);
|
|
347
|
+
// 4. Recency boost (0.0-0.1)
|
|
348
|
+
factors.recencyBoost = calculateRecencyBoost(targetLastModified);
|
|
349
|
+
// 5. Link graph boost (0.0-0.3, feature-gated)
|
|
350
|
+
factors.linkGraphBoost = calculateLinkGraphBoost(sourceContent, targetPath, features);
|
|
351
|
+
// Calculate final relevance as sum of all factors
|
|
352
|
+
const totalRelevance = factors.keywordOverlap +
|
|
353
|
+
factors.titleSimilarity +
|
|
354
|
+
factors.namespaceAffinity +
|
|
355
|
+
factors.recencyBoost +
|
|
356
|
+
factors.linkGraphBoost;
|
|
357
|
+
// Cap at 1.0 maximum as specified
|
|
358
|
+
const cappedRelevance = Math.min(1.0, totalRelevance);
|
|
359
|
+
// Determine primary contributing factors (top 2-3 with meaningful scores)
|
|
360
|
+
const primaryFactors = determinePrimaryFactors(factors);
|
|
361
|
+
// Debug logging to show factor breakdown
|
|
362
|
+
logger.debug('Multi-factor relevance calculated with breakdown', {
|
|
363
|
+
targetPath,
|
|
364
|
+
factors: {
|
|
365
|
+
keywordOverlap: Math.round(factors.keywordOverlap * 100) / 100,
|
|
366
|
+
titleSimilarity: Math.round(factors.titleSimilarity * 100) / 100,
|
|
367
|
+
namespaceAffinity: Math.round(factors.namespaceAffinity * 100) / 100,
|
|
368
|
+
recencyBoost: Math.round(factors.recencyBoost * 100) / 100,
|
|
369
|
+
linkGraphBoost: Math.round(factors.linkGraphBoost * 100) / 100
|
|
370
|
+
},
|
|
371
|
+
totalRelevance: Math.round(totalRelevance * 100) / 100,
|
|
372
|
+
cappedRelevance: Math.round(cappedRelevance * 100) / 100,
|
|
373
|
+
primaryFactors: primaryFactors.map(f => f.description)
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
relevance: cappedRelevance,
|
|
377
|
+
factors,
|
|
378
|
+
primaryFactors
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
catch (error) {
|
|
382
|
+
logger.warn('Multi-factor relevance calculation with breakdown failed', { error, targetPath });
|
|
383
|
+
return {
|
|
384
|
+
relevance: 0,
|
|
385
|
+
factors: {
|
|
386
|
+
keywordOverlap: 0,
|
|
387
|
+
titleSimilarity: 0,
|
|
388
|
+
namespaceAffinity: 0,
|
|
389
|
+
recencyBoost: 0,
|
|
390
|
+
linkGraphBoost: 0
|
|
391
|
+
},
|
|
392
|
+
primaryFactors: []
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Determine primary contributing factors from relevance calculation
|
|
398
|
+
*
|
|
399
|
+
* Analyzes the factor scores to identify the top 2-3 factors that meaningfully
|
|
400
|
+
* contributed to the relevance score, filtering out factors with minimal impact.
|
|
401
|
+
*
|
|
402
|
+
* @param factors - RelevanceFactors breakdown from calculation
|
|
403
|
+
*
|
|
404
|
+
* @returns Array of primary factors with descriptions for explanation generation
|
|
405
|
+
*/
|
|
406
|
+
function determinePrimaryFactors(factors) {
|
|
407
|
+
// Define thresholds for meaningful contribution
|
|
408
|
+
const MEANINGFUL_THRESHOLDS = {
|
|
409
|
+
keywordOverlap: 0.1, // At least 10% keyword overlap
|
|
410
|
+
titleSimilarity: 0.05, // At least 5% title similarity (0.05 out of max 0.3)
|
|
411
|
+
namespaceAffinity: 0.05, // At least 5% namespace affinity (0.05 out of max 0.2)
|
|
412
|
+
recencyBoost: 0.02, // At least 2% recency boost (0.02 out of max 0.1)
|
|
413
|
+
linkGraphBoost: 0.1 // At least 10% link boost (0.1 out of max 0.3)
|
|
414
|
+
};
|
|
415
|
+
// Generate factor entries with descriptions
|
|
416
|
+
const factorEntries = [];
|
|
417
|
+
// Keyword overlap factor
|
|
418
|
+
if (factors.keywordOverlap >= MEANINGFUL_THRESHOLDS.keywordOverlap) {
|
|
419
|
+
factorEntries.push({
|
|
420
|
+
factor: 'keywordOverlap',
|
|
421
|
+
score: factors.keywordOverlap,
|
|
422
|
+
description: factors.keywordOverlap >= 0.7 ? 'strong keyword overlap' :
|
|
423
|
+
factors.keywordOverlap >= 0.4 ? 'good keyword overlap' :
|
|
424
|
+
'shared keywords'
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
// Title similarity factor
|
|
428
|
+
if (factors.titleSimilarity >= MEANINGFUL_THRESHOLDS.titleSimilarity) {
|
|
429
|
+
factorEntries.push({
|
|
430
|
+
factor: 'titleSimilarity',
|
|
431
|
+
score: factors.titleSimilarity,
|
|
432
|
+
description: factors.titleSimilarity >= 0.2 ? 'very similar titles' :
|
|
433
|
+
factors.titleSimilarity >= 0.1 ? 'similar titles' :
|
|
434
|
+
'related title words'
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
// Namespace affinity factor
|
|
438
|
+
if (factors.namespaceAffinity >= MEANINGFUL_THRESHOLDS.namespaceAffinity) {
|
|
439
|
+
factorEntries.push({
|
|
440
|
+
factor: 'namespaceAffinity',
|
|
441
|
+
score: factors.namespaceAffinity,
|
|
442
|
+
description: factors.namespaceAffinity >= 0.2 ? 'same namespace' :
|
|
443
|
+
factors.namespaceAffinity >= 0.15 ? 'related namespace structure' :
|
|
444
|
+
'similar namespace'
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
// Recency boost factor
|
|
448
|
+
if (factors.recencyBoost >= MEANINGFUL_THRESHOLDS.recencyBoost) {
|
|
449
|
+
factorEntries.push({
|
|
450
|
+
factor: 'recencyBoost',
|
|
451
|
+
score: factors.recencyBoost,
|
|
452
|
+
description: factors.recencyBoost >= 0.08 ? 'recently updated' :
|
|
453
|
+
factors.recencyBoost >= 0.04 ? 'recent updates' :
|
|
454
|
+
'updated recently'
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
// Link graph boost factor (feature-gated)
|
|
458
|
+
if (factors.linkGraphBoost >= MEANINGFUL_THRESHOLDS.linkGraphBoost) {
|
|
459
|
+
factorEntries.push({
|
|
460
|
+
factor: 'linkGraphBoost',
|
|
461
|
+
score: factors.linkGraphBoost,
|
|
462
|
+
description: 'cross-referenced documentation'
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
// Sort by score (highest first) and return top 3 factors
|
|
466
|
+
return factorEntries
|
|
467
|
+
.sort((a, b) => b.score - a.score)
|
|
468
|
+
.slice(0, 3);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Generate human-readable explanation from primary factors
|
|
472
|
+
*
|
|
473
|
+
* Creates a concise, informative explanation of why a document was suggested
|
|
474
|
+
* based on the primary contributing factors from relevance calculation.
|
|
475
|
+
*
|
|
476
|
+
* @param primaryFactors - Array of primary factors from determinePrimaryFactors
|
|
477
|
+
* @param targetNamespace - Target document namespace for context
|
|
478
|
+
* @param hasExplicitKeywords - Whether source had explicit frontmatter keywords
|
|
479
|
+
*
|
|
480
|
+
* @returns Human-readable explanation string
|
|
481
|
+
*
|
|
482
|
+
* @example Factor-based explanation generation
|
|
483
|
+
* ```typescript
|
|
484
|
+
* const explanation = generateFactorBasedExplanation(
|
|
485
|
+
* [
|
|
486
|
+
* { factor: 'keywordOverlap', score: 0.8, description: 'strong keyword overlap' },
|
|
487
|
+
* { factor: 'namespaceAffinity', score: 0.2, description: 'same namespace' }
|
|
488
|
+
* ],
|
|
489
|
+
* 'api/specs',
|
|
490
|
+
* true
|
|
491
|
+
* );
|
|
492
|
+
* // Returns: "Strong keyword overlap with same namespace structure"
|
|
493
|
+
* ```
|
|
494
|
+
*/
|
|
495
|
+
export function generateFactorBasedExplanation(primaryFactors, targetNamespace, hasExplicitKeywords = false) {
|
|
496
|
+
if (primaryFactors.length === 0) {
|
|
497
|
+
return `Related documentation in ${targetNamespace}`;
|
|
498
|
+
}
|
|
499
|
+
// Generate explanation based on primary factors
|
|
500
|
+
const descriptions = primaryFactors.map(factor => factor.description);
|
|
501
|
+
// Add keyword source context if relevant
|
|
502
|
+
if (primaryFactors.some(f => f.factor === 'keywordOverlap') && hasExplicitKeywords) {
|
|
503
|
+
// Replace generic keyword descriptions with explicit keyword context
|
|
504
|
+
const keywordIndex = descriptions.findIndex(desc => desc.includes('keyword') || desc.includes('shared'));
|
|
505
|
+
if (keywordIndex >= 0 && descriptions[keywordIndex] != null) {
|
|
506
|
+
descriptions[keywordIndex] = descriptions[keywordIndex].replace(/keyword overlap|shared keywords/, 'explicit keyword matches');
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
// Create base explanation
|
|
510
|
+
let explanation;
|
|
511
|
+
if (descriptions.length === 1) {
|
|
512
|
+
const firstDesc = descriptions[0];
|
|
513
|
+
explanation = firstDesc != null ? capitalizeFirst(firstDesc) : 'Related documentation';
|
|
514
|
+
}
|
|
515
|
+
else if (descriptions.length === 2) {
|
|
516
|
+
const firstDesc = descriptions[0];
|
|
517
|
+
const secondDesc = descriptions[1];
|
|
518
|
+
explanation = firstDesc != null && secondDesc != null
|
|
519
|
+
? `${capitalizeFirst(firstDesc)} with ${secondDesc}`
|
|
520
|
+
: 'Related documentation';
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
// 3 factors: "X with Y and Z"
|
|
524
|
+
const firstDesc = descriptions[0];
|
|
525
|
+
const secondDesc = descriptions[1];
|
|
526
|
+
const thirdDesc = descriptions[2];
|
|
527
|
+
explanation = firstDesc != null && secondDesc != null && thirdDesc != null
|
|
528
|
+
? `${capitalizeFirst(firstDesc)} with ${secondDesc} and ${thirdDesc}`
|
|
529
|
+
: 'Related documentation';
|
|
530
|
+
}
|
|
531
|
+
// Add namespace context if not already mentioned
|
|
532
|
+
const hasNamespaceContext = descriptions.some(desc => desc.includes('namespace') || desc.includes('structure'));
|
|
533
|
+
if (!hasNamespaceContext) {
|
|
534
|
+
explanation += ` in ${targetNamespace}`;
|
|
535
|
+
}
|
|
536
|
+
return explanation;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Capitalize first letter of a string
|
|
540
|
+
*/
|
|
541
|
+
function capitalizeFirst(str) {
|
|
542
|
+
if (str.length === 0)
|
|
543
|
+
return str;
|
|
544
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Calculate keyword overlap score (legacy compatibility function)
|
|
548
|
+
*
|
|
549
|
+
* Maintains backward compatibility with the original calculateWeightedRelevance
|
|
550
|
+
* behavior for keyword overlap calculation only.
|
|
551
|
+
*
|
|
552
|
+
* @param sourceKeywords - Weighted keywords from source document
|
|
553
|
+
* @param targetTitle - Target document title
|
|
554
|
+
* @param targetContent - Target document content
|
|
555
|
+
* @param targetFingerprint - Target document fingerprint (optional)
|
|
556
|
+
*
|
|
557
|
+
* @returns Keyword overlap score between 0 and 1
|
|
558
|
+
*/
|
|
559
|
+
function calculateKeywordOverlapScore(sourceKeywords, targetTitle, targetContent, targetFingerprint) {
|
|
560
|
+
try {
|
|
561
|
+
if (sourceKeywords.length === 0) {
|
|
562
|
+
return 0;
|
|
563
|
+
}
|
|
564
|
+
// Extract target keywords for matching
|
|
565
|
+
const targetResult = extractKeywordsWithFingerprint(targetTitle ?? '', targetContent ?? '', targetFingerprint);
|
|
566
|
+
if (targetResult.keywords.length === 0) {
|
|
567
|
+
return 0;
|
|
568
|
+
}
|
|
569
|
+
// Create target keyword set for efficient lookup
|
|
570
|
+
const targetKeywordSet = new Set(targetResult.keywords);
|
|
571
|
+
// Calculate weighted matches
|
|
572
|
+
let totalMatchWeight = 0;
|
|
573
|
+
let totalSourceWeight = 0;
|
|
574
|
+
for (const sourceKeyword of sourceKeywords) {
|
|
575
|
+
totalSourceWeight += sourceKeyword.weight;
|
|
576
|
+
if (targetKeywordSet.has(sourceKeyword.keyword)) {
|
|
577
|
+
totalMatchWeight += sourceKeyword.weight;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
// Calculate relevance as weighted match ratio
|
|
581
|
+
const relevance = totalSourceWeight > 0 ? totalMatchWeight / totalSourceWeight : 0;
|
|
582
|
+
// Ensure result is within bounds
|
|
583
|
+
return Math.max(0, Math.min(1, relevance));
|
|
584
|
+
}
|
|
585
|
+
catch (error) {
|
|
586
|
+
logger.warn('Keyword overlap calculation failed', { error });
|
|
587
|
+
return 0;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Extract keywords using original algorithm for backward compatibility
|
|
592
|
+
*
|
|
593
|
+
* Maintains the original extractKeywords behavior for existing code
|
|
594
|
+
* that depends on the simple keyword extraction approach.
|
|
595
|
+
*
|
|
596
|
+
* @param title - Document title
|
|
597
|
+
* @param overview - Document overview
|
|
598
|
+
*
|
|
599
|
+
* @returns Array of extracted keywords (backward compatible)
|
|
600
|
+
*/
|
|
601
|
+
export function extractKeywords(title, overview) {
|
|
602
|
+
try {
|
|
603
|
+
// Use enhanced extraction but return only simple keywords for compatibility
|
|
604
|
+
const result = extractWeightedKeywords(title, overview);
|
|
605
|
+
return [...result.keywords]; // Return copy to maintain immutability
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
logger.warn('Backward compatible keyword extraction failed', { error });
|
|
609
|
+
// Fallback to simple word splitting as original did
|
|
610
|
+
const text = `${title ?? ''} ${overview ?? ''}`.toLowerCase();
|
|
611
|
+
return text
|
|
612
|
+
.split(/\s+/)
|
|
613
|
+
.map(word => word.trim())
|
|
614
|
+
.filter(word => word.length > 2)
|
|
615
|
+
.filter((word, index, array) => array.indexOf(word) === index) // Remove duplicates
|
|
616
|
+
.slice(0, 20); // Limit for performance
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* Calculate namespace affinity score between two namespaces
|
|
621
|
+
*
|
|
622
|
+
* Implements the multi-factor relevance algorithm namespace affinity rules:
|
|
623
|
+
* - Same namespace: 0.2 (api/specs === api/specs)
|
|
624
|
+
* - Parent/child relationship: 0.15 (api/* contains api/guides/*)
|
|
625
|
+
* - Sibling relationship: 0.1 (api/specs vs api/guides)
|
|
626
|
+
* - Unrelated: 0.0 (api/* vs frontend/*)
|
|
627
|
+
*
|
|
628
|
+
* @param sourceNamespace - The source document's namespace
|
|
629
|
+
* @param targetNamespace - The target document's namespace
|
|
630
|
+
*
|
|
631
|
+
* @returns Namespace affinity score between 0.0 and 0.2
|
|
632
|
+
*
|
|
633
|
+
* @example Namespace affinity examples
|
|
634
|
+
* ```typescript
|
|
635
|
+
* calculateNamespaceAffinity('api/specs', 'api/specs'); // 0.2 - exact match
|
|
636
|
+
* calculateNamespaceAffinity('api', 'api/guides'); // 0.15 - parent/child
|
|
637
|
+
* calculateNamespaceAffinity('api/specs', 'api/guides'); // 0.1 - siblings
|
|
638
|
+
* calculateNamespaceAffinity('api', 'frontend'); // 0.0 - unrelated
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
export function calculateNamespaceAffinity(sourceNamespace, targetNamespace) {
|
|
642
|
+
try {
|
|
643
|
+
// Input validation
|
|
644
|
+
if (sourceNamespace == null || targetNamespace == null) {
|
|
645
|
+
return 0.0;
|
|
646
|
+
}
|
|
647
|
+
const source = sourceNamespace.trim();
|
|
648
|
+
const target = targetNamespace.trim();
|
|
649
|
+
if (source === '' || target === '') {
|
|
650
|
+
return 0.0;
|
|
651
|
+
}
|
|
652
|
+
// Exact match: api/specs === api/specs
|
|
653
|
+
if (source === target) {
|
|
654
|
+
return 0.2;
|
|
655
|
+
}
|
|
656
|
+
// Parent-child relationships: api/* contains api/guides/* or vice versa
|
|
657
|
+
if (target.startsWith(`${source}/`)) {
|
|
658
|
+
return 0.15; // Parent: api/* contains api/guides/*
|
|
659
|
+
}
|
|
660
|
+
if (source.startsWith(`${target}/`)) {
|
|
661
|
+
return 0.15; // Child: api/guides/* in api/*
|
|
662
|
+
}
|
|
663
|
+
// Sibling relationships: api/specs vs api/guides (shared prefix)
|
|
664
|
+
if (shareCommonPrefix(source, target)) {
|
|
665
|
+
return 0.1;
|
|
666
|
+
}
|
|
667
|
+
// Unrelated namespaces
|
|
668
|
+
return 0.0;
|
|
669
|
+
}
|
|
670
|
+
catch (error) {
|
|
671
|
+
logger.warn('Namespace affinity calculation failed', { error, sourceNamespace, targetNamespace });
|
|
672
|
+
return 0.0;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Calculate recency boost score based on document modification time
|
|
677
|
+
*
|
|
678
|
+
* Implements the multi-factor relevance algorithm recency rules:
|
|
679
|
+
* - Modified within last week: 0.1 boost
|
|
680
|
+
* - Modified within last month: 0.05 boost
|
|
681
|
+
* - Modified within last 3 months: 0.02 boost
|
|
682
|
+
* - Older documents: 0.0 boost
|
|
683
|
+
*
|
|
684
|
+
* @param lastModified - Document's last modification date
|
|
685
|
+
*
|
|
686
|
+
* @returns Recency boost score between 0.0 and 0.1
|
|
687
|
+
*
|
|
688
|
+
* @example Recency boost examples
|
|
689
|
+
* ```typescript
|
|
690
|
+
* const today = new Date();
|
|
691
|
+
* const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
|
|
692
|
+
* const lastWeek = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
|
|
693
|
+
* const lastMonth = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);
|
|
694
|
+
*
|
|
695
|
+
* calculateRecencyBoost(yesterday); // 0.1 - within last week
|
|
696
|
+
* calculateRecencyBoost(lastWeek); // 0.1 - within last week
|
|
697
|
+
* calculateRecencyBoost(lastMonth); // 0.05 - within last month
|
|
698
|
+
* ```
|
|
699
|
+
*/
|
|
700
|
+
export function calculateRecencyBoost(lastModified) {
|
|
701
|
+
try {
|
|
702
|
+
// Input validation
|
|
703
|
+
if (lastModified == null || !(lastModified instanceof Date) || isNaN(lastModified.getTime())) {
|
|
704
|
+
return 0.0;
|
|
705
|
+
}
|
|
706
|
+
const now = new Date();
|
|
707
|
+
const timeDiff = now.getTime() - lastModified.getTime();
|
|
708
|
+
// Convert to days
|
|
709
|
+
const daysDiff = timeDiff / (1000 * 60 * 60 * 24);
|
|
710
|
+
// Apply recency boost rules
|
|
711
|
+
if (daysDiff <= 7) {
|
|
712
|
+
return 0.1; // Within last week
|
|
713
|
+
}
|
|
714
|
+
else if (daysDiff <= 30) {
|
|
715
|
+
return 0.05; // Within last month
|
|
716
|
+
}
|
|
717
|
+
else if (daysDiff <= 90) {
|
|
718
|
+
return 0.02; // Within last 3 months
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
return 0.0; // Older documents
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
logger.warn('Recency boost calculation failed', { error, lastModified });
|
|
726
|
+
return 0.0;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
/**
|
|
730
|
+
* Calculate title similarity score between two document titles
|
|
731
|
+
*
|
|
732
|
+
* Implements the multi-factor relevance algorithm title similarity factor.
|
|
733
|
+
* Analyzes word overlap between titles with emphasis on meaningful terms.
|
|
734
|
+
*
|
|
735
|
+
* @param sourceTitle - The source document's title
|
|
736
|
+
* @param targetTitle - The target document's title
|
|
737
|
+
*
|
|
738
|
+
* @returns Title similarity score between 0.0 and 0.3
|
|
739
|
+
*
|
|
740
|
+
* @example Title similarity examples
|
|
741
|
+
* ```typescript
|
|
742
|
+
* calculateTitleSimilarity('User Authentication API', 'Authentication Guide'); // ~0.2
|
|
743
|
+
* calculateTitleSimilarity('API Documentation', 'API Reference'); // ~0.15
|
|
744
|
+
* calculateTitleSimilarity('Frontend Guide', 'Backend Setup'); // 0.0
|
|
745
|
+
* ```
|
|
746
|
+
*/
|
|
747
|
+
export function calculateTitleSimilarity(sourceTitle, targetTitle) {
|
|
748
|
+
try {
|
|
749
|
+
// Input validation
|
|
750
|
+
if (sourceTitle == null || targetTitle == null) {
|
|
751
|
+
return 0.0;
|
|
752
|
+
}
|
|
753
|
+
const source = sourceTitle.trim().toLowerCase();
|
|
754
|
+
const target = targetTitle.trim().toLowerCase();
|
|
755
|
+
if (source === '' || target === '') {
|
|
756
|
+
return 0.0;
|
|
757
|
+
}
|
|
758
|
+
// Exact match (unlikely but highest score)
|
|
759
|
+
if (source === target) {
|
|
760
|
+
return 0.3;
|
|
761
|
+
}
|
|
762
|
+
// Extract meaningful words from titles
|
|
763
|
+
const sourceWords = extractMeaningfulTitleWords(source);
|
|
764
|
+
const targetWords = extractMeaningfulTitleWords(target);
|
|
765
|
+
if (sourceWords.length === 0 || targetWords.length === 0) {
|
|
766
|
+
return 0.0;
|
|
767
|
+
}
|
|
768
|
+
// Calculate word overlap
|
|
769
|
+
const targetWordSet = new Set(targetWords);
|
|
770
|
+
const matchingWords = sourceWords.filter(word => targetWordSet.has(word));
|
|
771
|
+
if (matchingWords.length === 0) {
|
|
772
|
+
return 0.0;
|
|
773
|
+
}
|
|
774
|
+
// Calculate similarity ratio and scale to max 0.3
|
|
775
|
+
const overlapRatio = matchingWords.length / Math.max(sourceWords.length, targetWords.length);
|
|
776
|
+
const titleSimilarity = overlapRatio * 0.3;
|
|
777
|
+
return Math.max(0.0, Math.min(0.3, titleSimilarity));
|
|
778
|
+
}
|
|
779
|
+
catch (error) {
|
|
780
|
+
logger.warn('Title similarity calculation failed', { error, sourceTitle, targetTitle });
|
|
781
|
+
return 0.0;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Calculate link graph boost score for documents that reference each other
|
|
786
|
+
*
|
|
787
|
+
* This is a feature-gated scoring factor that detects when documents
|
|
788
|
+
* reference each other using the @reference system.
|
|
789
|
+
*
|
|
790
|
+
* @param sourceContent - Content of the source document to scan for references
|
|
791
|
+
* @param targetPath - Path of the target document to check for references
|
|
792
|
+
* @param features - Feature flags controlling whether this factor is enabled
|
|
793
|
+
*
|
|
794
|
+
* @returns Link graph boost score between 0.0 and 0.3
|
|
795
|
+
*
|
|
796
|
+
* @example Link graph boost usage
|
|
797
|
+
* ```typescript
|
|
798
|
+
* const boost = calculateLinkGraphBoost(
|
|
799
|
+
* 'See @/api/auth.md for details',
|
|
800
|
+
* '/api/auth.md',
|
|
801
|
+
* { enableLinkGraphBoost: true }
|
|
802
|
+
* );
|
|
803
|
+
* // Returns 0.3 if reference found and feature enabled, 0.0 otherwise
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
export function calculateLinkGraphBoost(sourceContent, targetPath, features = DEFAULT_SCORING_FEATURES) {
|
|
807
|
+
try {
|
|
808
|
+
// Feature gate - return 0 if disabled
|
|
809
|
+
if (!features.enableLinkGraphBoost) {
|
|
810
|
+
return 0.0;
|
|
811
|
+
}
|
|
812
|
+
// Input validation
|
|
813
|
+
if (sourceContent == null || targetPath == null) {
|
|
814
|
+
return 0.0;
|
|
815
|
+
}
|
|
816
|
+
const content = sourceContent.trim();
|
|
817
|
+
const path = targetPath.trim();
|
|
818
|
+
if (content === '' || path === '') {
|
|
819
|
+
return 0.0;
|
|
820
|
+
}
|
|
821
|
+
// Simple reference detection - look for @references to the target document
|
|
822
|
+
// This is a basic implementation that can be enhanced with the full ReferenceExtractor
|
|
823
|
+
const referencePattern = new RegExp(`@[^\\s]*${path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`, 'gi');
|
|
824
|
+
const hasReference = referencePattern.test(content);
|
|
825
|
+
if (hasReference) {
|
|
826
|
+
logger.debug('Link graph boost applied', { targetPath: path });
|
|
827
|
+
return 0.3;
|
|
828
|
+
}
|
|
829
|
+
return 0.0;
|
|
830
|
+
}
|
|
831
|
+
catch (error) {
|
|
832
|
+
logger.warn('Link graph boost calculation failed', { error, targetPath });
|
|
833
|
+
return 0.0;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
// ==================== PRIVATE HELPER FUNCTIONS ====================
|
|
837
|
+
/**
|
|
838
|
+
* Parse content into structured sources for targeted extraction
|
|
839
|
+
*/
|
|
840
|
+
function parseContentSources(title, content) {
|
|
841
|
+
try {
|
|
842
|
+
const frontmatter = parseFrontmatter(content);
|
|
843
|
+
const headings = extractHeadings(content);
|
|
844
|
+
const emphasis = extractEmphasis(content);
|
|
845
|
+
// Remove frontmatter from content for body analysis
|
|
846
|
+
const bodyContent = removeFrontmatter(content);
|
|
847
|
+
return {
|
|
848
|
+
frontmatter,
|
|
849
|
+
title: title.trim(),
|
|
850
|
+
headings,
|
|
851
|
+
emphasis,
|
|
852
|
+
content: bodyContent
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
catch (error) {
|
|
856
|
+
logger.warn('Content source parsing failed', { error });
|
|
857
|
+
return {
|
|
858
|
+
frontmatter: null,
|
|
859
|
+
title: title.trim(),
|
|
860
|
+
headings: [],
|
|
861
|
+
emphasis: [],
|
|
862
|
+
content
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Parse YAML frontmatter from markdown content
|
|
868
|
+
*/
|
|
869
|
+
function parseFrontmatter(content) {
|
|
870
|
+
try {
|
|
871
|
+
const frontmatterMatch = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
872
|
+
if (frontmatterMatch == null) {
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
const yamlContent = frontmatterMatch[1];
|
|
876
|
+
if (yamlContent == null || yamlContent.trim() === '') {
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
879
|
+
// Simple YAML parsing for keywords field (avoiding external dependencies)
|
|
880
|
+
const data = {};
|
|
881
|
+
const lines = yamlContent.split('\n');
|
|
882
|
+
for (const line of lines) {
|
|
883
|
+
const trimmed = line.trim();
|
|
884
|
+
if (trimmed === '' || trimmed.startsWith('#'))
|
|
885
|
+
continue;
|
|
886
|
+
// Handle keywords field specifically
|
|
887
|
+
if (trimmed.startsWith('keywords:')) {
|
|
888
|
+
const keywordsPart = trimmed.substring('keywords:'.length).trim();
|
|
889
|
+
// Handle array format: keywords: [item1, item2, item3]
|
|
890
|
+
if (keywordsPart.startsWith('[') && keywordsPart.endsWith(']')) {
|
|
891
|
+
const arrayContent = keywordsPart.slice(1, -1);
|
|
892
|
+
const items = arrayContent
|
|
893
|
+
.split(',')
|
|
894
|
+
.map(item => item.trim().replace(/['"]/g, ''))
|
|
895
|
+
.filter(item => item.length > 0);
|
|
896
|
+
// Only set keywords if we have valid items (avoid empty array from malformed YAML)
|
|
897
|
+
if (items.length > 0) {
|
|
898
|
+
data.keywords = items;
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
// Handle list format: keywords: "item1, item2, item3"
|
|
902
|
+
else if (keywordsPart.startsWith('"') && keywordsPart.endsWith('"')) {
|
|
903
|
+
const quotedContent = keywordsPart.slice(1, -1);
|
|
904
|
+
data.keywords = quotedContent
|
|
905
|
+
.split(',')
|
|
906
|
+
.map(item => item.trim())
|
|
907
|
+
.filter(item => item.length > 0);
|
|
908
|
+
}
|
|
909
|
+
// Handle single value: keywords: value
|
|
910
|
+
else if (keywordsPart.length > 0) {
|
|
911
|
+
// Reject malformed array syntax (starts with [ but doesn't end with ])
|
|
912
|
+
if (keywordsPart.startsWith('[') && !keywordsPart.endsWith(']')) {
|
|
913
|
+
// This is malformed YAML, skip it
|
|
914
|
+
continue;
|
|
915
|
+
}
|
|
916
|
+
data.keywords = [keywordsPart.replace(/['"]/g, '')];
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
return Object.keys(data).length > 0 ? data : null;
|
|
921
|
+
}
|
|
922
|
+
catch (error) {
|
|
923
|
+
logger.warn('Frontmatter parsing failed', { error });
|
|
924
|
+
return null;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
/**
|
|
928
|
+
* Extract heading text from markdown content
|
|
929
|
+
*/
|
|
930
|
+
function extractHeadings(content) {
|
|
931
|
+
try {
|
|
932
|
+
const headingRegex = /^#{1,6}\s+(.+)$/gm;
|
|
933
|
+
const headings = [];
|
|
934
|
+
let match;
|
|
935
|
+
while ((match = headingRegex.exec(content)) != null) {
|
|
936
|
+
const headingText = match[1];
|
|
937
|
+
if (headingText != null && headingText.trim().length > 0) {
|
|
938
|
+
headings.push(headingText.trim());
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return headings;
|
|
942
|
+
}
|
|
943
|
+
catch (error) {
|
|
944
|
+
logger.warn('Heading extraction failed', { error });
|
|
945
|
+
return [];
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
/**
|
|
949
|
+
* Extract emphasized text (bold/italic) from markdown content
|
|
950
|
+
*/
|
|
951
|
+
function extractEmphasis(content) {
|
|
952
|
+
try {
|
|
953
|
+
const emphasis = [];
|
|
954
|
+
// Bold text: **text** or __text__
|
|
955
|
+
const boldRegex = /(?:\*\*|__)([^*_\n]+)(?:\*\*|__)/g;
|
|
956
|
+
let match;
|
|
957
|
+
while ((match = boldRegex.exec(content)) != null) {
|
|
958
|
+
const text = match[1];
|
|
959
|
+
if (text != null && text.trim().length > 0) {
|
|
960
|
+
emphasis.push(text.trim());
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
// Italic text: *text* or _text_ (but not already captured as bold)
|
|
964
|
+
const italicRegex = /(?<!\*)\*([^*\n]+)\*(?!\*)|(?<!_)_([^_\n]+)_(?!_)/g;
|
|
965
|
+
while ((match = italicRegex.exec(content)) != null) {
|
|
966
|
+
const text = match[1] ?? match[2];
|
|
967
|
+
if (text != null && text.trim().length > 0) {
|
|
968
|
+
emphasis.push(text.trim());
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return emphasis;
|
|
972
|
+
}
|
|
973
|
+
catch (error) {
|
|
974
|
+
logger.warn('Emphasis extraction failed', { error });
|
|
975
|
+
return [];
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Remove frontmatter from markdown content
|
|
980
|
+
*/
|
|
981
|
+
function removeFrontmatter(content) {
|
|
982
|
+
try {
|
|
983
|
+
return content.replace(/^---\s*\n[\s\S]*?\n---\s*\n/, '');
|
|
984
|
+
}
|
|
985
|
+
catch (error) {
|
|
986
|
+
logger.warn('Frontmatter removal failed', { error });
|
|
987
|
+
return content;
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
/**
|
|
991
|
+
* Extract explicit keywords from frontmatter
|
|
992
|
+
*/
|
|
993
|
+
function extractExplicitKeywords(frontmatter) {
|
|
994
|
+
if (frontmatter?.keywords == null) {
|
|
995
|
+
return [];
|
|
996
|
+
}
|
|
997
|
+
try {
|
|
998
|
+
if (Array.isArray(frontmatter.keywords)) {
|
|
999
|
+
return frontmatter.keywords
|
|
1000
|
+
.filter(keyword => typeof keyword === 'string' && keyword.trim().length > 0)
|
|
1001
|
+
.map(keyword => keyword.trim());
|
|
1002
|
+
}
|
|
1003
|
+
if (typeof frontmatter.keywords === 'string') {
|
|
1004
|
+
return frontmatter.keywords
|
|
1005
|
+
.split(',')
|
|
1006
|
+
.map(keyword => keyword.trim())
|
|
1007
|
+
.filter(keyword => keyword.length > 0);
|
|
1008
|
+
}
|
|
1009
|
+
return [];
|
|
1010
|
+
}
|
|
1011
|
+
catch (error) {
|
|
1012
|
+
logger.warn('Explicit keyword extraction failed', { error });
|
|
1013
|
+
return [];
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Extract weighted keywords from all content sources
|
|
1018
|
+
*/
|
|
1019
|
+
function extractFromContentSources(sources, weights) {
|
|
1020
|
+
const keywordMap = new Map();
|
|
1021
|
+
// Helper to add keywords with weight
|
|
1022
|
+
const addKeywords = (keywords, weight, source) => {
|
|
1023
|
+
for (const keyword of keywords) {
|
|
1024
|
+
const normalized = keyword.toLowerCase().trim();
|
|
1025
|
+
if (normalized.length <= 2)
|
|
1026
|
+
continue; // Skip short words
|
|
1027
|
+
const existing = keywordMap.get(normalized);
|
|
1028
|
+
if (existing != null) {
|
|
1029
|
+
existing.weight = Math.max(existing.weight, weight); // Use highest weight
|
|
1030
|
+
existing.sources.add(source);
|
|
1031
|
+
}
|
|
1032
|
+
else {
|
|
1033
|
+
keywordMap.set(normalized, {
|
|
1034
|
+
weight,
|
|
1035
|
+
sources: new Set([source])
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
};
|
|
1040
|
+
// Extract keywords from title
|
|
1041
|
+
if (sources.title.length > 0) {
|
|
1042
|
+
const titleKeywords = extractWordsFromText(sources.title);
|
|
1043
|
+
addKeywords(titleKeywords, weights.title, 'title');
|
|
1044
|
+
}
|
|
1045
|
+
// Extract keywords from headings
|
|
1046
|
+
for (const heading of sources.headings) {
|
|
1047
|
+
const headingKeywords = extractWordsFromText(heading);
|
|
1048
|
+
addKeywords(headingKeywords, weights.headings, 'headings');
|
|
1049
|
+
}
|
|
1050
|
+
// Extract keywords from emphasis
|
|
1051
|
+
for (const emphasis of sources.emphasis) {
|
|
1052
|
+
const emphasisKeywords = extractWordsFromText(emphasis);
|
|
1053
|
+
addKeywords(emphasisKeywords, weights.emphasis, 'emphasis');
|
|
1054
|
+
}
|
|
1055
|
+
// Extract keywords from content
|
|
1056
|
+
const contentKeywords = extractWordsFromText(sources.content);
|
|
1057
|
+
addKeywords(contentKeywords, weights.content, 'content');
|
|
1058
|
+
// Convert to WeightedKeyword array
|
|
1059
|
+
const weightedKeywords = [];
|
|
1060
|
+
for (const [keyword, data] of keywordMap) {
|
|
1061
|
+
weightedKeywords.push({
|
|
1062
|
+
keyword,
|
|
1063
|
+
weight: data.weight,
|
|
1064
|
+
sources: Array.from(data.sources)
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
// Sort by weight (highest first) and limit results
|
|
1068
|
+
return weightedKeywords
|
|
1069
|
+
.sort((a, b) => b.weight - a.weight)
|
|
1070
|
+
.slice(0, 50); // Reasonable limit for performance
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Extract meaningful words from text with stop word filtering
|
|
1074
|
+
*/
|
|
1075
|
+
function extractWordsFromText(text) {
|
|
1076
|
+
if (text == null || text.trim().length === 0) {
|
|
1077
|
+
return [];
|
|
1078
|
+
}
|
|
1079
|
+
try {
|
|
1080
|
+
// Split into words and filter by length
|
|
1081
|
+
const words = text
|
|
1082
|
+
.toLowerCase()
|
|
1083
|
+
.split(/\s+/)
|
|
1084
|
+
.map(word => word.replace(/[^\w]/g, '')) // Remove punctuation
|
|
1085
|
+
.filter(word => word.length > 2);
|
|
1086
|
+
// Remove stop words
|
|
1087
|
+
const stopWords = new Set([
|
|
1088
|
+
'the', 'and', 'for', 'with', 'this', 'that', 'will', 'can', 'are', 'you',
|
|
1089
|
+
'how', 'what', 'when', 'where', 'why', 'who', 'which', 'was', 'were',
|
|
1090
|
+
'been', 'have', 'has', 'had', 'should', 'would', 'could', 'may', 'might',
|
|
1091
|
+
'must', 'shall', 'not', 'but', 'however', 'therefore', 'thus', 'also',
|
|
1092
|
+
'such', 'very', 'more', 'most', 'much', 'many', 'some', 'any', 'all'
|
|
1093
|
+
]);
|
|
1094
|
+
return words.filter(word => !stopWords.has(word) &&
|
|
1095
|
+
!/^[\d\W]+$/.test(word) // Remove words that are just numbers/punctuation
|
|
1096
|
+
);
|
|
1097
|
+
}
|
|
1098
|
+
catch (error) {
|
|
1099
|
+
logger.warn('Word extraction failed', { error });
|
|
1100
|
+
return [];
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Check if two namespaces share a common prefix (for sibling detection)
|
|
1105
|
+
*/
|
|
1106
|
+
function shareCommonPrefix(namespace1, namespace2) {
|
|
1107
|
+
try {
|
|
1108
|
+
const parts1 = namespace1.split('/');
|
|
1109
|
+
const parts2 = namespace2.split('/');
|
|
1110
|
+
// Need at least one common part and both must have at least 2 parts for siblings
|
|
1111
|
+
if (parts1.length < 2 || parts2.length < 2) {
|
|
1112
|
+
return false;
|
|
1113
|
+
}
|
|
1114
|
+
// Check if they share the first part (making them siblings)
|
|
1115
|
+
return parts1[0] === parts2[0] && parts1[1] !== parts2[1];
|
|
1116
|
+
}
|
|
1117
|
+
catch (error) {
|
|
1118
|
+
logger.warn('Common prefix check failed', { error, namespace1, namespace2 });
|
|
1119
|
+
return false;
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
/**
|
|
1123
|
+
* Extract meaningful words from title text for similarity scoring
|
|
1124
|
+
*/
|
|
1125
|
+
function extractMeaningfulTitleWords(title) {
|
|
1126
|
+
try {
|
|
1127
|
+
// Split into words and filter by length
|
|
1128
|
+
const words = title
|
|
1129
|
+
.toLowerCase()
|
|
1130
|
+
.split(/\s+/)
|
|
1131
|
+
.map(word => word.replace(/[^\w]/g, '')) // Remove punctuation
|
|
1132
|
+
.filter(word => word.length > 2);
|
|
1133
|
+
// Title-specific stop words (more restrictive than general content)
|
|
1134
|
+
const titleStopWords = new Set([
|
|
1135
|
+
'the', 'and', 'for', 'with', 'this', 'that', 'guide', 'documentation',
|
|
1136
|
+
'doc', 'docs', 'reference', 'manual', 'tutorial', 'overview', 'introduction',
|
|
1137
|
+
'getting', 'started', 'start', 'how', 'what', 'when', 'where',
|
|
1138
|
+
'why', 'who', 'which'
|
|
1139
|
+
]);
|
|
1140
|
+
return words.filter(word => !titleStopWords.has(word));
|
|
1141
|
+
}
|
|
1142
|
+
catch (error) {
|
|
1143
|
+
logger.warn('Title word extraction failed', { error });
|
|
1144
|
+
return [];
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
//# sourceMappingURL=keyword-utils.js.map
|