fix(tags): Clean up rogue created properties and fix taskCount calculation
- Enhanced writeJSON to automatically filter rogue created/description properties from tag objects - Fixed tags command error by making taskCount calculation dynamic instead of hardcoded - Cleaned up existing rogue created property in master tag through forced write operation - All created properties now properly located in metadata objects only - Tags command working perfectly with proper task count display - Data integrity maintained with automatic cleanup during write operations
This commit is contained in:
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()}`,
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user