@langadventurellc/task-trellis-mcp 0.1.0-rc.3 → 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/README.md +357 -39
- package/dist/__tests__/e2e/configuration/activation.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/configuration/activation.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/configuration/activation.e2e.test.js +130 -0
- package/dist/__tests__/e2e/configuration/activation.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/configuration/commandLineArgs.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/configuration/commandLineArgs.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/configuration/commandLineArgs.e2e.test.js +125 -0
- package/dist/__tests__/e2e/configuration/commandLineArgs.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/configuration/directorySetup.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/configuration/directorySetup.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/configuration/directorySetup.e2e.test.js +262 -0
- package/dist/__tests__/e2e/configuration/directorySetup.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/configuration/invalidConfig.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/configuration/invalidConfig.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/configuration/invalidConfig.e2e.test.js +243 -0
- package/dist/__tests__/e2e/configuration/invalidConfig.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/configuration/preActivation.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/configuration/preActivation.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/configuration/preActivation.e2e.test.js +123 -0
- package/dist/__tests__/e2e/configuration/preActivation.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/createObject.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/createObject.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/createObject.e2e.test.js +376 -0
- package/dist/__tests__/e2e/crud/createObject.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/deleteObject.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/deleteObject.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/deleteObject.e2e.test.js +391 -0
- package/dist/__tests__/e2e/crud/deleteObject.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/fileValidation.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/fileValidation.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/fileValidation.e2e.test.js +409 -0
- package/dist/__tests__/e2e/crud/fileValidation.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/getObject.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/getObject.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/getObject.e2e.test.js +447 -0
- package/dist/__tests__/e2e/crud/getObject.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/listObjects.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/listObjects.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/listObjects.e2e.test.js +593 -0
- package/dist/__tests__/e2e/crud/listObjects.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/replaceObjectBodyRegex.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/replaceObjectBodyRegex.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/replaceObjectBodyRegex.e2e.test.js +693 -0
- package/dist/__tests__/e2e/crud/replaceObjectBodyRegex.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/crud/updateObject.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/crud/updateObject.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/crud/updateObject.e2e.test.js +662 -0
- package/dist/__tests__/e2e/crud/updateObject.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/infrastructure/client.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/infrastructure/client.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/infrastructure/client.e2e.test.js +68 -0
- package/dist/__tests__/e2e/infrastructure/client.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/infrastructure/server.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/infrastructure/server.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/infrastructure/server.e2e.test.js +37 -0
- package/dist/__tests__/e2e/infrastructure/server.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/utils/HierarchyOptions.d.ts +7 -0
- package/dist/__tests__/e2e/utils/HierarchyOptions.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/HierarchyOptions.js +3 -0
- package/dist/__tests__/e2e/utils/HierarchyOptions.js.map +1 -0
- package/dist/__tests__/e2e/utils/ObjectData.d.ts +17 -0
- package/dist/__tests__/e2e/utils/ObjectData.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/ObjectData.js +3 -0
- package/dist/__tests__/e2e/utils/ObjectData.js.map +1 -0
- package/dist/__tests__/e2e/utils/cleanup.d.ts +10 -0
- package/dist/__tests__/e2e/utils/cleanup.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/cleanup.js +99 -0
- package/dist/__tests__/e2e/utils/cleanup.js.map +1 -0
- package/dist/__tests__/e2e/utils/createObjectContent.d.ts +6 -0
- package/dist/__tests__/e2e/utils/createObjectContent.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/createObjectContent.js +34 -0
- package/dist/__tests__/e2e/utils/createObjectContent.js.map +1 -0
- package/dist/__tests__/e2e/utils/createObjectFile.d.ts +6 -0
- package/dist/__tests__/e2e/utils/createObjectFile.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/createObjectFile.js +88 -0
- package/dist/__tests__/e2e/utils/createObjectFile.js.map +1 -0
- package/dist/__tests__/e2e/utils/fileExists.d.ts +5 -0
- package/dist/__tests__/e2e/utils/fileExists.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/fileExists.js +52 -0
- package/dist/__tests__/e2e/utils/fileExists.js.map +1 -0
- package/dist/__tests__/e2e/utils/folderExists.d.ts +5 -0
- package/dist/__tests__/e2e/utils/folderExists.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/folderExists.js +52 -0
- package/dist/__tests__/e2e/utils/folderExists.js.map +1 -0
- package/dist/__tests__/e2e/utils/index.d.ts +15 -0
- package/dist/__tests__/e2e/utils/index.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/index.js +32 -0
- package/dist/__tests__/e2e/utils/index.js.map +1 -0
- package/dist/__tests__/e2e/utils/mcpTestClient.d.ts +13 -0
- package/dist/__tests__/e2e/utils/mcpTestClient.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/mcpTestClient.js +79 -0
- package/dist/__tests__/e2e/utils/mcpTestClient.js.map +1 -0
- package/dist/__tests__/e2e/utils/parseGetObjectResponse.d.ts +5 -0
- package/dist/__tests__/e2e/utils/parseGetObjectResponse.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/parseGetObjectResponse.js +15 -0
- package/dist/__tests__/e2e/utils/parseGetObjectResponse.js.map +1 -0
- package/dist/__tests__/e2e/utils/parseListObjectsResponse.d.ts +5 -0
- package/dist/__tests__/e2e/utils/parseListObjectsResponse.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/parseListObjectsResponse.js +15 -0
- package/dist/__tests__/e2e/utils/parseListObjectsResponse.js.map +1 -0
- package/dist/__tests__/e2e/utils/parseReplaceObjectBodyRegexResponse.d.ts +10 -0
- package/dist/__tests__/e2e/utils/parseReplaceObjectBodyRegexResponse.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/parseReplaceObjectBodyRegexResponse.js +40 -0
- package/dist/__tests__/e2e/utils/parseReplaceObjectBodyRegexResponse.js.map +1 -0
- package/dist/__tests__/e2e/utils/parseUpdateObjectResponse.d.ts +5 -0
- package/dist/__tests__/e2e/utils/parseUpdateObjectResponse.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/parseUpdateObjectResponse.js +15 -0
- package/dist/__tests__/e2e/utils/parseUpdateObjectResponse.js.map +1 -0
- package/dist/__tests__/e2e/utils/pathExists.d.ts +5 -0
- package/dist/__tests__/e2e/utils/pathExists.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/pathExists.js +50 -0
- package/dist/__tests__/e2e/utils/pathExists.js.map +1 -0
- package/dist/__tests__/e2e/utils/readObjectFile.d.ts +10 -0
- package/dist/__tests__/e2e/utils/readObjectFile.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/readObjectFile.js +54 -0
- package/dist/__tests__/e2e/utils/readObjectFile.js.map +1 -0
- package/dist/__tests__/e2e/utils/serverProcess.d.ts +11 -0
- package/dist/__tests__/e2e/utils/serverProcess.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/serverProcess.js +119 -0
- package/dist/__tests__/e2e/utils/serverProcess.js.map +1 -0
- package/dist/__tests__/e2e/utils/testEnvironment.d.ts +9 -0
- package/dist/__tests__/e2e/utils/testEnvironment.d.ts.map +1 -0
- package/dist/__tests__/e2e/utils/testEnvironment.js +74 -0
- package/dist/__tests__/e2e/utils/testEnvironment.js.map +1 -0
- package/dist/__tests__/e2e/workflow/appendLog.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/workflow/appendLog.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/workflow/appendLog.e2e.test.js +175 -0
- package/dist/__tests__/e2e/workflow/appendLog.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/workflow/claimTask.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/workflow/claimTask.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/workflow/claimTask.e2e.test.js +154 -0
- package/dist/__tests__/e2e/workflow/claimTask.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/workflow/completeTask.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/workflow/completeTask.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/workflow/completeTask.e2e.test.js +129 -0
- package/dist/__tests__/e2e/workflow/completeTask.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/workflow/prerequisites.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/workflow/prerequisites.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/workflow/prerequisites.e2e.test.js +547 -0
- package/dist/__tests__/e2e/workflow/prerequisites.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/workflow/pruneClosed.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/workflow/pruneClosed.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/workflow/pruneClosed.e2e.test.js +352 -0
- package/dist/__tests__/e2e/workflow/pruneClosed.e2e.test.js.map +1 -0
- package/dist/__tests__/e2e/workflow/taskLifecycle.e2e.test.d.ts +2 -0
- package/dist/__tests__/e2e/workflow/taskLifecycle.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/e2e/workflow/taskLifecycle.e2e.test.js +385 -0
- package/dist/__tests__/e2e/workflow/taskLifecycle.e2e.test.js.map +1 -0
- package/dist/models/TrellisObject.d.ts +2 -0
- package/dist/models/TrellisObject.d.ts.map +1 -1
- package/dist/models/__tests__/isClaimable.test.js +8 -0
- package/dist/models/__tests__/isClaimable.test.js.map +1 -1
- package/dist/models/__tests__/isClosed.test.js +6 -0
- package/dist/models/__tests__/isClosed.test.js.map +1 -1
- package/dist/models/__tests__/isOpen.test.js +6 -0
- package/dist/models/__tests__/isOpen.test.js.map +1 -1
- package/dist/repositories/local/__tests__/getChildrenByFilePath.test.d.ts +2 -0
- package/dist/repositories/local/__tests__/getChildrenByFilePath.test.d.ts.map +1 -0
- package/dist/repositories/local/__tests__/getChildrenByFilePath.test.js +118 -0
- package/dist/repositories/local/__tests__/getChildrenByFilePath.test.js.map +1 -0
- package/dist/repositories/local/__tests__/getObjectByFilePath.test.js +13 -1
- package/dist/repositories/local/__tests__/getObjectByFilePath.test.js.map +1 -1
- package/dist/repositories/local/__tests__/getObjectById.test.js +2 -0
- package/dist/repositories/local/__tests__/getObjectById.test.js.map +1 -1
- package/dist/repositories/local/__tests__/getObjectFilePath.test.js +2 -0
- package/dist/repositories/local/__tests__/getObjectFilePath.test.js.map +1 -1
- package/dist/repositories/local/deleteObjectById.js +2 -2
- package/dist/repositories/local/deleteObjectById.js.map +1 -1
- package/dist/repositories/local/findMarkdownFiles.d.ts.map +1 -1
- package/dist/repositories/local/findMarkdownFiles.js +6 -1
- package/dist/repositories/local/findMarkdownFiles.js.map +1 -1
- package/dist/repositories/local/getChildrenByFilePath.d.ts +14 -0
- package/dist/repositories/local/getChildrenByFilePath.d.ts.map +1 -0
- package/dist/repositories/local/getChildrenByFilePath.js +93 -0
- package/dist/repositories/local/getChildrenByFilePath.js.map +1 -0
- package/dist/repositories/local/getObjectByFilePath.d.ts.map +1 -1
- package/dist/repositories/local/getObjectByFilePath.js +5 -1
- package/dist/repositories/local/getObjectByFilePath.js.map +1 -1
- package/dist/repositories/local/getObjectById.d.ts.map +1 -1
- package/dist/repositories/local/getObjectById.js +4 -1
- package/dist/repositories/local/getObjectById.js.map +1 -1
- package/dist/repositories/local/getObjects.js +1 -1
- package/dist/repositories/local/getObjects.js.map +1 -1
- package/dist/repositories/local/saveObject.d.ts +1 -0
- package/dist/repositories/local/saveObject.d.ts.map +1 -1
- package/dist/repositories/local/saveObject.js +46 -0
- package/dist/repositories/local/saveObject.js.map +1 -1
- package/dist/server.js +52 -17
- package/dist/server.js.map +1 -1
- package/dist/tools/__tests__/appendObjectLogTool.test.js +2 -0
- package/dist/tools/__tests__/appendObjectLogTool.test.js.map +1 -1
- package/dist/tools/__tests__/claimTaskTool.test.js +4 -0
- package/dist/tools/__tests__/claimTaskTool.test.js.map +1 -1
- package/dist/tools/__tests__/completeTaskTool.test.js +2 -0
- package/dist/tools/__tests__/completeTaskTool.test.js.map +1 -1
- package/dist/tools/__tests__/createObjectTool.test.js +18 -0
- package/dist/tools/__tests__/createObjectTool.test.js.map +1 -1
- package/dist/tools/__tests__/getObjectTool.test.js +4 -0
- package/dist/tools/__tests__/getObjectTool.test.js.map +1 -1
- package/dist/tools/__tests__/listObjectsTool.test.js +4 -0
- package/dist/tools/__tests__/listObjectsTool.test.js.map +1 -1
- package/dist/tools/__tests__/pruneClosedTool.test.d.ts +2 -0
- package/dist/tools/__tests__/pruneClosedTool.test.d.ts.map +1 -0
- package/dist/tools/__tests__/pruneClosedTool.test.js +171 -0
- package/dist/tools/__tests__/pruneClosedTool.test.js.map +1 -0
- package/dist/tools/__tests__/replaceObjectBodyRegexTool.test.d.ts +2 -0
- package/dist/tools/__tests__/replaceObjectBodyRegexTool.test.d.ts.map +1 -0
- package/dist/tools/__tests__/replaceObjectBodyRegexTool.test.js +258 -0
- package/dist/tools/__tests__/replaceObjectBodyRegexTool.test.js.map +1 -0
- package/dist/tools/__tests__/updateObjectTool.test.js +2 -0
- package/dist/tools/__tests__/updateObjectTool.test.js.map +1 -1
- package/dist/tools/activateTool.d.ts +1 -1
- package/dist/tools/activateTool.d.ts.map +1 -1
- package/dist/tools/activateTool.js +35 -1
- package/dist/tools/activateTool.js.map +1 -1
- package/dist/tools/appendObjectLogTool.d.ts +1 -1
- package/dist/tools/appendObjectLogTool.d.ts.map +1 -1
- package/dist/tools/appendObjectLogTool.js +27 -1
- package/dist/tools/appendObjectLogTool.js.map +1 -1
- package/dist/tools/claimTaskTool.d.ts +1 -1
- package/dist/tools/claimTaskTool.d.ts.map +1 -1
- package/dist/tools/claimTaskTool.js +34 -5
- package/dist/tools/claimTaskTool.js.map +1 -1
- package/dist/tools/completeTaskTool.d.ts +1 -1
- package/dist/tools/completeTaskTool.d.ts.map +1 -1
- package/dist/tools/completeTaskTool.js +30 -1
- package/dist/tools/completeTaskTool.js.map +1 -1
- package/dist/tools/createObjectTool.d.ts +1 -1
- package/dist/tools/createObjectTool.d.ts.map +1 -1
- package/dist/tools/createObjectTool.js +43 -2
- package/dist/tools/createObjectTool.js.map +1 -1
- package/dist/tools/deleteObjectTool.d.ts +1 -1
- package/dist/tools/deleteObjectTool.d.ts.map +1 -1
- package/dist/tools/deleteObjectTool.js +23 -1
- package/dist/tools/deleteObjectTool.js.map +1 -1
- package/dist/tools/getObjectTool.d.ts +1 -1
- package/dist/tools/getObjectTool.d.ts.map +1 -1
- package/dist/tools/getObjectTool.js +21 -1
- package/dist/tools/getObjectTool.js.map +1 -1
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/listObjectsTool.d.ts +1 -1
- package/dist/tools/listObjectsTool.d.ts.map +1 -1
- package/dist/tools/listObjectsTool.js +37 -1
- package/dist/tools/listObjectsTool.js.map +1 -1
- package/dist/tools/pruneClosedTool.d.ts +3 -3
- package/dist/tools/pruneClosedTool.d.ts.map +1 -1
- package/dist/tools/pruneClosedTool.js +82 -11
- package/dist/tools/pruneClosedTool.js.map +1 -1
- package/dist/tools/replaceObjectBodyRegexTool.d.ts +35 -0
- package/dist/tools/replaceObjectBodyRegexTool.d.ts.map +1 -0
- package/dist/tools/replaceObjectBodyRegexTool.js +145 -0
- package/dist/tools/replaceObjectBodyRegexTool.js.map +1 -0
- package/dist/tools/updateObjectTool.d.ts +1 -1
- package/dist/tools/updateObjectTool.d.ts.map +1 -1
- package/dist/tools/updateObjectTool.js +35 -1
- package/dist/tools/updateObjectTool.js.map +1 -1
- package/dist/utils/MultipleMatchesError.d.ts +7 -0
- package/dist/utils/MultipleMatchesError.d.ts.map +1 -0
- package/dist/utils/MultipleMatchesError.js +15 -0
- package/dist/utils/MultipleMatchesError.js.map +1 -0
- package/dist/utils/ReplaceStringOptions.d.ts +12 -0
- package/dist/utils/ReplaceStringOptions.d.ts.map +1 -0
- package/dist/utils/ReplaceStringOptions.js +3 -0
- package/dist/utils/ReplaceStringOptions.js.map +1 -0
- package/dist/utils/__tests__/checkPrerequisitesComplete.test.js +2 -0
- package/dist/utils/__tests__/checkPrerequisitesComplete.test.js.map +1 -1
- package/dist/utils/__tests__/deserializeTrellisObject.test.js +48 -0
- package/dist/utils/__tests__/deserializeTrellisObject.test.js.map +1 -1
- package/dist/utils/__tests__/filterUnavailableObjects.test.js +11 -10
- package/dist/utils/__tests__/filterUnavailableObjects.test.js.map +1 -1
- package/dist/utils/__tests__/isRequiredForOtherObjects.test.js +2 -0
- package/dist/utils/__tests__/isRequiredForOtherObjects.test.js.map +1 -1
- package/dist/utils/__tests__/replaceStringWithRegex.test.d.ts +2 -0
- package/dist/utils/__tests__/replaceStringWithRegex.test.d.ts.map +1 -0
- package/dist/utils/__tests__/replaceStringWithRegex.test.js +281 -0
- package/dist/utils/__tests__/replaceStringWithRegex.test.js.map +1 -0
- package/dist/utils/__tests__/serializationRoundTrip.test.js +24 -0
- package/dist/utils/__tests__/serializationRoundTrip.test.js.map +1 -1
- package/dist/utils/__tests__/serializeTrellisObject.test.js +40 -0
- package/dist/utils/__tests__/serializeTrellisObject.test.js.map +1 -1
- package/dist/utils/__tests__/sortTrellisObjects.test.js +2 -0
- package/dist/utils/__tests__/sortTrellisObjects.test.js.map +1 -1
- package/dist/utils/checkPrerequisitesComplete.d.ts.map +1 -1
- package/dist/utils/checkPrerequisitesComplete.js +3 -4
- package/dist/utils/checkPrerequisitesComplete.js.map +1 -1
- package/dist/utils/deserializeTrellisObject.d.ts.map +1 -1
- package/dist/utils/deserializeTrellisObject.js +5 -0
- package/dist/utils/deserializeTrellisObject.js.map +1 -1
- package/dist/utils/filterUnavailableObjects.d.ts.map +1 -1
- package/dist/utils/filterUnavailableObjects.js +5 -6
- package/dist/utils/filterUnavailableObjects.js.map +1 -1
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +5 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/isRequiredForOtherObjects.d.ts.map +1 -1
- package/dist/utils/isRequiredForOtherObjects.js +2 -4
- package/dist/utils/isRequiredForOtherObjects.js.map +1 -1
- package/dist/utils/replaceStringWithRegex.d.ts +45 -0
- package/dist/utils/replaceStringWithRegex.d.ts.map +1 -0
- package/dist/utils/replaceStringWithRegex.js +91 -0
- package/dist/utils/replaceStringWithRegex.js.map +1 -0
- package/dist/utils/serializeTrellisObject.d.ts.map +1 -1
- package/dist/utils/serializeTrellisObject.js +3 -0
- package/dist/utils/serializeTrellisObject.js.map +1 -1
- package/dist/validation/__tests__/validateObjectCreation.test.js +2 -0
- package/dist/validation/__tests__/validateObjectCreation.test.js.map +1 -1
- package/dist/validation/__tests__/validateParentExists.test.js +2 -0
- package/dist/validation/__tests__/validateParentExists.test.js.map +1 -1
- package/dist/validation/__tests__/validateStatusTransition.test.js +2 -0
- package/dist/validation/__tests__/validateStatusTransition.test.js.map +1 -1
- package/package.json +8 -3
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
describe("E2E CRUD - replaceObjectBodyRegex", () => {
|
|
5
|
+
let testEnv;
|
|
6
|
+
let client;
|
|
7
|
+
beforeEach(async () => {
|
|
8
|
+
testEnv = new utils_1.TestEnvironment();
|
|
9
|
+
testEnv.setup();
|
|
10
|
+
client = new utils_1.McpTestClient(testEnv.projectRoot);
|
|
11
|
+
await client.connect();
|
|
12
|
+
// Activate server in local mode
|
|
13
|
+
await client.callTool("activate", {
|
|
14
|
+
mode: "local",
|
|
15
|
+
projectRoot: testEnv.projectRoot,
|
|
16
|
+
});
|
|
17
|
+
}, 30000);
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
await client?.disconnect();
|
|
20
|
+
testEnv?.cleanup();
|
|
21
|
+
});
|
|
22
|
+
describe("Basic Functionality Tests", () => {
|
|
23
|
+
it("should replace simple text patterns", async () => {
|
|
24
|
+
// Create task with simple text
|
|
25
|
+
const taskData = {
|
|
26
|
+
id: "T-simple-replace",
|
|
27
|
+
title: "Simple Replace Task",
|
|
28
|
+
status: "open",
|
|
29
|
+
body: "Hello World, welcome to the system",
|
|
30
|
+
};
|
|
31
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-simple-replace", (0, utils_1.createObjectContent)(taskData));
|
|
32
|
+
// Replace "World" with "Universe"
|
|
33
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
34
|
+
id: "T-simple-replace",
|
|
35
|
+
regex: "World",
|
|
36
|
+
replacement: "Universe",
|
|
37
|
+
});
|
|
38
|
+
expect(result.content[0].type).toBe("text");
|
|
39
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
40
|
+
expect(response.success).toBe(true);
|
|
41
|
+
expect(response.objectId).toBe("T-simple-replace");
|
|
42
|
+
expect(response.pattern).toBe("World");
|
|
43
|
+
// Verify file persistence
|
|
44
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-simple-replace.md");
|
|
45
|
+
expect(file.body).toBe("Hello Universe, welcome to the system");
|
|
46
|
+
});
|
|
47
|
+
it("should use backreferences for pattern reordering", async () => {
|
|
48
|
+
// Create task with name pattern
|
|
49
|
+
const taskData = {
|
|
50
|
+
id: "T-backreference",
|
|
51
|
+
title: "Backreference Test",
|
|
52
|
+
body: "Name: John Doe\nEmail: john.doe@example.com",
|
|
53
|
+
};
|
|
54
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-backreference", (0, utils_1.createObjectContent)(taskData));
|
|
55
|
+
// Reorder name using backreferences
|
|
56
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
57
|
+
id: "T-backreference",
|
|
58
|
+
regex: "Name: (\\w+) (\\w+)",
|
|
59
|
+
replacement: "Name: $2, $1",
|
|
60
|
+
});
|
|
61
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
62
|
+
expect(response.success).toBe(true);
|
|
63
|
+
// Verify file persistence
|
|
64
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-backreference.md");
|
|
65
|
+
expect(file.body).toBe("Name: Doe, John\nEmail: john.doe@example.com");
|
|
66
|
+
});
|
|
67
|
+
it("should work with multiline content", async () => {
|
|
68
|
+
// Create feature with multiline content
|
|
69
|
+
const featureData = {
|
|
70
|
+
id: "F-multiline",
|
|
71
|
+
title: "Multiline Content Feature",
|
|
72
|
+
body: `# Feature Description
|
|
73
|
+
|
|
74
|
+
## Old Implementation
|
|
75
|
+
This is the old way
|
|
76
|
+
of doing things
|
|
77
|
+
across multiple lines
|
|
78
|
+
|
|
79
|
+
## Other Section
|
|
80
|
+
Keep this unchanged`,
|
|
81
|
+
};
|
|
82
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "feature", "F-multiline", (0, utils_1.createObjectContent)(featureData));
|
|
83
|
+
// Replace multiline section
|
|
84
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
85
|
+
id: "F-multiline",
|
|
86
|
+
regex: "## Old Implementation.*?(?=## Other Section)",
|
|
87
|
+
replacement: "## New Implementation\nThis is the new way\nof doing things\nbetter\n\n",
|
|
88
|
+
});
|
|
89
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
90
|
+
expect(response.success).toBe(true);
|
|
91
|
+
// Verify file persistence
|
|
92
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "f/F-multiline/F-multiline.md");
|
|
93
|
+
expect(file.body).toBe(`# Feature Description
|
|
94
|
+
|
|
95
|
+
## New Implementation
|
|
96
|
+
This is the new way
|
|
97
|
+
of doing things
|
|
98
|
+
better
|
|
99
|
+
|
|
100
|
+
## Other Section
|
|
101
|
+
Keep this unchanged`);
|
|
102
|
+
});
|
|
103
|
+
it("should work across different object types", async () => {
|
|
104
|
+
// First create the parent project for the epic
|
|
105
|
+
const parentProjectData = {
|
|
106
|
+
id: "P-test",
|
|
107
|
+
title: "Test Parent Project",
|
|
108
|
+
body: "Parent project body",
|
|
109
|
+
};
|
|
110
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "project", "P-test", (0, utils_1.createObjectContent)(parentProjectData));
|
|
111
|
+
const objectTypes = [
|
|
112
|
+
{
|
|
113
|
+
type: "project",
|
|
114
|
+
id: "P-regex-test",
|
|
115
|
+
path: "p/P-regex-test/P-regex-test.md",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: "epic",
|
|
119
|
+
id: "E-regex-test",
|
|
120
|
+
path: "p/P-test/e/E-regex-test/E-regex-test.md",
|
|
121
|
+
options: { projectId: "P-test" },
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: "feature",
|
|
125
|
+
id: "F-regex-test",
|
|
126
|
+
path: "f/F-regex-test/F-regex-test.md",
|
|
127
|
+
},
|
|
128
|
+
{ type: "task", id: "T-regex-test", path: "t/open/T-regex-test.md" },
|
|
129
|
+
];
|
|
130
|
+
for (const obj of objectTypes) {
|
|
131
|
+
const objectData = {
|
|
132
|
+
id: obj.id,
|
|
133
|
+
title: `${obj.type} Regex Test`,
|
|
134
|
+
body: `Old content for ${obj.type}`,
|
|
135
|
+
};
|
|
136
|
+
if (obj.type === "epic") {
|
|
137
|
+
// Epic needs parent project
|
|
138
|
+
objectData.parent = "P-test";
|
|
139
|
+
}
|
|
140
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, obj.type, obj.id, (0, utils_1.createObjectContent)(objectData), obj.options);
|
|
141
|
+
// Replace content
|
|
142
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
143
|
+
id: obj.id,
|
|
144
|
+
regex: `Old content for ${obj.type}`,
|
|
145
|
+
replacement: `New content for ${obj.type}`,
|
|
146
|
+
});
|
|
147
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
148
|
+
if (!response.success) {
|
|
149
|
+
console.log(`Failed for ${obj.type}:`, response.message);
|
|
150
|
+
console.log("Full result:", result.content[0].text);
|
|
151
|
+
}
|
|
152
|
+
expect(response.success).toBe(true);
|
|
153
|
+
// Verify file persistence
|
|
154
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, obj.path);
|
|
155
|
+
expect(file.body).toBe(`New content for ${obj.type}`);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe("Regex Feature Tests", () => {
|
|
160
|
+
it("should handle case-sensitive matching by default", async () => {
|
|
161
|
+
const taskData = {
|
|
162
|
+
id: "T-case-sensitive",
|
|
163
|
+
title: "Case Sensitive Test",
|
|
164
|
+
body: "Test content with Test and test variations",
|
|
165
|
+
};
|
|
166
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-case-sensitive", (0, utils_1.createObjectContent)(taskData));
|
|
167
|
+
// Only match "Test" (capital T)
|
|
168
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
169
|
+
id: "T-case-sensitive",
|
|
170
|
+
regex: "Test",
|
|
171
|
+
replacement: "Match",
|
|
172
|
+
allowMultipleOccurrences: true,
|
|
173
|
+
});
|
|
174
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
175
|
+
expect(response.success).toBe(true);
|
|
176
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-case-sensitive.md");
|
|
177
|
+
expect(file.body).toBe("Match content with Match and test variations");
|
|
178
|
+
});
|
|
179
|
+
it("should handle case-insensitive patterns with flag", async () => {
|
|
180
|
+
const taskData = {
|
|
181
|
+
id: "T-case-insensitive",
|
|
182
|
+
title: "Case Insensitive Test",
|
|
183
|
+
body: "Test content with TEST and test variations",
|
|
184
|
+
};
|
|
185
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-case-insensitive", (0, utils_1.createObjectContent)(taskData));
|
|
186
|
+
// Replace each case variation individually since (?i) flag might not be supported
|
|
187
|
+
// First replace "Test"
|
|
188
|
+
let result = await client.callTool("replace_object_body_regex", {
|
|
189
|
+
id: "T-case-insensitive",
|
|
190
|
+
regex: "Test",
|
|
191
|
+
replacement: "match",
|
|
192
|
+
});
|
|
193
|
+
let response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
194
|
+
expect(response.success).toBe(true);
|
|
195
|
+
// Then replace "TEST"
|
|
196
|
+
result = await client.callTool("replace_object_body_regex", {
|
|
197
|
+
id: "T-case-insensitive",
|
|
198
|
+
regex: "TEST",
|
|
199
|
+
replacement: "match",
|
|
200
|
+
});
|
|
201
|
+
response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
202
|
+
expect(response.success).toBe(true);
|
|
203
|
+
// Finally replace "test"
|
|
204
|
+
result = await client.callTool("replace_object_body_regex", {
|
|
205
|
+
id: "T-case-insensitive",
|
|
206
|
+
regex: "test",
|
|
207
|
+
replacement: "match",
|
|
208
|
+
});
|
|
209
|
+
response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
210
|
+
expect(response.success).toBe(true);
|
|
211
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-case-insensitive.md");
|
|
212
|
+
expect(file.body).toBe("match content with match and match variations");
|
|
213
|
+
});
|
|
214
|
+
it("should handle word boundaries", async () => {
|
|
215
|
+
const taskData = {
|
|
216
|
+
id: "T-word-boundaries",
|
|
217
|
+
title: "Word Boundaries Test",
|
|
218
|
+
body: "The cat category has catalog items",
|
|
219
|
+
};
|
|
220
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-word-boundaries", (0, utils_1.createObjectContent)(taskData));
|
|
221
|
+
// Only match whole word "cat"
|
|
222
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
223
|
+
id: "T-word-boundaries",
|
|
224
|
+
regex: "\\bcat\\b",
|
|
225
|
+
replacement: "dog",
|
|
226
|
+
});
|
|
227
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
228
|
+
expect(response.success).toBe(true);
|
|
229
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-word-boundaries.md");
|
|
230
|
+
expect(file.body).toBe("The dog category has catalog items");
|
|
231
|
+
});
|
|
232
|
+
it("should handle anchored patterns", async () => {
|
|
233
|
+
const taskData = {
|
|
234
|
+
id: "T-anchors",
|
|
235
|
+
title: "Anchors Test",
|
|
236
|
+
body: `Start of document
|
|
237
|
+
Middle content
|
|
238
|
+
End of document`,
|
|
239
|
+
};
|
|
240
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-anchors", (0, utils_1.createObjectContent)(taskData));
|
|
241
|
+
// Replace line starting with "Start" using a simpler pattern
|
|
242
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
243
|
+
id: "T-anchors",
|
|
244
|
+
regex: "Start of document",
|
|
245
|
+
replacement: "Beginning of document",
|
|
246
|
+
});
|
|
247
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
248
|
+
expect(response.success).toBe(true);
|
|
249
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-anchors.md");
|
|
250
|
+
expect(file.body).toBe(`Beginning of document
|
|
251
|
+
Middle content
|
|
252
|
+
End of document`);
|
|
253
|
+
});
|
|
254
|
+
it("should handle quantifiers", async () => {
|
|
255
|
+
const taskData = {
|
|
256
|
+
id: "T-quantifiers",
|
|
257
|
+
title: "Quantifiers Test",
|
|
258
|
+
body: "Version 1.2.3 and Version 10.20.30",
|
|
259
|
+
};
|
|
260
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-quantifiers", (0, utils_1.createObjectContent)(taskData));
|
|
261
|
+
// Match version patterns with quantifiers
|
|
262
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
263
|
+
id: "T-quantifiers",
|
|
264
|
+
regex: "Version \\d+\\.\\d+\\.\\d+",
|
|
265
|
+
replacement: "Release 2.0.0",
|
|
266
|
+
allowMultipleOccurrences: true,
|
|
267
|
+
});
|
|
268
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
269
|
+
expect(response.success).toBe(true);
|
|
270
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-quantifiers.md");
|
|
271
|
+
expect(file.body).toBe("Release 2.0.0 and Release 2.0.0");
|
|
272
|
+
});
|
|
273
|
+
it("should handle character classes", async () => {
|
|
274
|
+
const taskData = {
|
|
275
|
+
id: "T-char-classes",
|
|
276
|
+
title: "Character Classes Test",
|
|
277
|
+
body: "Phone: 123-456-7890, Phone: 987.654.3210, Phone: (555) 123-4567",
|
|
278
|
+
};
|
|
279
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-char-classes", (0, utils_1.createObjectContent)(taskData));
|
|
280
|
+
// Match phone numbers with various separators
|
|
281
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
282
|
+
id: "T-char-classes",
|
|
283
|
+
regex: "Phone: [\\d\\-\\.(\\) ]+",
|
|
284
|
+
replacement: "Phone: XXX-XXX-XXXX",
|
|
285
|
+
allowMultipleOccurrences: true,
|
|
286
|
+
});
|
|
287
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
288
|
+
expect(response.success).toBe(true);
|
|
289
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-char-classes.md");
|
|
290
|
+
expect(file.body).toBe("Phone: XXX-XXX-XXXX, Phone: XXX-XXX-XXXX, Phone: XXX-XXX-XXXX");
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
describe("Multiple Occurrences Handling", () => {
|
|
294
|
+
it("should reject multiple matches by default", async () => {
|
|
295
|
+
const taskData = {
|
|
296
|
+
id: "T-multiple-reject",
|
|
297
|
+
title: "Multiple Matches Reject",
|
|
298
|
+
body: "TODO: Fix bug 1\nTODO: Fix bug 2\nTODO: Fix bug 3",
|
|
299
|
+
};
|
|
300
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-multiple-reject", (0, utils_1.createObjectContent)(taskData));
|
|
301
|
+
// Attempt to replace all TODOs (should fail)
|
|
302
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
303
|
+
id: "T-multiple-reject",
|
|
304
|
+
regex: "TODO:",
|
|
305
|
+
replacement: "DONE:",
|
|
306
|
+
});
|
|
307
|
+
expect(result.content[0].type).toBe("text");
|
|
308
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
309
|
+
expect(response.success).toBe(false);
|
|
310
|
+
expect(response.message).toContain("Found 3 matches for pattern");
|
|
311
|
+
expect(response.message).toContain("allowMultipleOccurrences is false");
|
|
312
|
+
// Verify file unchanged
|
|
313
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-multiple-reject.md");
|
|
314
|
+
expect(file.body).toBe("TODO: Fix bug 1\nTODO: Fix bug 2\nTODO: Fix bug 3");
|
|
315
|
+
});
|
|
316
|
+
it("should replace all when allowMultipleOccurrences is true", async () => {
|
|
317
|
+
const taskData = {
|
|
318
|
+
id: "T-multiple-allow",
|
|
319
|
+
title: "Multiple Matches Allow",
|
|
320
|
+
body: "TODO: Fix bug 1\nTODO: Fix bug 2\nCompleted: Fix bug 3",
|
|
321
|
+
};
|
|
322
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-multiple-allow", (0, utils_1.createObjectContent)(taskData));
|
|
323
|
+
// Replace all TODOs with allowMultipleOccurrences
|
|
324
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
325
|
+
id: "T-multiple-allow",
|
|
326
|
+
regex: "TODO:",
|
|
327
|
+
replacement: "DONE:",
|
|
328
|
+
allowMultipleOccurrences: true,
|
|
329
|
+
});
|
|
330
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
331
|
+
expect(response.success).toBe(true);
|
|
332
|
+
// Verify file updated
|
|
333
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-multiple-allow.md");
|
|
334
|
+
expect(file.body).toBe("DONE: Fix bug 1\nDONE: Fix bug 2\nCompleted: Fix bug 3");
|
|
335
|
+
});
|
|
336
|
+
it("should handle no matches gracefully", async () => {
|
|
337
|
+
const taskData = {
|
|
338
|
+
id: "T-no-matches",
|
|
339
|
+
title: "No Matches Test",
|
|
340
|
+
body: "This content has no matching patterns",
|
|
341
|
+
};
|
|
342
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-no-matches", (0, utils_1.createObjectContent)(taskData));
|
|
343
|
+
// Search for non-existent pattern
|
|
344
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
345
|
+
id: "T-no-matches",
|
|
346
|
+
regex: "nonexistent",
|
|
347
|
+
replacement: "replacement",
|
|
348
|
+
});
|
|
349
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
350
|
+
expect(response.success).toBe(false);
|
|
351
|
+
expect(response.message).toContain("No matches found for pattern");
|
|
352
|
+
expect(response.pattern).toBe("nonexistent");
|
|
353
|
+
// Verify file unchanged
|
|
354
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-no-matches.md");
|
|
355
|
+
expect(file.body).toBe("This content has no matching patterns");
|
|
356
|
+
});
|
|
357
|
+
});
|
|
358
|
+
describe("Error Handling & Edge Cases", () => {
|
|
359
|
+
it("should handle non-existent object ID", async () => {
|
|
360
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
361
|
+
id: "T-nonexistent",
|
|
362
|
+
regex: "pattern",
|
|
363
|
+
replacement: "replacement",
|
|
364
|
+
});
|
|
365
|
+
expect(result.content[0].type).toBe("text");
|
|
366
|
+
expect(result.content[0].text).toBe("Error: Object with ID 'T-nonexistent' not found");
|
|
367
|
+
});
|
|
368
|
+
it("should handle empty body content", async () => {
|
|
369
|
+
const taskData = {
|
|
370
|
+
id: "T-empty-body",
|
|
371
|
+
title: "Empty Body Test",
|
|
372
|
+
body: "",
|
|
373
|
+
};
|
|
374
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-empty-body", (0, utils_1.createObjectContent)(taskData));
|
|
375
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
376
|
+
id: "T-empty-body",
|
|
377
|
+
regex: "pattern",
|
|
378
|
+
replacement: "replacement",
|
|
379
|
+
});
|
|
380
|
+
expect(result.content[0].text).toBe("Error: Object with ID 'T-empty-body' has no body content to replace");
|
|
381
|
+
});
|
|
382
|
+
it("should handle invalid regex patterns", async () => {
|
|
383
|
+
const taskData = {
|
|
384
|
+
id: "T-invalid-regex",
|
|
385
|
+
title: "Invalid Regex Test",
|
|
386
|
+
body: "Some content here",
|
|
387
|
+
};
|
|
388
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-invalid-regex", (0, utils_1.createObjectContent)(taskData));
|
|
389
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
390
|
+
id: "T-invalid-regex",
|
|
391
|
+
regex: "[invalid regex",
|
|
392
|
+
replacement: "replacement",
|
|
393
|
+
});
|
|
394
|
+
expect(result.content[0].text).toContain("Error replacing object body:");
|
|
395
|
+
expect(result.content[0].text).toContain("Invalid regex pattern");
|
|
396
|
+
});
|
|
397
|
+
it("should handle large body content", async () => {
|
|
398
|
+
// Create 10KB+ content
|
|
399
|
+
const largeContent = "A".repeat(5000) + "\n\nMIDDLE MARKER\n\n" + "B".repeat(5000);
|
|
400
|
+
const taskData = {
|
|
401
|
+
id: "T-large-body",
|
|
402
|
+
title: "Large Body Test",
|
|
403
|
+
body: largeContent,
|
|
404
|
+
};
|
|
405
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-large-body", (0, utils_1.createObjectContent)(taskData));
|
|
406
|
+
// Replace marker in the middle
|
|
407
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
408
|
+
id: "T-large-body",
|
|
409
|
+
regex: "MIDDLE MARKER",
|
|
410
|
+
replacement: "UPDATED MARKER",
|
|
411
|
+
});
|
|
412
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
413
|
+
expect(response.success).toBe(true);
|
|
414
|
+
// Verify large content was processed correctly
|
|
415
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-large-body.md");
|
|
416
|
+
expect(file.body).toContain("UPDATED MARKER");
|
|
417
|
+
expect(file.body.length).toBe(largeContent.length +
|
|
418
|
+
("UPDATED MARKER".length - "MIDDLE MARKER".length));
|
|
419
|
+
});
|
|
420
|
+
it("should handle special characters and unicode", async () => {
|
|
421
|
+
const taskData = {
|
|
422
|
+
id: "T-special-chars",
|
|
423
|
+
title: "Special Characters Test",
|
|
424
|
+
body: `# Special Content 🚀
|
|
425
|
+
|
|
426
|
+
Code: const test = "value with 'quotes' and \\"double quotes\\"";
|
|
427
|
+
Math: α β γ δ ε
|
|
428
|
+
Arrows: → ← ↑ ↓
|
|
429
|
+
Symbols: & < > | \\ / * ? : " ' \` ~ ! @ # $ % ^ & * ( ) [ ] { }
|
|
430
|
+
Unicode: 你好世界`,
|
|
431
|
+
};
|
|
432
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-special-chars", (0, utils_1.createObjectContent)(taskData));
|
|
433
|
+
// Replace unicode content
|
|
434
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
435
|
+
id: "T-special-chars",
|
|
436
|
+
regex: "你好世界",
|
|
437
|
+
replacement: "Hello World",
|
|
438
|
+
});
|
|
439
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
440
|
+
expect(response.success).toBe(true);
|
|
441
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-special-chars.md");
|
|
442
|
+
expect(file.body).toContain("Hello World");
|
|
443
|
+
expect(file.body).not.toContain("你好世界");
|
|
444
|
+
});
|
|
445
|
+
it("should handle empty regex pattern", async () => {
|
|
446
|
+
const taskData = {
|
|
447
|
+
id: "T-empty-regex",
|
|
448
|
+
title: "Empty Regex Test",
|
|
449
|
+
body: "Some content",
|
|
450
|
+
};
|
|
451
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-empty-regex", (0, utils_1.createObjectContent)(taskData));
|
|
452
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
453
|
+
id: "T-empty-regex",
|
|
454
|
+
regex: "",
|
|
455
|
+
replacement: "replacement",
|
|
456
|
+
});
|
|
457
|
+
expect(result.content[0].text).toContain("Regex pattern cannot be empty");
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
describe("File System Persistence", () => {
|
|
461
|
+
it("should verify changes persist across file reads", async () => {
|
|
462
|
+
const taskData = {
|
|
463
|
+
id: "T-persistence",
|
|
464
|
+
title: "Persistence Test",
|
|
465
|
+
status: "open",
|
|
466
|
+
priority: "high",
|
|
467
|
+
body: "Original content for persistence testing",
|
|
468
|
+
};
|
|
469
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-persistence", (0, utils_1.createObjectContent)(taskData));
|
|
470
|
+
// Perform replacement
|
|
471
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
472
|
+
id: "T-persistence",
|
|
473
|
+
regex: "Original content",
|
|
474
|
+
replacement: "Updated content",
|
|
475
|
+
});
|
|
476
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
477
|
+
expect(response.success).toBe(true);
|
|
478
|
+
// Read file multiple times to verify persistence
|
|
479
|
+
for (let i = 0; i < 3; i++) {
|
|
480
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-persistence.md");
|
|
481
|
+
expect(file.body).toBe("Updated content for persistence testing");
|
|
482
|
+
expect(file.yaml.title).toBe("Persistence Test");
|
|
483
|
+
expect(file.yaml.status).toBe("open");
|
|
484
|
+
expect(file.yaml.priority).toBe("high");
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
it("should preserve YAML frontmatter during body updates", async () => {
|
|
488
|
+
const taskData = {
|
|
489
|
+
id: "T-yaml-preserve",
|
|
490
|
+
title: "YAML Preservation Test",
|
|
491
|
+
status: "open",
|
|
492
|
+
priority: "high",
|
|
493
|
+
prerequisites: ["T-dep-1", "T-dep-2"],
|
|
494
|
+
body: "Body content to be modified",
|
|
495
|
+
};
|
|
496
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-yaml-preserve", (0, utils_1.createObjectContent)(taskData));
|
|
497
|
+
// Update body content
|
|
498
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
499
|
+
id: "T-yaml-preserve",
|
|
500
|
+
regex: "Body content",
|
|
501
|
+
replacement: "Modified body content",
|
|
502
|
+
});
|
|
503
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
504
|
+
expect(response.success).toBe(true);
|
|
505
|
+
// Verify YAML metadata preserved (using open status so file is in t/open/ folder)
|
|
506
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-yaml-preserve.md");
|
|
507
|
+
expect(file.yaml.id).toBe("T-yaml-preserve");
|
|
508
|
+
expect(file.yaml.title).toBe("YAML Preservation Test");
|
|
509
|
+
expect(file.yaml.status).toBe("open");
|
|
510
|
+
expect(file.yaml.priority).toBe("high");
|
|
511
|
+
expect(file.yaml.prerequisites).toEqual(["T-dep-1", "T-dep-2"]);
|
|
512
|
+
expect(file.body).toBe("Modified body content to be modified");
|
|
513
|
+
});
|
|
514
|
+
it("should work with objects in hierarchy paths", async () => {
|
|
515
|
+
// Create project structure
|
|
516
|
+
const projectData = {
|
|
517
|
+
id: "P-hierarchy",
|
|
518
|
+
title: "Hierarchy Project",
|
|
519
|
+
body: "Project description",
|
|
520
|
+
};
|
|
521
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "project", "P-hierarchy", (0, utils_1.createObjectContent)(projectData));
|
|
522
|
+
// Create epic in project
|
|
523
|
+
const epicData = {
|
|
524
|
+
id: "E-hierarchy",
|
|
525
|
+
title: "Hierarchy Epic",
|
|
526
|
+
parent: "P-hierarchy",
|
|
527
|
+
body: "Epic content for replacement",
|
|
528
|
+
};
|
|
529
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "epic", "E-hierarchy", (0, utils_1.createObjectContent)(epicData), { projectId: "P-hierarchy" });
|
|
530
|
+
// Create feature in epic
|
|
531
|
+
const featureData = {
|
|
532
|
+
id: "F-hierarchy",
|
|
533
|
+
title: "Hierarchy Feature",
|
|
534
|
+
parent: "E-hierarchy",
|
|
535
|
+
body: "Feature content for replacement",
|
|
536
|
+
};
|
|
537
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "feature", "F-hierarchy", (0, utils_1.createObjectContent)(featureData), { projectId: "P-hierarchy", epicId: "E-hierarchy" });
|
|
538
|
+
// Update feature content
|
|
539
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
540
|
+
id: "F-hierarchy",
|
|
541
|
+
regex: "Feature content",
|
|
542
|
+
replacement: "Updated feature content",
|
|
543
|
+
});
|
|
544
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
545
|
+
expect(response.success).toBe(true);
|
|
546
|
+
// Verify file in correct hierarchy path
|
|
547
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "p/P-hierarchy/e/E-hierarchy/f/F-hierarchy/F-hierarchy.md");
|
|
548
|
+
expect(file.body).toBe("Updated feature content for replacement");
|
|
549
|
+
});
|
|
550
|
+
});
|
|
551
|
+
describe("Integration Scenarios", () => {
|
|
552
|
+
it("should handle complex markdown content", async () => {
|
|
553
|
+
const complexMarkdown = `# Main Title
|
|
554
|
+
|
|
555
|
+
## Section 1
|
|
556
|
+
Some content here with **bold** and *italic* text.
|
|
557
|
+
|
|
558
|
+
\`\`\`typescript
|
|
559
|
+
const example = "code block";
|
|
560
|
+
function test() {
|
|
561
|
+
return "old implementation";
|
|
562
|
+
}
|
|
563
|
+
\`\`\`
|
|
564
|
+
|
|
565
|
+
### Subsection
|
|
566
|
+
- List item 1
|
|
567
|
+
- List item 2
|
|
568
|
+
- List item 3
|
|
569
|
+
|
|
570
|
+
| Column 1 | Column 2 |
|
|
571
|
+
|----------|----------|
|
|
572
|
+
| Value 1 | Value 2 |
|
|
573
|
+
|
|
574
|
+
> This is a blockquote with old information
|
|
575
|
+
|
|
576
|
+
## Section 2
|
|
577
|
+
More content here.`;
|
|
578
|
+
const featureData = {
|
|
579
|
+
id: "F-complex-markdown",
|
|
580
|
+
title: "Complex Markdown Test",
|
|
581
|
+
body: complexMarkdown,
|
|
582
|
+
};
|
|
583
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "feature", "F-complex-markdown", (0, utils_1.createObjectContent)(featureData));
|
|
584
|
+
// Update code block content - escape quotes properly
|
|
585
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
586
|
+
id: "F-complex-markdown",
|
|
587
|
+
regex: 'return "old implementation";',
|
|
588
|
+
replacement: 'return "new implementation";',
|
|
589
|
+
});
|
|
590
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
591
|
+
if (!response.success) {
|
|
592
|
+
console.log("Complex markdown failed:", response.message);
|
|
593
|
+
console.log("Full result:", result.content[0].text);
|
|
594
|
+
}
|
|
595
|
+
expect(response.success).toBe(true);
|
|
596
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "f/F-complex-markdown/F-complex-markdown.md");
|
|
597
|
+
expect(file.body).toContain('return "new implementation";');
|
|
598
|
+
expect(file.body).not.toContain('return "old implementation";');
|
|
599
|
+
expect(file.body).toContain("# Main Title");
|
|
600
|
+
expect(file.body).toContain("| Column 1 | Column 2 |");
|
|
601
|
+
});
|
|
602
|
+
it("should handle template placeholder replacements", async () => {
|
|
603
|
+
const templateContent = `# {{TITLE}} Implementation
|
|
604
|
+
|
|
605
|
+
## Overview
|
|
606
|
+
This {{TYPE}} implements {{FEATURE_NAME}} functionality.
|
|
607
|
+
|
|
608
|
+
## Configuration
|
|
609
|
+
- Environment: {{ENV}}
|
|
610
|
+
- Version: {{VERSION}}
|
|
611
|
+
- Database: {{DB_TYPE}}
|
|
612
|
+
|
|
613
|
+
## Implementation Details
|
|
614
|
+
The {{FEATURE_NAME}} feature uses {{TECHNOLOGY}} to provide {{BENEFIT}}.`;
|
|
615
|
+
const taskData = {
|
|
616
|
+
id: "T-template",
|
|
617
|
+
title: "Template Replacement Test",
|
|
618
|
+
body: templateContent,
|
|
619
|
+
};
|
|
620
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-template", (0, utils_1.createObjectContent)(taskData));
|
|
621
|
+
// Replace all template variables
|
|
622
|
+
const replacements = [
|
|
623
|
+
{ pattern: "\\{\\{TITLE\\}\\}", value: "Authentication" },
|
|
624
|
+
{ pattern: "\\{\\{TYPE\\}\\}", value: "module" },
|
|
625
|
+
{ pattern: "\\{\\{FEATURE_NAME\\}\\}", value: "user login" },
|
|
626
|
+
{ pattern: "\\{\\{ENV\\}\\}", value: "production" },
|
|
627
|
+
{ pattern: "\\{\\{VERSION\\}\\}", value: "2.0.0" },
|
|
628
|
+
{ pattern: "\\{\\{DB_TYPE\\}\\}", value: "PostgreSQL" },
|
|
629
|
+
{ pattern: "\\{\\{TECHNOLOGY\\}\\}", value: "JWT tokens" },
|
|
630
|
+
{ pattern: "\\{\\{BENEFIT\\}\\}", value: "secure authentication" },
|
|
631
|
+
];
|
|
632
|
+
for (const replacement of replacements) {
|
|
633
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
634
|
+
id: "T-template",
|
|
635
|
+
regex: replacement.pattern,
|
|
636
|
+
replacement: replacement.value,
|
|
637
|
+
allowMultipleOccurrences: true, // For template replacements, we want to replace all occurrences
|
|
638
|
+
});
|
|
639
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
640
|
+
if (!response.success) {
|
|
641
|
+
console.log(`Template replacement failed for ${replacement.pattern}:`, response.message);
|
|
642
|
+
console.log("Full result:", result.content[0].text);
|
|
643
|
+
}
|
|
644
|
+
expect(response.success).toBe(true);
|
|
645
|
+
}
|
|
646
|
+
// Verify all placeholders replaced
|
|
647
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-template.md");
|
|
648
|
+
expect(file.body).not.toContain("{{");
|
|
649
|
+
expect(file.body).not.toContain("}}");
|
|
650
|
+
expect(file.body).toContain("# Authentication Implementation");
|
|
651
|
+
expect(file.body).toContain("This module implements user login functionality");
|
|
652
|
+
expect(file.body).toContain("Version: 2.0.0");
|
|
653
|
+
expect(file.body).toContain("uses JWT tokens to provide secure authentication");
|
|
654
|
+
});
|
|
655
|
+
it("should handle cross-references and object IDs in content", async () => {
|
|
656
|
+
const contentWithRefs = `# Task Dependencies
|
|
657
|
+
|
|
658
|
+
This task depends on:
|
|
659
|
+
- P-auth-system (Authentication Project)
|
|
660
|
+
- E-user-management (User Management Epic)
|
|
661
|
+
- F-login-form (Login Form Feature)
|
|
662
|
+
|
|
663
|
+
## Related Tasks
|
|
664
|
+
- T-create-models: Database model creation
|
|
665
|
+
- T-setup-routes: API route setup
|
|
666
|
+
- T-add-validation: Input validation
|
|
667
|
+
|
|
668
|
+
## Status Updates
|
|
669
|
+
Updated T-old-task-id to completed status.
|
|
670
|
+
Blocked by F-payment-integration until resolved.`;
|
|
671
|
+
const taskData = {
|
|
672
|
+
id: "T-refs-test",
|
|
673
|
+
title: "Cross References Test",
|
|
674
|
+
body: contentWithRefs,
|
|
675
|
+
};
|
|
676
|
+
await (0, utils_1.createObjectFile)(testEnv.projectRoot, "task", "T-refs-test", (0, utils_1.createObjectContent)(taskData));
|
|
677
|
+
// Update old task reference
|
|
678
|
+
const result = await client.callTool("replace_object_body_regex", {
|
|
679
|
+
id: "T-refs-test",
|
|
680
|
+
regex: "T-old-task-id",
|
|
681
|
+
replacement: "T-new-task-id",
|
|
682
|
+
});
|
|
683
|
+
const response = (0, utils_1.parseReplaceObjectBodyRegexResponse)(result.content[0].text);
|
|
684
|
+
expect(response.success).toBe(true);
|
|
685
|
+
const file = await (0, utils_1.readObjectFile)(testEnv.projectRoot, "t/open/T-refs-test.md");
|
|
686
|
+
expect(file.body).toContain("T-new-task-id");
|
|
687
|
+
expect(file.body).not.toContain("T-old-task-id");
|
|
688
|
+
expect(file.body).toContain("P-auth-system");
|
|
689
|
+
expect(file.body).toContain("F-payment-integration");
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
//# sourceMappingURL=replaceObjectBodyRegex.e2e.test.js.map
|