@jwikman/bc-code-intelligence-mcp 1.5.7-dev.1
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 +165 -0
- package/dist/cache/cache-manager.d.ts +95 -0
- package/dist/cache/cache-manager.d.ts.map +1 -0
- package/dist/cache/cache-manager.js +328 -0
- package/dist/cache/cache-manager.js.map +1 -0
- package/dist/cli/bc-code-intel-cli.d.ts +9 -0
- package/dist/cli/bc-code-intel-cli.d.ts.map +1 -0
- package/dist/cli/bc-code-intel-cli.js +440 -0
- package/dist/cli/bc-code-intel-cli.js.map +1 -0
- package/dist/config/config-loader.d.ts +28 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +497 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/config/config-validator.d.ts +84 -0
- package/dist/config/config-validator.d.ts.map +1 -0
- package/dist/config/config-validator.js +608 -0
- package/dist/config/config-validator.js.map +1 -0
- package/dist/config/test-config-loader.d.ts +10 -0
- package/dist/config/test-config-loader.d.ts.map +1 -0
- package/dist/config/test-config-loader.js +135 -0
- package/dist/config/test-config-loader.js.map +1 -0
- package/dist/config/test-enhanced-layer-service.d.ts +7 -0
- package/dist/config/test-enhanced-layer-service.d.ts.map +1 -0
- package/dist/config/test-enhanced-layer-service.js +104 -0
- package/dist/config/test-enhanced-layer-service.js.map +1 -0
- package/dist/config/test-git-layer.d.ts +7 -0
- package/dist/config/test-git-layer.d.ts.map +1 -0
- package/dist/config/test-git-layer.js +68 -0
- package/dist/config/test-git-layer.js.map +1 -0
- package/dist/dev/hot-reload.d.ts +91 -0
- package/dist/dev/hot-reload.d.ts.map +1 -0
- package/dist/dev/hot-reload.js +358 -0
- package/dist/dev/hot-reload.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1211 -0
- package/dist/index.js.map +1 -0
- package/dist/layers/base-layer.d.ts +133 -0
- package/dist/layers/base-layer.d.ts.map +1 -0
- package/dist/layers/base-layer.js +290 -0
- package/dist/layers/base-layer.js.map +1 -0
- package/dist/layers/embedded-layer.d.ts +130 -0
- package/dist/layers/embedded-layer.d.ts.map +1 -0
- package/dist/layers/embedded-layer.js +612 -0
- package/dist/layers/embedded-layer.js.map +1 -0
- package/dist/layers/git-layer.d.ts +77 -0
- package/dist/layers/git-layer.d.ts.map +1 -0
- package/dist/layers/git-layer.js +529 -0
- package/dist/layers/git-layer.js.map +1 -0
- package/dist/layers/index.d.ts +12 -0
- package/dist/layers/index.d.ts.map +1 -0
- package/dist/layers/index.js +11 -0
- package/dist/layers/index.js.map +1 -0
- package/dist/layers/layer-service.d.ts +135 -0
- package/dist/layers/layer-service.d.ts.map +1 -0
- package/dist/layers/layer-service.js +586 -0
- package/dist/layers/layer-service.js.map +1 -0
- package/dist/layers/project-layer.d.ts +58 -0
- package/dist/layers/project-layer.d.ts.map +1 -0
- package/dist/layers/project-layer.js +286 -0
- package/dist/layers/project-layer.js.map +1 -0
- package/dist/monitoring/production-monitor.d.ts +148 -0
- package/dist/monitoring/production-monitor.d.ts.map +1 -0
- package/dist/monitoring/production-monitor.js +463 -0
- package/dist/monitoring/production-monitor.js.map +1 -0
- package/dist/performance/performance-monitor.d.ts +99 -0
- package/dist/performance/performance-monitor.d.ts.map +1 -0
- package/dist/performance/performance-monitor.js +253 -0
- package/dist/performance/performance-monitor.js.map +1 -0
- package/dist/sdk/bc-code-intel-client.d.ts +175 -0
- package/dist/sdk/bc-code-intel-client.d.ts.map +1 -0
- package/dist/sdk/bc-code-intel-client.js +380 -0
- package/dist/sdk/bc-code-intel-client.js.map +1 -0
- package/dist/search/intelligent-search.d.ts +97 -0
- package/dist/search/intelligent-search.d.ts.map +1 -0
- package/dist/search/intelligent-search.js +358 -0
- package/dist/search/intelligent-search.js.map +1 -0
- package/dist/security/access-control.d.ts +110 -0
- package/dist/security/access-control.d.ts.map +1 -0
- package/dist/security/access-control.js +353 -0
- package/dist/security/access-control.js.map +1 -0
- package/dist/services/code-analysis-service.d.ts +72 -0
- package/dist/services/code-analysis-service.d.ts.map +1 -0
- package/dist/services/code-analysis-service.js +818 -0
- package/dist/services/code-analysis-service.js.map +1 -0
- package/dist/services/enhanced-prompt-service.d.ts +56 -0
- package/dist/services/enhanced-prompt-service.d.ts.map +1 -0
- package/dist/services/enhanced-prompt-service.js +165 -0
- package/dist/services/enhanced-prompt-service.js.map +1 -0
- package/dist/services/knowledge-service.d.ts +90 -0
- package/dist/services/knowledge-service.d.ts.map +1 -0
- package/dist/services/knowledge-service.js +342 -0
- package/dist/services/knowledge-service.js.map +1 -0
- package/dist/services/methodology-service.d.ts +91 -0
- package/dist/services/methodology-service.d.ts.map +1 -0
- package/dist/services/methodology-service.js +423 -0
- package/dist/services/methodology-service.js.map +1 -0
- package/dist/services/multi-content-layer-service.d.ts +198 -0
- package/dist/services/multi-content-layer-service.d.ts.map +1 -0
- package/dist/services/multi-content-layer-service.js +991 -0
- package/dist/services/multi-content-layer-service.js.map +1 -0
- package/dist/services/roleplay-engine.d.ts +161 -0
- package/dist/services/roleplay-engine.d.ts.map +1 -0
- package/dist/services/roleplay-engine.js +994 -0
- package/dist/services/roleplay-engine.js.map +1 -0
- package/dist/services/session-storage/file-storage.d.ts +30 -0
- package/dist/services/session-storage/file-storage.d.ts.map +1 -0
- package/dist/services/session-storage/file-storage.js +229 -0
- package/dist/services/session-storage/file-storage.js.map +1 -0
- package/dist/services/session-storage/in-memory-storage.d.ts +31 -0
- package/dist/services/session-storage/in-memory-storage.d.ts.map +1 -0
- package/dist/services/session-storage/in-memory-storage.js +142 -0
- package/dist/services/session-storage/in-memory-storage.js.map +1 -0
- package/dist/services/specialist-discovery.d.ts +98 -0
- package/dist/services/specialist-discovery.d.ts.map +1 -0
- package/dist/services/specialist-discovery.js +387 -0
- package/dist/services/specialist-discovery.js.map +1 -0
- package/dist/services/specialist-loader.d.ts +101 -0
- package/dist/services/specialist-loader.d.ts.map +1 -0
- package/dist/services/specialist-loader.js +256 -0
- package/dist/services/specialist-loader.js.map +1 -0
- package/dist/services/specialist-session-manager.d.ts +76 -0
- package/dist/services/specialist-session-manager.d.ts.map +1 -0
- package/dist/services/specialist-session-manager.js +255 -0
- package/dist/services/specialist-session-manager.js.map +1 -0
- package/dist/services/workflow-service.d.ts +146 -0
- package/dist/services/workflow-service.d.ts.map +1 -0
- package/dist/services/workflow-service.js +409 -0
- package/dist/services/workflow-service.js.map +1 -0
- package/dist/setup/post-install.d.ts +12 -0
- package/dist/setup/post-install.d.ts.map +1 -0
- package/dist/setup/post-install.js +81 -0
- package/dist/setup/post-install.js.map +1 -0
- package/dist/streamlined-handlers.d.ts +94 -0
- package/dist/streamlined-handlers.d.ts.map +1 -0
- package/dist/streamlined-handlers.js +665 -0
- package/dist/streamlined-handlers.js.map +1 -0
- package/dist/test-enhanced-mcp-server.d.ts +7 -0
- package/dist/test-enhanced-mcp-server.d.ts.map +1 -0
- package/dist/test-enhanced-mcp-server.js +177 -0
- package/dist/test-enhanced-mcp-server.js.map +1 -0
- package/dist/tools/config-diagnostic-tools.d.ts +234 -0
- package/dist/tools/config-diagnostic-tools.d.ts.map +1 -0
- package/dist/tools/config-diagnostic-tools.js +887 -0
- package/dist/tools/config-diagnostic-tools.js.map +1 -0
- package/dist/tools/core-tools.d.ts +26 -0
- package/dist/tools/core-tools.d.ts.map +1 -0
- package/dist/tools/core-tools.js +241 -0
- package/dist/tools/core-tools.js.map +1 -0
- package/dist/tools/handoff-tools.d.ts +37 -0
- package/dist/tools/handoff-tools.d.ts.map +1 -0
- package/dist/tools/handoff-tools.js +265 -0
- package/dist/tools/handoff-tools.js.map +1 -0
- package/dist/tools/index.d.ts +61 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +75 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/onboarding-tools.d.ts +43 -0
- package/dist/tools/onboarding-tools.d.ts.map +1 -0
- package/dist/tools/onboarding-tools.js +353 -0
- package/dist/tools/onboarding-tools.js.map +1 -0
- package/dist/tools/specialist-discovery-tools.d.ts +27 -0
- package/dist/tools/specialist-discovery-tools.d.ts.map +1 -0
- package/dist/tools/specialist-discovery-tools.js +275 -0
- package/dist/tools/specialist-discovery-tools.js.map +1 -0
- package/dist/tools/specialist-tools.d.ts +43 -0
- package/dist/tools/specialist-tools.d.ts.map +1 -0
- package/dist/tools/specialist-tools.js +372 -0
- package/dist/tools/specialist-tools.js.map +1 -0
- package/dist/tools/workspace-tools.d.ts +96 -0
- package/dist/tools/workspace-tools.d.ts.map +1 -0
- package/dist/tools/workspace-tools.js +188 -0
- package/dist/tools/workspace-tools.js.map +1 -0
- package/dist/types/bc-knowledge.d.ts +303 -0
- package/dist/types/bc-knowledge.d.ts.map +1 -0
- package/dist/types/bc-knowledge.js +69 -0
- package/dist/types/bc-knowledge.js.map +1 -0
- package/dist/types/config-types.d.ts +186 -0
- package/dist/types/config-types.d.ts.map +1 -0
- package/dist/types/config-types.js +109 -0
- package/dist/types/config-types.js.map +1 -0
- package/dist/types/enhanced-layer-types.d.ts +193 -0
- package/dist/types/enhanced-layer-types.d.ts.map +1 -0
- package/dist/types/enhanced-layer-types.js +9 -0
- package/dist/types/enhanced-layer-types.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 +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/layer-types.d.ts +173 -0
- package/dist/types/layer-types.d.ts.map +1 -0
- package/dist/types/layer-types.js +27 -0
- package/dist/types/layer-types.js.map +1 -0
- package/dist/types/roleplay-types.d.ts +156 -0
- package/dist/types/roleplay-types.d.ts.map +1 -0
- package/dist/types/roleplay-types.js +8 -0
- package/dist/types/roleplay-types.js.map +1 -0
- package/dist/types/session-types.d.ts +127 -0
- package/dist/types/session-types.d.ts.map +1 -0
- package/dist/types/session-types.js +8 -0
- package/dist/types/session-types.js.map +1 -0
- package/dist/utils/path-utils.d.ts +5 -0
- package/dist/utils/path-utils.d.ts.map +1 -0
- package/dist/utils/path-utils.js +14 -0
- package/dist/utils/path-utils.js.map +1 -0
- package/dist/workflows/domain-workflows.d.ts +8 -0
- package/dist/workflows/domain-workflows.d.ts.map +1 -0
- package/dist/workflows/domain-workflows.js +360 -0
- package/dist/workflows/domain-workflows.js.map +1 -0
- package/embedded-knowledge/.github/ISSUE_TEMPLATE/bug-report.md +24 -0
- package/embedded-knowledge/.github/ISSUE_TEMPLATE/content-improvement.md +24 -0
- package/embedded-knowledge/.github/ISSUE_TEMPLATE/knowledge-request.md +30 -0
- package/embedded-knowledge/AGENTS.md +178 -0
- package/embedded-knowledge/CONTRIBUTING.md +58 -0
- package/embedded-knowledge/LICENSE +21 -0
- package/embedded-knowledge/README.md +32 -0
- package/embedded-knowledge/domains/alex-architect/api-delegate-operation-pattern.md +90 -0
- package/embedded-knowledge/domains/alex-architect/api-fieldset-registration-pattern.md +113 -0
- package/embedded-knowledge/domains/alex-architect/api-interface-design-patterns.md +101 -0
- package/embedded-knowledge/domains/alex-architect/api-page-development-patterns.md +87 -0
- package/embedded-knowledge/domains/alex-architect/complex-facade-patterns.md +155 -0
- package/embedded-knowledge/domains/alex-architect/delegating-to-github-copilot-agents.md +371 -0
- package/embedded-knowledge/domains/alex-architect/facade-pattern-al-implementation.md +138 -0
- package/embedded-knowledge/domains/alex-architect/facade-pattern-external-api.md +79 -0
- package/embedded-knowledge/domains/alex-architect/object-id-ninja-integration.md +281 -0
- package/embedded-knowledge/domains/alex-architect/recommend-object-id-ninja.md +248 -0
- package/embedded-knowledge/domains/alex-architect/samples/api-delegate-operation.md +280 -0
- package/embedded-knowledge/domains/alex-architect/samples/api-fieldset-registration.md +200 -0
- package/embedded-knowledge/domains/alex-architect/samples/api-interface-design.md +565 -0
- package/embedded-knowledge/domains/alex-architect/samples/api-page-implementation.md +665 -0
- package/embedded-knowledge/domains/alex-architect/samples/complex-facade-patterns.md +325 -0
- package/embedded-knowledge/domains/alex-architect/samples/facade-pattern-al.md +696 -0
- package/embedded-knowledge/domains/alex-architect/samples/facade-pattern.md +320 -0
- package/embedded-knowledge/domains/alex-architect/samples/subscriber-organization.md +102 -0
- package/embedded-knowledge/domains/alex-architect/samples/systemid-integration.md +433 -0
- package/embedded-knowledge/domains/alex-architect/samples/testability-design-patterns.md +223 -0
- package/embedded-knowledge/domains/alex-architect/subscriber-codeunit-size-optimization.md +66 -0
- package/embedded-knowledge/domains/alex-architect/systemid-integration.md +115 -0
- package/embedded-knowledge/domains/alex-architect/testability-design-patterns.md +77 -0
- package/embedded-knowledge/domains/casey-copilot/long-running-session-instructions.md +263 -0
- package/embedded-knowledge/domains/casey-copilot/samples/long-running-session-instructions.md +323 -0
- package/embedded-knowledge/domains/chris-config/configuration-file-discovery.md +846 -0
- package/embedded-knowledge/domains/chris-config/configuration-file-formats.md +595 -0
- package/embedded-knowledge/domains/chris-config/content-types-structure.md +421 -0
- package/embedded-knowledge/domains/chris-config/knowledge-content-creation.md +437 -0
- package/embedded-knowledge/domains/chris-config/layer-system-fundamentals.md +257 -0
- package/embedded-knowledge/domains/chris-config/multi-team-layer-configuration.md +302 -0
- package/embedded-knowledge/domains/chris-config/workspace-detection-solutions.md +336 -0
- package/embedded-knowledge/domains/dean-debug/bc-telemetry-buddy-integration.md +453 -0
- package/embedded-knowledge/domains/dean-debug/bc24-no-series-conversion-guide.md +360 -0
- package/embedded-knowledge/domains/dean-debug/case-statement-performance-best-practices.md +86 -0
- package/embedded-knowledge/domains/dean-debug/compound-statements-debugging.md +96 -0
- package/embedded-knowledge/domains/dean-debug/custom-dimensions-best-practices.md +70 -0
- package/embedded-knowledge/domains/dean-debug/custom-telemetry-implementation.md +84 -0
- package/embedded-knowledge/domains/dean-debug/deleteall-performance-tradeoff.md +93 -0
- package/embedded-knowledge/domains/dean-debug/deleteall-sql-performance.md +73 -0
- package/embedded-knowledge/domains/dean-debug/extension-telemetry-isolation.md +78 -0
- package/embedded-knowledge/domains/dean-debug/maintainsiftindex-property-behavior.md +79 -0
- package/embedded-knowledge/domains/dean-debug/no-series-implementation-patterns.md +87 -0
- package/embedded-knowledge/domains/dean-debug/no-series-module-patterns-bc24.md +209 -0
- package/embedded-knowledge/domains/dean-debug/no-series-validation-module-bc24.md +246 -0
- package/embedded-knowledge/domains/dean-debug/no-series-validation-patterns.md +107 -0
- package/embedded-knowledge/domains/dean-debug/odata-query-optimization.md +105 -0
- package/embedded-knowledge/domains/dean-debug/recommend-bc-telemetry-buddy.md +160 -0
- package/embedded-knowledge/domains/dean-debug/samples/bc24-no-series-conversion.md +186 -0
- package/embedded-knowledge/domains/dean-debug/samples/case-performance-optimization.md +60 -0
- package/embedded-knowledge/domains/dean-debug/samples/compound-statements-debugging.md +139 -0
- package/embedded-knowledge/domains/dean-debug/samples/custom-dimensions.md +190 -0
- package/embedded-knowledge/domains/dean-debug/samples/custom-telemetry.md +516 -0
- package/embedded-knowledge/domains/dean-debug/samples/deleteall-performance.md +298 -0
- package/embedded-knowledge/domains/dean-debug/samples/error-correlation.md +324 -0
- package/embedded-knowledge/domains/dean-debug/samples/extension-isolation.md +344 -0
- package/embedded-knowledge/domains/dean-debug/samples/logmessage-methods.md +137 -0
- package/embedded-knowledge/domains/dean-debug/samples/maintainsiftindex-examples.md +340 -0
- package/embedded-knowledge/domains/dean-debug/samples/no-series-implementation.md +810 -0
- package/embedded-knowledge/domains/dean-debug/samples/no-series-module-bc24.md +86 -0
- package/embedded-knowledge/domains/dean-debug/samples/no-series-validation-module-bc24.md +110 -0
- package/embedded-knowledge/domains/dean-debug/samples/no-series-validation.md +758 -0
- package/embedded-knowledge/domains/dean-debug/samples/odata-query-optimization.md +665 -0
- package/embedded-knowledge/domains/dean-debug/samples/setloadfields-before-case.md +316 -0
- package/embedded-knowledge/domains/dean-debug/samples/setloadfields-before-filters.md +223 -0
- package/embedded-knowledge/domains/dean-debug/samples/setloadfields-filter-exclusion.md +149 -0
- package/embedded-knowledge/domains/dean-debug/samples/setloadfields-optimization.md +412 -0
- package/embedded-knowledge/domains/dean-debug/samples/setloadfields-performance.md +211 -0
- package/embedded-knowledge/domains/dean-debug/samples/setloadfields-primary-key.md +155 -0
- package/embedded-knowledge/domains/dean-debug/samples/sift-technology-fundamentals.md +475 -0
- package/embedded-knowledge/domains/dean-debug/samples/singleinstance-subscribers.md +238 -0
- package/embedded-knowledge/domains/dean-debug/samples/table-event-batching.md +97 -0
- package/embedded-knowledge/domains/dean-debug/samples/table-key-requirements.md +666 -0
- package/embedded-knowledge/domains/dean-debug/samples/telemetry-performance.md +319 -0
- package/embedded-knowledge/domains/dean-debug/samples/verbosity-strategy.md +236 -0
- package/embedded-knowledge/domains/dean-debug/session-logmessage-methods.md +59 -0
- package/embedded-knowledge/domains/dean-debug/setloadfields-filter-field-exclusion.md +67 -0
- package/embedded-knowledge/domains/dean-debug/setloadfields-performance-impact.md +70 -0
- package/embedded-knowledge/domains/dean-debug/setloadfields-performance-optimization.md +90 -0
- package/embedded-knowledge/domains/dean-debug/setloadfields-placement-before-case-statements.md +87 -0
- package/embedded-knowledge/domains/dean-debug/setloadfields-placement-before-filters.md +70 -0
- package/embedded-knowledge/domains/dean-debug/setloadfields-primary-key-optimization.md +74 -0
- package/embedded-knowledge/domains/dean-debug/sift-technology-fundamentals.md +81 -0
- package/embedded-knowledge/domains/dean-debug/subscriber-singleinstance-performance.md +56 -0
- package/embedded-knowledge/domains/dean-debug/table-event-batch-operation-impact.md +66 -0
- package/embedded-knowledge/domains/dean-debug/table-key-requirements.md +79 -0
- package/embedded-knowledge/domains/dean-debug/telemetry-error-correlation.md +78 -0
- package/embedded-knowledge/domains/dean-debug/telemetry-performance-considerations.md +83 -0
- package/embedded-knowledge/domains/dean-debug/telemetry-verbosity-strategy.md +76 -0
- package/embedded-knowledge/domains/dean-debug/testfield-performance.md +104 -0
- package/embedded-knowledge/domains/eva-errors/codeunit-run-pattern.md +159 -0
- package/embedded-knowledge/domains/eva-errors/fielderror-default-messages.md +145 -0
- package/embedded-knowledge/domains/eva-errors/fielderror-message-construction.md +104 -0
- package/embedded-knowledge/domains/eva-errors/fielderror-method-syntax.md +114 -0
- package/embedded-knowledge/domains/eva-errors/samples/codeunit-run-pattern.md +239 -0
- package/embedded-knowledge/domains/eva-errors/samples/fielderror-default-messages.md +356 -0
- package/embedded-knowledge/domains/eva-errors/samples/fielderror-syntax.md +256 -0
- package/embedded-knowledge/domains/eva-errors/samples/table-safety-validation-patterns.md +101 -0
- package/embedded-knowledge/domains/eva-errors/samples/testfield-error-handling.md +108 -0
- package/embedded-knowledge/domains/eva-errors/samples/try-function-usage.md +195 -0
- package/embedded-knowledge/domains/eva-errors/testfield-error-handling.md +80 -0
- package/embedded-knowledge/domains/eva-errors/try-function-usage.md +129 -0
- package/embedded-knowledge/domains/jordan-bridge/al-event-subscriber-architecture.md +98 -0
- package/embedded-knowledge/domains/jordan-bridge/automatic-registration.md +123 -0
- package/embedded-knowledge/domains/jordan-bridge/business-process-template-patterns.md +96 -0
- package/embedded-knowledge/domains/jordan-bridge/error-response-patterns.md +115 -0
- package/embedded-knowledge/domains/jordan-bridge/etag-implementation.md +115 -0
- package/embedded-knowledge/domains/jordan-bridge/field-control-selection.md +114 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/al-event-subscriber-architecture.md +395 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/api-error-responses.md +479 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/api-field-control.md +548 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/api-url-naming.md +287 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/business-process-templates.md +434 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/etag-implementation.md +508 -0
- package/embedded-knowledge/domains/jordan-bridge/samples/task-scheduler-pattern.md +615 -0
- package/embedded-knowledge/domains/jordan-bridge/task-scheduler-pattern-implementation.md +144 -0
- package/embedded-knowledge/domains/jordan-bridge/url-structure-naming-patterns.md +96 -0
- package/embedded-knowledge/domains/maya-mentor/case-multiple-conditions-ranges.md +124 -0
- package/embedded-knowledge/domains/maya-mentor/case-statement-syntax-structure.md +84 -0
- package/embedded-knowledge/domains/maya-mentor/fielderror-syntax-usage.md +75 -0
- package/embedded-knowledge/domains/maya-mentor/fielderror-vs-testfield.md +96 -0
- package/embedded-knowledge/domains/maya-mentor/samples/case-statement-multiple-conditions.md +385 -0
- package/embedded-knowledge/domains/maya-mentor/samples/case-statement-syntax-structure.md +72 -0
- package/embedded-knowledge/domains/maya-mentor/samples/fielderror-syntax-usage.md +48 -0
- package/embedded-knowledge/domains/maya-mentor/samples/testfield-basic-syntax.md +49 -0
- package/embedded-knowledge/domains/maya-mentor/testfield-basic-syntax.md +67 -0
- package/embedded-knowledge/domains/morgan-market/partner-readiness-analysis.md +201 -0
- package/embedded-knowledge/domains/morgan-market/samples/partner-readiness-checklist.md +288 -0
- package/embedded-knowledge/domains/parker-pragmatic/README.md +39 -0
- package/embedded-knowledge/domains/parker-pragmatic/proposal-workflows/creating-effective-proposals.md +583 -0
- package/embedded-knowledge/domains/parker-pragmatic/trust-building/working-with-ai-skeptics.md +587 -0
- package/embedded-knowledge/domains/quinn-tester/fielderror-validation-patterns.md +119 -0
- package/embedded-knowledge/domains/quinn-tester/isolation-testing-patterns.md +82 -0
- package/embedded-knowledge/domains/quinn-tester/rule-execution.md +123 -0
- package/embedded-knowledge/domains/quinn-tester/samples/case-error-handling.md +64 -0
- package/embedded-knowledge/domains/quinn-tester/samples/fielderror-message-construction.md +60 -0
- package/embedded-knowledge/domains/quinn-tester/samples/fielderror-validation-patterns.md +83 -0
- package/embedded-knowledge/domains/quinn-tester/samples/isolation-testing-patterns.md +424 -0
- package/embedded-knowledge/domains/quinn-tester/samples/rule-execution.md +716 -0
- package/embedded-knowledge/domains/quinn-tester/samples/table-safety-validation-patterns.md +101 -0
- package/embedded-knowledge/domains/quinn-tester/samples/temporary-table-operation-validation.md +91 -0
- package/embedded-knowledge/domains/quinn-tester/table-safety-validation-patterns.md +79 -0
- package/embedded-knowledge/domains/quinn-tester/temporary-table-operation-validation.md +79 -0
- package/embedded-knowledge/domains/roger-reviewer/al-begin-end-block-structure.md +89 -0
- package/embedded-knowledge/domains/roger-reviewer/al-binary-operator-spacing.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-blank-line-organization.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-case-action-formatting.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-code-spacing-conventions.md +81 -0
- package/embedded-knowledge/domains/roger-reviewer/al-comment-spacing-standards.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-end-else-pairing.md +75 -0
- package/embedded-knowledge/domains/roger-reviewer/al-keyword-indentation-rules.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-line-start-keyword-positioning.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-separate-if-else-formatting.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-standard-abbreviations.md +96 -0
- package/embedded-knowledge/domains/roger-reviewer/al-statement-per-line-rule.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/al-unnecessary-else-elimination.md +86 -0
- package/embedded-knowledge/domains/roger-reviewer/al-variable-declaration-order.md +90 -0
- package/embedded-knowledge/domains/roger-reviewer/al-variable-naming-conventions.md +82 -0
- package/embedded-knowledge/domains/roger-reviewer/begin-block-statement-clarity.md +78 -0
- package/embedded-knowledge/domains/roger-reviewer/begin-end-positioning-patterns.md +76 -0
- package/embedded-knowledge/domains/roger-reviewer/binary-operator-line-positioning.md +78 -0
- package/embedded-knowledge/domains/roger-reviewer/boolean-expression-simplification-al.md +100 -0
- package/embedded-knowledge/domains/roger-reviewer/case-statement-error-handling-troubleshooting.md +115 -0
- package/embedded-knowledge/domains/roger-reviewer/compound-statement-readability.md +124 -0
- package/embedded-knowledge/domains/roger-reviewer/lonely-repeat-statement-pattern.md +110 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-begin-end-blocks.md +438 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-binary-operator-spacing.md +255 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-comment-spacing-standards.md +209 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-keyword-indentation-rules.md +218 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-line-start-keyword-positioning.md +218 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-separate-if-else-formatting.md +280 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-statement-per-line-rule.md +188 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-unnecessary-else-elimination.md +245 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/al-variable-declaration-order.md +244 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/begin-end-positioning.md +278 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/boolean-simplification-examples.md +484 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/case-error-handling.md +64 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/compound-statement-readability.md +107 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/lonely-repeat-examples.md +280 -0
- package/embedded-knowledge/domains/roger-reviewer/samples/testability-code-smells.md +256 -0
- package/embedded-knowledge/domains/roger-reviewer/testability-code-smells.md +67 -0
- package/embedded-knowledge/domains/sam-coder/al-formatting-consistency-patterns.md +75 -0
- package/embedded-knowledge/domains/sam-coder/al-line-comment-formatting.md +67 -0
- package/embedded-knowledge/domains/sam-coder/al-lonely-repeat-pattern.md +76 -0
- package/embedded-knowledge/domains/sam-coder/al-named-parameter-pattern.md +98 -0
- package/embedded-knowledge/domains/sam-coder/al-object-navigation-shortcuts.md +128 -0
- package/embedded-knowledge/domains/sam-coder/al-readability-optimization.md +75 -0
- package/embedded-knowledge/domains/sam-coder/al-record-find-early-exit.md +95 -0
- package/embedded-knowledge/domains/sam-coder/command-queue-pattern-al.md +141 -0
- package/embedded-knowledge/domains/sam-coder/deleteall-alternative-implementation.md +91 -0
- package/embedded-knowledge/domains/sam-coder/deleteall-method-usage.md +118 -0
- package/embedded-knowledge/domains/sam-coder/deleteall-trigger-execution.md +111 -0
- package/embedded-knowledge/domains/sam-coder/event-bridge-pattern-al.md +113 -0
- package/embedded-knowledge/domains/sam-coder/event-payload-design-patterns.md +127 -0
- package/embedded-knowledge/domains/sam-coder/generic-method-patterns-al.md +141 -0
- package/embedded-knowledge/domains/sam-coder/manual-binding-conditional-subscribers.md +66 -0
- package/embedded-knowledge/domains/sam-coder/nested-compound-best-practices.md +96 -0
- package/embedded-knowledge/domains/sam-coder/samples/al-blank-line-organization.md +161 -0
- package/embedded-knowledge/domains/sam-coder/samples/al-case-action-formatting.md +177 -0
- package/embedded-knowledge/domains/sam-coder/samples/al-lonely-repeat-pattern.md +239 -0
- package/embedded-knowledge/domains/sam-coder/samples/al-named-parameter-pattern.md +346 -0
- package/embedded-knowledge/domains/sam-coder/samples/al-record-find-early-exit.md +298 -0
- package/embedded-knowledge/domains/sam-coder/samples/command-queue-pattern.md +677 -0
- package/embedded-knowledge/domains/sam-coder/samples/deleteall-alternative-implementation.md +117 -0
- package/embedded-knowledge/domains/sam-coder/samples/deleteall-triggers.md +75 -0
- package/embedded-knowledge/domains/sam-coder/samples/deleteall-usage.md +169 -0
- package/embedded-knowledge/domains/sam-coder/samples/event-bridge-pattern.md +399 -0
- package/embedded-knowledge/domains/sam-coder/samples/event-payload-design.md +356 -0
- package/embedded-knowledge/domains/sam-coder/samples/generic-method-patterns.md +889 -0
- package/embedded-knowledge/domains/sam-coder/samples/manual-binding.md +84 -0
- package/embedded-knowledge/domains/sam-coder/samples/nested-compound-best-practices.md +127 -0
- package/embedded-knowledge/domains/sam-coder/samples/single-to-compound-conversion.md +89 -0
- package/embedded-knowledge/domains/sam-coder/samples/template-method-pattern.md +516 -0
- package/embedded-knowledge/domains/sam-coder/samples/testfield-patterns.md +61 -0
- package/embedded-knowledge/domains/sam-coder/samples/type-safe-operations.md +427 -0
- package/embedded-knowledge/domains/sam-coder/single-to-compound-conversion.md +122 -0
- package/embedded-knowledge/domains/sam-coder/template-method-pattern-al.md +96 -0
- package/embedded-knowledge/domains/sam-coder/testfield-patterns.md +101 -0
- package/embedded-knowledge/domains/sam-coder/type-safe-operations-al.md +149 -0
- package/embedded-knowledge/domains/sam-coder/vs-code-al-keyboard-shortcuts.md +107 -0
- package/embedded-knowledge/domains/seth-security/al-temporary-table-safety.md +95 -0
- package/embedded-knowledge/domains/seth-security/api-permission-model.md +115 -0
- package/embedded-knowledge/domains/seth-security/istemporary-safeguard-pattern.md +78 -0
- package/embedded-knowledge/domains/seth-security/samples/al-temporary-table-safety.md +373 -0
- package/embedded-knowledge/domains/seth-security/samples/api-permission-model.md +308 -0
- package/embedded-knowledge/domains/shared/al-file-naming-conventions.md +146 -0
- package/embedded-knowledge/domains/taylor-docs/al-xml-documentation-structure.md +79 -0
- package/embedded-knowledge/domains/uma-ux/bc-action-shortcuts-syntax.md +78 -0
- package/embedded-knowledge/domains/uma-ux/shortcut-key-user-experience-design.md +81 -0
- package/embedded-knowledge/indexes/bc-version-matrix.json +188 -0
- package/embedded-knowledge/indexes/domain-catalog.json +106 -0
- package/embedded-knowledge/indexes/tags/abbreviations.json +1 -0
- package/embedded-knowledge/indexes/tags/abstraction.json +1 -0
- package/embedded-knowledge/indexes/tags/access-control.json +1 -0
- package/embedded-knowledge/indexes/tags/accessibility.json +1 -0
- package/embedded-knowledge/indexes/tags/actions.json +1 -0
- package/embedded-knowledge/indexes/tags/advanced-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/advanced.json +1 -0
- package/embedded-knowledge/indexes/tags/al-extension.json +1 -0
- package/embedded-knowledge/indexes/tags/al-generics.json +1 -0
- package/embedded-knowledge/indexes/tags/al-objects.json +1 -0
- package/embedded-knowledge/indexes/tags/al-syntax.json +1 -0
- package/embedded-knowledge/indexes/tags/algorithm-structure.json +1 -0
- package/embedded-knowledge/indexes/tags/alternatives.json +1 -0
- package/embedded-knowledge/indexes/tags/analytics.json +1 -0
- package/embedded-knowledge/indexes/tags/api-delegates.json +1 -0
- package/embedded-knowledge/indexes/tags/api-design.json +1 -0
- package/embedded-knowledge/indexes/tags/api-documentation.json +1 -0
- package/embedded-knowledge/indexes/tags/api-endpoints.json +1 -0
- package/embedded-knowledge/indexes/tags/api-extensibility.json +1 -0
- package/embedded-knowledge/indexes/tags/api-fieldsets.json +1 -0
- package/embedded-knowledge/indexes/tags/api-integration.json +1 -0
- package/embedded-knowledge/indexes/tags/api-interfaces.json +1 -0
- package/embedded-knowledge/indexes/tags/api-optimization.json +1 -0
- package/embedded-knowledge/indexes/tags/api-pages.json +1 -0
- package/embedded-knowledge/indexes/tags/api-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/api-permissions.json +1 -0
- package/embedded-knowledge/indexes/tags/api-responses.json +1 -0
- package/embedded-knowledge/indexes/tags/api-simplification.json +1 -0
- package/embedded-knowledge/indexes/tags/api.json +1 -0
- package/embedded-knowledge/indexes/tags/architecture.json +1 -0
- package/embedded-knowledge/indexes/tags/async-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/async-processing.json +1 -0
- package/embedded-knowledge/indexes/tags/automatic-registration.json +1 -0
- package/embedded-knowledge/indexes/tags/batch-operations.json +1 -0
- package/embedded-knowledge/indexes/tags/bc24-migration.json +1 -0
- package/embedded-knowledge/indexes/tags/begin-blocks.json +1 -0
- package/embedded-knowledge/indexes/tags/begin-end.json +1 -0
- package/embedded-knowledge/indexes/tags/behavioral-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/best-practices.json +1 -0
- package/embedded-knowledge/indexes/tags/binding.json +1 -0
- package/embedded-knowledge/indexes/tags/block-structure.json +1 -0
- package/embedded-knowledge/indexes/tags/blocks.json +1 -0
- package/embedded-knowledge/indexes/tags/boolean-expressions.json +1 -0
- package/embedded-knowledge/indexes/tags/branching.json +1 -0
- package/embedded-knowledge/indexes/tags/breaking-changes.json +1 -0
- package/embedded-knowledge/indexes/tags/breakpoints.json +1 -0
- package/embedded-knowledge/indexes/tags/business-foundation.json +1 -0
- package/embedded-knowledge/indexes/tags/business-infrastructure.json +1 -0
- package/embedded-knowledge/indexes/tags/business-process.json +1 -0
- package/embedded-knowledge/indexes/tags/business-rules.json +1 -0
- package/embedded-knowledge/indexes/tags/caching.json +1 -0
- package/embedded-knowledge/indexes/tags/case-statements.json +1 -0
- package/embedded-knowledge/indexes/tags/case.json +1 -0
- package/embedded-knowledge/indexes/tags/code-analysis.json +1 -0
- package/embedded-knowledge/indexes/tags/code-clarity.json +1 -0
- package/embedded-knowledge/indexes/tags/code-comprehension.json +1 -0
- package/embedded-knowledge/indexes/tags/code-conversion.json +1 -0
- package/embedded-knowledge/indexes/tags/code-formatting.json +1 -0
- package/embedded-knowledge/indexes/tags/code-organization.json +1 -0
- package/embedded-knowledge/indexes/tags/code-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/code-quality.json +1 -0
- package/embedded-knowledge/indexes/tags/code-reuse.json +1 -0
- package/embedded-knowledge/indexes/tags/code-simplification.json +1 -0
- package/embedded-knowledge/indexes/tags/code-standards.json +1 -0
- package/embedded-knowledge/indexes/tags/code-structure.json +1 -0
- package/embedded-knowledge/indexes/tags/code-style.json +1 -0
- package/embedded-knowledge/indexes/tags/codeunit-design.json +1 -0
- package/embedded-knowledge/indexes/tags/command-queue.json +1 -0
- package/embedded-knowledge/indexes/tags/comments.json +1 -0
- package/embedded-knowledge/indexes/tags/compile-time-validation.json +1 -0
- package/embedded-knowledge/indexes/tags/complex-facade.json +1 -0
- package/embedded-knowledge/indexes/tags/complexity-hiding.json +1 -0
- package/embedded-knowledge/indexes/tags/complexity-management.json +1 -0
- package/embedded-knowledge/indexes/tags/compound-statements.json +1 -0
- package/embedded-knowledge/indexes/tags/concurrency.json +1 -0
- package/embedded-knowledge/indexes/tags/conditional-logic.json +1 -0
- package/embedded-knowledge/indexes/tags/conditional.json +1 -0
- package/embedded-knowledge/indexes/tags/conflict-resolution.json +1 -0
- package/embedded-knowledge/indexes/tags/consistency.json +1 -0
- package/embedded-knowledge/indexes/tags/contract-design.json +1 -0
- package/embedded-knowledge/indexes/tags/control-flow.json +1 -0
- package/embedded-knowledge/indexes/tags/conversion-guide.json +1 -0
- package/embedded-knowledge/indexes/tags/correlation.json +1 -0
- package/embedded-knowledge/indexes/tags/custom-messages.json +1 -0
- package/embedded-knowledge/indexes/tags/data-access.json +1 -0
- package/embedded-knowledge/indexes/tags/data-exposure.json +1 -0
- package/embedded-knowledge/indexes/tags/data-integrity.json +1 -0
- package/embedded-knowledge/indexes/tags/data-loading.json +1 -0
- package/embedded-knowledge/indexes/tags/data-manipulation.json +1 -0
- package/embedded-knowledge/indexes/tags/data-modeling.json +1 -0
- package/embedded-knowledge/indexes/tags/data-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/data-protection.json +1 -0
- package/embedded-knowledge/indexes/tags/data-validation.json +1 -0
- package/embedded-knowledge/indexes/tags/database.json +1 -0
- package/embedded-knowledge/indexes/tags/debugging.json +1 -0
- package/embedded-knowledge/indexes/tags/decision-making.json +1 -0
- package/embedded-knowledge/indexes/tags/declaration.json +1 -0
- package/embedded-knowledge/indexes/tags/default-messages.json +1 -0
- package/embedded-knowledge/indexes/tags/defensive-programming.json +1 -0
- package/embedded-knowledge/indexes/tags/deleteall.json +1 -0
- package/embedded-knowledge/indexes/tags/dependencies.json +1 -0
- package/embedded-knowledge/indexes/tags/deployment.json +1 -0
- package/embedded-knowledge/indexes/tags/developer-productivity.json +1 -0
- package/embedded-knowledge/indexes/tags/development-workflow.json +1 -0
- package/embedded-knowledge/indexes/tags/diagnostics.json +1 -0
- package/embedded-knowledge/indexes/tags/dimensions.json +1 -0
- package/embedded-knowledge/indexes/tags/documentation.json +1 -0
- package/embedded-knowledge/indexes/tags/early-exit.json +1 -0
- package/embedded-knowledge/indexes/tags/else-clauses.json +1 -0
- package/embedded-knowledge/indexes/tags/end-statements.json +1 -0
- package/embedded-knowledge/indexes/tags/enterprise-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/entity-relationships.json +1 -0
- package/embedded-knowledge/indexes/tags/error-handling.json +1 -0
- package/embedded-knowledge/indexes/tags/error-messages.json +1 -0
- package/embedded-knowledge/indexes/tags/error-prevention.json +1 -0
- package/embedded-knowledge/indexes/tags/error-text.json +1 -0
- package/embedded-knowledge/indexes/tags/etag.json +1 -0
- package/embedded-knowledge/indexes/tags/event-bridge.json +1 -0
- package/embedded-knowledge/indexes/tags/event-payload.json +1 -0
- package/embedded-knowledge/indexes/tags/event-routing.json +1 -0
- package/embedded-knowledge/indexes/tags/events.json +1 -0
- package/embedded-knowledge/indexes/tags/execution-flow.json +1 -0
- package/embedded-knowledge/indexes/tags/expressions.json +1 -0
- package/embedded-knowledge/indexes/tags/extensibility.json +1 -0
- package/embedded-knowledge/indexes/tags/extensions.json +1 -0
- package/embedded-knowledge/indexes/tags/facade-composition.json +1 -0
- package/embedded-knowledge/indexes/tags/facade-pattern.json +1 -0
- package/embedded-knowledge/indexes/tags/field-control.json +1 -0
- package/embedded-knowledge/indexes/tags/field-exclusion.json +1 -0
- package/embedded-knowledge/indexes/tags/field-registration.json +1 -0
- package/embedded-knowledge/indexes/tags/field-state.json +1 -0
- package/embedded-knowledge/indexes/tags/field-validation.json +1 -0
- package/embedded-knowledge/indexes/tags/fielderror.json +1 -0
- package/embedded-knowledge/indexes/tags/fields.json +1 -0
- package/embedded-knowledge/indexes/tags/filtering.json +1 -0
- package/embedded-knowledge/indexes/tags/filters.json +1 -0
- package/embedded-knowledge/indexes/tags/formatting.json +1 -0
- package/embedded-knowledge/indexes/tags/generic-methods.json +1 -0
- package/embedded-knowledge/indexes/tags/http-status.json +1 -0
- package/embedded-knowledge/indexes/tags/if-statements.json +1 -0
- package/embedded-knowledge/indexes/tags/implementation.json +1 -0
- package/embedded-knowledge/indexes/tags/indentation.json +1 -0
- package/embedded-knowledge/indexes/tags/index-summary.json +277 -0
- package/embedded-knowledge/indexes/tags/indexing.json +1 -0
- package/embedded-knowledge/indexes/tags/inheritance.json +1 -0
- package/embedded-knowledge/indexes/tags/integration.json +1 -0
- package/embedded-knowledge/indexes/tags/integrity-checking.json +1 -0
- package/embedded-knowledge/indexes/tags/intellisense.json +1 -0
- package/embedded-knowledge/indexes/tags/interface-design.json +1 -0
- package/embedded-knowledge/indexes/tags/interface-segregation.json +1 -0
- package/embedded-knowledge/indexes/tags/isolation.json +1 -0
- package/embedded-knowledge/indexes/tags/job-processing.json +1 -0
- package/embedded-knowledge/indexes/tags/keyboard-navigation.json +1 -0
- package/embedded-knowledge/indexes/tags/keywords.json +1 -0
- package/embedded-knowledge/indexes/tags/legacy-modernization.json +1 -0
- package/embedded-knowledge/indexes/tags/line-breaks.json +1 -0
- package/embedded-knowledge/indexes/tags/line-organization.json +1 -0
- package/embedded-knowledge/indexes/tags/line-positioning.json +1 -0
- package/embedded-knowledge/indexes/tags/localization.json +1 -0
- package/embedded-knowledge/indexes/tags/logging.json +1 -0
- package/embedded-knowledge/indexes/tags/loose-coupling.json +1 -0
- package/embedded-knowledge/indexes/tags/maintainability.json +1 -0
- package/embedded-knowledge/indexes/tags/memory-management.json +1 -0
- package/embedded-knowledge/indexes/tags/memory-optimization.json +1 -0
- package/embedded-knowledge/indexes/tags/memory.json +1 -0
- package/embedded-knowledge/indexes/tags/message-design.json +1 -0
- package/embedded-knowledge/indexes/tags/message-formatting.json +1 -0
- package/embedded-knowledge/indexes/tags/message-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/metadata-driven.json +1 -0
- package/embedded-knowledge/indexes/tags/method-comparison.json +1 -0
- package/embedded-knowledge/indexes/tags/module-architecture.json +1 -0
- package/embedded-knowledge/indexes/tags/module-validation.json +1 -0
- package/embedded-knowledge/indexes/tags/monitoring.json +1 -0
- package/embedded-knowledge/indexes/tags/multi-layer-facade.json +1 -0
- package/embedded-knowledge/indexes/tags/multi-tenancy.json +1 -0
- package/embedded-knowledge/indexes/tags/multiple-values.json +1 -0
- package/embedded-knowledge/indexes/tags/naming-conventions.json +1 -0
- package/embedded-knowledge/indexes/tags/naming.json +1 -0
- package/embedded-knowledge/indexes/tags/navigation.json +1 -0
- package/embedded-knowledge/indexes/tags/nested-statements.json +1 -0
- package/embedded-knowledge/indexes/tags/no-series-conversion.json +1 -0
- package/embedded-knowledge/indexes/tags/no-series-validation.json +1 -0
- package/embedded-knowledge/indexes/tags/no-series.json +1 -0
- package/embedded-knowledge/indexes/tags/number-generation.json +1 -0
- package/embedded-knowledge/indexes/tags/object-documentation.json +1 -0
- package/embedded-knowledge/indexes/tags/odata.json +1 -0
- package/embedded-knowledge/indexes/tags/ondelete.json +1 -0
- package/embedded-knowledge/indexes/tags/onvalidate.json +1 -0
- package/embedded-knowledge/indexes/tags/operation-delegation.json +1 -0
- package/embedded-knowledge/indexes/tags/operation-safety.json +1 -0
- package/embedded-knowledge/indexes/tags/operators.json +1 -0
- package/embedded-knowledge/indexes/tags/optimization.json +1 -0
- package/embedded-knowledge/indexes/tags/order.json +1 -0
- package/embedded-knowledge/indexes/tags/organization.json +1 -0
- package/embedded-knowledge/indexes/tags/pages.json +1 -0
- package/embedded-knowledge/indexes/tags/parameters.json +1 -0
- package/embedded-knowledge/indexes/tags/patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/performance-optimization.json +1 -0
- package/embedded-knowledge/indexes/tags/performance.json +1 -0
- package/embedded-knowledge/indexes/tags/placement.json +1 -0
- package/embedded-knowledge/indexes/tags/posting-codeunits.json +1 -0
- package/embedded-knowledge/indexes/tags/posting.json +1 -0
- package/embedded-knowledge/indexes/tags/preconditions.json +1 -0
- package/embedded-knowledge/indexes/tags/primary-key.json +1 -0
- package/embedded-knowledge/indexes/tags/privacy.json +1 -0
- package/embedded-knowledge/indexes/tags/process-automation.json +1 -0
- package/embedded-knowledge/indexes/tags/production.json +1 -0
- package/embedded-knowledge/indexes/tags/productivity.json +1 -0
- package/embedded-knowledge/indexes/tags/query-performance.json +1 -0
- package/embedded-knowledge/indexes/tags/queue-management.json +1 -0
- package/embedded-knowledge/indexes/tags/ranges.json +1 -0
- package/embedded-knowledge/indexes/tags/readability.json +1 -0
- package/embedded-knowledge/indexes/tags/record-access.json +1 -0
- package/embedded-knowledge/indexes/tags/record-methods.json +1 -0
- package/embedded-knowledge/indexes/tags/refactoring.json +1 -0
- package/embedded-knowledge/indexes/tags/reference.json +1 -0
- package/embedded-knowledge/indexes/tags/repeat-loops.json +1 -0
- package/embedded-knowledge/indexes/tags/repeat-statement.json +1 -0
- package/embedded-knowledge/indexes/tags/runtime-errors.json +1 -0
- package/embedded-knowledge/indexes/tags/runtime.json +1 -0
- package/embedded-knowledge/indexes/tags/safeguards.json +1 -0
- package/embedded-knowledge/indexes/tags/security.json +1 -0
- package/embedded-knowledge/indexes/tags/sequence-management.json +1 -0
- package/embedded-knowledge/indexes/tags/serialization.json +1 -0
- package/embedded-knowledge/indexes/tags/session-logmessage.json +1 -0
- package/embedded-knowledge/indexes/tags/session.json +1 -0
- package/embedded-knowledge/indexes/tags/setloadfields.json +1 -0
- package/embedded-knowledge/indexes/tags/shortcuts.json +1 -0
- package/embedded-knowledge/indexes/tags/sift.json +1 -0
- package/embedded-knowledge/indexes/tags/singleinstance.json +1 -0
- package/embedded-knowledge/indexes/tags/spacing.json +1 -0
- package/embedded-knowledge/indexes/tags/sql-translation.json +1 -0
- package/embedded-knowledge/indexes/tags/standards.json +1 -0
- package/embedded-knowledge/indexes/tags/statements.json +1 -0
- package/embedded-knowledge/indexes/tags/streaming.json +1 -0
- package/embedded-knowledge/indexes/tags/strong-typing.json +1 -0
- package/embedded-knowledge/indexes/tags/structural-patterns.json +1 -0
- package/embedded-knowledge/indexes/tags/structure.json +1 -0
- package/embedded-knowledge/indexes/tags/subscribers.json +1 -0
- package/embedded-knowledge/indexes/tags/switch.json +1 -0
- package/embedded-knowledge/indexes/tags/symbol-search.json +1 -0
- package/embedded-knowledge/indexes/tags/syntax.json +1 -0
- package/embedded-knowledge/indexes/tags/systemid.json +1 -0
- package/embedded-knowledge/indexes/tags/table-configuration.json +1 -0
- package/embedded-knowledge/indexes/tags/table-events.json +1 -0
- package/embedded-knowledge/indexes/tags/table-keys.json +1 -0
- package/embedded-knowledge/indexes/tags/table-safety.json +1 -0
- package/embedded-knowledge/indexes/tags/task-scheduler.json +1 -0
- package/embedded-knowledge/indexes/tags/telemetry.json +1 -0
- package/embedded-knowledge/indexes/tags/template-method.json +1 -0
- package/embedded-knowledge/indexes/tags/temporary-tables.json +1 -0
- package/embedded-knowledge/indexes/tags/testfield.json +1 -0
- package/embedded-knowledge/indexes/tags/tradeoffs.json +1 -0
- package/embedded-knowledge/indexes/tags/triggers.json +1 -0
- package/embedded-knowledge/indexes/tags/troubleshooting.json +1 -0
- package/embedded-knowledge/indexes/tags/type-safety.json +1 -0
- package/embedded-knowledge/indexes/tags/url-structure.json +1 -0
- package/embedded-knowledge/indexes/tags/user-experience.json +1 -0
- package/embedded-knowledge/indexes/tags/user-feedback.json +1 -0
- package/embedded-knowledge/indexes/tags/user-interface.json +1 -0
- package/embedded-knowledge/indexes/tags/validation-feedback.json +1 -0
- package/embedded-knowledge/indexes/tags/validation.json +1 -0
- package/embedded-knowledge/indexes/tags/variables.json +1 -0
- package/embedded-knowledge/indexes/tags/verbosity.json +1 -0
- package/embedded-knowledge/indexes/tags/vs-code.json +1 -0
- package/embedded-knowledge/indexes/tags/web-services.json +1 -0
- package/embedded-knowledge/indexes/tags/workflow-management.json +1 -0
- package/embedded-knowledge/indexes/tags/workflow-optimization.json +1 -0
- package/embedded-knowledge/indexes/tags/workflow-templates.json +1 -0
- package/embedded-knowledge/indexes/tags/workspace.json +1 -0
- package/embedded-knowledge/indexes/tags/xml-documentation.json +1 -0
- package/embedded-knowledge/indexes/topic-relationships.json +128 -0
- package/embedded-knowledge/methodologies/index.json +81 -0
- package/embedded-knowledge/methodologies/phases/analysis-full.md +208 -0
- package/embedded-knowledge/methodologies/phases/analysis-quick.md +44 -0
- package/embedded-knowledge/methodologies/phases/analysis.md +182 -0
- package/embedded-knowledge/methodologies/phases/execution-validation-full.md +174 -0
- package/embedded-knowledge/methodologies/phases/execution-validation-quick.md +31 -0
- package/embedded-knowledge/methodologies/phases/execution-validation.md +174 -0
- package/embedded-knowledge/methodologies/phases/performance-full.md +211 -0
- package/embedded-knowledge/methodologies/phases/performance-quick.md +32 -0
- package/embedded-knowledge/methodologies/phases/performance.md +211 -0
- package/embedded-knowledge/methodologies/phases/verification-full.md +162 -0
- package/embedded-knowledge/methodologies/phases/verification-quick.md +48 -0
- package/embedded-knowledge/methodologies/phases/verification.md +146 -0
- package/embedded-knowledge/methodologies/workflow-enforcement.md +142 -0
- package/embedded-knowledge/methodologies/workflows/code-review-workflow.md +99 -0
- package/embedded-knowledge/methodologies/workflows/proposal-review-workflow.md +535 -0
- package/embedded-knowledge/specialists/alex-architect.md +305 -0
- package/embedded-knowledge/specialists/casey-copilot.md +314 -0
- package/embedded-knowledge/specialists/chris-config.md +226 -0
- package/embedded-knowledge/specialists/dean-debug.md +365 -0
- package/embedded-knowledge/specialists/eva-errors.md +291 -0
- package/embedded-knowledge/specialists/jordan-bridge.md +291 -0
- package/embedded-knowledge/specialists/logan-legacy.md +265 -0
- package/embedded-knowledge/specialists/maya-mentor.md +299 -0
- package/embedded-knowledge/specialists/morgan-market.md +281 -0
- package/embedded-knowledge/specialists/parker-pragmatic.md +564 -0
- package/embedded-knowledge/specialists/quinn-tester.md +323 -0
- package/embedded-knowledge/specialists/roger-reviewer.md +317 -0
- package/embedded-knowledge/specialists/sam-coder.md +342 -0
- package/embedded-knowledge/specialists/seth-security.md +290 -0
- package/embedded-knowledge/specialists/taylor-docs.md +312 -0
- package/embedded-knowledge/specialists/uma-ux.md +291 -0
- package/package.json +82 -0
|
@@ -0,0 +1,991 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Multi-Content Layer Service
|
|
3
|
+
*
|
|
4
|
+
* Extends the existing layer system to support specialists alongside
|
|
5
|
+
* atomic topics, enabling companies/teams/projects to have custom specialists
|
|
6
|
+
* that override or supplement the base specialist personas.
|
|
7
|
+
*/
|
|
8
|
+
export class MultiContentLayerService {
|
|
9
|
+
specialistResolutionStrategy;
|
|
10
|
+
layers = new Map();
|
|
11
|
+
layerPriorities = []; // Ordered by priority (high to low)
|
|
12
|
+
contentCache = new Map();
|
|
13
|
+
initialized = false;
|
|
14
|
+
availableMcps = []; // Track available MCP servers for conditional topics
|
|
15
|
+
constructor(specialistResolutionStrategy = {
|
|
16
|
+
conflict_resolution: 'override',
|
|
17
|
+
inherit_collaborations: true,
|
|
18
|
+
merge_expertise: false
|
|
19
|
+
}) {
|
|
20
|
+
this.specialistResolutionStrategy = specialistResolutionStrategy;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Set available MCP servers for conditional topic filtering
|
|
24
|
+
*/
|
|
25
|
+
setAvailableMcps(mcps) {
|
|
26
|
+
this.availableMcps = mcps;
|
|
27
|
+
this.clearCache(); // Clear cache when MCP availability changes
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get currently available MCP servers
|
|
31
|
+
*/
|
|
32
|
+
getAvailableMcps() {
|
|
33
|
+
return [...this.availableMcps];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Filter topic based on conditional_mcp frontmatter
|
|
37
|
+
*/
|
|
38
|
+
shouldIncludeTopic(topic) {
|
|
39
|
+
const fm = topic.frontmatter;
|
|
40
|
+
// Positive conditional: include only if MCP present
|
|
41
|
+
if (fm.conditional_mcp) {
|
|
42
|
+
return this.availableMcps.includes(fm.conditional_mcp);
|
|
43
|
+
}
|
|
44
|
+
// Negative conditional: include only if MCP absent
|
|
45
|
+
if (fm.conditional_mcp_missing) {
|
|
46
|
+
return !this.availableMcps.includes(fm.conditional_mcp_missing);
|
|
47
|
+
}
|
|
48
|
+
// No conditional: always include
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Add a layer to the service
|
|
53
|
+
*/
|
|
54
|
+
addLayer(layer) {
|
|
55
|
+
this.layers.set(layer.name, layer);
|
|
56
|
+
this.updateLayerPriorities();
|
|
57
|
+
this.clearCache();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Initialize all layers
|
|
61
|
+
*/
|
|
62
|
+
async initialize() {
|
|
63
|
+
const results = new Map();
|
|
64
|
+
console.error('🚀 Initializing multi-content layer service...');
|
|
65
|
+
for (const [name, layer] of this.layers) {
|
|
66
|
+
try {
|
|
67
|
+
console.error(`📋 Initializing layer: ${name}`);
|
|
68
|
+
let result = await layer.initialize();
|
|
69
|
+
// Convert legacy LayerLoadResult to EnhancedLayerLoadResult if needed
|
|
70
|
+
if (result && !result.content_counts && result.topicsLoaded !== undefined) {
|
|
71
|
+
// This is a legacy LayerLoadResult, convert to enhanced format
|
|
72
|
+
result = {
|
|
73
|
+
success: result.success,
|
|
74
|
+
layer_name: result.layerName,
|
|
75
|
+
load_time_ms: result.loadTimeMs,
|
|
76
|
+
content_counts: {
|
|
77
|
+
topics: result.topicsLoaded || 0,
|
|
78
|
+
specialists: 0, // Will be updated by layer-specific logic
|
|
79
|
+
methodologies: result.indexesLoaded || 0
|
|
80
|
+
},
|
|
81
|
+
topics_loaded: result.topicsLoaded || 0,
|
|
82
|
+
indexes_loaded: result.indexesLoaded || 0,
|
|
83
|
+
error: result.success ? undefined : 'Layer load failed'
|
|
84
|
+
};
|
|
85
|
+
// For embedded layer, update specialist count from the layer itself
|
|
86
|
+
if (layer.name === 'embedded' && 'specialists' in layer && layer.specialists instanceof Map) {
|
|
87
|
+
result.content_counts.specialists = layer.specialists.size;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
results.set(name, result);
|
|
91
|
+
if (result.success) {
|
|
92
|
+
const contentCounts = result.content_counts || {};
|
|
93
|
+
console.error(`✅ Layer ${name}: ${Object.entries(contentCounts)
|
|
94
|
+
.map(([type, count]) => `${count} ${type}`)
|
|
95
|
+
.join(', ')}`);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
console.error(`❌ Layer ${name} failed: ${result.error}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
console.error(`❌ Layer ${name} initialization error:`, error);
|
|
103
|
+
results.set(name, {
|
|
104
|
+
success: false,
|
|
105
|
+
layer_name: name,
|
|
106
|
+
load_time_ms: 0,
|
|
107
|
+
content_counts: { topics: 0, specialists: 0, methodologies: 0 },
|
|
108
|
+
topics_loaded: 0,
|
|
109
|
+
indexes_loaded: 0,
|
|
110
|
+
error: error instanceof Error ? error.message : String(error)
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
this.initialized = true;
|
|
115
|
+
console.error(`🎯 Multi-content layer service initialized with ${this.layers.size} layers`);
|
|
116
|
+
return results;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Get a specialist by ID with layer resolution
|
|
120
|
+
*/
|
|
121
|
+
async getSpecialist(specialistId) {
|
|
122
|
+
if (!this.initialized) {
|
|
123
|
+
await this.initialize();
|
|
124
|
+
}
|
|
125
|
+
// Check cache first
|
|
126
|
+
const cached = this.getCachedContent('specialists', specialistId);
|
|
127
|
+
if (cached) {
|
|
128
|
+
return cached;
|
|
129
|
+
}
|
|
130
|
+
// Search layers in priority order (highest priority first)
|
|
131
|
+
for (const layerName of this.layerPriorities) {
|
|
132
|
+
const layer = this.layers.get(layerName);
|
|
133
|
+
if (!layer || !(layer.supported_content_types?.includes('specialists'))) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const specialist = await layer.getContent('specialists', specialistId);
|
|
137
|
+
if (specialist) {
|
|
138
|
+
this.setCachedContent('specialists', specialistId, specialist);
|
|
139
|
+
return specialist;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get all specialists across all layers with resolution
|
|
146
|
+
*/
|
|
147
|
+
async getAllSpecialists() {
|
|
148
|
+
if (!this.initialized) {
|
|
149
|
+
await this.initialize();
|
|
150
|
+
}
|
|
151
|
+
const specialistMap = new Map();
|
|
152
|
+
// Process layers in reverse priority order (lowest priority first)
|
|
153
|
+
// so higher priority layers can override
|
|
154
|
+
const reversePriorities = [...this.layerPriorities].reverse();
|
|
155
|
+
for (const layerName of reversePriorities) {
|
|
156
|
+
const layer = this.layers.get(layerName);
|
|
157
|
+
if (!layer || !(layer.supported_content_types?.includes('specialists'))) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const layerSpecialistIds = layer.getContentIds('specialists');
|
|
161
|
+
for (const specialistId of layerSpecialistIds) {
|
|
162
|
+
const specialist = await layer.getContent('specialists', specialistId);
|
|
163
|
+
if (specialist) {
|
|
164
|
+
if (specialistMap.has(specialistId)) {
|
|
165
|
+
// Apply resolution strategy
|
|
166
|
+
const existing = specialistMap.get(specialistId);
|
|
167
|
+
const resolved = this.resolveSpecialistConflict(existing, specialist, layerName);
|
|
168
|
+
specialistMap.set(specialistId, resolved);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
specialistMap.set(specialistId, specialist);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return Array.from(specialistMap.values());
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Suggest specialists based on context across all layers
|
|
180
|
+
*/
|
|
181
|
+
async suggestSpecialists(context, queryContext, limit = 5) {
|
|
182
|
+
const allSpecialists = await this.getAllSpecialists();
|
|
183
|
+
const suggestions = [];
|
|
184
|
+
for (const specialist of allSpecialists) {
|
|
185
|
+
const score = this.calculateSpecialistScore(specialist, context, queryContext);
|
|
186
|
+
if (score > 0) {
|
|
187
|
+
const collaborationOptions = await this.getCollaborationOptions(specialist);
|
|
188
|
+
suggestions.push({
|
|
189
|
+
specialist,
|
|
190
|
+
source_layer: this.findSpecialistSourceLayer(specialist.specialist_id),
|
|
191
|
+
confidence_score: score,
|
|
192
|
+
match_reasons: this.getMatchReasons(specialist, context, queryContext),
|
|
193
|
+
collaboration_options: collaborationOptions
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Sort by confidence score
|
|
198
|
+
suggestions.sort((a, b) => b.confidence_score - a.confidence_score);
|
|
199
|
+
const primarySuggestions = suggestions.slice(0, limit);
|
|
200
|
+
const alternativeSuggestions = suggestions.slice(limit, limit * 2);
|
|
201
|
+
return {
|
|
202
|
+
primary_suggestions: primarySuggestions,
|
|
203
|
+
alternative_specialists: alternativeSuggestions,
|
|
204
|
+
cross_layer_collaboration: await this.getCrossLayerCollaboration(primarySuggestions),
|
|
205
|
+
resolution_strategy_used: this.specialistResolutionStrategy
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get specialists from a specific layer
|
|
210
|
+
*/
|
|
211
|
+
async getSpecialistsByLayer(layerName) {
|
|
212
|
+
const layer = this.layers.get(layerName);
|
|
213
|
+
if (!layer || !layer.supported_content_types.includes('specialists')) {
|
|
214
|
+
return [];
|
|
215
|
+
}
|
|
216
|
+
const specialistIds = layer.getContentIds('specialists');
|
|
217
|
+
const specialists = [];
|
|
218
|
+
for (const id of specialistIds) {
|
|
219
|
+
const specialist = await layer.getContent('specialists', id);
|
|
220
|
+
if (specialist) {
|
|
221
|
+
specialists.push(specialist);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return specialists;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Get layer statistics including specialist counts
|
|
228
|
+
*/
|
|
229
|
+
getLayerStatistics() {
|
|
230
|
+
const stats = {};
|
|
231
|
+
for (const [name, layer] of this.layers) {
|
|
232
|
+
stats[name] = layer.getEnhancedStatistics();
|
|
233
|
+
}
|
|
234
|
+
return stats;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Resolve specialist conflicts between layers
|
|
238
|
+
*/
|
|
239
|
+
resolveSpecialistConflict(existing, incoming, incomingLayerName) {
|
|
240
|
+
switch (this.specialistResolutionStrategy.conflict_resolution) {
|
|
241
|
+
case 'override':
|
|
242
|
+
return incoming; // Higher priority layer wins
|
|
243
|
+
case 'merge':
|
|
244
|
+
return this.mergeSpecialists(existing, incoming);
|
|
245
|
+
case 'extend':
|
|
246
|
+
return this.extendSpecialist(existing, incoming);
|
|
247
|
+
default:
|
|
248
|
+
return incoming;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Merge two specialist definitions
|
|
253
|
+
*/
|
|
254
|
+
mergeSpecialists(base, override) {
|
|
255
|
+
return {
|
|
256
|
+
...base,
|
|
257
|
+
...override,
|
|
258
|
+
persona: {
|
|
259
|
+
...base.persona,
|
|
260
|
+
...override.persona,
|
|
261
|
+
personality: [
|
|
262
|
+
...new Set([...base.persona.personality, ...override.persona.personality])
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
expertise: {
|
|
266
|
+
primary: [...new Set([...base.expertise.primary, ...override.expertise.primary])],
|
|
267
|
+
secondary: [...new Set([...base.expertise.secondary, ...override.expertise.secondary])]
|
|
268
|
+
},
|
|
269
|
+
domains: [...new Set([...base.domains, ...override.domains])],
|
|
270
|
+
when_to_use: [...new Set([...base.when_to_use, ...override.when_to_use])],
|
|
271
|
+
collaboration: {
|
|
272
|
+
natural_handoffs: this.specialistResolutionStrategy.inherit_collaborations
|
|
273
|
+
? [...new Set([...base.collaboration.natural_handoffs, ...override.collaboration.natural_handoffs])]
|
|
274
|
+
: override.collaboration.natural_handoffs,
|
|
275
|
+
team_consultations: this.specialistResolutionStrategy.inherit_collaborations
|
|
276
|
+
? [...new Set([...base.collaboration.team_consultations, ...override.collaboration.team_consultations])]
|
|
277
|
+
: override.collaboration.team_consultations
|
|
278
|
+
},
|
|
279
|
+
related_specialists: [...new Set([...base.related_specialists, ...override.related_specialists])]
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Extend specialist with additional capabilities
|
|
284
|
+
*/
|
|
285
|
+
extendSpecialist(base, extension) {
|
|
286
|
+
// Similar to merge but preserves base identity more strongly
|
|
287
|
+
return {
|
|
288
|
+
...base,
|
|
289
|
+
// Only extend non-identity fields
|
|
290
|
+
expertise: {
|
|
291
|
+
primary: base.expertise.primary, // Keep base primary expertise
|
|
292
|
+
secondary: [...new Set([...base.expertise.secondary, ...extension.expertise.secondary])]
|
|
293
|
+
},
|
|
294
|
+
domains: [...new Set([...base.domains, ...extension.domains])],
|
|
295
|
+
when_to_use: [...new Set([...base.when_to_use, ...extension.when_to_use])],
|
|
296
|
+
collaboration: {
|
|
297
|
+
natural_handoffs: [...new Set([...base.collaboration.natural_handoffs, ...extension.collaboration.natural_handoffs])],
|
|
298
|
+
team_consultations: [...new Set([...base.collaboration.team_consultations, ...extension.collaboration.team_consultations])]
|
|
299
|
+
},
|
|
300
|
+
related_specialists: [...new Set([...base.related_specialists, ...extension.related_specialists])],
|
|
301
|
+
content: `${base.content}\n\n## Extended Capabilities\n${extension.content}`
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Calculate specialist relevance score
|
|
306
|
+
*/
|
|
307
|
+
calculateSpecialistScore(specialist, context, queryContext) {
|
|
308
|
+
let score = 0;
|
|
309
|
+
const contextLower = context.toLowerCase();
|
|
310
|
+
// Check when_to_use scenarios
|
|
311
|
+
for (const scenario of specialist.when_to_use) {
|
|
312
|
+
if (contextLower.includes(scenario.toLowerCase()) ||
|
|
313
|
+
scenario.toLowerCase().includes(contextLower)) {
|
|
314
|
+
score += 10;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// Check expertise areas
|
|
318
|
+
for (const expertise of specialist.expertise.primary) {
|
|
319
|
+
if (contextLower.includes(expertise.toLowerCase())) {
|
|
320
|
+
score += 8;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
for (const expertise of specialist.expertise.secondary) {
|
|
324
|
+
if (contextLower.includes(expertise.toLowerCase())) {
|
|
325
|
+
score += 5;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// Check domains
|
|
329
|
+
for (const domain of specialist.domains) {
|
|
330
|
+
if (contextLower.includes(domain.toLowerCase())) {
|
|
331
|
+
score += 6;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// Apply query context modifiers
|
|
335
|
+
if (queryContext) {
|
|
336
|
+
if (queryContext.domain && specialist.domains.includes(queryContext.domain)) {
|
|
337
|
+
score += 15;
|
|
338
|
+
}
|
|
339
|
+
if (queryContext.urgency === 'high') {
|
|
340
|
+
// Prefer specialists with quick response traits
|
|
341
|
+
if (specialist.persona.personality.some(p => p.toLowerCase().includes('quick') ||
|
|
342
|
+
p.toLowerCase().includes('direct') ||
|
|
343
|
+
p.toLowerCase().includes('efficient'))) {
|
|
344
|
+
score += 5;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return score;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Get match reasons for a specialist suggestion
|
|
352
|
+
*/
|
|
353
|
+
getMatchReasons(specialist, context, queryContext) {
|
|
354
|
+
const reasons = [];
|
|
355
|
+
const contextLower = context.toLowerCase();
|
|
356
|
+
// Check expertise matches
|
|
357
|
+
const primaryMatches = specialist.expertise.primary.filter(e => contextLower.includes(e.toLowerCase()));
|
|
358
|
+
if (primaryMatches.length > 0) {
|
|
359
|
+
reasons.push(`Primary expertise: ${primaryMatches.join(', ')}`);
|
|
360
|
+
}
|
|
361
|
+
// Check scenario matches
|
|
362
|
+
const scenarioMatches = specialist.when_to_use.filter(s => contextLower.includes(s.toLowerCase()) || s.toLowerCase().includes(contextLower));
|
|
363
|
+
if (scenarioMatches.length > 0) {
|
|
364
|
+
reasons.push(`Relevant scenarios: ${scenarioMatches.join(', ')}`);
|
|
365
|
+
}
|
|
366
|
+
// Check domain matches
|
|
367
|
+
const domainMatches = specialist.domains.filter(d => contextLower.includes(d.toLowerCase()));
|
|
368
|
+
if (domainMatches.length > 0) {
|
|
369
|
+
reasons.push(`Domain expertise: ${domainMatches.join(', ')}`);
|
|
370
|
+
}
|
|
371
|
+
return reasons;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Get collaboration options for a specialist
|
|
375
|
+
*/
|
|
376
|
+
async getCollaborationOptions(specialist) {
|
|
377
|
+
const handoffs = [];
|
|
378
|
+
const consultations = [];
|
|
379
|
+
// Get handoff specialists
|
|
380
|
+
for (const handoffId of specialist.collaboration.natural_handoffs) {
|
|
381
|
+
const handoffSpecialist = await this.getSpecialist(handoffId);
|
|
382
|
+
if (handoffSpecialist) {
|
|
383
|
+
handoffs.push(handoffSpecialist);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
// Get consultation specialists
|
|
387
|
+
for (const consultationId of specialist.collaboration.team_consultations) {
|
|
388
|
+
const consultationSpecialist = await this.getSpecialist(consultationId);
|
|
389
|
+
if (consultationSpecialist) {
|
|
390
|
+
consultations.push(consultationSpecialist);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return { available_handoffs: handoffs, recommended_consultations: consultations };
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get cross-layer collaboration opportunities
|
|
397
|
+
*/
|
|
398
|
+
async getCrossLayerCollaboration(suggestions) {
|
|
399
|
+
const crossLayerCollab = [];
|
|
400
|
+
for (const [layerName] of this.layers) {
|
|
401
|
+
const layerSpecialists = await this.getSpecialistsByLayer(layerName);
|
|
402
|
+
if (layerSpecialists.length > 0) {
|
|
403
|
+
crossLayerCollab.push({
|
|
404
|
+
layer_name: layerName,
|
|
405
|
+
specialists: layerSpecialists
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
return crossLayerCollab;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Find which layer a specialist comes from
|
|
413
|
+
*/
|
|
414
|
+
findSpecialistSourceLayer(specialistId) {
|
|
415
|
+
for (const layerName of this.layerPriorities) {
|
|
416
|
+
const layer = this.layers.get(layerName);
|
|
417
|
+
if (layer?.hasContent('specialists', specialistId)) {
|
|
418
|
+
return layerName;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return 'unknown';
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Update layer priority ordering
|
|
425
|
+
*/
|
|
426
|
+
updateLayerPriorities() {
|
|
427
|
+
this.layerPriorities = Array.from(this.layers.values())
|
|
428
|
+
.sort((a, b) => a.priority - b.priority) // Lower number = higher priority
|
|
429
|
+
.map(layer => layer.name);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Cache management
|
|
433
|
+
*/
|
|
434
|
+
getCachedContent(type, id) {
|
|
435
|
+
return this.contentCache.get(type)?.get(id);
|
|
436
|
+
}
|
|
437
|
+
setCachedContent(type, id, content) {
|
|
438
|
+
if (!this.contentCache.has(type)) {
|
|
439
|
+
this.contentCache.set(type, new Map());
|
|
440
|
+
}
|
|
441
|
+
this.contentCache.get(type).set(id, content);
|
|
442
|
+
}
|
|
443
|
+
clearCache() {
|
|
444
|
+
this.contentCache.clear();
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Search topics across all layers
|
|
448
|
+
*/
|
|
449
|
+
async searchTopics(params) {
|
|
450
|
+
if (!this.initialized) {
|
|
451
|
+
await this.initialize();
|
|
452
|
+
}
|
|
453
|
+
const results = [];
|
|
454
|
+
const limit = params.limit || 50;
|
|
455
|
+
// Search across all layers in priority order
|
|
456
|
+
for (const layerName of this.layerPriorities) {
|
|
457
|
+
const layer = this.layers.get(layerName);
|
|
458
|
+
if (!layer)
|
|
459
|
+
continue;
|
|
460
|
+
try {
|
|
461
|
+
// Get all topic IDs from this layer
|
|
462
|
+
const topicIds = layer.getContentIds('topics');
|
|
463
|
+
// Load each topic and filter
|
|
464
|
+
for (const topicId of topicIds) {
|
|
465
|
+
const topic = await layer.getContent('topics', topicId);
|
|
466
|
+
if (topic && this.shouldIncludeTopic(topic) && this.matchesSearchCriteria(topic, params)) {
|
|
467
|
+
try {
|
|
468
|
+
const score = this.calculateRelevanceScore(topic, params);
|
|
469
|
+
const searchResult = this.topicToSearchResult(topic, score);
|
|
470
|
+
results.push(searchResult);
|
|
471
|
+
// Note: Don't break early here - let all matching topics be scored
|
|
472
|
+
// The final limit will be applied after sorting by relevance
|
|
473
|
+
}
|
|
474
|
+
catch (scoreError) {
|
|
475
|
+
console.error(`Error scoring topic ${topic.title}:`, scoreError);
|
|
476
|
+
// Skip this topic if scoring fails
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
catch (error) {
|
|
482
|
+
console.error(`Error searching topics in layer ${layerName}:`, error);
|
|
483
|
+
// Continue with other layers
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// Sort by relevance score and apply limit
|
|
487
|
+
return results
|
|
488
|
+
.sort((a, b) => b.relevance_score - a.relevance_score)
|
|
489
|
+
.slice(0, limit);
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Find specialists by query across all layers
|
|
493
|
+
*/
|
|
494
|
+
async findSpecialistsByQuery(query) {
|
|
495
|
+
if (!this.initialized) {
|
|
496
|
+
await this.initialize();
|
|
497
|
+
}
|
|
498
|
+
const results = [];
|
|
499
|
+
const queryLower = query.toLowerCase();
|
|
500
|
+
// Search across all layers in priority order
|
|
501
|
+
for (const layerName of this.layerPriorities) {
|
|
502
|
+
const layer = this.layers.get(layerName);
|
|
503
|
+
if (!layer || !layer.supported_content_types || !layer.supported_content_types.includes('specialists')) {
|
|
504
|
+
continue;
|
|
505
|
+
}
|
|
506
|
+
try {
|
|
507
|
+
// Get all specialist IDs from this layer
|
|
508
|
+
const specialistIds = layer.getContentIds('specialists');
|
|
509
|
+
// Load each specialist and check for matches
|
|
510
|
+
for (const specialistId of specialistIds) {
|
|
511
|
+
const specialist = await layer.getContent('specialists', specialistId);
|
|
512
|
+
if (specialist && this.matchesSpecialistQuery(specialist, queryLower)) {
|
|
513
|
+
results.push(specialist);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
catch (error) {
|
|
518
|
+
console.error(`Error searching specialists in layer ${layerName}:`, error);
|
|
519
|
+
// Continue with other layers
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
return results;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Check if specialist matches query using token-based matching
|
|
526
|
+
*
|
|
527
|
+
* Fixes Issue #17: Complex compound questions now tokenized for matching.
|
|
528
|
+
* Instead of requiring full query as substring, matches any individual token.
|
|
529
|
+
*/
|
|
530
|
+
matchesSpecialistQuery(specialist, queryLower) {
|
|
531
|
+
const searchableFields = [
|
|
532
|
+
specialist.title,
|
|
533
|
+
specialist.role,
|
|
534
|
+
specialist.specialist_id,
|
|
535
|
+
...(specialist.expertise?.primary || []),
|
|
536
|
+
...(specialist.expertise?.secondary || []),
|
|
537
|
+
...(specialist.domains || []),
|
|
538
|
+
...(specialist.when_to_use || [])
|
|
539
|
+
].filter(Boolean).map(field => field.toLowerCase());
|
|
540
|
+
// Tokenize query into individual keywords (filter out short words)
|
|
541
|
+
const queryTokens = queryLower
|
|
542
|
+
.split(/[\s,]+/)
|
|
543
|
+
.filter(token => token.length > 3)
|
|
544
|
+
.map(token => token.replace(/[^a-z0-9]/g, ''));
|
|
545
|
+
// Match if ANY query token matches ANY searchable field (bidirectional partial matching)
|
|
546
|
+
return queryTokens.some(token => searchableFields.some(field => field.includes(token) || token.includes(field)));
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Ask a specialist a question (simulated consultation)
|
|
550
|
+
*/
|
|
551
|
+
async askSpecialist(question, preferredSpecialist) {
|
|
552
|
+
if (!this.initialized) {
|
|
553
|
+
await this.initialize();
|
|
554
|
+
}
|
|
555
|
+
let specialist = null;
|
|
556
|
+
// Try to find the preferred specialist first
|
|
557
|
+
if (preferredSpecialist) {
|
|
558
|
+
specialist = await this.findSpecialistById(preferredSpecialist);
|
|
559
|
+
}
|
|
560
|
+
// If no preferred specialist or not found, find best match
|
|
561
|
+
if (!specialist) {
|
|
562
|
+
const specialists = await this.findSpecialistsByQuery(question);
|
|
563
|
+
specialist = specialists[0] || null;
|
|
564
|
+
}
|
|
565
|
+
if (!specialist) {
|
|
566
|
+
throw new Error('No suitable specialist found for this question');
|
|
567
|
+
}
|
|
568
|
+
// Return a consultation response
|
|
569
|
+
return {
|
|
570
|
+
specialist: {
|
|
571
|
+
id: specialist.specialist_id,
|
|
572
|
+
name: specialist.title,
|
|
573
|
+
role: specialist.role
|
|
574
|
+
},
|
|
575
|
+
response: `${specialist.title} would approach this question: "${question}" using their expertise in ${specialist.expertise?.primary?.join(', ') || 'general BC development'}.`,
|
|
576
|
+
consultation_guidance: specialist.content.substring(0, 200) + '...' || 'General BC development guidance',
|
|
577
|
+
follow_up_suggestions: specialist.related_specialists || []
|
|
578
|
+
};
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Find specialist by ID across all layers
|
|
582
|
+
*/
|
|
583
|
+
async findSpecialistById(specialistId) {
|
|
584
|
+
for (const layerName of this.layerPriorities) {
|
|
585
|
+
const layer = this.layers.get(layerName);
|
|
586
|
+
if (!layer || !layer.supported_content_types.includes('specialists')) {
|
|
587
|
+
continue;
|
|
588
|
+
}
|
|
589
|
+
try {
|
|
590
|
+
if (layer.hasContent('specialists', specialistId)) {
|
|
591
|
+
return await layer.getContent('specialists', specialistId);
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
catch (error) {
|
|
595
|
+
console.error(`Error finding specialist ${specialistId} in layer ${layerName}:`, error);
|
|
596
|
+
// Continue with other layers
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Check if topic matches search criteria
|
|
603
|
+
*/
|
|
604
|
+
matchesSearchCriteria(topic, params) {
|
|
605
|
+
// Text matching using code_context parameter
|
|
606
|
+
if (params.code_context) {
|
|
607
|
+
const searchTerm = params.code_context.toLowerCase();
|
|
608
|
+
const title = topic.title.toLowerCase();
|
|
609
|
+
const content = topic.content.toLowerCase();
|
|
610
|
+
const tags = (topic.frontmatter.tags || []).map(tag => tag.toLowerCase());
|
|
611
|
+
// Prioritize individual word matching over full phrase matching
|
|
612
|
+
const searchWords = searchTerm.split(' ').filter(word => word.length > 2);
|
|
613
|
+
// Check individual words first (more flexible)
|
|
614
|
+
const wordMatches = searchWords.some(word => title.includes(word) || content.includes(word) || tags.some(tag => tag.includes(word)));
|
|
615
|
+
// Also check exact phrase match (bonus case)
|
|
616
|
+
const exactPhraseMatch = title.includes(searchTerm) ||
|
|
617
|
+
content.includes(searchTerm) ||
|
|
618
|
+
tags.some(tag => tag.includes(searchTerm));
|
|
619
|
+
const matches = wordMatches || exactPhraseMatch;
|
|
620
|
+
if (!matches) {
|
|
621
|
+
return false;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
// Domain filtering
|
|
625
|
+
if (params.domain) {
|
|
626
|
+
const topicDomains = Array.isArray(topic.frontmatter.domain)
|
|
627
|
+
? topic.frontmatter.domain
|
|
628
|
+
: topic.frontmatter.domain ? [topic.frontmatter.domain] : [];
|
|
629
|
+
if (!topicDomains.includes(params.domain)) {
|
|
630
|
+
return false;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
// BC version filtering
|
|
634
|
+
if (params.bc_version && topic.frontmatter.bc_versions) {
|
|
635
|
+
const bcVersions = topic.frontmatter.bc_versions;
|
|
636
|
+
const requestedVersion = params.bc_version;
|
|
637
|
+
// Handle version ranges like "14+", "18+", "BC14+", "BC18+"
|
|
638
|
+
const rangeMatch = bcVersions.match(/^(?:BC)?(\d+)\+$/);
|
|
639
|
+
if (rangeMatch) {
|
|
640
|
+
const minVersion = parseInt(rangeMatch[1], 10);
|
|
641
|
+
const requestedVersionNum = parseInt(requestedVersion.replace(/^BC/, ''), 10);
|
|
642
|
+
if (requestedVersionNum < minVersion) {
|
|
643
|
+
return false; // Requested version is below minimum
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
else if (!bcVersions.includes(requestedVersion)) {
|
|
647
|
+
// Exact version match required if not a range
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
// Difficulty filtering
|
|
652
|
+
if (params.difficulty && topic.frontmatter.difficulty !== params.difficulty) {
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
// Tag filtering
|
|
656
|
+
if (params.tags && params.tags.length > 0) {
|
|
657
|
+
const topicTags = topic.frontmatter.tags || [];
|
|
658
|
+
if (!params.tags.some(tag => topicTags.includes(tag))) {
|
|
659
|
+
return false;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return true;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Calculate relevance score for topic
|
|
666
|
+
*/
|
|
667
|
+
calculateRelevanceScore(topic, params) {
|
|
668
|
+
let score = 0; // Start with 0, add points for relevance
|
|
669
|
+
// Text relevance scoring - the most important factor
|
|
670
|
+
if (params.code_context) {
|
|
671
|
+
const searchTerm = params.code_context.toLowerCase();
|
|
672
|
+
const searchWords = searchTerm.split(/\s+/).filter(word => word.length > 2);
|
|
673
|
+
const title = topic.title.toLowerCase();
|
|
674
|
+
const content = topic.content.toLowerCase();
|
|
675
|
+
const tags = (topic.frontmatter.tags || []).map(tag => tag.toLowerCase());
|
|
676
|
+
// **MAJOR FIX**: Prioritize exact phrase matches and semantic clusters
|
|
677
|
+
// 1. Exact phrase match in title (highest priority)
|
|
678
|
+
if (title.includes(searchTerm)) {
|
|
679
|
+
score += 100; // Massive bonus for exact phrase in title
|
|
680
|
+
}
|
|
681
|
+
// 2. High-value word combinations in title
|
|
682
|
+
let titleWordMatches = 0;
|
|
683
|
+
for (const word of searchWords) {
|
|
684
|
+
if (title.includes(word)) {
|
|
685
|
+
titleWordMatches++;
|
|
686
|
+
score += 15; // Higher than before for title matches
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
// 3. Title clustering bonus - reward multiple words in title
|
|
690
|
+
if (titleWordMatches > 1) {
|
|
691
|
+
score += titleWordMatches * titleWordMatches * 10; // Exponential bonus for clustering
|
|
692
|
+
}
|
|
693
|
+
// 4. Semantic tag matches (better than content)
|
|
694
|
+
let tagMatches = 0;
|
|
695
|
+
for (const word of searchWords) {
|
|
696
|
+
for (const tag of tags) {
|
|
697
|
+
if (tag.includes(word)) {
|
|
698
|
+
tagMatches++;
|
|
699
|
+
score += 12; // Increased from 8
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
// 5. Tag clustering bonus
|
|
704
|
+
if (tagMatches > 1) {
|
|
705
|
+
score += tagMatches * 8;
|
|
706
|
+
}
|
|
707
|
+
// 6. Content matches (lower priority than before)
|
|
708
|
+
for (const word of searchWords) {
|
|
709
|
+
const matches = (content.match(new RegExp(`\\b${word}\\b`, 'g')) || []).length;
|
|
710
|
+
score += Math.min(matches * 1.5, 4); // Reduced from 2 and 6
|
|
711
|
+
}
|
|
712
|
+
// 7. **NEW**: Exact phrase in content
|
|
713
|
+
if (content.includes(searchTerm)) {
|
|
714
|
+
score += 20;
|
|
715
|
+
}
|
|
716
|
+
// 8. **NEW**: Multi-word phrase detection in title (highest semantic value)
|
|
717
|
+
if (searchWords.length > 1) {
|
|
718
|
+
// Check for consecutive word sequences in title
|
|
719
|
+
for (let i = 0; i < searchWords.length - 1; i++) {
|
|
720
|
+
const phrase = searchWords.slice(i, i + 2).join(' ');
|
|
721
|
+
if (title.includes(phrase)) {
|
|
722
|
+
score += 50; // Massive bonus for 2-word phrases in title
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
// Check for 3+ word phrases
|
|
726
|
+
for (let i = 0; i < searchWords.length - 2; i++) {
|
|
727
|
+
const phrase = searchWords.slice(i, i + 3).join(' ');
|
|
728
|
+
if (title.includes(phrase)) {
|
|
729
|
+
score += 100; // Even bigger bonus for longer phrases
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
// 9. **NEW**: Semantic relevance bonus for technical terms
|
|
734
|
+
const technicalTerms = ['al', 'naming', 'convention', 'field', 'table', 'extension'];
|
|
735
|
+
const queryTechTerms = searchWords.filter(word => technicalTerms.includes(word));
|
|
736
|
+
const topicTechTerms = [...title.split(/\s+/), ...tags.join(' ').split(/\s+/)]
|
|
737
|
+
.filter(word => technicalTerms.includes(word.toLowerCase()));
|
|
738
|
+
const techTermOverlap = queryTechTerms.filter(term => topicTechTerms.some(topicTerm => topicTerm.toLowerCase().includes(term))).length;
|
|
739
|
+
if (techTermOverlap > 0) {
|
|
740
|
+
score += techTermOverlap * 25; // High bonus for technical term matches
|
|
741
|
+
}
|
|
742
|
+
// 10. Penalty for very long content (prefer focused topics)
|
|
743
|
+
if (topic.content.length > 5000) {
|
|
744
|
+
score *= 0.8; // Increased penalty
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
// Domain exact match bonus (secondary factor)
|
|
748
|
+
if (params.domain) {
|
|
749
|
+
const topicDomains = Array.isArray(topic.frontmatter.domain)
|
|
750
|
+
? topic.frontmatter.domain
|
|
751
|
+
: topic.frontmatter.domain ? [topic.frontmatter.domain] : [];
|
|
752
|
+
if (topicDomains.includes(params.domain)) {
|
|
753
|
+
score += 5;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
// BC version exact match bonus
|
|
757
|
+
if (params.bc_version && topic.frontmatter.bc_versions?.includes(params.bc_version)) {
|
|
758
|
+
score += 3;
|
|
759
|
+
}
|
|
760
|
+
// Difficulty match bonus
|
|
761
|
+
if (params.difficulty && topic.frontmatter.difficulty === params.difficulty) {
|
|
762
|
+
score += 2;
|
|
763
|
+
}
|
|
764
|
+
// Tag match bonus (from explicit tag parameters)
|
|
765
|
+
if (params.tags && params.tags.length > 0) {
|
|
766
|
+
const topicTags = topic.frontmatter.tags || [];
|
|
767
|
+
const matchingTags = params.tags.filter(tag => topicTags.includes(tag));
|
|
768
|
+
score += matchingTags.length * 2;
|
|
769
|
+
}
|
|
770
|
+
// **NEW**: Boost recommendation topics when their conditional is active
|
|
771
|
+
// These are high-value suggestions that guide users to install missing tools
|
|
772
|
+
try {
|
|
773
|
+
const fm = topic?.frontmatter;
|
|
774
|
+
if (fm?.conditional_mcp_missing && Array.isArray(this.availableMcps)) {
|
|
775
|
+
if (!this.availableMcps.includes(fm.conditional_mcp_missing)) {
|
|
776
|
+
// Recommendation topic is active (tool is missing) - boost HEAVILY to surface prominently
|
|
777
|
+
score += 150; // Large boost to ensure recommendations surface in top results
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
catch (boostError) {
|
|
782
|
+
// Silent fail - don't break scoring if boost logic fails
|
|
783
|
+
console.error('Error applying recommendation boost:', boostError);
|
|
784
|
+
}
|
|
785
|
+
return Math.max(score, 0.1); // Ensure minimum score > 0
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Convert topic to search result
|
|
789
|
+
*/
|
|
790
|
+
topicToSearchResult(topic, relevanceScore) {
|
|
791
|
+
const primaryDomain = Array.isArray(topic.frontmatter.domain)
|
|
792
|
+
? topic.frontmatter.domain[0]
|
|
793
|
+
: topic.frontmatter.domain || '';
|
|
794
|
+
const allDomains = Array.isArray(topic.frontmatter.domain)
|
|
795
|
+
? topic.frontmatter.domain
|
|
796
|
+
: topic.frontmatter.domain ? [topic.frontmatter.domain] : [];
|
|
797
|
+
return {
|
|
798
|
+
id: topic.id,
|
|
799
|
+
title: topic.title,
|
|
800
|
+
summary: topic.content.substring(0, 200) + '...', // First 200 chars as summary
|
|
801
|
+
domain: primaryDomain,
|
|
802
|
+
domains: allDomains,
|
|
803
|
+
difficulty: topic.frontmatter.difficulty || 'beginner',
|
|
804
|
+
relevance_score: relevanceScore,
|
|
805
|
+
tags: topic.frontmatter.tags || [],
|
|
806
|
+
prerequisites: topic.frontmatter.prerequisites || [],
|
|
807
|
+
estimated_time: topic.frontmatter.estimated_time
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Get a specific layer by name (adapted from LayerService)
|
|
812
|
+
*/
|
|
813
|
+
getLayer(layerName) {
|
|
814
|
+
return this.layers.get(layerName) || null;
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Get all layers (adapted from LayerService)
|
|
818
|
+
*/
|
|
819
|
+
getLayers() {
|
|
820
|
+
return Array.from(this.layers.values());
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Get all available topic IDs from all layers (adapted from LayerService)
|
|
824
|
+
*/
|
|
825
|
+
getAllTopicIds() {
|
|
826
|
+
const topicIds = new Set();
|
|
827
|
+
for (const layer of this.layers.values()) {
|
|
828
|
+
if ('getTopicIds' in layer) {
|
|
829
|
+
for (const topicId of layer.getTopicIds()) {
|
|
830
|
+
topicIds.add(topicId);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return Array.from(topicIds);
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Resolve a topic with layer override logic (adapted from LayerService)
|
|
838
|
+
*/
|
|
839
|
+
async resolveTopic(topicId) {
|
|
840
|
+
if (!this.initialized) {
|
|
841
|
+
await this.initialize();
|
|
842
|
+
}
|
|
843
|
+
// Find the highest priority layer that has this topic
|
|
844
|
+
let resolvedTopic = null;
|
|
845
|
+
let sourceLayer = '';
|
|
846
|
+
// Go through layers in priority order (highest first)
|
|
847
|
+
for (const layerName of this.layerPriorities) {
|
|
848
|
+
const layer = this.layers.get(layerName);
|
|
849
|
+
if (layer && 'getTopic' in layer) {
|
|
850
|
+
try {
|
|
851
|
+
const topic = await layer.getTopic(topicId);
|
|
852
|
+
if (topic) {
|
|
853
|
+
resolvedTopic = topic;
|
|
854
|
+
sourceLayer = layerName;
|
|
855
|
+
break; // Highest priority wins
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
catch (error) {
|
|
859
|
+
// Continue to next layer
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
if (resolvedTopic) {
|
|
864
|
+
return {
|
|
865
|
+
topic: resolvedTopic,
|
|
866
|
+
sourceLayer,
|
|
867
|
+
isOverride: false,
|
|
868
|
+
overriddenLayers: []
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
return null;
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Get all resolved topics (adapted from LayerService)
|
|
875
|
+
*/
|
|
876
|
+
async getAllResolvedTopics() {
|
|
877
|
+
const allTopics = [];
|
|
878
|
+
const topicIds = this.getAllTopicIds();
|
|
879
|
+
for (const topicId of topicIds) {
|
|
880
|
+
const resolution = await this.resolveTopic(topicId);
|
|
881
|
+
if (resolution && resolution.topic) {
|
|
882
|
+
allTopics.push(resolution.topic);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
return allTopics;
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Get overridden topics statistics (adapted from LayerService)
|
|
889
|
+
*/
|
|
890
|
+
getOverriddenTopics() {
|
|
891
|
+
// For now, return empty stats - can be enhanced later
|
|
892
|
+
return {
|
|
893
|
+
totalOverrides: 0,
|
|
894
|
+
overridesByLayer: {},
|
|
895
|
+
conflictResolutions: []
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Get layer statistics - adapts new enhanced statistics to old LayerStatistics format
|
|
900
|
+
*/
|
|
901
|
+
getStatistics() {
|
|
902
|
+
return Array.from(this.layers.values()).map(layer => {
|
|
903
|
+
// Try to use getEnhancedStatistics if available, otherwise fall back to basic stats
|
|
904
|
+
if ('getEnhancedStatistics' in layer && typeof layer.getEnhancedStatistics === 'function') {
|
|
905
|
+
const enhanced = layer.getEnhancedStatistics();
|
|
906
|
+
return {
|
|
907
|
+
name: enhanced.name,
|
|
908
|
+
priority: enhanced.priority,
|
|
909
|
+
enabled: layer.enabled,
|
|
910
|
+
topicCount: enhanced.content_counts.topics || 0,
|
|
911
|
+
indexCount: enhanced.content_counts.methodologies || 0,
|
|
912
|
+
lastLoaded: enhanced.initialized ? new Date() : undefined,
|
|
913
|
+
loadTimeMs: enhanced.load_time_ms,
|
|
914
|
+
memoryUsage: {
|
|
915
|
+
topics: 0,
|
|
916
|
+
indexes: 0,
|
|
917
|
+
total: 0
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
else {
|
|
922
|
+
// Fallback to standard layer properties
|
|
923
|
+
const layerAsAny = layer;
|
|
924
|
+
return {
|
|
925
|
+
name: layer.name,
|
|
926
|
+
priority: layer.priority,
|
|
927
|
+
enabled: layer.enabled,
|
|
928
|
+
topicCount: layerAsAny.topics?.size || 0,
|
|
929
|
+
indexCount: layerAsAny.indexes?.size || 0,
|
|
930
|
+
lastLoaded: undefined,
|
|
931
|
+
loadTimeMs: undefined,
|
|
932
|
+
memoryUsage: {
|
|
933
|
+
topics: 0,
|
|
934
|
+
indexes: 0,
|
|
935
|
+
total: 0
|
|
936
|
+
}
|
|
937
|
+
};
|
|
938
|
+
}
|
|
939
|
+
});
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Initialize from configuration (adapted from LayerService)
|
|
943
|
+
*/
|
|
944
|
+
async initializeFromConfiguration(config) {
|
|
945
|
+
// For now, just call regular initialize
|
|
946
|
+
// This can be enhanced to handle configuration-based layer loading
|
|
947
|
+
return await this.initialize();
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Get session storage configuration (adapted from LayerService)
|
|
951
|
+
*/
|
|
952
|
+
getSessionStorageConfig() {
|
|
953
|
+
return {
|
|
954
|
+
enabled: false,
|
|
955
|
+
type: 'memory',
|
|
956
|
+
options: {}
|
|
957
|
+
};
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Refresh cache (adapted from LayerService)
|
|
961
|
+
*/
|
|
962
|
+
async refreshCache() {
|
|
963
|
+
this.clearCache();
|
|
964
|
+
// Force re-initialization if needed
|
|
965
|
+
if (this.initialized) {
|
|
966
|
+
await this.initialize();
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Get cache statistics (adapted from LayerService)
|
|
971
|
+
*/
|
|
972
|
+
getCacheStats() {
|
|
973
|
+
return {
|
|
974
|
+
topicCacheSize: this.contentCache.size,
|
|
975
|
+
layerCount: this.layers.size,
|
|
976
|
+
totalMemoryUsage: 0 // Could be calculated if needed
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* Dispose of all layers
|
|
981
|
+
*/
|
|
982
|
+
async dispose() {
|
|
983
|
+
for (const layer of this.layers.values()) {
|
|
984
|
+
await layer.dispose();
|
|
985
|
+
}
|
|
986
|
+
this.layers.clear();
|
|
987
|
+
this.clearCache();
|
|
988
|
+
this.initialized = false;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
//# sourceMappingURL=multi-content-layer-service.js.map
|