@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.
Files changed (104) hide show
  1. package/README.md +66 -7
  2. package/dist/core/add.d.ts +23 -0
  3. package/dist/core/add.d.ts.map +1 -0
  4. package/dist/core/add.js +102 -0
  5. package/dist/core/add.js.map +1 -0
  6. package/dist/core/archive.d.ts +24 -0
  7. package/dist/core/archive.d.ts.map +1 -0
  8. package/dist/core/archive.js +109 -0
  9. package/dist/core/archive.js.map +1 -0
  10. package/dist/core/bulk-update.d.ts +34 -0
  11. package/dist/core/bulk-update.d.ts.map +1 -0
  12. package/dist/core/bulk-update.js +141 -0
  13. package/dist/core/bulk-update.js.map +1 -0
  14. package/dist/core/context.d.ts +54 -0
  15. package/dist/core/context.d.ts.map +1 -0
  16. package/dist/core/context.js +198 -0
  17. package/dist/core/context.js.map +1 -0
  18. package/dist/core/get.d.ts +10 -0
  19. package/dist/core/get.d.ts.map +1 -0
  20. package/dist/core/get.js +28 -0
  21. package/dist/core/get.js.map +1 -0
  22. package/dist/core/index.d.ts +9 -0
  23. package/dist/core/index.d.ts.map +1 -0
  24. package/dist/core/index.js +9 -0
  25. package/dist/core/index.js.map +1 -0
  26. package/dist/core/list.d.ts +19 -0
  27. package/dist/core/list.d.ts.map +1 -0
  28. package/dist/core/list.js +64 -0
  29. package/dist/core/list.js.map +1 -0
  30. package/dist/core/update.d.ts +23 -0
  31. package/dist/core/update.d.ts.map +1 -0
  32. package/dist/core/update.js +118 -0
  33. package/dist/core/update.js.map +1 -0
  34. package/dist/core/validation.d.ts +28 -0
  35. package/dist/core/validation.d.ts.map +1 -0
  36. package/dist/core/validation.js +205 -0
  37. package/dist/core/validation.js.map +1 -0
  38. package/dist/index.d.ts +5 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +5 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/schemas/index.d.ts +286 -0
  43. package/dist/schemas/index.d.ts.map +1 -0
  44. package/dist/schemas/index.js +200 -0
  45. package/dist/schemas/index.js.map +1 -0
  46. package/dist/schemas/project.d.ts +134 -0
  47. package/dist/schemas/project.d.ts.map +1 -0
  48. package/dist/schemas/project.js +54 -0
  49. package/dist/schemas/project.js.map +1 -0
  50. package/dist/schemas/relationships.d.ts +30 -0
  51. package/dist/schemas/relationships.d.ts.map +1 -0
  52. package/dist/schemas/relationships.js +41 -0
  53. package/dist/schemas/relationships.js.map +1 -0
  54. package/dist/types/commands.d.ts +92 -0
  55. package/dist/types/commands.d.ts.map +1 -0
  56. package/dist/types/commands.js +14 -0
  57. package/dist/types/commands.js.map +1 -0
  58. package/dist/types/index.d.ts +3 -0
  59. package/dist/types/index.d.ts.map +1 -0
  60. package/dist/types/index.js +2 -0
  61. package/dist/types/index.js.map +1 -0
  62. package/dist/utils/cache.d.ts +80 -0
  63. package/dist/utils/cache.d.ts.map +1 -0
  64. package/dist/utils/cache.js +169 -0
  65. package/dist/utils/cache.js.map +1 -0
  66. package/dist/utils/index.d.ts +72 -0
  67. package/dist/utils/index.d.ts.map +1 -0
  68. package/dist/utils/index.js +148 -0
  69. package/dist/utils/index.js.map +1 -0
  70. package/package.json +48 -15
  71. package/src/core/add.js.map +1 -0
  72. package/src/core/add.ts +145 -0
  73. package/src/core/archive.js.map +1 -0
  74. package/src/core/archive.ts +153 -0
  75. package/src/core/bulk-update.js.map +1 -0
  76. package/src/core/bulk-update.ts +180 -0
  77. package/src/core/context.js.map +1 -0
  78. package/src/core/context.ts +269 -0
  79. package/src/core/get.js.map +1 -0
  80. package/src/core/get.ts +39 -0
  81. package/src/core/index.js.map +1 -0
  82. package/src/core/index.ts +26 -0
  83. package/src/core/list.js.map +1 -0
  84. package/src/core/list.ts +96 -0
  85. package/src/core/update.js.map +1 -0
  86. package/src/core/update.ts +154 -0
  87. package/src/core/validation.ts +252 -0
  88. package/src/index.js +21 -0
  89. package/src/index.js.map +1 -0
  90. package/src/index.ts +4 -0
  91. package/src/schemas/index.js.map +1 -0
  92. package/src/schemas/index.ts +226 -0
  93. package/src/schemas/project.js.map +1 -0
  94. package/src/schemas/project.ts +73 -0
  95. package/src/schemas/relationships.ts +48 -0
  96. package/src/types/commands.js.map +1 -0
  97. package/src/types/commands.ts +116 -0
  98. package/src/types/index.js.map +1 -0
  99. package/src/types/index.ts +13 -0
  100. package/src/utils/cache.js.map +1 -0
  101. package/src/utils/cache.ts +200 -0
  102. package/src/utils/index.js.map +1 -0
  103. package/src/utils/index.ts +170 -0
  104. package/index.js +0 -6
@@ -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":"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"}
@@ -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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"}