ai-prompt-guide-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +271 -0
- package/dist/__tests__/config-loading.test.d.ts +5 -0
- package/dist/__tests__/config-loading.test.d.ts.map +1 -0
- package/dist/__tests__/config-loading.test.js +127 -0
- package/dist/__tests__/config-loading.test.js.map +1 -0
- package/dist/__tests__/config-logging.test.d.ts +5 -0
- package/dist/__tests__/config-logging.test.d.ts.map +1 -0
- package/dist/__tests__/config-logging.test.js +146 -0
- package/dist/__tests__/config-logging.test.js.map +1 -0
- package/dist/__tests__/config-path-resolution.test.d.ts +5 -0
- package/dist/__tests__/config-path-resolution.test.d.ts.map +1 -0
- package/dist/__tests__/config-path-resolution.test.js +88 -0
- package/dist/__tests__/config-path-resolution.test.js.map +1 -0
- package/dist/__tests__/config-path-validation.test.d.ts +6 -0
- package/dist/__tests__/config-path-validation.test.d.ts.map +1 -0
- package/dist/__tests__/config-path-validation.test.js +203 -0
- package/dist/__tests__/config-path-validation.test.js.map +1 -0
- package/dist/__tests__/config-precedence.test.d.ts +5 -0
- package/dist/__tests__/config-precedence.test.d.ts.map +1 -0
- package/dist/__tests__/config-precedence.test.js +200 -0
- package/dist/__tests__/config-precedence.test.js.map +1 -0
- package/dist/__tests__/config-types.test.d.ts +5 -0
- package/dist/__tests__/config-types.test.d.ts.map +1 -0
- package/dist/__tests__/config-types.test.js +189 -0
- package/dist/__tests__/config-types.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +5 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +229 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/config.d.ts +87 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +498 -0
- package/dist/config.js.map +1 -0
- package/dist/constants/defaults.d.ts +78 -0
- package/dist/constants/defaults.d.ts.map +1 -0
- package/dist/constants/defaults.js +78 -0
- package/dist/constants/defaults.js.map +1 -0
- package/dist/document-cache.d.ts +485 -0
- package/dist/document-cache.d.ts.map +1 -0
- package/dist/document-cache.hierarchical.test.d.ts +2 -0
- package/dist/document-cache.hierarchical.test.d.ts.map +1 -0
- package/dist/document-cache.hierarchical.test.js +243 -0
- package/dist/document-cache.hierarchical.test.js.map +1 -0
- package/dist/document-cache.js +965 -0
- package/dist/document-cache.js.map +1 -0
- package/dist/document-cache.test.d.ts +8 -0
- package/dist/document-cache.test.d.ts.map +1 -0
- package/dist/document-cache.test.js +624 -0
- package/dist/document-cache.test.js.map +1 -0
- package/dist/document-manager.d.ts +252 -0
- package/dist/document-manager.d.ts.map +1 -0
- package/dist/document-manager.js +760 -0
- package/dist/document-manager.js.map +1 -0
- package/dist/document-manager.race-condition.test.d.ts +8 -0
- package/dist/document-manager.race-condition.test.d.ts.map +1 -0
- package/dist/document-manager.race-condition.test.js +139 -0
- package/dist/document-manager.race-condition.test.js.map +1 -0
- package/dist/fingerprint-index.d.ts +177 -0
- package/dist/fingerprint-index.d.ts.map +1 -0
- package/dist/fingerprint-index.js +374 -0
- package/dist/fingerprint-index.js.map +1 -0
- package/dist/fingerprint-index.test.d.ts +15 -0
- package/dist/fingerprint-index.test.d.ts.map +1 -0
- package/dist/fingerprint-index.test.js +482 -0
- package/dist/fingerprint-index.test.js.map +1 -0
- package/dist/fsio.d.ts +76 -0
- package/dist/fsio.d.ts.map +1 -0
- package/dist/fsio.js +506 -0
- package/dist/fsio.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown-tools.test.d.ts +5 -0
- package/dist/markdown-tools.test.d.ts.map +1 -0
- package/dist/markdown-tools.test.js +200 -0
- package/dist/markdown-tools.test.js.map +1 -0
- package/dist/parse.d.ts +19 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +144 -0
- package/dist/parse.js.map +1 -0
- package/dist/prompts/__tests__/prompt-loader.test.d.ts +5 -0
- package/dist/prompts/__tests__/prompt-loader.test.d.ts.map +1 -0
- package/dist/prompts/__tests__/prompt-loader.test.js +300 -0
- package/dist/prompts/__tests__/prompt-loader.test.js.map +1 -0
- package/dist/prompts/prompt-loader.d.ts +58 -0
- package/dist/prompts/prompt-loader.d.ts.map +1 -0
- package/dist/prompts/prompt-loader.js +215 -0
- package/dist/prompts/prompt-loader.js.map +1 -0
- package/dist/prompts/prompt-validator.d.ts +30 -0
- package/dist/prompts/prompt-validator.d.ts.map +1 -0
- package/dist/prompts/prompt-validator.js +65 -0
- package/dist/prompts/prompt-validator.js.map +1 -0
- package/dist/prompts/types.d.ts +46 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +14 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/prompts/workflow-prompts.d.ts +42 -0
- package/dist/prompts/workflow-prompts.d.ts.map +1 -0
- package/dist/prompts/workflow-prompts.js +61 -0
- package/dist/prompts/workflow-prompts.js.map +1 -0
- package/dist/sections.d.ts +67 -0
- package/dist/sections.d.ts.map +1 -0
- package/dist/sections.hierarchical.test.d.ts +8 -0
- package/dist/sections.hierarchical.test.d.ts.map +1 -0
- package/dist/sections.hierarchical.test.js +397 -0
- package/dist/sections.hierarchical.test.js.map +1 -0
- package/dist/sections.js +1229 -0
- package/dist/sections.js.map +1 -0
- package/dist/server/default-dependencies.d.ts +134 -0
- package/dist/server/default-dependencies.d.ts.map +1 -0
- package/dist/server/default-dependencies.js +176 -0
- package/dist/server/default-dependencies.js.map +1 -0
- package/dist/server/dependencies.d.ts +161 -0
- package/dist/server/dependencies.d.ts.map +1 -0
- package/dist/server/dependencies.js +50 -0
- package/dist/server/dependencies.js.map +1 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +9 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/middleware/error-handling.d.ts +52 -0
- package/dist/server/middleware/error-handling.d.ts.map +1 -0
- package/dist/server/middleware/error-handling.js +76 -0
- package/dist/server/middleware/error-handling.js.map +1 -0
- package/dist/server/middleware/index.d.ts +7 -0
- package/dist/server/middleware/index.d.ts.map +1 -0
- package/dist/server/middleware/index.js +7 -0
- package/dist/server/middleware/index.js.map +1 -0
- package/dist/server/middleware/logging.d.ts +29 -0
- package/dist/server/middleware/logging.d.ts.map +1 -0
- package/dist/server/middleware/logging.js +49 -0
- package/dist/server/middleware/logging.js.map +1 -0
- package/dist/server/middleware/session-management.d.ts +38 -0
- package/dist/server/middleware/session-management.d.ts.map +1 -0
- package/dist/server/middleware/session-management.js +66 -0
- package/dist/server/middleware/session-management.js.map +1 -0
- package/dist/server/request-handlers/index.d.ts +5 -0
- package/dist/server/request-handlers/index.d.ts.map +1 -0
- package/dist/server/request-handlers/index.js +5 -0
- package/dist/server/request-handlers/index.js.map +1 -0
- package/dist/server/request-handlers/prompt-handlers.d.ts +13 -0
- package/dist/server/request-handlers/prompt-handlers.d.ts.map +1 -0
- package/dist/server/request-handlers/prompt-handlers.js +80 -0
- package/dist/server/request-handlers/prompt-handlers.js.map +1 -0
- package/dist/server/request-handlers/tool-handlers.d.ts +11 -0
- package/dist/server/request-handlers/tool-handlers.d.ts.map +1 -0
- package/dist/server/request-handlers/tool-handlers.js +85 -0
- package/dist/server/request-handlers/tool-handlers.js.map +1 -0
- package/dist/server/server-factory.d.ts +68 -0
- package/dist/server/server-factory.d.ts.map +1 -0
- package/dist/server/server-factory.js +135 -0
- package/dist/server/server-factory.js.map +1 -0
- package/dist/server/transport/stdio-transport.d.ts +9 -0
- package/dist/server/transport/stdio-transport.d.ts.map +1 -0
- package/dist/server/transport/stdio-transport.js +11 -0
- package/dist/server/transport/stdio-transport.js.map +1 -0
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +7 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/session-store.d.ts +74 -0
- package/dist/session/session-store.d.ts.map +1 -0
- package/dist/session/session-store.js +150 -0
- package/dist/session/session-store.js.map +1 -0
- package/dist/session/types.d.ts +96 -0
- package/dist/session/types.d.ts.map +1 -0
- package/dist/session/types.js +9 -0
- package/dist/session/types.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.d.ts +12 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.js +306 -0
- package/dist/shared/__tests__/addressing-system.batch-cache.test.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.d.ts +6 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.js +205 -0
- package/dist/shared/__tests__/addressing-system.hierarchical.test.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.lru.test.d.ts +6 -0
- package/dist/shared/__tests__/addressing-system.lru.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.lru.test.js +159 -0
- package/dist/shared/__tests__/addressing-system.lru.test.js.map +1 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.d.ts +14 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.d.ts.map +1 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.js +249 -0
- package/dist/shared/__tests__/addressing-system.relative-paths.test.js.map +1 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.d.ts +9 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.d.ts.map +1 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.js +419 -0
- package/dist/shared/__tests__/document-analysis-enhanced.test.js.map +1 -0
- package/dist/shared/__tests__/document-analysis.test.d.ts +8 -0
- package/dist/shared/__tests__/document-analysis.test.d.ts.map +1 -0
- package/dist/shared/__tests__/document-analysis.test.js +904 -0
- package/dist/shared/__tests__/document-analysis.test.js.map +1 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.d.ts +9 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.d.ts.map +1 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.js +317 -0
- package/dist/shared/__tests__/keyword-utils-integration.test.js.map +1 -0
- package/dist/shared/__tests__/link-utils.test.d.ts +5 -0
- package/dist/shared/__tests__/link-utils.test.d.ts.map +1 -0
- package/dist/shared/__tests__/link-utils.test.js +560 -0
- package/dist/shared/__tests__/link-utils.test.js.map +1 -0
- package/dist/shared/__tests__/link-validation.test.d.ts +5 -0
- package/dist/shared/__tests__/link-validation.test.d.ts.map +1 -0
- package/dist/shared/__tests__/link-validation.test.js +473 -0
- package/dist/shared/__tests__/link-validation.test.js.map +1 -0
- package/dist/shared/__tests__/reference-extractor.test.d.ts +8 -0
- package/dist/shared/__tests__/reference-extractor.test.d.ts.map +1 -0
- package/dist/shared/__tests__/reference-extractor.test.js +260 -0
- package/dist/shared/__tests__/reference-extractor.test.js.map +1 -0
- package/dist/shared/__tests__/reference-loader.test.d.ts +8 -0
- package/dist/shared/__tests__/reference-loader.test.d.ts.map +1 -0
- package/dist/shared/__tests__/reference-loader.test.js +622 -0
- package/dist/shared/__tests__/reference-loader.test.js.map +1 -0
- package/dist/shared/__tests__/section-operations.append.test.d.ts +8 -0
- package/dist/shared/__tests__/section-operations.append.test.d.ts.map +1 -0
- package/dist/shared/__tests__/section-operations.append.test.js +150 -0
- package/dist/shared/__tests__/section-operations.append.test.js.map +1 -0
- package/dist/shared/__tests__/section-operations.test.d.ts +7 -0
- package/dist/shared/__tests__/section-operations.test.d.ts.map +1 -0
- package/dist/shared/__tests__/section-operations.test.js +118 -0
- package/dist/shared/__tests__/section-operations.test.js.map +1 -0
- package/dist/shared/__tests__/slug-utils.test.d.ts +5 -0
- package/dist/shared/__tests__/slug-utils.test.d.ts.map +1 -0
- package/dist/shared/__tests__/slug-utils.test.js +542 -0
- package/dist/shared/__tests__/slug-utils.test.js.map +1 -0
- package/dist/shared/__tests__/task-operations.test.d.ts +9 -0
- package/dist/shared/__tests__/task-operations.test.d.ts.map +1 -0
- package/dist/shared/__tests__/task-operations.test.js +257 -0
- package/dist/shared/__tests__/task-operations.test.js.map +1 -0
- package/dist/shared/__tests__/task-validation.test.d.ts +6 -0
- package/dist/shared/__tests__/task-validation.test.d.ts.map +1 -0
- package/dist/shared/__tests__/task-validation.test.js +129 -0
- package/dist/shared/__tests__/task-validation.test.js.map +1 -0
- package/dist/shared/__tests__/task-view-utilities.test.d.ts +5 -0
- package/dist/shared/__tests__/task-view-utilities.test.d.ts.map +1 -0
- package/dist/shared/__tests__/task-view-utilities.test.js +312 -0
- package/dist/shared/__tests__/task-view-utilities.test.js.map +1 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.d.ts +7 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.d.ts.map +1 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.js +169 -0
- package/dist/shared/__tests__/tool-integration.array-validation.test.js.map +1 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.d.ts +7 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.d.ts.map +1 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.js +204 -0
- package/dist/shared/__tests__/tool-integration.hierarchical.test.js.map +1 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.d.ts +8 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.d.ts.map +1 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.js +722 -0
- package/dist/shared/__tests__/workflow-prompt-utilities.test.js.map +1 -0
- package/dist/shared/addressing-system.d.ts +799 -0
- package/dist/shared/addressing-system.d.ts.map +1 -0
- package/dist/shared/addressing-system.js +1074 -0
- package/dist/shared/addressing-system.js.map +1 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.d.ts +8 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.d.ts.map +1 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.js +601 -0
- package/dist/shared/document-analysis/__tests__/keyword-utils.test.js.map +1 -0
- package/dist/shared/document-analysis/index.d.ts +67 -0
- package/dist/shared/document-analysis/index.d.ts.map +1 -0
- package/dist/shared/document-analysis/index.js +166 -0
- package/dist/shared/document-analysis/index.js.map +1 -0
- package/dist/shared/document-analysis/keyword-utils.d.ts +405 -0
- package/dist/shared/document-analysis/keyword-utils.d.ts.map +1 -0
- package/dist/shared/document-analysis/keyword-utils.js +1147 -0
- package/dist/shared/document-analysis/keyword-utils.js.map +1 -0
- package/dist/shared/document-analysis/reference-validation.d.ts +27 -0
- package/dist/shared/document-analysis/reference-validation.d.ts.map +1 -0
- package/dist/shared/document-analysis/reference-validation.js +173 -0
- package/dist/shared/document-analysis/reference-validation.js.map +1 -0
- package/dist/shared/document-analysis/related-docs.d.ts +27 -0
- package/dist/shared/document-analysis/related-docs.d.ts.map +1 -0
- package/dist/shared/document-analysis/related-docs.js +459 -0
- package/dist/shared/document-analysis/related-docs.js.map +1 -0
- package/dist/shared/document-analysis/types.d.ts +89 -0
- package/dist/shared/document-analysis/types.d.ts.map +1 -0
- package/dist/shared/document-analysis/types.js +41 -0
- package/dist/shared/document-analysis/types.js.map +1 -0
- package/dist/shared/document-analysis.d.ts +15 -0
- package/dist/shared/document-analysis.d.ts.map +1 -0
- package/dist/shared/document-analysis.js +16 -0
- package/dist/shared/document-analysis.js.map +1 -0
- package/dist/shared/document-manager-factory.d.ts +32 -0
- package/dist/shared/document-manager-factory.d.ts.map +1 -0
- package/dist/shared/document-manager-factory.js +75 -0
- package/dist/shared/document-manager-factory.js.map +1 -0
- package/dist/shared/index.d.ts +5 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +7 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/link-analysis.d.ts +84 -0
- package/dist/shared/link-analysis.d.ts.map +1 -0
- package/dist/shared/link-analysis.js +213 -0
- package/dist/shared/link-analysis.js.map +1 -0
- package/dist/shared/link-context.d.ts +23 -0
- package/dist/shared/link-context.d.ts.map +1 -0
- package/dist/shared/link-context.js +172 -0
- package/dist/shared/link-context.js.map +1 -0
- package/dist/shared/link-utils.d.ts +33 -0
- package/dist/shared/link-utils.d.ts.map +1 -0
- package/dist/shared/link-utils.js +301 -0
- package/dist/shared/link-utils.js.map +1 -0
- package/dist/shared/link-validation.d.ts +79 -0
- package/dist/shared/link-validation.d.ts.map +1 -0
- package/dist/shared/link-validation.js +340 -0
- package/dist/shared/link-validation.js.map +1 -0
- package/dist/shared/namespace-analysis.d.ts +10 -0
- package/dist/shared/namespace-analysis.d.ts.map +1 -0
- package/dist/shared/namespace-analysis.js +100 -0
- package/dist/shared/namespace-analysis.js.map +1 -0
- package/dist/shared/namespace-constants.d.ts +69 -0
- package/dist/shared/namespace-constants.d.ts.map +1 -0
- package/dist/shared/namespace-constants.js +97 -0
- package/dist/shared/namespace-constants.js.map +1 -0
- package/dist/shared/path-utilities.d.ts +13 -0
- package/dist/shared/path-utilities.d.ts.map +1 -0
- package/dist/shared/path-utilities.js +39 -0
- package/dist/shared/path-utilities.js.map +1 -0
- package/dist/shared/reference-extractor.d.ts +121 -0
- package/dist/shared/reference-extractor.d.ts.map +1 -0
- package/dist/shared/reference-extractor.js +195 -0
- package/dist/shared/reference-extractor.js.map +1 -0
- package/dist/shared/reference-loader.d.ts +163 -0
- package/dist/shared/reference-loader.d.ts.map +1 -0
- package/dist/shared/reference-loader.js +265 -0
- package/dist/shared/reference-loader.js.map +1 -0
- package/dist/shared/section-operations.d.ts +14 -0
- package/dist/shared/section-operations.d.ts.map +1 -0
- package/dist/shared/section-operations.js +115 -0
- package/dist/shared/section-operations.js.map +1 -0
- package/dist/shared/slug-utils.d.ts +109 -0
- package/dist/shared/slug-utils.d.ts.map +1 -0
- package/dist/shared/slug-utils.js +302 -0
- package/dist/shared/slug-utils.js.map +1 -0
- package/dist/shared/task-operations.d.ts +152 -0
- package/dist/shared/task-operations.d.ts.map +1 -0
- package/dist/shared/task-operations.js +416 -0
- package/dist/shared/task-operations.js.map +1 -0
- package/dist/shared/task-utilities.d.ts +63 -0
- package/dist/shared/task-utilities.d.ts.map +1 -0
- package/dist/shared/task-utilities.js +86 -0
- package/dist/shared/task-utilities.js.map +1 -0
- package/dist/shared/task-validation.d.ts +50 -0
- package/dist/shared/task-validation.d.ts.map +1 -0
- package/dist/shared/task-validation.js +97 -0
- package/dist/shared/task-validation.js.map +1 -0
- package/dist/shared/task-view-utilities.d.ts +109 -0
- package/dist/shared/task-view-utilities.d.ts.map +1 -0
- package/dist/shared/task-view-utilities.js +255 -0
- package/dist/shared/task-view-utilities.js.map +1 -0
- package/dist/shared/utilities.d.ts +14 -0
- package/dist/shared/utilities.d.ts.map +1 -0
- package/dist/shared/utilities.js +23 -0
- package/dist/shared/utilities.js.map +1 -0
- package/dist/shared/utilities.test.d.ts +5 -0
- package/dist/shared/utilities.test.d.ts.map +1 -0
- package/dist/shared/utilities.test.js +422 -0
- package/dist/shared/utilities.test.js.map +1 -0
- package/dist/shared/validation-utils.d.ts +57 -0
- package/dist/shared/validation-utils.d.ts.map +1 -0
- package/dist/shared/validation-utils.js +63 -0
- package/dist/shared/validation-utils.js.map +1 -0
- package/dist/shared/workflow-prompt-utilities.d.ts +64 -0
- package/dist/shared/workflow-prompt-utilities.d.ts.map +1 -0
- package/dist/shared/workflow-prompt-utilities.js +163 -0
- package/dist/shared/workflow-prompt-utilities.js.map +1 -0
- package/dist/slug.d.ts +9 -0
- package/dist/slug.d.ts.map +1 -0
- package/dist/slug.js +40 -0
- package/dist/slug.js.map +1 -0
- package/dist/template-loader.d.ts +6 -0
- package/dist/template-loader.d.ts.map +1 -0
- package/dist/template-loader.js +8 -0
- package/dist/template-loader.js.map +1 -0
- package/dist/tools/__tests__/create-document-self-reference.test.d.ts +2 -0
- package/dist/tools/__tests__/create-document-self-reference.test.d.ts.map +1 -0
- package/dist/tools/__tests__/create-document-self-reference.test.js +124 -0
- package/dist/tools/__tests__/create-document-self-reference.test.js.map +1 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.d.ts +16 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.d.ts.map +1 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.js +655 -0
- package/dist/tools/__tests__/create-document-workflow-regression.test.js.map +1 -0
- package/dist/tools/__tests__/create-document.test.d.ts +2 -0
- package/dist/tools/__tests__/create-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/create-document.test.js +255 -0
- package/dist/tools/__tests__/create-document.test.js.map +1 -0
- package/dist/tools/__tests__/delete-document.test.d.ts +7 -0
- package/dist/tools/__tests__/delete-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/delete-document.test.js +311 -0
- package/dist/tools/__tests__/delete-document.test.js.map +1 -0
- package/dist/tools/__tests__/edit-document.test.d.ts +2 -0
- package/dist/tools/__tests__/edit-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/edit-document.test.js +644 -0
- package/dist/tools/__tests__/edit-document.test.js.map +1 -0
- package/dist/tools/__tests__/error-scenarios.test.d.ts +5 -0
- package/dist/tools/__tests__/error-scenarios.test.d.ts.map +1 -0
- package/dist/tools/__tests__/error-scenarios.test.js +105 -0
- package/dist/tools/__tests__/error-scenarios.test.js.map +1 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.d.ts +99 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.d.ts.map +1 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.js +457 -0
- package/dist/tools/__tests__/mocks/document-manager.mock.js.map +1 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.d.ts +103 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.d.ts.map +1 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.js +247 -0
- package/dist/tools/__tests__/mocks/filesystem.mock.js.map +1 -0
- package/dist/tools/__tests__/move-document.test.d.ts +12 -0
- package/dist/tools/__tests__/move-document.test.d.ts.map +1 -0
- package/dist/tools/__tests__/move-document.test.js +214 -0
- package/dist/tools/__tests__/move-document.test.js.map +1 -0
- package/dist/tools/__tests__/move.test.d.ts +13 -0
- package/dist/tools/__tests__/move.test.d.ts.map +1 -0
- package/dist/tools/__tests__/move.test.js +939 -0
- package/dist/tools/__tests__/move.test.js.map +1 -0
- package/dist/tools/__tests__/section.integration.improved.test.d.ts +5 -0
- package/dist/tools/__tests__/section.integration.improved.test.d.ts.map +1 -0
- package/dist/tools/__tests__/section.integration.improved.test.js +199 -0
- package/dist/tools/__tests__/section.integration.improved.test.js.map +1 -0
- package/dist/tools/__tests__/section.integration.test.d.ts +5 -0
- package/dist/tools/__tests__/section.integration.test.d.ts.map +1 -0
- package/dist/tools/__tests__/section.integration.test.js +637 -0
- package/dist/tools/__tests__/section.integration.test.js.map +1 -0
- package/dist/tools/__tests__/setup/test-environment.d.ts +111 -0
- package/dist/tools/__tests__/setup/test-environment.d.ts.map +1 -0
- package/dist/tools/__tests__/setup/test-environment.js +322 -0
- package/dist/tools/__tests__/setup/test-environment.js.map +1 -0
- package/dist/tools/__tests__/suggestion-generator.test.d.ts +8 -0
- package/dist/tools/__tests__/suggestion-generator.test.d.ts.map +1 -0
- package/dist/tools/__tests__/suggestion-generator.test.js +508 -0
- package/dist/tools/__tests__/suggestion-generator.test.js.map +1 -0
- package/dist/tools/__tests__/task-consistency.test.d.ts +11 -0
- package/dist/tools/__tests__/task-consistency.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task-consistency.test.js +93 -0
- package/dist/tools/__tests__/task-consistency.test.js.map +1 -0
- package/dist/tools/__tests__/task-status-parsing.test.d.ts +15 -0
- package/dist/tools/__tests__/task-status-parsing.test.d.ts.map +1 -0
- package/dist/tools/__tests__/task-status-parsing.test.js +126 -0
- package/dist/tools/__tests__/task-status-parsing.test.js.map +1 -0
- package/dist/tools/__tests__/view-section-boundary.test.d.ts +2 -0
- package/dist/tools/__tests__/view-section-boundary.test.d.ts.map +1 -0
- package/dist/tools/__tests__/view-section-boundary.test.js +132 -0
- package/dist/tools/__tests__/view-section-boundary.test.js.map +1 -0
- package/dist/tools/__tests__/write-operations-integration.test.d.ts +8 -0
- package/dist/tools/__tests__/write-operations-integration.test.d.ts.map +1 -0
- package/dist/tools/__tests__/write-operations-integration.test.js +136 -0
- package/dist/tools/__tests__/write-operations-integration.test.js.map +1 -0
- package/dist/tools/browse/content-analyzer.d.ts +27 -0
- package/dist/tools/browse/content-analyzer.d.ts.map +1 -0
- package/dist/tools/browse/content-analyzer.js +150 -0
- package/dist/tools/browse/content-analyzer.js.map +1 -0
- package/dist/tools/browse/dependency-analyzer.d.ts +63 -0
- package/dist/tools/browse/dependency-analyzer.d.ts.map +1 -0
- package/dist/tools/browse/dependency-analyzer.js +261 -0
- package/dist/tools/browse/dependency-analyzer.js.map +1 -0
- package/dist/tools/browse/folder-navigator.d.ts +35 -0
- package/dist/tools/browse/folder-navigator.d.ts.map +1 -0
- package/dist/tools/browse/folder-navigator.js +154 -0
- package/dist/tools/browse/folder-navigator.js.map +1 -0
- package/dist/tools/browse/index.d.ts +10 -0
- package/dist/tools/browse/index.d.ts.map +1 -0
- package/dist/tools/browse/index.js +14 -0
- package/dist/tools/browse/index.js.map +1 -0
- package/dist/tools/browse/relationship-classifier.d.ts +9 -0
- package/dist/tools/browse/relationship-classifier.d.ts.map +1 -0
- package/dist/tools/browse/relationship-classifier.js +38 -0
- package/dist/tools/browse/relationship-classifier.js.map +1 -0
- package/dist/tools/browse/search-engine.d.ts +69 -0
- package/dist/tools/browse/search-engine.d.ts.map +1 -0
- package/dist/tools/browse/search-engine.js +197 -0
- package/dist/tools/browse/search-engine.js.map +1 -0
- package/dist/tools/create/__tests__/file-creator.test.d.ts +6 -0
- package/dist/tools/create/__tests__/file-creator.test.d.ts.map +1 -0
- package/dist/tools/create/__tests__/file-creator.test.js +138 -0
- package/dist/tools/create/__tests__/file-creator.test.js.map +1 -0
- package/dist/tools/create/__tests__/template-processor.test.d.ts +6 -0
- package/dist/tools/create/__tests__/template-processor.test.d.ts.map +1 -0
- package/dist/tools/create/__tests__/template-processor.test.js +130 -0
- package/dist/tools/create/__tests__/template-processor.test.js.map +1 -0
- package/dist/tools/create/file-creator.d.ts +35 -0
- package/dist/tools/create/file-creator.d.ts.map +1 -0
- package/dist/tools/create/file-creator.js +103 -0
- package/dist/tools/create/file-creator.js.map +1 -0
- package/dist/tools/create/index.d.ts +6 -0
- package/dist/tools/create/index.d.ts.map +1 -0
- package/dist/tools/create/index.js +7 -0
- package/dist/tools/create/index.js.map +1 -0
- package/dist/tools/create/pipeline.d.ts +39 -0
- package/dist/tools/create/pipeline.d.ts.map +1 -0
- package/dist/tools/create/pipeline.js +112 -0
- package/dist/tools/create/pipeline.js.map +1 -0
- package/dist/tools/create/suggestion-generator.d.ts +47 -0
- package/dist/tools/create/suggestion-generator.d.ts.map +1 -0
- package/dist/tools/create/suggestion-generator.js +51 -0
- package/dist/tools/create/suggestion-generator.js.map +1 -0
- package/dist/tools/create/template-processor.d.ts +27 -0
- package/dist/tools/create/template-processor.d.ts.map +1 -0
- package/dist/tools/create/template-processor.js +74 -0
- package/dist/tools/create/template-processor.js.map +1 -0
- package/dist/tools/create/validation-processor.d.ts +48 -0
- package/dist/tools/create/validation-processor.d.ts.map +1 -0
- package/dist/tools/create/validation-processor.js +107 -0
- package/dist/tools/create/validation-processor.js.map +1 -0
- package/dist/tools/executor.d.ts +19 -0
- package/dist/tools/executor.d.ts.map +1 -0
- package/dist/tools/executor.js +53 -0
- package/dist/tools/executor.js.map +1 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.js +319 -0
- package/dist/tools/implementations/__tests__/browse-documents.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.js +440 -0
- package/dist/tools/implementations/__tests__/complete-coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.d.ts +14 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.js +851 -0
- package/dist/tools/implementations/__tests__/complete-subagent-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.d.ts +6 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.js +157 -0
- package/dist/tools/implementations/__tests__/complete-task-notes.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task.test.d.ts +14 -0
- package/dist/tools/implementations/__tests__/complete-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/complete-task.test.js +867 -0
- package/dist/tools/implementations/__tests__/complete-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/continue-task.test.d.ts +11 -0
- package/dist/tools/implementations/__tests__/continue-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/continue-task.test.js +845 -0
- package/dist/tools/implementations/__tests__/continue-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.js +495 -0
- package/dist/tools/implementations/__tests__/coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/get-guide.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/get-guide.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/get-guide.test.js +242 -0
- package/dist/tools/implementations/__tests__/get-guide.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.js +232 -0
- package/dist/tools/implementations/__tests__/get-workflow.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/search-documents.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/search-documents.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/search-documents.test.js +336 -0
- package/dist/tools/implementations/__tests__/search-documents.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.js +177 -0
- package/dist/tools/implementations/__tests__/start-coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.d.ts +11 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.js +846 -0
- package/dist/tools/implementations/__tests__/start-subagent-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/start-task.test.d.ts +11 -0
- package/dist/tools/implementations/__tests__/start-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/start-task.test.js +828 -0
- package/dist/tools/implementations/__tests__/start-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.js +199 -0
- package/dist/tools/implementations/__tests__/subagent-task-batch-operations.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.js +720 -0
- package/dist/tools/implementations/__tests__/subagent-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.js +200 -0
- package/dist/tools/implementations/__tests__/task-batch-operations.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/task.test.d.ts +7 -0
- package/dist/tools/implementations/__tests__/task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/task.test.js +578 -0
- package/dist/tools/implementations/__tests__/task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.d.ts +13 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.js +1404 -0
- package/dist/tools/implementations/__tests__/view-coordinator-task.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.d.ts +8 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.js +235 -0
- package/dist/tools/implementations/__tests__/view-document.linked-context.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.d.ts +9 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.js +160 -0
- package/dist/tools/implementations/__tests__/view-document.simplification.test.js.map +1 -0
- package/dist/tools/implementations/__tests__/view-task.test.d.ts +12 -0
- package/dist/tools/implementations/__tests__/view-task.test.d.ts.map +1 -0
- package/dist/tools/implementations/__tests__/view-task.test.js +1158 -0
- package/dist/tools/implementations/__tests__/view-task.test.js.map +1 -0
- package/dist/tools/implementations/browse-documents.d.ts +36 -0
- package/dist/tools/implementations/browse-documents.d.ts.map +1 -0
- package/dist/tools/implementations/browse-documents.js +123 -0
- package/dist/tools/implementations/browse-documents.js.map +1 -0
- package/dist/tools/implementations/complete-coordinator-task.d.ts +53 -0
- package/dist/tools/implementations/complete-coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/complete-coordinator-task.js +159 -0
- package/dist/tools/implementations/complete-coordinator-task.js.map +1 -0
- package/dist/tools/implementations/complete-subagent-task.d.ts +47 -0
- package/dist/tools/implementations/complete-subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/complete-subagent-task.js +141 -0
- package/dist/tools/implementations/complete-subagent-task.js.map +1 -0
- package/dist/tools/implementations/complete-task.d.ts +32 -0
- package/dist/tools/implementations/complete-task.d.ts.map +1 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.js +363 -0
- package/dist/tools/implementations/complete-task.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/complete-task.js +122 -0
- package/dist/tools/implementations/complete-task.js.map +1 -0
- package/dist/tools/implementations/continue-task.d.ts +48 -0
- package/dist/tools/implementations/continue-task.d.ts.map +1 -0
- package/dist/tools/implementations/continue-task.js +167 -0
- package/dist/tools/implementations/continue-task.js.map +1 -0
- package/dist/tools/implementations/coordinator-task.d.ts +72 -0
- package/dist/tools/implementations/coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/coordinator-task.js +169 -0
- package/dist/tools/implementations/coordinator-task.js.map +1 -0
- package/dist/tools/implementations/create-document.d.ts +12 -0
- package/dist/tools/implementations/create-document.d.ts.map +1 -0
- package/dist/tools/implementations/create-document.js +15 -0
- package/dist/tools/implementations/create-document.js.map +1 -0
- package/dist/tools/implementations/delete-document.d.ts +16 -0
- package/dist/tools/implementations/delete-document.d.ts.map +1 -0
- package/dist/tools/implementations/delete-document.js +70 -0
- package/dist/tools/implementations/delete-document.js.map +1 -0
- package/dist/tools/implementations/edit-document.d.ts +8 -0
- package/dist/tools/implementations/edit-document.d.ts.map +1 -0
- package/dist/tools/implementations/edit-document.js +118 -0
- package/dist/tools/implementations/edit-document.js.map +1 -0
- package/dist/tools/implementations/get-guide.d.ts +13 -0
- package/dist/tools/implementations/get-guide.d.ts.map +1 -0
- package/dist/tools/implementations/get-guide.js +64 -0
- package/dist/tools/implementations/get-guide.js.map +1 -0
- package/dist/tools/implementations/get-workflow.d.ts +12 -0
- package/dist/tools/implementations/get-workflow.d.ts.map +1 -0
- package/dist/tools/implementations/get-workflow.js +71 -0
- package/dist/tools/implementations/get-workflow.js.map +1 -0
- package/dist/tools/implementations/index.d.ts +24 -0
- package/dist/tools/implementations/index.d.ts.map +1 -0
- package/dist/tools/implementations/index.js +24 -0
- package/dist/tools/implementations/index.js.map +1 -0
- package/dist/tools/implementations/manage-document.d.ts +8 -0
- package/dist/tools/implementations/manage-document.d.ts.map +1 -0
- package/dist/tools/implementations/manage-document.js +180 -0
- package/dist/tools/implementations/manage-document.js.map +1 -0
- package/dist/tools/implementations/move-document.d.ts +12 -0
- package/dist/tools/implementations/move-document.d.ts.map +1 -0
- package/dist/tools/implementations/move-document.js +72 -0
- package/dist/tools/implementations/move-document.js.map +1 -0
- package/dist/tools/implementations/move.d.ts +24 -0
- package/dist/tools/implementations/move.d.ts.map +1 -0
- package/dist/tools/implementations/move.js +167 -0
- package/dist/tools/implementations/move.js.map +1 -0
- package/dist/tools/implementations/search-documents.d.ts +39 -0
- package/dist/tools/implementations/search-documents.d.ts.map +1 -0
- package/dist/tools/implementations/search-documents.js +246 -0
- package/dist/tools/implementations/search-documents.js.map +1 -0
- package/dist/tools/implementations/section.d.ts +42 -0
- package/dist/tools/implementations/section.d.ts.map +1 -0
- package/dist/tools/implementations/section.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/section.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/section.hierarchical.test.js +299 -0
- package/dist/tools/implementations/section.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/section.js +244 -0
- package/dist/tools/implementations/section.js.map +1 -0
- package/dist/tools/implementations/section.test.d.ts +5 -0
- package/dist/tools/implementations/section.test.d.ts.map +1 -0
- package/dist/tools/implementations/section.test.js +371 -0
- package/dist/tools/implementations/section.test.js.map +1 -0
- package/dist/tools/implementations/start-coordinator-task.d.ts +44 -0
- package/dist/tools/implementations/start-coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/start-coordinator-task.js +125 -0
- package/dist/tools/implementations/start-coordinator-task.js.map +1 -0
- package/dist/tools/implementations/start-subagent-task.d.ts +53 -0
- package/dist/tools/implementations/start-subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/start-subagent-task.js +179 -0
- package/dist/tools/implementations/start-subagent-task.js.map +1 -0
- package/dist/tools/implementations/start-task.d.ts +48 -0
- package/dist/tools/implementations/start-task.d.ts.map +1 -0
- package/dist/tools/implementations/start-task.js +216 -0
- package/dist/tools/implementations/start-task.js.map +1 -0
- package/dist/tools/implementations/subagent-task.d.ts +98 -0
- package/dist/tools/implementations/subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/subagent-task.js +277 -0
- package/dist/tools/implementations/subagent-task.js.map +1 -0
- package/dist/tools/implementations/task.d.ts +97 -0
- package/dist/tools/implementations/task.d.ts.map +1 -0
- package/dist/tools/implementations/task.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/task.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/task.hierarchical.test.js +333 -0
- package/dist/tools/implementations/task.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/task.js +235 -0
- package/dist/tools/implementations/task.js.map +1 -0
- package/dist/tools/implementations/view-coordinator-task.d.ts +61 -0
- package/dist/tools/implementations/view-coordinator-task.d.ts.map +1 -0
- package/dist/tools/implementations/view-coordinator-task.js +295 -0
- package/dist/tools/implementations/view-coordinator-task.js.map +1 -0
- package/dist/tools/implementations/view-document.d.ts +84 -0
- package/dist/tools/implementations/view-document.d.ts.map +1 -0
- package/dist/tools/implementations/view-document.js +287 -0
- package/dist/tools/implementations/view-document.js.map +1 -0
- package/dist/tools/implementations/view-section.d.ts +28 -0
- package/dist/tools/implementations/view-section.d.ts.map +1 -0
- package/dist/tools/implementations/view-section.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/view-section.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/view-section.hierarchical.test.js +318 -0
- package/dist/tools/implementations/view-section.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/view-section.js +167 -0
- package/dist/tools/implementations/view-section.js.map +1 -0
- package/dist/tools/implementations/view-subagent-task.d.ts +46 -0
- package/dist/tools/implementations/view-subagent-task.d.ts.map +1 -0
- package/dist/tools/implementations/view-subagent-task.js +283 -0
- package/dist/tools/implementations/view-subagent-task.js.map +1 -0
- package/dist/tools/implementations/view-task.d.ts +43 -0
- package/dist/tools/implementations/view-task.d.ts.map +1 -0
- package/dist/tools/implementations/view-task.hierarchical.test.d.ts +8 -0
- package/dist/tools/implementations/view-task.hierarchical.test.d.ts.map +1 -0
- package/dist/tools/implementations/view-task.hierarchical.test.js +420 -0
- package/dist/tools/implementations/view-task.hierarchical.test.js.map +1 -0
- package/dist/tools/implementations/view-task.js +280 -0
- package/dist/tools/implementations/view-task.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +10 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +132 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.d.ts +8 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.d.ts.map +1 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.js +216 -0
- package/dist/tools/schemas/__tests__/get-guide-schemas.test.js.map +1 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.d.ts +8 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.d.ts.map +1 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.js +229 -0
- package/dist/tools/schemas/__tests__/get-workflow-schemas.test.js.map +1 -0
- package/dist/tools/schemas/browse-documents-schemas.d.ts +47 -0
- package/dist/tools/schemas/browse-documents-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/browse-documents-schemas.js +48 -0
- package/dist/tools/schemas/browse-documents-schemas.js.map +1 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.d.ts +41 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.js +42 -0
- package/dist/tools/schemas/complete-coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.d.ts +38 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.js +41 -0
- package/dist/tools/schemas/complete-subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/complete-task-schemas.d.ts +33 -0
- package/dist/tools/schemas/complete-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/complete-task-schemas.js +36 -0
- package/dist/tools/schemas/complete-task-schemas.js.map +1 -0
- package/dist/tools/schemas/continue-task-schemas.d.ts +27 -0
- package/dist/tools/schemas/continue-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/continue-task-schemas.js +28 -0
- package/dist/tools/schemas/continue-task-schemas.js.map +1 -0
- package/dist/tools/schemas/coordinator-task-schemas.d.ts +87 -0
- package/dist/tools/schemas/coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/coordinator-task-schemas.js +80 -0
- package/dist/tools/schemas/coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/create-document-schemas.d.ts +61 -0
- package/dist/tools/schemas/create-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/create-document-schemas.js +143 -0
- package/dist/tools/schemas/create-document-schemas.js.map +1 -0
- package/dist/tools/schemas/delete-document-schemas.d.ts +24 -0
- package/dist/tools/schemas/delete-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/delete-document-schemas.js +25 -0
- package/dist/tools/schemas/delete-document-schemas.js.map +1 -0
- package/dist/tools/schemas/edit-document-schemas.d.ts +27 -0
- package/dist/tools/schemas/edit-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/edit-document-schemas.js +28 -0
- package/dist/tools/schemas/edit-document-schemas.js.map +1 -0
- package/dist/tools/schemas/get-guide-schemas.d.ts +35 -0
- package/dist/tools/schemas/get-guide-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/get-guide-schemas.js +66 -0
- package/dist/tools/schemas/get-guide-schemas.js.map +1 -0
- package/dist/tools/schemas/get-workflow-schemas.d.ts +35 -0
- package/dist/tools/schemas/get-workflow-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/get-workflow-schemas.js +67 -0
- package/dist/tools/schemas/get-workflow-schemas.js.map +1 -0
- package/dist/tools/schemas/manage-document-schemas.d.ts +59 -0
- package/dist/tools/schemas/manage-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/manage-document-schemas.js +83 -0
- package/dist/tools/schemas/manage-document-schemas.js.map +1 -0
- package/dist/tools/schemas/move-document-schemas.d.ts +25 -0
- package/dist/tools/schemas/move-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/move-document-schemas.js +26 -0
- package/dist/tools/schemas/move-document-schemas.js.map +1 -0
- package/dist/tools/schemas/move-schemas.d.ts +43 -0
- package/dist/tools/schemas/move-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/move-schemas.js +43 -0
- package/dist/tools/schemas/move-schemas.js.map +1 -0
- package/dist/tools/schemas/search-documents-schemas.d.ts +77 -0
- package/dist/tools/schemas/search-documents-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/search-documents-schemas.js +78 -0
- package/dist/tools/schemas/search-documents-schemas.js.map +1 -0
- package/dist/tools/schemas/section-schemas.d.ts +361 -0
- package/dist/tools/schemas/section-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/section-schemas.js +182 -0
- package/dist/tools/schemas/section-schemas.js.map +1 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.d.ts +30 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.js +31 -0
- package/dist/tools/schemas/start-coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/start-subagent-task-schemas.d.ts +29 -0
- package/dist/tools/schemas/start-subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/start-subagent-task-schemas.js +40 -0
- package/dist/tools/schemas/start-subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/start-task-schemas.d.ts +23 -0
- package/dist/tools/schemas/start-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/start-task-schemas.js +39 -0
- package/dist/tools/schemas/start-task-schemas.js.map +1 -0
- package/dist/tools/schemas/subagent-task-schemas.d.ts +93 -0
- package/dist/tools/schemas/subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/subagent-task-schemas.js +81 -0
- package/dist/tools/schemas/subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/task-schemas.d.ts +88 -0
- package/dist/tools/schemas/task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/task-schemas.js +80 -0
- package/dist/tools/schemas/task-schemas.js.map +1 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.d.ts +27 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.js +46 -0
- package/dist/tools/schemas/view-coordinator-task-schemas.js.map +1 -0
- package/dist/tools/schemas/view-document-schemas.d.ts +152 -0
- package/dist/tools/schemas/view-document-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-document-schemas.js +70 -0
- package/dist/tools/schemas/view-document-schemas.js.map +1 -0
- package/dist/tools/schemas/view-section-schemas.d.ts +31 -0
- package/dist/tools/schemas/view-section-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-section-schemas.js +56 -0
- package/dist/tools/schemas/view-section-schemas.js.map +1 -0
- package/dist/tools/schemas/view-subagent-task-schemas.d.ts +31 -0
- package/dist/tools/schemas/view-subagent-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-subagent-task-schemas.js +65 -0
- package/dist/tools/schemas/view-subagent-task-schemas.js.map +1 -0
- package/dist/tools/schemas/view-task-schemas.d.ts +31 -0
- package/dist/tools/schemas/view-task-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/view-task-schemas.js +62 -0
- package/dist/tools/schemas/view-task-schemas.js.map +1 -0
- package/dist/tools/types.d.ts +98 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +9 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools-manager.d.ts +8 -0
- package/dist/tools-manager.d.ts.map +1 -0
- package/dist/tools-manager.js +9 -0
- package/dist/tools-manager.js.map +1 -0
- package/dist/types/core.d.ts +71 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +5 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/linking.d.ts +97 -0
- package/dist/types/linking.d.ts.map +1 -0
- package/dist/types/linking.js +5 -0
- package/dist/types/linking.js.map +1 -0
- package/dist/utils/__tests__/path-handler.archive.test.d.ts +8 -0
- package/dist/utils/__tests__/path-handler.archive.test.d.ts.map +1 -0
- package/dist/utils/__tests__/path-handler.archive.test.js +163 -0
- package/dist/utils/__tests__/path-handler.archive.test.js.map +1 -0
- package/dist/utils/error-formatter.d.ts +32 -0
- package/dist/utils/error-formatter.d.ts.map +1 -0
- package/dist/utils/error-formatter.js +79 -0
- package/dist/utils/error-formatter.js.map +1 -0
- package/dist/utils/logger.d.ts +21 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +154 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/path-handler.d.ts +52 -0
- package/dist/utils/path-handler.d.ts.map +1 -0
- package/dist/utils/path-handler.js +129 -0
- package/dist/utils/path-handler.js.map +1 -0
- package/dist/utils/security-audit-logger.d.ts +64 -0
- package/dist/utils/security-audit-logger.d.ts.map +1 -0
- package/dist/utils/security-audit-logger.js +56 -0
- package/dist/utils/security-audit-logger.js.map +1 -0
- package/dist/utils/virtual-path-resolver.d.ts +126 -0
- package/dist/utils/virtual-path-resolver.d.ts.map +1 -0
- package/dist/utils/virtual-path-resolver.js +171 -0
- package/dist/utils/virtual-path-resolver.js.map +1 -0
- package/package.json +82 -0
package/dist/sections.js
ADDED
|
@@ -0,0 +1,1229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown sections CRUD operations using heading ranges
|
|
3
|
+
*/
|
|
4
|
+
import { unified } from 'unified';
|
|
5
|
+
import remarkParse from 'remark-parse';
|
|
6
|
+
import { toMarkdown } from 'mdast-util-to-markdown';
|
|
7
|
+
import { toString } from 'mdast-util-to-string';
|
|
8
|
+
import { headingRange } from 'mdast-util-heading-range';
|
|
9
|
+
import { visitParents } from 'unist-util-visit-parents';
|
|
10
|
+
import { titleToSlug } from './slug.js';
|
|
11
|
+
import { listHeadings } from './parse.js';
|
|
12
|
+
import { ERROR_CODES, DEFAULT_LIMITS } from './constants/defaults.js';
|
|
13
|
+
import { AddressingError } from './shared/addressing-system.js';
|
|
14
|
+
import { validateHeadingDepth } from './shared/validation-utils.js';
|
|
15
|
+
/**
|
|
16
|
+
* Specialized error classes for section operations using standardized AddressingError hierarchy
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Base error class for all section operation failures
|
|
20
|
+
*
|
|
21
|
+
* This error provides structured information about section operation failures,
|
|
22
|
+
* including operation context and recovery patterns specific to section manipulation.
|
|
23
|
+
*
|
|
24
|
+
* @param message - Human-readable error description
|
|
25
|
+
* @param code - Machine-readable error code for programmatic handling
|
|
26
|
+
* @param context - Additional context about the failed operation
|
|
27
|
+
*
|
|
28
|
+
* @example Basic section error handling
|
|
29
|
+
* ```typescript
|
|
30
|
+
* try {
|
|
31
|
+
* await performSectionOperation(document, section, operation);
|
|
32
|
+
* } catch (error) {
|
|
33
|
+
* if (error instanceof SectionOperationError) {
|
|
34
|
+
* console.error('Section operation failed:', error.code);
|
|
35
|
+
* console.error('Context:', error.context);
|
|
36
|
+
* // Implement recovery based on error code
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @example Error code patterns
|
|
42
|
+
* ```typescript
|
|
43
|
+
* try {
|
|
44
|
+
* await editSection(docPath, sectionSlug, content);
|
|
45
|
+
* } catch (error) {
|
|
46
|
+
* if (error instanceof SectionOperationError) {
|
|
47
|
+
* switch (error.code) {
|
|
48
|
+
* case 'HEADING_NOT_FOUND':
|
|
49
|
+
* // Suggest similar section names or create section
|
|
50
|
+
* break;
|
|
51
|
+
* case 'INVALID_OPERATION':
|
|
52
|
+
* // Provide valid operation options
|
|
53
|
+
* break;
|
|
54
|
+
* case 'DUPLICATE_HEADING':
|
|
55
|
+
* // Handle heading conflicts
|
|
56
|
+
* break;
|
|
57
|
+
* }
|
|
58
|
+
* }
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
class SectionOperationError extends AddressingError {
|
|
63
|
+
constructor(message, code, context) {
|
|
64
|
+
super(message, code, context);
|
|
65
|
+
this.name = 'SectionOperationError';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Error thrown when section content is invalid or malformed
|
|
70
|
+
*
|
|
71
|
+
* This error indicates that the provided section content violates format requirements,
|
|
72
|
+
* contains invalid markup, or fails content validation rules.
|
|
73
|
+
*
|
|
74
|
+
* @param message - Specific validation error description
|
|
75
|
+
* @param context - Additional context about the invalid content
|
|
76
|
+
*
|
|
77
|
+
* @example Handling invalid content
|
|
78
|
+
* ```typescript
|
|
79
|
+
* try {
|
|
80
|
+
* await updateSectionContent(docPath, sectionSlug, content);
|
|
81
|
+
* } catch (error) {
|
|
82
|
+
* if (error instanceof InvalidSectionContentError) {
|
|
83
|
+
* console.error('Invalid content:', error.message);
|
|
84
|
+
* console.error('Content length:', error.context?.contentLength);
|
|
85
|
+
* // Provide content formatting guidance
|
|
86
|
+
* }
|
|
87
|
+
* }
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @example Content validation patterns
|
|
91
|
+
* ```typescript
|
|
92
|
+
* function validateSectionContent(content: string): void {
|
|
93
|
+
* try {
|
|
94
|
+
* if (!content || content.trim() === '') {
|
|
95
|
+
* throw new InvalidSectionContentError('Section content cannot be empty');
|
|
96
|
+
* }
|
|
97
|
+
* if (content.length > MAX_SECTION_LENGTH) {
|
|
98
|
+
* throw new InvalidSectionContentError('Section content exceeds maximum length', {
|
|
99
|
+
* contentLength: content.length,
|
|
100
|
+
* maxLength: MAX_SECTION_LENGTH
|
|
101
|
+
* });
|
|
102
|
+
* }
|
|
103
|
+
* } catch (error) {
|
|
104
|
+
* // Handle validation failure with user-friendly guidance
|
|
105
|
+
* throw error;
|
|
106
|
+
* }
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
110
|
+
* @throws {InvalidSectionContentError} When content validation fails
|
|
111
|
+
* @see {@link SectionOperationError} Base class for section operation errors
|
|
112
|
+
*/
|
|
113
|
+
class InvalidSectionContentError extends SectionOperationError {
|
|
114
|
+
constructor(message, context) {
|
|
115
|
+
super(message, ERROR_CODES.INVALID_SECTION_CONTENT, context);
|
|
116
|
+
this.name = 'InvalidSectionContentError';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Error thrown when a section slug is invalid or malformed
|
|
121
|
+
*
|
|
122
|
+
* This error indicates that the provided section slug does not conform to
|
|
123
|
+
* slug formatting rules, contains invalid characters, or conflicts with
|
|
124
|
+
* hierarchical addressing patterns.
|
|
125
|
+
*
|
|
126
|
+
* @param message - Specific slug validation error description
|
|
127
|
+
* @param context - Additional context about the invalid slug
|
|
128
|
+
*
|
|
129
|
+
* @example Handling invalid slugs
|
|
130
|
+
* ```typescript
|
|
131
|
+
* try {
|
|
132
|
+
* const section = parseSectionSlug(userProvidedSlug);
|
|
133
|
+
* } catch (error) {
|
|
134
|
+
* if (error instanceof InvalidSlugError) {
|
|
135
|
+
* console.error('Invalid slug format:', error.message);
|
|
136
|
+
* console.error('Provided slug:', error.context?.slug);
|
|
137
|
+
* // Suggest valid slug format
|
|
138
|
+
* console.log('Valid format: lowercase letters, numbers, hyphens only');
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @example Slug validation and normalization
|
|
144
|
+
* ```typescript
|
|
145
|
+
* function normalizeSlug(rawSlug: string): string {
|
|
146
|
+
* try {
|
|
147
|
+
* // Remove invalid characters and normalize
|
|
148
|
+
* const normalized = rawSlug.toLowerCase()
|
|
149
|
+
* .replace(/[^a-z0-9-]/g, '-')
|
|
150
|
+
* .replace(/-+/g, '-')
|
|
151
|
+
* .replace(/^-|-$/g, '');
|
|
152
|
+
*
|
|
153
|
+
* if (!normalized) {
|
|
154
|
+
* throw new InvalidSlugError('Slug cannot be empty after normalization', {
|
|
155
|
+
* originalSlug: rawSlug,
|
|
156
|
+
* normalizedSlug: normalized
|
|
157
|
+
* });
|
|
158
|
+
* }
|
|
159
|
+
*
|
|
160
|
+
* return normalized;
|
|
161
|
+
* } catch (error) {
|
|
162
|
+
* if (error instanceof InvalidSlugError) {
|
|
163
|
+
* // Provide alternative slug suggestions
|
|
164
|
+
* throw error;
|
|
165
|
+
* }
|
|
166
|
+
* throw new InvalidSlugError('Slug normalization failed', { originalSlug: rawSlug });
|
|
167
|
+
* }
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @throws {InvalidSlugError} When slug format validation fails
|
|
172
|
+
* @see {@link SectionOperationError} Base class for section operation errors
|
|
173
|
+
* @see {@link parseDocumentAddress} Related addressing functionality
|
|
174
|
+
*/
|
|
175
|
+
class InvalidSlugError extends SectionOperationError {
|
|
176
|
+
constructor(message, context) {
|
|
177
|
+
super(message, ERROR_CODES.INVALID_SLUG, context);
|
|
178
|
+
this.name = 'InvalidSlugError';
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Error thrown when a heading cannot be found in the document
|
|
183
|
+
*
|
|
184
|
+
* This error indicates that the specified heading slug does not match any
|
|
185
|
+
* existing heading in the document. It provides context for recovery including
|
|
186
|
+
* similar headings and hierarchical path suggestions.
|
|
187
|
+
*
|
|
188
|
+
* @param slug - The heading slug that was not found
|
|
189
|
+
* @param context - Additional context including available headings
|
|
190
|
+
*
|
|
191
|
+
* @example Handling missing headings
|
|
192
|
+
* ```typescript
|
|
193
|
+
* try {
|
|
194
|
+
* const heading = findHeadingBySlug(document, targetSlug);
|
|
195
|
+
* } catch (error) {
|
|
196
|
+
* if (error instanceof HeadingNotFoundError) {
|
|
197
|
+
* console.error('Heading not found:', error.context.slug);
|
|
198
|
+
* console.log('Available headings:', error.context.availableHeadings);
|
|
199
|
+
* // Suggest similar headings for recovery
|
|
200
|
+
* }
|
|
201
|
+
* }
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* @example Hierarchical heading recovery
|
|
205
|
+
* ```typescript
|
|
206
|
+
* try {
|
|
207
|
+
* return findHeadingBySlug(document, hierarchicalSlug);
|
|
208
|
+
* } catch (error) {
|
|
209
|
+
* if (error instanceof HeadingNotFoundError) {
|
|
210
|
+
* const slug = error.context.slug as string;
|
|
211
|
+
*
|
|
212
|
+
* // Try parent heading for hierarchical addresses
|
|
213
|
+
* if (slug.includes('/')) {
|
|
214
|
+
* const parentSlug = slug.split('/').slice(0, -1).join('/');
|
|
215
|
+
* console.log(`Heading not found. Try parent: ${parentSlug}`);
|
|
216
|
+
* return findHeadingBySlug(document, parentSlug);
|
|
217
|
+
* }
|
|
218
|
+
*
|
|
219
|
+
* // Suggest similar headings based on edit distance
|
|
220
|
+
* const suggestions = findSimilarHeadings(document, slug);
|
|
221
|
+
* console.log('Similar headings:', suggestions);
|
|
222
|
+
* }
|
|
223
|
+
* throw error;
|
|
224
|
+
* }
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
227
|
+
* @example Creating missing headings
|
|
228
|
+
* ```typescript
|
|
229
|
+
* async function getOrCreateHeading(document: Document, slug: string): Promise<Heading> {
|
|
230
|
+
* try {
|
|
231
|
+
* return findHeadingBySlug(document, slug);
|
|
232
|
+
* } catch (error) {
|
|
233
|
+
* if (error instanceof HeadingNotFoundError) {
|
|
234
|
+
* // Prompt user to create the heading
|
|
235
|
+
* const shouldCreate = await promptUser(`Create heading "${slug}"?`);
|
|
236
|
+
* if (shouldCreate) {
|
|
237
|
+
* return await createHeading(document, slug);
|
|
238
|
+
* }
|
|
239
|
+
* }
|
|
240
|
+
* throw error;
|
|
241
|
+
* }
|
|
242
|
+
* }
|
|
243
|
+
* ```
|
|
244
|
+
*
|
|
245
|
+
* @throws {HeadingNotFoundError} When heading lookup fails
|
|
246
|
+
* @see {@link SectionOperationError} Base class for section operation errors
|
|
247
|
+
* @see {@link findTargetHierarchicalHeading} Hierarchical heading lookup
|
|
248
|
+
*/
|
|
249
|
+
class HeadingNotFoundError extends SectionOperationError {
|
|
250
|
+
constructor(slug, context) {
|
|
251
|
+
super(`Heading not found: ${slug}`, ERROR_CODES.HEADING_NOT_FOUND, { slug, ...context });
|
|
252
|
+
this.name = 'HeadingNotFoundError';
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Error thrown when attempting to create a duplicate heading
|
|
257
|
+
*
|
|
258
|
+
* This error indicates that a heading with the same title already exists at the
|
|
259
|
+
* specified depth level, which would create ambiguous addressing. It provides
|
|
260
|
+
* context for resolving the conflict through slug disambiguation or restructuring.
|
|
261
|
+
*
|
|
262
|
+
* @param title - The duplicate heading title
|
|
263
|
+
* @param slug - The conflicting slug that would be generated
|
|
264
|
+
* @param depth - The heading depth where the conflict occurs
|
|
265
|
+
* @param context - Additional context including existing headings
|
|
266
|
+
*
|
|
267
|
+
* @example Handling duplicate headings
|
|
268
|
+
* ```typescript
|
|
269
|
+
* try {
|
|
270
|
+
* await createHeading(document, title, depth);
|
|
271
|
+
* } catch (error) {
|
|
272
|
+
* if (error instanceof DuplicateHeadingError) {
|
|
273
|
+
* console.error('Duplicate heading:', error.context.title);
|
|
274
|
+
* console.error('Existing slug:', error.context.slug);
|
|
275
|
+
* console.error('Conflict at depth:', error.context.depth);
|
|
276
|
+
* // Suggest disambiguation strategies
|
|
277
|
+
* }
|
|
278
|
+
* }
|
|
279
|
+
* ```
|
|
280
|
+
*
|
|
281
|
+
* @example Automatic slug disambiguation
|
|
282
|
+
* ```typescript
|
|
283
|
+
* async function createHeadingWithDisambiguation(
|
|
284
|
+
* document: Document,
|
|
285
|
+
* title: string,
|
|
286
|
+
* depth: number
|
|
287
|
+
* ): Promise<Heading> {
|
|
288
|
+
* try {
|
|
289
|
+
* return await createHeading(document, title, depth);
|
|
290
|
+
* } catch (error) {
|
|
291
|
+
* if (error instanceof DuplicateHeadingError) {
|
|
292
|
+
* // Automatically add suffix for disambiguation
|
|
293
|
+
* const baseSlug = error.context.slug as string;
|
|
294
|
+
* let counter = 1;
|
|
295
|
+
*
|
|
296
|
+
* while (true) {
|
|
297
|
+
* try {
|
|
298
|
+
* const disambiguatedTitle = `${title} ${counter}`;
|
|
299
|
+
* return await createHeading(document, disambiguatedTitle, depth);
|
|
300
|
+
* } catch (duplicateError) {
|
|
301
|
+
* if (duplicateError instanceof DuplicateHeadingError) {
|
|
302
|
+
* counter++;
|
|
303
|
+
* continue;
|
|
304
|
+
* }
|
|
305
|
+
* throw duplicateError;
|
|
306
|
+
* }
|
|
307
|
+
* }
|
|
308
|
+
* }
|
|
309
|
+
* throw error;
|
|
310
|
+
* }
|
|
311
|
+
* }
|
|
312
|
+
* ```
|
|
313
|
+
*
|
|
314
|
+
* @example Manual conflict resolution
|
|
315
|
+
* ```typescript
|
|
316
|
+
* function handleDuplicateHeading(error: DuplicateHeadingError): void {
|
|
317
|
+
* const { title, slug, depth } = error.context;
|
|
318
|
+
*
|
|
319
|
+
* console.log(`Conflict: Heading "${title}" already exists at depth ${depth}`);
|
|
320
|
+
* console.log(`Current slug: ${slug}`);
|
|
321
|
+
* console.log('Resolution options:');
|
|
322
|
+
* console.log('1. Use different title');
|
|
323
|
+
* console.log('2. Move to different section');
|
|
324
|
+
* console.log('3. Merge with existing heading');
|
|
325
|
+
* console.log('4. Add disambiguating suffix');
|
|
326
|
+
* }
|
|
327
|
+
* ```
|
|
328
|
+
*
|
|
329
|
+
* @throws {DuplicateHeadingError} When heading title conflicts with existing heading
|
|
330
|
+
* @see {@link SectionOperationError} Base class for section operation errors
|
|
331
|
+
* @see {@link GithubSlugger} Slug generation with automatic disambiguation
|
|
332
|
+
*/
|
|
333
|
+
class DuplicateHeadingError extends SectionOperationError {
|
|
334
|
+
constructor(title, slug, depth, context) {
|
|
335
|
+
super(`Duplicate heading at depth ${depth}: "${title}" (slug: ${slug})`, ERROR_CODES.DUPLICATE_HEADING, {
|
|
336
|
+
title,
|
|
337
|
+
slug,
|
|
338
|
+
depth,
|
|
339
|
+
...context
|
|
340
|
+
});
|
|
341
|
+
this.name = 'DuplicateHeadingError';
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Error thrown when a section title is invalid or malformed
|
|
346
|
+
*
|
|
347
|
+
* This error indicates that the provided section title violates title formatting
|
|
348
|
+
* rules, contains invalid characters, or fails title validation constraints.
|
|
349
|
+
*
|
|
350
|
+
* @param message - Specific title validation error description
|
|
351
|
+
* @param context - Additional context about the invalid title
|
|
352
|
+
*
|
|
353
|
+
* @example Handling invalid titles
|
|
354
|
+
* ```typescript
|
|
355
|
+
* try {
|
|
356
|
+
* await createSectionWithTitle(document, invalidTitle);
|
|
357
|
+
* } catch (error) {
|
|
358
|
+
* if (error instanceof InvalidTitleError) {
|
|
359
|
+
* console.error('Invalid title format:', error.message);
|
|
360
|
+
* console.error('Provided title:', error.context?.title);
|
|
361
|
+
* // Provide title formatting guidance
|
|
362
|
+
* }
|
|
363
|
+
* }
|
|
364
|
+
* ```
|
|
365
|
+
*
|
|
366
|
+
* @example Title validation patterns
|
|
367
|
+
* ```typescript
|
|
368
|
+
* function validateSectionTitle(title: string): void {
|
|
369
|
+
* if (!title || title.trim() === '') {
|
|
370
|
+
* throw new InvalidTitleError('Section title cannot be empty', { title });
|
|
371
|
+
* }
|
|
372
|
+
*
|
|
373
|
+
* if (title.length > MAX_TITLE_LENGTH) {
|
|
374
|
+
* throw new InvalidTitleError('Section title too long', {
|
|
375
|
+
* title,
|
|
376
|
+
* length: title.length,
|
|
377
|
+
* maxLength: MAX_TITLE_LENGTH
|
|
378
|
+
* });
|
|
379
|
+
* }
|
|
380
|
+
*
|
|
381
|
+
* if (title.includes('#')) {
|
|
382
|
+
* throw new InvalidTitleError('Section title cannot contain # characters', { title });
|
|
383
|
+
* }
|
|
384
|
+
*
|
|
385
|
+
* // Check for markdown formatting issues
|
|
386
|
+
* if (title.startsWith('*') || title.startsWith('_')) {
|
|
387
|
+
* throw new InvalidTitleError('Section title cannot start with markdown formatting', { title });
|
|
388
|
+
* }
|
|
389
|
+
* }
|
|
390
|
+
* ```
|
|
391
|
+
*
|
|
392
|
+
* @example Title normalization and recovery
|
|
393
|
+
* ```typescript
|
|
394
|
+
* function normalizeSectionTitle(rawTitle: string): string {
|
|
395
|
+
* try {
|
|
396
|
+
* validateSectionTitle(rawTitle);
|
|
397
|
+
* return rawTitle.trim();
|
|
398
|
+
* } catch (error) {
|
|
399
|
+
* if (error instanceof InvalidTitleError) {
|
|
400
|
+
* // Attempt automatic title fixing
|
|
401
|
+
* let normalized = rawTitle.trim();
|
|
402
|
+
*
|
|
403
|
+
* // Remove problematic characters
|
|
404
|
+
* normalized = normalized.replace(/[#*_]/g, '');
|
|
405
|
+
*
|
|
406
|
+
* // Truncate if too long
|
|
407
|
+
* if (normalized.length > MAX_TITLE_LENGTH) {
|
|
408
|
+
* normalized = normalized.substring(0, MAX_TITLE_LENGTH - 3) + '...';
|
|
409
|
+
* }
|
|
410
|
+
*
|
|
411
|
+
* if (normalized) {
|
|
412
|
+
* console.warn(`Title normalized: "${rawTitle}" -> "${normalized}"`);
|
|
413
|
+
* return normalized;
|
|
414
|
+
* }
|
|
415
|
+
* }
|
|
416
|
+
* throw error;
|
|
417
|
+
* }
|
|
418
|
+
* }
|
|
419
|
+
* ```
|
|
420
|
+
*
|
|
421
|
+
* @throws {InvalidTitleError} When title validation fails
|
|
422
|
+
* @see {@link SectionOperationError} Base class for section operation errors
|
|
423
|
+
* @see {@link InvalidSlugError} Related slug validation errors
|
|
424
|
+
*/
|
|
425
|
+
class InvalidTitleError extends SectionOperationError {
|
|
426
|
+
constructor(message, context) {
|
|
427
|
+
super(message, ERROR_CODES.INVALID_TITLE, context);
|
|
428
|
+
this.name = 'InvalidTitleError';
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Error thrown when a section operation is invalid or not supported
|
|
433
|
+
*
|
|
434
|
+
* This error indicates that the requested operation cannot be performed due to
|
|
435
|
+
* invalid operation type, incompatible parameters, or operation constraints.
|
|
436
|
+
*
|
|
437
|
+
* @param message - Specific operation validation error description
|
|
438
|
+
* @param context - Additional context about the invalid operation
|
|
439
|
+
*
|
|
440
|
+
* @example Handling invalid operations
|
|
441
|
+
* ```typescript
|
|
442
|
+
* try {
|
|
443
|
+
* await performSectionOperation(document, section, operation, params);
|
|
444
|
+
* } catch (error) {
|
|
445
|
+
* if (error instanceof InvalidOperationError) {
|
|
446
|
+
* console.error('Invalid operation:', error.message);
|
|
447
|
+
* console.error('Operation:', error.context?.operation);
|
|
448
|
+
* console.error('Valid operations:', error.context?.validOperations);
|
|
449
|
+
* }
|
|
450
|
+
* }
|
|
451
|
+
* ```
|
|
452
|
+
*
|
|
453
|
+
* @example Operation validation patterns
|
|
454
|
+
* ```typescript
|
|
455
|
+
* function validateSectionOperation(
|
|
456
|
+
* operation: string,
|
|
457
|
+
* section: Section,
|
|
458
|
+
* content?: string
|
|
459
|
+
* ): void {
|
|
460
|
+
* const validOperations = ['replace', 'append', 'prepend', 'insert_before', 'insert_after', 'append_child', 'remove'];
|
|
461
|
+
*
|
|
462
|
+
* if (!validOperations.includes(operation)) {
|
|
463
|
+
* throw new InvalidOperationError('Unknown section operation', {
|
|
464
|
+
* operation,
|
|
465
|
+
* validOperations
|
|
466
|
+
* });
|
|
467
|
+
* }
|
|
468
|
+
*
|
|
469
|
+
* // Content required for most operations
|
|
470
|
+
* if (['replace', 'append', 'prepend', 'insert_before', 'insert_after', 'append_child'].includes(operation)) {
|
|
471
|
+
* if (!content || content.trim() === '') {
|
|
472
|
+
* throw new InvalidOperationError(`Content required for operation: ${operation}`, {
|
|
473
|
+
* operation,
|
|
474
|
+
* hasContent: !!content
|
|
475
|
+
* });
|
|
476
|
+
* }
|
|
477
|
+
* }
|
|
478
|
+
*
|
|
479
|
+
* // Title required for creation operations
|
|
480
|
+
* if (['insert_before', 'insert_after', 'append_child'].includes(operation)) {
|
|
481
|
+
* if (!context?.title) {
|
|
482
|
+
* throw new InvalidOperationError(`Title required for creation operation: ${operation}`, {
|
|
483
|
+
* operation,
|
|
484
|
+
* requiredFields: ['title', 'content']
|
|
485
|
+
* });
|
|
486
|
+
* }
|
|
487
|
+
* }
|
|
488
|
+
* }
|
|
489
|
+
* ```
|
|
490
|
+
*
|
|
491
|
+
* @example Operation compatibility checking
|
|
492
|
+
* ```typescript
|
|
493
|
+
* async function performCompatibleOperation(
|
|
494
|
+
* document: Document,
|
|
495
|
+
* section: Section,
|
|
496
|
+
* operation: string,
|
|
497
|
+
* params: OperationParams
|
|
498
|
+
* ): Promise<OperationResult> {
|
|
499
|
+
* try {
|
|
500
|
+
* validateSectionOperation(operation, section, params.content);
|
|
501
|
+
* return await executeSectionOperation(document, section, operation, params);
|
|
502
|
+
* } catch (error) {
|
|
503
|
+
* if (error instanceof InvalidOperationError) {
|
|
504
|
+
* // Suggest compatible operations
|
|
505
|
+
* const suggestions = getCompatibleOperations(section, params);
|
|
506
|
+
* console.log('Suggested operations:', suggestions);
|
|
507
|
+
*
|
|
508
|
+
* // Try fallback operation if available
|
|
509
|
+
* if (suggestions.length > 0) {
|
|
510
|
+
* console.log(`Trying fallback operation: ${suggestions[0]}`);
|
|
511
|
+
* return await executeSectionOperation(document, section, suggestions[0], params);
|
|
512
|
+
* }
|
|
513
|
+
* }
|
|
514
|
+
* throw error;
|
|
515
|
+
* }
|
|
516
|
+
* }
|
|
517
|
+
* ```
|
|
518
|
+
*
|
|
519
|
+
* @throws {InvalidOperationError} When operation validation fails
|
|
520
|
+
* @see {@link SectionOperationError} Base class for section operation errors
|
|
521
|
+
* @see {@link SECTION_CONSTANTS.OPERATIONS} Valid operation types
|
|
522
|
+
*/
|
|
523
|
+
class InvalidOperationError extends SectionOperationError {
|
|
524
|
+
constructor(message, context) {
|
|
525
|
+
super(message, ERROR_CODES.INVALID_OPERATION, context);
|
|
526
|
+
this.name = 'InvalidOperationError';
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Parses markdown into AST
|
|
531
|
+
*/
|
|
532
|
+
function parseMarkdown(markdown) {
|
|
533
|
+
try {
|
|
534
|
+
return unified().use(remarkParse).parse(markdown);
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
throw new InvalidSectionContentError('Failed to parse markdown', { error: error instanceof Error ? error.message : String(error) });
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Creates a heading matcher function for the given slug with hierarchical support
|
|
542
|
+
*/
|
|
543
|
+
function matchHeadingBySlug(slug, headings) {
|
|
544
|
+
let headingIndex = -1; // Track which heading we're currently testing
|
|
545
|
+
return (value) => {
|
|
546
|
+
headingIndex++; // Increment for each heading tested
|
|
547
|
+
const basicSlug = titleToSlug(value.trim());
|
|
548
|
+
// For hierarchical paths, we need to match the specific heading, not just any heading with the same title
|
|
549
|
+
if (slug.includes('/') && headings) {
|
|
550
|
+
// Find the target heading using our hierarchical logic
|
|
551
|
+
const targetHeading = findTargetHierarchicalHeading(slug, headings);
|
|
552
|
+
if (targetHeading) {
|
|
553
|
+
// Only match if this is the exact heading we want
|
|
554
|
+
return headingIndex === targetHeading.index && titleToSlug(targetHeading.title) === basicSlug;
|
|
555
|
+
}
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
// Direct flat match (current behavior)
|
|
559
|
+
return basicSlug === slug;
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Finds all headings that could potentially match a given slug, including disambiguated versions
|
|
564
|
+
*
|
|
565
|
+
* @param finalSlug - The target slug to match (e.g., "overview")
|
|
566
|
+
* @param headings - Array of all headings in the document
|
|
567
|
+
* @returns Array of candidate headings that match the slug exactly or with disambiguation suffix
|
|
568
|
+
*
|
|
569
|
+
* @example
|
|
570
|
+
* // For slug "overview", finds headings with slugs: "overview", "overview-1", "overview-2", etc.
|
|
571
|
+
* const candidateHeadings = findCandidateHeadings("overview", headings);
|
|
572
|
+
*/
|
|
573
|
+
function findCandidateHeadings(finalSlug, headings) {
|
|
574
|
+
return headings.filter(h => {
|
|
575
|
+
return h.slug === finalSlug || h.slug.startsWith(`${finalSlug}-`);
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
// HierarchyIndex interface removed (dead code cleanup)
|
|
579
|
+
// buildHierarchyIndex function removed (dead code cleanup)
|
|
580
|
+
// buildHierarchicalPathOptimized function removed (dead code cleanup)
|
|
581
|
+
/**
|
|
582
|
+
* Build hierarchical path using parent pointers - O(depth) instead of O(n)
|
|
583
|
+
*
|
|
584
|
+
* Leverages existing parentIndex field to follow parent chain upward.
|
|
585
|
+
* Typical performance: 1-6 iterations for standard markdown heading depths.
|
|
586
|
+
*
|
|
587
|
+
* Performance improvement: For a 100-heading document with target at index 50:
|
|
588
|
+
* - Old: ~50 iterations (walks back from index 50 to 0)
|
|
589
|
+
* - New: ~3 iterations (follows 3 parent pointers for depth-3 heading)
|
|
590
|
+
* - Result: 10-30x faster
|
|
591
|
+
*
|
|
592
|
+
* @param targetHeading - The heading to build the path for
|
|
593
|
+
* @param headings - Complete array of all headings in the document (must be in document order)
|
|
594
|
+
* @returns Array of slugs representing the hierarchical path from root to target
|
|
595
|
+
*
|
|
596
|
+
* @example
|
|
597
|
+
* // For a heading at depth 3 with parents, returns something like:
|
|
598
|
+
* // ["api", "authentication", "jwt-tokens"]
|
|
599
|
+
* const path = buildHierarchicalPath(jwtHeading, allHeadings);
|
|
600
|
+
*/
|
|
601
|
+
function buildHierarchicalPath(targetHeading, headings) {
|
|
602
|
+
const pathSegments = [];
|
|
603
|
+
let current = targetHeading;
|
|
604
|
+
// Follow parent pointers backward - O(depth) typically 1-6 iterations
|
|
605
|
+
while (current != null) {
|
|
606
|
+
pathSegments.unshift(current.slug);
|
|
607
|
+
// Move to parent using parentIndex
|
|
608
|
+
if (current.parentIndex !== null) {
|
|
609
|
+
const parent = headings[current.parentIndex];
|
|
610
|
+
current = parent ?? null; // Handle case where parent index is invalid
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
current = null; // Reached root (depth 1 heading has parentIndex: null)
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
return pathSegments;
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Checks if an actual path matches the expected path pattern (exact or suffix match)
|
|
620
|
+
*
|
|
621
|
+
* @param actualPath - The actual hierarchical path built from document structure
|
|
622
|
+
* @param expectedParts - The expected path parts to match against
|
|
623
|
+
* @returns true if the actual path exactly matches or ends with the expected pattern
|
|
624
|
+
*
|
|
625
|
+
* @example
|
|
626
|
+
* // Exact match
|
|
627
|
+
* matchesPathPattern(["api", "auth"], ["api", "auth"]) // → true
|
|
628
|
+
*
|
|
629
|
+
* // Suffix match (allows deeper nesting)
|
|
630
|
+
* matchesPathPattern(["docs", "api", "auth"], ["api", "auth"]) // → true
|
|
631
|
+
*/
|
|
632
|
+
function matchesPathPattern(actualPath, expectedParts) {
|
|
633
|
+
const actualPathString = actualPath.join('/');
|
|
634
|
+
const expectedPathString = expectedParts.join('/');
|
|
635
|
+
// For hierarchical matching, check if the expected path is a suffix of the actual path
|
|
636
|
+
return actualPathString === expectedPathString || actualPathString.endsWith(`/${expectedPathString}`);
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Attempts to match paths by handling disambiguation in intermediate path components
|
|
640
|
+
*
|
|
641
|
+
* @param actualPath - The actual hierarchical path with potential disambiguation suffixes
|
|
642
|
+
* @param expectedParts - The expected path parts without disambiguation suffixes
|
|
643
|
+
* @returns true if the paths match when accounting for disambiguation (e.g., "-1", "-2" suffixes)
|
|
644
|
+
*
|
|
645
|
+
* @example
|
|
646
|
+
* // Handles disambiguation in path components
|
|
647
|
+
* const actual = ["frontend", "authentication-1", "jwt-tokens-1"];
|
|
648
|
+
* const expected = ["frontend", "authentication", "jwt-tokens"];
|
|
649
|
+
* tryDisambiguationMatching(actual, expected) // → true
|
|
650
|
+
*
|
|
651
|
+
* @throws Never throws - returns false for any invalid input
|
|
652
|
+
*/
|
|
653
|
+
function tryDisambiguationMatching(actualPath, expectedParts) {
|
|
654
|
+
if (expectedParts.length <= 1) {
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
// Build expected path with potential disambiguation
|
|
658
|
+
const expectedWithPossibleDisambiguation = expectedParts.map((part, index) => {
|
|
659
|
+
// For each part, see if there's a disambiguated version in the actual path
|
|
660
|
+
const actualPart = actualPath[actualPath.length - expectedParts.length + index];
|
|
661
|
+
if (actualPart != null && actualPart !== '' && (actualPart === part || actualPart.startsWith(`${part}-`))) {
|
|
662
|
+
return actualPart;
|
|
663
|
+
}
|
|
664
|
+
return part;
|
|
665
|
+
});
|
|
666
|
+
return matchesPathPattern(actualPath, expectedWithPossibleDisambiguation);
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Finds the specific heading that matches the hierarchical path
|
|
670
|
+
*
|
|
671
|
+
* This function implements a three-stage matching algorithm to handle both flat and hierarchical
|
|
672
|
+
* section addressing with automatic disambiguation support (e.g., "overview", "overview-1", "overview-2").
|
|
673
|
+
*
|
|
674
|
+
* Algorithm stages:
|
|
675
|
+
* 1. Exact/suffix matching: Direct path comparison for simple hierarchical paths
|
|
676
|
+
* 2. Intermediate disambiguation: Handles disambiguation in parent path components
|
|
677
|
+
* 3. Final slug disambiguation: Handles disambiguation in the target section itself
|
|
678
|
+
*
|
|
679
|
+
* @param targetPath - Hierarchical path to match (e.g., "api/auth/jwt-tokens")
|
|
680
|
+
* @param headings - Complete array of all headings in the document (must be in document order)
|
|
681
|
+
* @returns The matching heading or null if no match found
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* // Find a heading using hierarchical path
|
|
685
|
+
* const heading = findTargetHierarchicalHeading("api/auth/jwt-tokens", allHeadings);
|
|
686
|
+
* if (heading) {
|
|
687
|
+
* console.log(`Found heading: ${heading.title} (slug: ${heading.slug})`);
|
|
688
|
+
* }
|
|
689
|
+
*
|
|
690
|
+
* @throws Never throws - returns null for invalid input or no match
|
|
691
|
+
*/
|
|
692
|
+
function findTargetHierarchicalHeading(targetPath, headings) {
|
|
693
|
+
// Step 1: Parse target path into components
|
|
694
|
+
const pathParts = targetPath.toLowerCase().split('/');
|
|
695
|
+
const finalSlug = pathParts[pathParts.length - 1];
|
|
696
|
+
if (finalSlug == null) {
|
|
697
|
+
return null; // Empty path parts, should not happen due to validation
|
|
698
|
+
}
|
|
699
|
+
// Step 2: Find all headings that could match the target slug
|
|
700
|
+
// This includes exact matches ("overview") and disambiguated versions ("overview-1", "overview-2")
|
|
701
|
+
const candidateHeadings = findCandidateHeadings(finalSlug, headings);
|
|
702
|
+
// Step 3: Test each candidate heading against the target path using three matching strategies
|
|
703
|
+
for (const candidateHeading of candidateHeadings) {
|
|
704
|
+
// Build the actual hierarchical path for this candidate by walking up the document structure
|
|
705
|
+
const actualPath = buildHierarchicalPath(candidateHeading, headings);
|
|
706
|
+
// Strategy 1: Try exact or suffix matching first
|
|
707
|
+
// Example: ["api", "auth"] matches ["api", "auth"] or ["docs", "api", "auth"]
|
|
708
|
+
if (matchesPathPattern(actualPath, pathParts)) {
|
|
709
|
+
return candidateHeading;
|
|
710
|
+
}
|
|
711
|
+
// Strategy 2: Try disambiguation matching for intermediate path components
|
|
712
|
+
// This handles cases where parent sections have disambiguation suffixes
|
|
713
|
+
// Example: User searches for "api/auth" but actual path is "api-1/auth-1"
|
|
714
|
+
if (tryDisambiguationMatching(actualPath, pathParts)) {
|
|
715
|
+
return candidateHeading;
|
|
716
|
+
}
|
|
717
|
+
// Strategy 3: Check if we can match by replacing the final slug with the disambiguated version
|
|
718
|
+
// This handles cases where the target section itself has a disambiguation suffix
|
|
719
|
+
// Example: User searches for "api/auth/jwt" but actual slug is "jwt-tokens-1"
|
|
720
|
+
const expectedWithDisambiguated = pathParts.slice(0, -1).concat([candidateHeading.slug]);
|
|
721
|
+
if (matchesPathPattern(actualPath, expectedWithDisambiguated)) {
|
|
722
|
+
return candidateHeading;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
// Step 4: No match found after trying all strategies
|
|
726
|
+
return null;
|
|
727
|
+
}
|
|
728
|
+
// Function removed as it was unused (dead code cleanup)
|
|
729
|
+
// findCommonPrefix function removed (dead code cleanup)
|
|
730
|
+
/**
|
|
731
|
+
* Finds the parent heading index for a given slug
|
|
732
|
+
*/
|
|
733
|
+
function findParentHeadingIndex(tree, slug) {
|
|
734
|
+
const headings = [];
|
|
735
|
+
let counter = -1;
|
|
736
|
+
visitParents(tree, 'heading', (node) => {
|
|
737
|
+
counter++;
|
|
738
|
+
headings.push({ node, index: counter });
|
|
739
|
+
});
|
|
740
|
+
const target = headings.find(h => titleToSlug(toString(h.node).trim()) === slug);
|
|
741
|
+
if (!target) {
|
|
742
|
+
return null;
|
|
743
|
+
}
|
|
744
|
+
// Find the most recent heading with smaller depth
|
|
745
|
+
for (let i = target.index - 1; i >= 0; i--) {
|
|
746
|
+
const heading = headings[i];
|
|
747
|
+
if (heading && heading.node.depth < target.node.depth) {
|
|
748
|
+
return i;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return null; // Top-level heading
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Ensures uniqueness among sibling headings
|
|
755
|
+
*/
|
|
756
|
+
function ensureUniqueAmongSiblings(tree, parentIndex, depth, newTitle) {
|
|
757
|
+
const targetSlug = titleToSlug(newTitle);
|
|
758
|
+
const headings = [];
|
|
759
|
+
let counter = -1;
|
|
760
|
+
visitParents(tree, 'heading', (node) => {
|
|
761
|
+
counter++;
|
|
762
|
+
headings.push({ node, index: counter });
|
|
763
|
+
});
|
|
764
|
+
// Get parent index for each heading
|
|
765
|
+
const getParentIndex = (index) => {
|
|
766
|
+
for (let i = index - 1; i >= 0; i--) {
|
|
767
|
+
const heading = headings[i];
|
|
768
|
+
const targetHeading = headings[index];
|
|
769
|
+
if (heading && targetHeading && heading.node.depth < targetHeading.node.depth) {
|
|
770
|
+
return i;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return null;
|
|
774
|
+
};
|
|
775
|
+
// Check for duplicates among siblings
|
|
776
|
+
for (let i = 0; i < headings.length; i++) {
|
|
777
|
+
const heading = headings[i];
|
|
778
|
+
if (heading?.node === undefined)
|
|
779
|
+
continue;
|
|
780
|
+
const headingParentIndex = getParentIndex(i);
|
|
781
|
+
if (headingParentIndex === parentIndex && heading.node.depth === depth) {
|
|
782
|
+
const existingSlug = titleToSlug(toString(heading.node).trim());
|
|
783
|
+
if (existingSlug === targetSlug) {
|
|
784
|
+
throw new DuplicateHeadingError(newTitle, targetSlug, depth, {
|
|
785
|
+
parentIndex,
|
|
786
|
+
conflictingIndex: i,
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Validates hierarchical path for security and format compliance
|
|
794
|
+
*/
|
|
795
|
+
function validateHierarchicalPath(slug) {
|
|
796
|
+
// Maximum path length (total characters)
|
|
797
|
+
const MAX_PATH_LENGTH = 1000;
|
|
798
|
+
// Maximum path depth (number of segments)
|
|
799
|
+
const MAX_PATH_DEPTH = 20;
|
|
800
|
+
// Maximum individual component length
|
|
801
|
+
const MAX_COMPONENT_LENGTH = 200;
|
|
802
|
+
if (slug.length > MAX_PATH_LENGTH) {
|
|
803
|
+
throw new InvalidSlugError(`Hierarchical path too long (max: ${MAX_PATH_LENGTH} characters)`, { slug, length: slug.length, maxLength: MAX_PATH_LENGTH });
|
|
804
|
+
}
|
|
805
|
+
// Normalize Unicode to prevent normalization attacks
|
|
806
|
+
const normalizedSlug = slug.normalize('NFC');
|
|
807
|
+
if (normalizedSlug !== slug) {
|
|
808
|
+
throw new InvalidSlugError('Path contains non-normalized Unicode characters', { slug, normalized: normalizedSlug });
|
|
809
|
+
}
|
|
810
|
+
// Check for dangerous characters
|
|
811
|
+
// eslint-disable-next-line no-control-regex
|
|
812
|
+
const dangerousChars = /[\x00-\x1F\x7F\uFFFE\uFFFF\\%]/;
|
|
813
|
+
if (dangerousChars.test(slug)) {
|
|
814
|
+
throw new InvalidSlugError('Path contains dangerous characters (control chars, null bytes, backslashes, or percent encoding)', { slug });
|
|
815
|
+
}
|
|
816
|
+
// Check for whitespace at start/end or in problematic positions
|
|
817
|
+
if (slug.trim() !== slug || /\s{2,}/.test(slug)) {
|
|
818
|
+
throw new InvalidSlugError('Path contains leading/trailing whitespace or multiple consecutive spaces', { slug });
|
|
819
|
+
}
|
|
820
|
+
// Split into components for detailed validation
|
|
821
|
+
const components = slug.split('/');
|
|
822
|
+
if (components.length > MAX_PATH_DEPTH) {
|
|
823
|
+
throw new InvalidSlugError(`Path too deep (max: ${MAX_PATH_DEPTH} levels)`, { slug, depth: components.length, maxDepth: MAX_PATH_DEPTH });
|
|
824
|
+
}
|
|
825
|
+
for (const component of components) {
|
|
826
|
+
if (component.length === 0) {
|
|
827
|
+
throw new InvalidSlugError('Path contains empty components (double slashes)', { slug });
|
|
828
|
+
}
|
|
829
|
+
if (component.length > MAX_COMPONENT_LENGTH) {
|
|
830
|
+
throw new InvalidSlugError(`Path component too long (max: ${MAX_COMPONENT_LENGTH} characters)`, { slug, component, length: component.length, maxLength: MAX_COMPONENT_LENGTH });
|
|
831
|
+
}
|
|
832
|
+
// Check for path traversal attempts
|
|
833
|
+
if (component === '.' || component === '..' || component.includes('..')) {
|
|
834
|
+
throw new InvalidSlugError('Path contains path traversal attempts', { slug, component });
|
|
835
|
+
}
|
|
836
|
+
// Check for percent encoding (simple detection)
|
|
837
|
+
if (component.includes('%')) {
|
|
838
|
+
throw new InvalidSlugError('Path contains percent encoding which is not allowed', { slug, component });
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
// Additional security checks
|
|
842
|
+
if (slug.startsWith('/') || slug.endsWith('/')) {
|
|
843
|
+
throw new InvalidSlugError('Path cannot start or end with forward slash', { slug });
|
|
844
|
+
}
|
|
845
|
+
if (slug.includes('//')) {
|
|
846
|
+
throw new InvalidSlugError('Path cannot contain double slashes', { slug });
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Validates section body content
|
|
851
|
+
*/
|
|
852
|
+
function validateSectionBody(body) {
|
|
853
|
+
if (typeof body !== 'string') {
|
|
854
|
+
throw new InvalidSectionContentError('Section body must be a string', { type: typeof body });
|
|
855
|
+
}
|
|
856
|
+
if (body.length > DEFAULT_LIMITS.MAX_SECTION_BODY_LENGTH) {
|
|
857
|
+
throw new InvalidSectionContentError(`Section body too long (max: ${DEFAULT_LIMITS.MAX_SECTION_BODY_LENGTH} characters)`, { length: body.length, maxLength: DEFAULT_LIMITS.MAX_SECTION_BODY_LENGTH });
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Validates a slug for security and format compliance (both flat and hierarchical)
|
|
862
|
+
* Returns the normalized slug for further processing
|
|
863
|
+
*/
|
|
864
|
+
function validateSlugSecurity(slug) {
|
|
865
|
+
// Auto-normalize Unicode to prevent normalization attacks
|
|
866
|
+
const normalizedSlug = slug.normalize('NFC');
|
|
867
|
+
// Check for dangerous characters in the normalized slug
|
|
868
|
+
// eslint-disable-next-line no-control-regex
|
|
869
|
+
const dangerousChars = /[\x00-\x1F\x7F\uFFFE\uFFFF\\%]/;
|
|
870
|
+
if (dangerousChars.test(normalizedSlug)) {
|
|
871
|
+
throw new InvalidSlugError('Slug contains dangerous characters (control chars, null bytes, backslashes, or percent encoding)', { slug: normalizedSlug });
|
|
872
|
+
}
|
|
873
|
+
// Check for length limits
|
|
874
|
+
const MAX_SLUG_LENGTH = 1000;
|
|
875
|
+
if (normalizedSlug.length > MAX_SLUG_LENGTH) {
|
|
876
|
+
throw new InvalidSlugError(`Slug too long (max: ${MAX_SLUG_LENGTH} characters)`, { slug: normalizedSlug, length: normalizedSlug.length, maxLength: MAX_SLUG_LENGTH });
|
|
877
|
+
}
|
|
878
|
+
// Check for whitespace issues
|
|
879
|
+
if (normalizedSlug.trim() !== normalizedSlug || /\s{2,}/.test(normalizedSlug)) {
|
|
880
|
+
throw new InvalidSlugError('Slug contains leading/trailing whitespace or multiple consecutive spaces', { slug: normalizedSlug });
|
|
881
|
+
}
|
|
882
|
+
return normalizedSlug;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Extracts the content of a specific section from a markdown document
|
|
886
|
+
*
|
|
887
|
+
* Supports both flat slug addressing (e.g., "overview") and hierarchical addressing
|
|
888
|
+
* (e.g., "api/auth/jwt-tokens") with comprehensive security validation and disambiguation handling.
|
|
889
|
+
*
|
|
890
|
+
* @param markdown - The complete markdown content to search
|
|
891
|
+
* @param slug - Section identifier (flat slug or hierarchical path)
|
|
892
|
+
* @returns The section content (heading + body) or null if not found
|
|
893
|
+
*
|
|
894
|
+
* @example
|
|
895
|
+
* // Flat addressing
|
|
896
|
+
* const content = readSection(markdownContent, "overview");
|
|
897
|
+
*
|
|
898
|
+
* // Hierarchical addressing
|
|
899
|
+
* const content = readSection(markdownContent, "api/auth/jwt-tokens");
|
|
900
|
+
*
|
|
901
|
+
* // Returns the heading and body content:
|
|
902
|
+
* // "## Overview\n\nThis section covers..."
|
|
903
|
+
*
|
|
904
|
+
* @throws {Error} When slug is invalid, contains dangerous characters, or violates security constraints
|
|
905
|
+
* @throws {Error} When hierarchical path validation fails (too long, dangerous chars, etc.)
|
|
906
|
+
*/
|
|
907
|
+
export function readSection(markdown, slug) {
|
|
908
|
+
// Validate markdown parameter
|
|
909
|
+
if (typeof markdown !== 'string') {
|
|
910
|
+
throw new InvalidSectionContentError('Markdown content must be a string', { type: typeof markdown });
|
|
911
|
+
}
|
|
912
|
+
if (markdown.trim() === '') {
|
|
913
|
+
throw new InvalidSectionContentError('Markdown content cannot be empty', { length: markdown.length });
|
|
914
|
+
}
|
|
915
|
+
if (!slug || typeof slug !== 'string') {
|
|
916
|
+
throw new InvalidSlugError('Slug must be a non-empty string', { slug });
|
|
917
|
+
}
|
|
918
|
+
// Validate slug security and get normalized version
|
|
919
|
+
const normalizedSlug = validateSlugSecurity(slug);
|
|
920
|
+
// For hierarchical paths, perform additional hierarchical validation
|
|
921
|
+
if (normalizedSlug.includes('/')) {
|
|
922
|
+
validateHierarchicalPath(normalizedSlug);
|
|
923
|
+
const headings = listHeadings(markdown);
|
|
924
|
+
const targetHeading = findTargetHierarchicalHeading(normalizedSlug, headings);
|
|
925
|
+
if (!targetHeading) {
|
|
926
|
+
throw new HeadingNotFoundError(normalizedSlug, { hierarchicalContext: true });
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
const tree = parseMarkdown(markdown);
|
|
930
|
+
const headings = listHeadings(markdown); // Get heading context
|
|
931
|
+
let captured = null;
|
|
932
|
+
headingRange(tree, matchHeadingBySlug(normalizedSlug, headings), (start, nodes, end) => {
|
|
933
|
+
// Serialize the captured section INCLUDING the heading BUT EXCLUDING the end boundary
|
|
934
|
+
// The end parameter is the next section's heading and should not be part of this section's content
|
|
935
|
+
const section = {
|
|
936
|
+
type: 'root',
|
|
937
|
+
children: [start, ...nodes].filter(Boolean),
|
|
938
|
+
};
|
|
939
|
+
try {
|
|
940
|
+
captured = toMarkdown(section);
|
|
941
|
+
}
|
|
942
|
+
catch (error) {
|
|
943
|
+
throw new InvalidSectionContentError('Failed to serialize section', {
|
|
944
|
+
slug: normalizedSlug,
|
|
945
|
+
error: error instanceof Error ? error.message : String(error)
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
return [start, ...nodes, end]; // Still return all nodes (no modification to AST)
|
|
949
|
+
});
|
|
950
|
+
return captured;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Replaces the body of a section while keeping the heading
|
|
954
|
+
*/
|
|
955
|
+
export function replaceSectionBody(markdown, slug, newBodyMarkdown) {
|
|
956
|
+
if (!slug || typeof slug !== 'string') {
|
|
957
|
+
throw new InvalidSlugError('Slug must be a non-empty string', { slug });
|
|
958
|
+
}
|
|
959
|
+
validateSectionBody(newBodyMarkdown);
|
|
960
|
+
const tree = parseMarkdown(markdown);
|
|
961
|
+
const headings = listHeadings(markdown); // Get heading context
|
|
962
|
+
const newBodyTree = parseMarkdown(newBodyMarkdown);
|
|
963
|
+
// Filter out any heading nodes from the new body (safety measure)
|
|
964
|
+
const sanitizedChildren = newBodyTree.children.filter(node => node.type !== 'heading');
|
|
965
|
+
let found = false;
|
|
966
|
+
headingRange(tree, matchHeadingBySlug(slug, headings), (start, _nodes, end) => {
|
|
967
|
+
found = true;
|
|
968
|
+
return [start, ...sanitizedChildren, end].filter(Boolean);
|
|
969
|
+
});
|
|
970
|
+
if (!found) {
|
|
971
|
+
throw new HeadingNotFoundError(slug);
|
|
972
|
+
}
|
|
973
|
+
try {
|
|
974
|
+
return toMarkdown(tree);
|
|
975
|
+
}
|
|
976
|
+
catch (error) {
|
|
977
|
+
throw new InvalidSectionContentError('Failed to serialize updated markdown', {
|
|
978
|
+
slug,
|
|
979
|
+
error: error instanceof Error ? error.message : String(error)
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Strategy for inserting a section before the reference heading
|
|
985
|
+
*/
|
|
986
|
+
class InsertBeforeStrategy {
|
|
987
|
+
determineParentAndDepth(context) {
|
|
988
|
+
return {
|
|
989
|
+
parentIndex: findParentHeadingIndex(context.tree, context.refSlug),
|
|
990
|
+
finalDepth: context.newDepth
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
insertInAST(start, nodes, end, insertNodes) {
|
|
994
|
+
return [...insertNodes, start, ...nodes, end].filter((node) => node != null);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Strategy for inserting a section after the reference heading
|
|
999
|
+
*/
|
|
1000
|
+
class InsertAfterStrategy {
|
|
1001
|
+
determineParentAndDepth(context) {
|
|
1002
|
+
return {
|
|
1003
|
+
parentIndex: findParentHeadingIndex(context.tree, context.refSlug),
|
|
1004
|
+
finalDepth: context.newDepth
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
insertInAST(start, nodes, end, insertNodes) {
|
|
1008
|
+
return [start, ...nodes, end, ...insertNodes].filter((node) => node != null);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Strategy for appending a section as a child of the reference heading
|
|
1013
|
+
*/
|
|
1014
|
+
class AppendChildStrategy {
|
|
1015
|
+
determineParentAndDepth(context) {
|
|
1016
|
+
// Find the reference heading to use as parent
|
|
1017
|
+
const headings = [];
|
|
1018
|
+
let counter = -1;
|
|
1019
|
+
visitParents(context.tree, 'heading', (node) => {
|
|
1020
|
+
counter++;
|
|
1021
|
+
headings.push({ node, index: counter });
|
|
1022
|
+
});
|
|
1023
|
+
const refHeading = headings.find(h => titleToSlug(toString(h.node).trim()) === context.refSlug);
|
|
1024
|
+
if (!refHeading) {
|
|
1025
|
+
throw new HeadingNotFoundError(context.refSlug);
|
|
1026
|
+
}
|
|
1027
|
+
const calculatedDepth = refHeading.node.depth + 1;
|
|
1028
|
+
return {
|
|
1029
|
+
parentIndex: refHeading.index,
|
|
1030
|
+
finalDepth: validateHeadingDepth(calculatedDepth)
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
insertInAST(start, nodes, end, insertNodes) {
|
|
1034
|
+
return [start, ...nodes, ...insertNodes, end].filter((node) => node != null);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Factory for creating insertion strategies
|
|
1039
|
+
*/
|
|
1040
|
+
class SectionInsertionStrategyFactory {
|
|
1041
|
+
static createStrategy(mode) {
|
|
1042
|
+
switch (mode) {
|
|
1043
|
+
case 'insert_before':
|
|
1044
|
+
return new InsertBeforeStrategy();
|
|
1045
|
+
case 'insert_after':
|
|
1046
|
+
return new InsertAfterStrategy();
|
|
1047
|
+
case 'append_child':
|
|
1048
|
+
return new AppendChildStrategy();
|
|
1049
|
+
default:
|
|
1050
|
+
throw new InvalidOperationError(`Invalid insert mode: ${mode}`, { mode });
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Inserts a new section relative to an existing heading
|
|
1056
|
+
*/
|
|
1057
|
+
export function insertRelative(markdown, refSlug, mode, newDepth, newTitle, bodyMarkdown = '') {
|
|
1058
|
+
// Input validation
|
|
1059
|
+
if (!refSlug || typeof refSlug !== 'string') {
|
|
1060
|
+
throw new InvalidSlugError('Reference slug must be a non-empty string', { slug: refSlug });
|
|
1061
|
+
}
|
|
1062
|
+
if (!newTitle || typeof newTitle !== 'string') {
|
|
1063
|
+
throw new InvalidTitleError('New title must be a non-empty string', { title: newTitle });
|
|
1064
|
+
}
|
|
1065
|
+
validateSectionBody(bodyMarkdown);
|
|
1066
|
+
// Parse markdown and prepare context
|
|
1067
|
+
const tree = parseMarkdown(markdown);
|
|
1068
|
+
const headings = listHeadings(markdown);
|
|
1069
|
+
const context = {
|
|
1070
|
+
markdown,
|
|
1071
|
+
refSlug,
|
|
1072
|
+
newTitle,
|
|
1073
|
+
newDepth,
|
|
1074
|
+
bodyMarkdown,
|
|
1075
|
+
tree,
|
|
1076
|
+
headings
|
|
1077
|
+
};
|
|
1078
|
+
// Get strategy for the specified mode
|
|
1079
|
+
const strategy = SectionInsertionStrategyFactory.createStrategy(mode);
|
|
1080
|
+
// Determine parent and depth using strategy
|
|
1081
|
+
const { parentIndex, finalDepth } = strategy.determineParentAndDepth(context);
|
|
1082
|
+
// Ensure uniqueness among siblings
|
|
1083
|
+
ensureUniqueAmongSiblings(tree, parentIndex, finalDepth, newTitle);
|
|
1084
|
+
// Parse body content and create insertion nodes
|
|
1085
|
+
const bodyTree = parseMarkdown(bodyMarkdown);
|
|
1086
|
+
const bodyChildren = bodyTree.children.filter(node => node.type !== 'heading');
|
|
1087
|
+
const headingNode = {
|
|
1088
|
+
type: 'heading',
|
|
1089
|
+
depth: finalDepth,
|
|
1090
|
+
children: [{ type: 'text', value: newTitle }],
|
|
1091
|
+
};
|
|
1092
|
+
const insertNodes = [headingNode, ...bodyChildren];
|
|
1093
|
+
// Perform the insertion using strategy
|
|
1094
|
+
let found = false;
|
|
1095
|
+
const resultTree = parseMarkdown(markdown); // Fresh tree for mutation
|
|
1096
|
+
headingRange(resultTree, matchHeadingBySlug(refSlug, headings), (start, nodes, end) => {
|
|
1097
|
+
found = true;
|
|
1098
|
+
return strategy.insertInAST(start, nodes, end, insertNodes);
|
|
1099
|
+
});
|
|
1100
|
+
if (!found) {
|
|
1101
|
+
throw new HeadingNotFoundError(refSlug);
|
|
1102
|
+
}
|
|
1103
|
+
try {
|
|
1104
|
+
return toMarkdown(resultTree);
|
|
1105
|
+
}
|
|
1106
|
+
catch (error) {
|
|
1107
|
+
throw new InvalidSectionContentError('Failed to serialize updated markdown', {
|
|
1108
|
+
refSlug,
|
|
1109
|
+
newTitle,
|
|
1110
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
/**
|
|
1115
|
+
* Renames a heading (changes its title and thus its slug)
|
|
1116
|
+
*/
|
|
1117
|
+
export function renameHeading(markdown, slug, newTitle) {
|
|
1118
|
+
if (!slug || typeof slug !== 'string') {
|
|
1119
|
+
throw new InvalidSlugError('Slug must be a non-empty string', { slug });
|
|
1120
|
+
}
|
|
1121
|
+
if (!newTitle || typeof newTitle !== 'string') {
|
|
1122
|
+
throw new InvalidTitleError('New title must be a non-empty string', { title: newTitle });
|
|
1123
|
+
}
|
|
1124
|
+
const tree = parseMarkdown(markdown);
|
|
1125
|
+
// Find the target heading
|
|
1126
|
+
const headings = [];
|
|
1127
|
+
let counter = -1;
|
|
1128
|
+
visitParents(tree, 'heading', (node) => {
|
|
1129
|
+
counter++;
|
|
1130
|
+
headings.push({ node, index: counter });
|
|
1131
|
+
});
|
|
1132
|
+
let targetHeading = null;
|
|
1133
|
+
let targetIndex = -1;
|
|
1134
|
+
for (const { node, index } of headings) {
|
|
1135
|
+
if (titleToSlug(toString(node).trim()) === slug) {
|
|
1136
|
+
targetHeading = node;
|
|
1137
|
+
targetIndex = index;
|
|
1138
|
+
break;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
if (!targetHeading) {
|
|
1142
|
+
throw new HeadingNotFoundError(slug);
|
|
1143
|
+
}
|
|
1144
|
+
// Find parent of target heading
|
|
1145
|
+
let parentIndex = null;
|
|
1146
|
+
for (let i = targetIndex - 1; i >= 0; i--) {
|
|
1147
|
+
const heading = headings[i];
|
|
1148
|
+
if (heading && heading.node.depth < targetHeading.depth) {
|
|
1149
|
+
parentIndex = i;
|
|
1150
|
+
break;
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
// Ensure uniqueness among siblings
|
|
1154
|
+
const validatedDepth = validateHeadingDepth(targetHeading.depth);
|
|
1155
|
+
ensureUniqueAmongSiblings(tree, parentIndex, validatedDepth, newTitle);
|
|
1156
|
+
// Update the heading's text
|
|
1157
|
+
targetHeading.children = [{ type: 'text', value: newTitle }];
|
|
1158
|
+
try {
|
|
1159
|
+
return toMarkdown(tree);
|
|
1160
|
+
}
|
|
1161
|
+
catch (error) {
|
|
1162
|
+
throw new InvalidSectionContentError('Failed to serialize updated markdown', {
|
|
1163
|
+
slug,
|
|
1164
|
+
newTitle,
|
|
1165
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Gets the content that would be removed by a deleteSection operation
|
|
1171
|
+
* This excludes the end boundary marker to match actual removal behavior
|
|
1172
|
+
*/
|
|
1173
|
+
export function getSectionContentForRemoval(markdown, slug) {
|
|
1174
|
+
if (!slug || typeof slug !== 'string') {
|
|
1175
|
+
throw new InvalidSlugError('Slug must be a non-empty string', { slug });
|
|
1176
|
+
}
|
|
1177
|
+
const tree = parseMarkdown(markdown);
|
|
1178
|
+
const headings = listHeadings(markdown); // Get heading context
|
|
1179
|
+
let captured = null;
|
|
1180
|
+
headingRange(tree, matchHeadingBySlug(slug, headings), (start, nodes, _end) => {
|
|
1181
|
+
// Serialize only the content that will be removed (excluding end boundary)
|
|
1182
|
+
// This matches the behavior of deleteSection which preserves the end marker
|
|
1183
|
+
const section = {
|
|
1184
|
+
type: 'root',
|
|
1185
|
+
children: [start, ...nodes].filter(Boolean),
|
|
1186
|
+
};
|
|
1187
|
+
try {
|
|
1188
|
+
captured = toMarkdown(section);
|
|
1189
|
+
}
|
|
1190
|
+
catch (error) {
|
|
1191
|
+
throw new InvalidSectionContentError('Failed to serialize section content for removal', {
|
|
1192
|
+
slug,
|
|
1193
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
return [start, ...nodes]; // No modification (not actually removing anything here)
|
|
1197
|
+
});
|
|
1198
|
+
return captured;
|
|
1199
|
+
}
|
|
1200
|
+
/**
|
|
1201
|
+
* Deletes an entire section (heading and its content)
|
|
1202
|
+
*/
|
|
1203
|
+
export function deleteSection(markdown, slug) {
|
|
1204
|
+
if (!slug || typeof slug !== 'string') {
|
|
1205
|
+
throw new InvalidSlugError('Slug must be a non-empty string', { slug });
|
|
1206
|
+
}
|
|
1207
|
+
const tree = parseMarkdown(markdown);
|
|
1208
|
+
const headings = listHeadings(markdown); // Get heading context
|
|
1209
|
+
let found = false;
|
|
1210
|
+
headingRange(tree, matchHeadingBySlug(slug, headings), (_start, _nodes, end) => {
|
|
1211
|
+
found = true;
|
|
1212
|
+
// CRITICAL BUG FIX: Preserve the end heading to prevent data loss
|
|
1213
|
+
// The end heading marks the start of the next section and must not be deleted
|
|
1214
|
+
return end ? [end] : [];
|
|
1215
|
+
});
|
|
1216
|
+
if (!found) {
|
|
1217
|
+
throw new HeadingNotFoundError(slug);
|
|
1218
|
+
}
|
|
1219
|
+
try {
|
|
1220
|
+
return toMarkdown(tree);
|
|
1221
|
+
}
|
|
1222
|
+
catch (error) {
|
|
1223
|
+
throw new InvalidSectionContentError('Failed to serialize updated markdown', {
|
|
1224
|
+
slug,
|
|
1225
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
//# sourceMappingURL=sections.js.map
|