diff --git a/.taskmaster/tasks/tasks.json b/.taskmaster/tasks/tasks.json index ad0d23e5..e1c7b7aa 100644 --- a/.taskmaster/tasks/tasks.json +++ b/.taskmaster/tasks/tasks.json @@ -6724,9 +6724,18 @@ "subtasks": [] } ], - "description": "Tasks live here by default", - "created": "2025-06-12T21:50:50.489Z", - "taskCount": 101 + "metadata": { + "created": "2025-06-13T02:26:02.431Z", + "updated": "2025-06-13T02:26:02.431Z", + "description": "Tasks for master context" + } }, - "tag": "master" + "test": { + "tasks": [], + "metadata": { + "created": "2025-06-13T02:36:12.840Z", + "updated": "2025-06-13T02:36:12.840Z", + "description": "Tag created on 6/12/2025" + } + } } \ No newline at end of file diff --git a/scripts/modules/task-manager/tag-management.js b/scripts/modules/task-manager/tag-management.js index 32b82e89..7f3de586 100644 --- a/scripts/modules/task-manager/tag-management.js +++ b/scripts/modules/task-manager/tag-management.js @@ -78,8 +78,32 @@ async function createTag( throw new Error(`Could not read tasks file at ${tasksPath}`); } - // Use raw tagged data for tag operations - const rawData = data._rawTaggedData || data; + // Use raw tagged data for tag operations - ensure we get the actual tagged structure + let rawData; + if (data._rawTaggedData) { + // If we have _rawTaggedData, use it (this is the clean tagged structure) + rawData = data._rawTaggedData; + } else if (data.tasks && !data.master) { + // This is legacy format - create a master tag structure + rawData = { + master: { + tasks: data.tasks, + metadata: data.metadata || { + created: new Date().toISOString(), + updated: new Date().toISOString(), + description: 'Tasks live here by default' + } + } + }; + } else { + // This is already in tagged format, use it directly but exclude internal fields + rawData = {}; + for (const [key, value] of Object.entries(data)) { + if (key !== '_rawTaggedData' && key !== 'tag') { + rawData[key] = value; + } + } + } // Check if tag already exists if (rawData[tagName]) { @@ -106,6 +130,7 @@ async function createTag( tasks: [...sourceTasks], // Create a copy of the tasks array metadata: { created: new Date().toISOString(), + updated: new Date().toISOString(), description: description || `Tag created on ${new Date().toLocaleDateString()}` } @@ -227,8 +252,32 @@ async function deleteTag( throw new Error(`Could not read tasks file at ${tasksPath}`); } - // Use raw tagged data for tag operations - const rawData = data._rawTaggedData || data; + // Use raw tagged data for tag operations - ensure we get the actual tagged structure + let rawData; + if (data._rawTaggedData) { + // If we have _rawTaggedData, use it (this is the clean tagged structure) + rawData = data._rawTaggedData; + } else if (data.tasks && !data.master) { + // This is legacy format - create a master tag structure + rawData = { + master: { + tasks: data.tasks, + metadata: data.metadata || { + created: new Date().toISOString(), + updated: new Date().toISOString(), + description: 'Tasks live here by default' + } + } + }; + } else { + // This is already in tagged format, use it directly but exclude internal fields + rawData = {}; + for (const [key, value] of Object.entries(data)) { + if (key !== '_rawTaggedData' && key !== 'tag') { + rawData[key] = value; + } + } + } // Check if tag exists if (!rawData[tagName]) { @@ -979,6 +1028,7 @@ async function copyTag( tasks: JSON.parse(JSON.stringify(sourceTasks)), // Deep copy tasks metadata: { created: new Date().toISOString(), + updated: new Date().toISOString(), description: description || `Copy of "${sourceName}" created on ${new Date().toLocaleDateString()}`, diff --git a/scripts/modules/utils.js b/scripts/modules/utils.js index d9d598bf..81b0e9b8 100644 --- a/scripts/modules/utils.js +++ b/scripts/modules/utils.js @@ -587,14 +587,44 @@ function writeJSON(filepath, data) { // Clean the data before writing - remove internal properties that should not be persisted let cleanData = data; - if ( - data && - typeof data === 'object' && - (data._rawTaggedData !== undefined || data.tag !== undefined) - ) { - // Create a clean copy without internal properties using destructuring - const { _rawTaggedData, tag, ...cleanedData } = data; - cleanData = cleanedData; + if (data && typeof data === 'object') { + // First, filter out top-level internal properties + if (data._rawTaggedData !== undefined || data.tag !== undefined) { + const { _rawTaggedData, tag, ...cleanedData } = data; + cleanData = cleanedData; + } + + // For tagged task data, also clean up any rogue properties in tag objects + if ( + filepath.includes('tasks.json') && + cleanData && + typeof cleanData === 'object' + ) { + const finalCleanData = {}; + for (const [key, value] of Object.entries(cleanData)) { + if ( + value && + typeof value === 'object' && + Array.isArray(value.tasks) + ) { + // This is a tag object - clean up any rogue root-level properties + const { created, description, ...cleanTagData } = value; + + // Only keep the description if there's no metadata.description + if ( + description && + (!cleanTagData.metadata || !cleanTagData.metadata.description) + ) { + cleanTagData.description = description; + } + + finalCleanData[key] = cleanTagData; + } else { + finalCleanData[key] = value; + } + } + cleanData = finalCleanData; + } } fs.writeFileSync(filepath, JSON.stringify(cleanData, null, 2), 'utf8');