@schnick371/devsteps-shared 0.0.1 → 0.5.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 +66 -7
- package/dist/core/add.d.ts +23 -0
- package/dist/core/add.d.ts.map +1 -0
- package/dist/core/add.js +102 -0
- package/dist/core/add.js.map +1 -0
- package/dist/core/archive.d.ts +24 -0
- package/dist/core/archive.d.ts.map +1 -0
- package/dist/core/archive.js +109 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/bulk-update.d.ts +34 -0
- package/dist/core/bulk-update.d.ts.map +1 -0
- package/dist/core/bulk-update.js +141 -0
- package/dist/core/bulk-update.js.map +1 -0
- package/dist/core/context.d.ts +54 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +198 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/get.d.ts +10 -0
- package/dist/core/get.d.ts.map +1 -0
- package/dist/core/get.js +28 -0
- package/dist/core/get.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/list.d.ts +19 -0
- package/dist/core/list.d.ts.map +1 -0
- package/dist/core/list.js +64 -0
- package/dist/core/list.js.map +1 -0
- package/dist/core/update.d.ts +23 -0
- package/dist/core/update.d.ts.map +1 -0
- package/dist/core/update.js +118 -0
- package/dist/core/update.js.map +1 -0
- package/dist/core/validation.d.ts +28 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +205 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/index.d.ts +286 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +200 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/project.d.ts +134 -0
- package/dist/schemas/project.d.ts.map +1 -0
- package/dist/schemas/project.js +54 -0
- package/dist/schemas/project.js.map +1 -0
- package/dist/schemas/relationships.d.ts +30 -0
- package/dist/schemas/relationships.d.ts.map +1 -0
- package/dist/schemas/relationships.js +41 -0
- package/dist/schemas/relationships.js.map +1 -0
- package/dist/types/commands.d.ts +92 -0
- package/dist/types/commands.d.ts.map +1 -0
- package/dist/types/commands.js +14 -0
- package/dist/types/commands.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/cache.d.ts +80 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +169 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/index.d.ts +72 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +148 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +48 -15
- package/src/core/add.js.map +1 -0
- package/src/core/add.ts +145 -0
- package/src/core/archive.js.map +1 -0
- package/src/core/archive.ts +153 -0
- package/src/core/bulk-update.js.map +1 -0
- package/src/core/bulk-update.ts +180 -0
- package/src/core/context.js.map +1 -0
- package/src/core/context.ts +269 -0
- package/src/core/get.js.map +1 -0
- package/src/core/get.ts +39 -0
- package/src/core/index.js.map +1 -0
- package/src/core/index.ts +26 -0
- package/src/core/list.js.map +1 -0
- package/src/core/list.ts +96 -0
- package/src/core/update.js.map +1 -0
- package/src/core/update.ts +154 -0
- package/src/core/validation.ts +252 -0
- package/src/index.js +21 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +4 -0
- package/src/schemas/index.js.map +1 -0
- package/src/schemas/index.ts +226 -0
- package/src/schemas/project.js.map +1 -0
- package/src/schemas/project.ts +73 -0
- package/src/schemas/relationships.ts +48 -0
- package/src/types/commands.js.map +1 -0
- package/src/types/commands.ts +116 -0
- package/src/types/index.js.map +1 -0
- package/src/types/index.ts +13 -0
- package/src/utils/cache.js.map +1 -0
- package/src/utils/cache.ts +200 -0
- package/src/utils/index.js.map +1 -0
- package/src/utils/index.ts +170 -0
- package/index.js +0 -6
package/src/core/add.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import type {
|
|
4
|
+
DevCrumbsConfig,
|
|
5
|
+
DevCrumbsIndex,
|
|
6
|
+
EisenhowerQuadrant,
|
|
7
|
+
ItemMetadata,
|
|
8
|
+
ItemType,
|
|
9
|
+
Priority,
|
|
10
|
+
} from '../schemas/index.js';
|
|
11
|
+
import { TYPE_TO_DIRECTORY, generateItemId, getCurrentTimestamp } from '../utils/index.js';
|
|
12
|
+
|
|
13
|
+
export interface AddItemArgs {
|
|
14
|
+
type: ItemType;
|
|
15
|
+
title: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
category?: string;
|
|
18
|
+
priority?: Priority;
|
|
19
|
+
tags?: string[];
|
|
20
|
+
affected_paths?: string[];
|
|
21
|
+
assignee?: string;
|
|
22
|
+
eisenhower?: EisenhowerQuadrant;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AddItemResult {
|
|
26
|
+
itemId: string;
|
|
27
|
+
metadata: ItemMetadata;
|
|
28
|
+
config: DevCrumbsConfig;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Core business logic for adding a new item to devcrumbs
|
|
33
|
+
* Pure function that handles all file I/O and validation
|
|
34
|
+
*/
|
|
35
|
+
export async function addItem(devcrumbsDir: string, args: AddItemArgs): Promise<AddItemResult> {
|
|
36
|
+
// Check if initialized
|
|
37
|
+
if (!existsSync(devcrumbsDir)) {
|
|
38
|
+
throw new Error('Project not initialized. Run devcrumbs-init first.');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Read config and index
|
|
42
|
+
const configPath = join(devcrumbsDir, 'config.json');
|
|
43
|
+
const indexPath = join(devcrumbsDir, 'index.json');
|
|
44
|
+
|
|
45
|
+
const config: DevCrumbsConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
46
|
+
const index: DevCrumbsIndex = JSON.parse(readFileSync(indexPath, 'utf-8'));
|
|
47
|
+
|
|
48
|
+
// Migration: Initialize counters if missing (for legacy projects)
|
|
49
|
+
if (!index.counters) {
|
|
50
|
+
index.counters = {};
|
|
51
|
+
// Calculate existing max IDs per type
|
|
52
|
+
for (const item of index.items) {
|
|
53
|
+
const match = item.id.match(/-(\d+)$/);
|
|
54
|
+
if (match) {
|
|
55
|
+
const num = Number.parseInt(match[1], 10);
|
|
56
|
+
index.counters[item.type] = Math.max(index.counters[item.type] || 0, num);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Generate ID using global counter
|
|
62
|
+
const typeFolder = TYPE_TO_DIRECTORY[args.type];
|
|
63
|
+
const counter = (index.counters[args.type] || 0) + 1;
|
|
64
|
+
const itemId = generateItemId(args.type, counter);
|
|
65
|
+
|
|
66
|
+
// Check for duplicate ID (data integrity validation)
|
|
67
|
+
const existingIds = index.items.map((i) => i.id);
|
|
68
|
+
if (existingIds.includes(itemId)) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`Duplicate ID detected: ${itemId}. Index may be corrupted or counter was reset. Please check .devcrumbs/index.json`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Increment counter
|
|
75
|
+
index.counters[args.type] = counter;
|
|
76
|
+
|
|
77
|
+
// Create metadata
|
|
78
|
+
const now = getCurrentTimestamp();
|
|
79
|
+
const metadata: ItemMetadata = {
|
|
80
|
+
id: itemId,
|
|
81
|
+
type: args.type,
|
|
82
|
+
category: args.category || 'general',
|
|
83
|
+
title: args.title,
|
|
84
|
+
status: 'draft',
|
|
85
|
+
priority: args.priority || 'medium',
|
|
86
|
+
eisenhower: args.eisenhower,
|
|
87
|
+
created: now,
|
|
88
|
+
updated: now,
|
|
89
|
+
author: args.assignee || config.settings.default_author,
|
|
90
|
+
assignee: args.assignee,
|
|
91
|
+
affected_paths: args.affected_paths || [],
|
|
92
|
+
linked_items: {
|
|
93
|
+
implements: [],
|
|
94
|
+
'implemented-by': [],
|
|
95
|
+
'tested-by': [],
|
|
96
|
+
tests: [],
|
|
97
|
+
blocks: [],
|
|
98
|
+
'blocked-by': [],
|
|
99
|
+
'relates-to': [],
|
|
100
|
+
'depends-on': [],
|
|
101
|
+
'required-by': [],
|
|
102
|
+
supersedes: [],
|
|
103
|
+
'superseded-by': [],
|
|
104
|
+
},
|
|
105
|
+
tags: args.tags || [],
|
|
106
|
+
commits: [],
|
|
107
|
+
metadata: {},
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// Save metadata
|
|
111
|
+
const itemDir = join(devcrumbsDir, typeFolder);
|
|
112
|
+
const metadataPath = join(itemDir, `${itemId}.json`);
|
|
113
|
+
const descriptionPath = join(itemDir, `${itemId}.md`);
|
|
114
|
+
|
|
115
|
+
writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
116
|
+
|
|
117
|
+
// Save description
|
|
118
|
+
const description =
|
|
119
|
+
args.description || `# ${args.title}\n\n<!-- Add detailed description here -->\n`;
|
|
120
|
+
writeFileSync(descriptionPath, description);
|
|
121
|
+
|
|
122
|
+
// Update index
|
|
123
|
+
index.items.push({
|
|
124
|
+
id: itemId,
|
|
125
|
+
type: args.type,
|
|
126
|
+
title: args.title,
|
|
127
|
+
status: 'draft',
|
|
128
|
+
priority: args.priority || 'medium',
|
|
129
|
+
updated: now,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
index.last_updated = now;
|
|
133
|
+
index.stats = index.stats || { total: 0, by_type: {}, by_status: {} };
|
|
134
|
+
index.stats.total = index.items.length;
|
|
135
|
+
index.stats.by_type[args.type] = (index.stats.by_type[args.type] || 0) + 1;
|
|
136
|
+
index.stats.by_status.draft = (index.stats.by_status.draft || 0) + 1;
|
|
137
|
+
|
|
138
|
+
writeFileSync(indexPath, JSON.stringify(index, null, 2));
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
itemId,
|
|
142
|
+
metadata,
|
|
143
|
+
config,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import type { DevCrumbsIndex, ItemStatus } from '../schemas/index.js';
|
|
4
|
+
import { TYPE_TO_DIRECTORY, getCurrentTimestamp, parseItemId } from '../utils/index.js';
|
|
5
|
+
|
|
6
|
+
export interface ArchiveItemResult {
|
|
7
|
+
itemId: string;
|
|
8
|
+
archivedAt: string;
|
|
9
|
+
originalStatus: ItemStatus;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Core business logic for archiving a single item
|
|
14
|
+
*/
|
|
15
|
+
export async function archiveItem(devcrumbsDir: string, itemId: string): Promise<ArchiveItemResult> {
|
|
16
|
+
if (!existsSync(devcrumbsDir)) {
|
|
17
|
+
throw new Error('Project not initialized. Run devcrumbs-init first.');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const parsed = parseItemId(itemId);
|
|
21
|
+
if (!parsed) {
|
|
22
|
+
throw new Error(`Invalid item ID: ${itemId}`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const typeFolder = TYPE_TO_DIRECTORY[parsed.type];
|
|
26
|
+
const metadataPath = join(devcrumbsDir, typeFolder, `${itemId}.json`);
|
|
27
|
+
const descriptionPath = join(devcrumbsDir, typeFolder, `${itemId}.md`);
|
|
28
|
+
|
|
29
|
+
if (!existsSync(metadataPath)) {
|
|
30
|
+
throw new Error(`Item not found: ${itemId}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Read metadata
|
|
34
|
+
const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
|
|
35
|
+
const originalStatus = metadata.status;
|
|
36
|
+
|
|
37
|
+
// Create archive directory if not exists
|
|
38
|
+
const archiveDir = join(devcrumbsDir, 'archive', typeFolder);
|
|
39
|
+
mkdirSync(archiveDir, { recursive: true });
|
|
40
|
+
|
|
41
|
+
// Move files to archive
|
|
42
|
+
const archiveMetadataPath = join(archiveDir, `${itemId}.json`);
|
|
43
|
+
const archiveDescriptionPath = join(archiveDir, `${itemId}.md`);
|
|
44
|
+
|
|
45
|
+
renameSync(metadataPath, archiveMetadataPath);
|
|
46
|
+
if (existsSync(descriptionPath)) {
|
|
47
|
+
renameSync(descriptionPath, archiveDescriptionPath);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Update index
|
|
51
|
+
const indexPath = join(devcrumbsDir, 'index.json');
|
|
52
|
+
const index: DevCrumbsIndex = JSON.parse(readFileSync(indexPath, 'utf-8'));
|
|
53
|
+
|
|
54
|
+
// Remove from items
|
|
55
|
+
const itemIndex = index.items.findIndex((i) => i.id === itemId);
|
|
56
|
+
if (itemIndex !== -1) {
|
|
57
|
+
index.items.splice(itemIndex, 1);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Add to archived_items
|
|
61
|
+
const archivedAt = getCurrentTimestamp();
|
|
62
|
+
index.archived_items = index.archived_items || [];
|
|
63
|
+
index.archived_items.push({
|
|
64
|
+
id: itemId,
|
|
65
|
+
type: parsed.type,
|
|
66
|
+
title: metadata.title,
|
|
67
|
+
archived_at: archivedAt,
|
|
68
|
+
original_status: originalStatus,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Update stats
|
|
72
|
+
if (index.stats) {
|
|
73
|
+
index.stats.total = index.items.length;
|
|
74
|
+
index.stats.by_status[originalStatus] = Math.max(
|
|
75
|
+
(index.stats.by_status[originalStatus] || 1) - 1,
|
|
76
|
+
0
|
|
77
|
+
);
|
|
78
|
+
index.stats.archived = (index.stats.archived || 0) + 1;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
index.last_updated = archivedAt;
|
|
82
|
+
writeFileSync(indexPath, JSON.stringify(index, null, 2));
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
itemId,
|
|
86
|
+
archivedAt,
|
|
87
|
+
originalStatus,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface PurgeItemsArgs {
|
|
92
|
+
status?: ItemStatus[];
|
|
93
|
+
type?: string;
|
|
94
|
+
olderThan?: Date;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface PurgeItemsResult {
|
|
98
|
+
count: number;
|
|
99
|
+
archivedIds: string[];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Core business logic for bulk archiving items
|
|
104
|
+
*/
|
|
105
|
+
export async function purgeItems(
|
|
106
|
+
devcrumbsDir: string,
|
|
107
|
+
args: PurgeItemsArgs = {}
|
|
108
|
+
): Promise<PurgeItemsResult> {
|
|
109
|
+
if (!existsSync(devcrumbsDir)) {
|
|
110
|
+
throw new Error('Project not initialized. Run devcrumbs-init first.');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const indexPath = join(devcrumbsDir, 'index.json');
|
|
114
|
+
const index: DevCrumbsIndex = JSON.parse(readFileSync(indexPath, 'utf-8'));
|
|
115
|
+
|
|
116
|
+
// Find items to archive
|
|
117
|
+
let itemsToArchive = [...index.items];
|
|
118
|
+
|
|
119
|
+
// Filter by status (default: done, cancelled)
|
|
120
|
+
const statusFilter = args.status || ['done', 'cancelled'];
|
|
121
|
+
itemsToArchive = itemsToArchive.filter((i) => statusFilter.includes(i.status));
|
|
122
|
+
|
|
123
|
+
// Filter by type
|
|
124
|
+
if (args.type) {
|
|
125
|
+
itemsToArchive = itemsToArchive.filter((i) => i.type === args.type);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Filter by date
|
|
129
|
+
if (args.olderThan) {
|
|
130
|
+
const cutoffDate = args.olderThan;
|
|
131
|
+
itemsToArchive = itemsToArchive.filter((i) => {
|
|
132
|
+
const updated = new Date(i.updated);
|
|
133
|
+
return updated < cutoffDate;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Archive each item
|
|
138
|
+
const archivedIds: string[] = [];
|
|
139
|
+
for (const item of itemsToArchive) {
|
|
140
|
+
try {
|
|
141
|
+
await archiveItem(devcrumbsDir, item.id);
|
|
142
|
+
archivedIds.push(item.id);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
// Continue with next item on error
|
|
145
|
+
console.error(`Failed to archive ${item.id}:`, error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
count: archivedIds.length,
|
|
151
|
+
archivedIds,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-update.js","sourceRoot":"","sources":["bulk-update.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,0CA2BC;AASD,kCA4DC;AASD,wCAuDC;AAnLD,qCAAkE;AAClE,yCAAiC;AAEjC,gDAAwD;AACxD,2CAAyC;AAQzC;;;;;;GAMG;AACI,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,OAAiB,EACjB,OAA8B;IAE9B,MAAM,MAAM,GAAqB;QAC/B,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,OAAO,CAAC,MAAM;KACtB,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,IAAA,sBAAU,EAAC,SAAS,EAAE;gBAC1B,EAAE;gBACF,GAAG,OAAO;aACX,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBACjB,EAAE;gBACF,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,WAAW,CAC/B,SAAiB,EACjB,OAAiB,EACjB,SAAmB;IAEnB,MAAM,MAAM,GAAqB;QAC/B,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,OAAO,CAAC,MAAM;KACtB,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,kDAAO,mBAAmB,IAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtE,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI;gBAC7B,MAAM,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC;aAC/D,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,YAAY,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAC3D,IAAI,CAAC,IAAA,oBAAU,EAAC,YAAY,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,QAAQ,GAAiB,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;YAE/E,kCAAkC;YAClC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC5C,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;gBAC5B,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;YAED,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACzC,QAAQ,CAAC,OAAO,GAAG,IAAA,8BAAmB,GAAE,CAAC;YAEzC,IAAA,uBAAa,EAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAE/D,eAAe;YACf,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5E,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;gBACnB,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACpD,CAAC;YACD,KAAK,CAAC,YAAY,GAAG,IAAA,8BAAmB,GAAE,CAAC;YAC3C,IAAA,uBAAa,EAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAEzD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBACjB,EAAE;gBACF,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,cAAc,CAClC,SAAiB,EACjB,OAAiB,EACjB,YAAsB;IAEtB,MAAM,MAAM,GAAqB;QAC/B,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,OAAO,CAAC,MAAM;KACtB,CAAC;IAEF,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,kDAAO,mBAAmB,IAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtE,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI;gBAC7B,MAAM,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC;aAC/D,CAAC,CAAC,CAAC;YAEJ,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;YAC5C,CAAC;YAED,MAAM,YAAY,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAC3D,IAAI,CAAC,IAAA,oBAAU,EAAC,YAAY,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,QAAQ,GAAiB,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;YAE/E,cAAc;YACd,QAAQ,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3E,QAAQ,CAAC,OAAO,GAAG,IAAA,8BAAmB,GAAE,CAAC;YAEzC,IAAA,uBAAa,EAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAE/D,eAAe;YACf,MAAM,SAAS,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3D,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;YAC5E,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;gBACnB,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;YACpD,CAAC;YACD,KAAK,CAAC,YAAY,GAAG,IAAA,8BAAmB,GAAE,CAAC;YAC3C,IAAA,uBAAa,EAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAEzD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBACjB,EAAE;gBACF,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import type { ItemMetadata, ItemStatus } from '../schemas/index.js';
|
|
4
|
+
import { getCurrentTimestamp } from '../utils/index.js';
|
|
5
|
+
import { updateItem } from './update.js';
|
|
6
|
+
|
|
7
|
+
export interface BulkUpdateResult {
|
|
8
|
+
success: string[];
|
|
9
|
+
failed: Array<{ id: string; error: string }>;
|
|
10
|
+
total: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Bulk update multiple items at once
|
|
15
|
+
* @param devcrumbsDir Path to .devcrumbs directory
|
|
16
|
+
* @param itemIds Array of item IDs to update
|
|
17
|
+
* @param updates Partial item metadata to apply to all items
|
|
18
|
+
* @returns Result with success and failure lists
|
|
19
|
+
*/
|
|
20
|
+
export async function bulkUpdateItems(
|
|
21
|
+
devcrumbsDir: string,
|
|
22
|
+
itemIds: string[],
|
|
23
|
+
updates: Partial<ItemMetadata>
|
|
24
|
+
): Promise<BulkUpdateResult> {
|
|
25
|
+
const result: BulkUpdateResult = {
|
|
26
|
+
success: [],
|
|
27
|
+
failed: [],
|
|
28
|
+
total: itemIds.length,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
for (const id of itemIds) {
|
|
32
|
+
try {
|
|
33
|
+
await updateItem(devcrumbsDir, {
|
|
34
|
+
id,
|
|
35
|
+
...updates,
|
|
36
|
+
});
|
|
37
|
+
result.success.push(id);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
result.failed.push({
|
|
40
|
+
id,
|
|
41
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Bulk add tags to multiple items
|
|
51
|
+
* @param devcrumbsDir Path to .devcrumbs directory
|
|
52
|
+
* @param itemIds Array of item IDs
|
|
53
|
+
* @param tagsToAdd Tags to add
|
|
54
|
+
* @returns Result with success and failure lists
|
|
55
|
+
*/
|
|
56
|
+
export async function bulkAddTags(
|
|
57
|
+
devcrumbsDir: string,
|
|
58
|
+
itemIds: string[],
|
|
59
|
+
tagsToAdd: string[]
|
|
60
|
+
): Promise<BulkUpdateResult> {
|
|
61
|
+
const result: BulkUpdateResult = {
|
|
62
|
+
success: [],
|
|
63
|
+
failed: [],
|
|
64
|
+
total: itemIds.length,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
for (const id of itemIds) {
|
|
68
|
+
try {
|
|
69
|
+
const { type, folder } = await import('../utils/index.js').then((m) => ({
|
|
70
|
+
type: m.parseItemId(id)?.type,
|
|
71
|
+
folder: m.TYPE_TO_DIRECTORY[m.parseItemId(id)?.type || 'task'],
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
if (!type) {
|
|
75
|
+
throw new Error(`Invalid item ID: ${id}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const metadataPath = join(devcrumbsDir, folder, `${id}.json`);
|
|
79
|
+
if (!existsSync(metadataPath)) {
|
|
80
|
+
throw new Error(`Item ${id} not found`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const metadata: ItemMetadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
|
|
84
|
+
|
|
85
|
+
// Add new tags (avoid duplicates)
|
|
86
|
+
const existingTags = new Set(metadata.tags);
|
|
87
|
+
for (const tag of tagsToAdd) {
|
|
88
|
+
existingTags.add(tag);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
metadata.tags = Array.from(existingTags);
|
|
92
|
+
metadata.updated = getCurrentTimestamp();
|
|
93
|
+
|
|
94
|
+
writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
95
|
+
|
|
96
|
+
// Update index
|
|
97
|
+
const indexPath = join(devcrumbsDir, 'index.json');
|
|
98
|
+
const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
|
|
99
|
+
const itemIndex = index.items.findIndex((i: { id: string }) => i.id === id);
|
|
100
|
+
if (itemIndex >= 0) {
|
|
101
|
+
index.items[itemIndex].updated = metadata.updated;
|
|
102
|
+
}
|
|
103
|
+
index.last_updated = getCurrentTimestamp();
|
|
104
|
+
writeFileSync(indexPath, JSON.stringify(index, null, 2));
|
|
105
|
+
|
|
106
|
+
result.success.push(id);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
result.failed.push({
|
|
109
|
+
id,
|
|
110
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Bulk remove tags from multiple items
|
|
120
|
+
* @param devcrumbsDir Path to .devcrumbs directory
|
|
121
|
+
* @param itemIds Array of item IDs
|
|
122
|
+
* @param tagsToRemove Tags to remove
|
|
123
|
+
* @returns Result with success and failure lists
|
|
124
|
+
*/
|
|
125
|
+
export async function bulkRemoveTags(
|
|
126
|
+
devcrumbsDir: string,
|
|
127
|
+
itemIds: string[],
|
|
128
|
+
tagsToRemove: string[]
|
|
129
|
+
): Promise<BulkUpdateResult> {
|
|
130
|
+
const result: BulkUpdateResult = {
|
|
131
|
+
success: [],
|
|
132
|
+
failed: [],
|
|
133
|
+
total: itemIds.length,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
for (const id of itemIds) {
|
|
137
|
+
try {
|
|
138
|
+
const { type, folder } = await import('../utils/index.js').then((m) => ({
|
|
139
|
+
type: m.parseItemId(id)?.type,
|
|
140
|
+
folder: m.TYPE_TO_DIRECTORY[m.parseItemId(id)?.type || 'task'],
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
if (!type) {
|
|
144
|
+
throw new Error(`Invalid item ID: ${id}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const metadataPath = join(devcrumbsDir, folder, `${id}.json`);
|
|
148
|
+
if (!existsSync(metadataPath)) {
|
|
149
|
+
throw new Error(`Item ${id} not found`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const metadata: ItemMetadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
|
|
153
|
+
|
|
154
|
+
// Remove tags
|
|
155
|
+
metadata.tags = metadata.tags.filter((tag) => !tagsToRemove.includes(tag));
|
|
156
|
+
metadata.updated = getCurrentTimestamp();
|
|
157
|
+
|
|
158
|
+
writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
|
|
159
|
+
|
|
160
|
+
// Update index
|
|
161
|
+
const indexPath = join(devcrumbsDir, 'index.json');
|
|
162
|
+
const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
|
|
163
|
+
const itemIndex = index.items.findIndex((i: { id: string }) => i.id === id);
|
|
164
|
+
if (itemIndex >= 0) {
|
|
165
|
+
index.items[itemIndex].updated = metadata.updated;
|
|
166
|
+
}
|
|
167
|
+
index.last_updated = getCurrentTimestamp();
|
|
168
|
+
writeFileSync(indexPath, JSON.stringify(index, null, 2));
|
|
169
|
+
|
|
170
|
+
result.success.push(id);
|
|
171
|
+
} catch (error) {
|
|
172
|
+
result.failed.push({
|
|
173
|
+
id,
|
|
174
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["context.ts"],"names":[],"mappings":"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"}
|