@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
package/README.md CHANGED
@@ -1,15 +1,74 @@
1
1
  # @schnick371/devsteps-shared
2
2
 
3
- **Status:** Package name reserved for the DevSteps project.
3
+ > Never Code Alone. Shared utilities and types for DevSteps packages.
4
4
 
5
- ## About DevSteps
5
+ ## Overview
6
6
 
7
- DevSteps - Never Code Alone. AI-powered task tracking and development workflow management.
7
+ Core package providing shared types, schemas, and utilities used across all DevSteps packages (CLI, MCP Server, VS Code Extension).
8
8
 
9
- **Coming Soon:** Shared types, schemas, and utilities for structured software development.
9
+ ## Features
10
10
 
11
- For more information, visit: https://devsteps.dev (coming soon)
11
+ - **TypeScript Types**: Complete type definitions for work items, configurations, and API responses
12
+ - **Zod Schemas**: Runtime validation for all data structures
13
+ - **Core Functions**: File operations, item management, relationship handling
14
+ - **Utilities**: ID parsing, timestamp handling, configuration management
12
15
 
13
- ---
16
+ ## Installation
14
17
 
15
- *This package is currently a placeholder to reserve the name. Full implementation coming soon.*
18
+ ```bash
19
+ npm install @schnick371/devsteps-shared
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ```typescript
25
+ import { addItem, getItem, listItems } from '@schnick371/devsteps-shared';
26
+ import type { ItemType, ItemStatus } from '@schnick371/devsteps-shared';
27
+
28
+ // Add a new work item
29
+ const result = await addItem('/path/to/.devsteps', {
30
+ type: 'task',
31
+ title: 'Implement feature',
32
+ priority: 'high'
33
+ });
34
+
35
+ // Get work item
36
+ const item = await getItem('/path/to/.devsteps', 'TASK-001');
37
+
38
+ // List all items
39
+ const items = await listItems('/path/to/.devsteps');
40
+ ```
41
+
42
+ ## Exports
43
+
44
+ ### Core Functions
45
+ - `addItem()` - Create new work item
46
+ - `getItem()` - Retrieve work item by ID
47
+ - `updateItem()` - Update existing work item
48
+ - `deleteItem()` - Delete work item
49
+ - `listItems()` - List all work items with filters
50
+ - `searchItems()` - Full-text search across items
51
+ - `linkItems()` - Create relationships between items
52
+ - `archiveItem()` - Archive completed items
53
+
54
+ ### Types
55
+ - `ItemType` - Epic, Story, Task, Bug, etc.
56
+ - `ItemStatus` - Draft, In Progress, Done, etc.
57
+ - `Priority` - Critical, High, Medium, Low
58
+ - `Methodology` - Scrum, Waterfall, Hybrid
59
+ - `ItemMetadata` - Complete work item structure
60
+
61
+ ### Schemas
62
+ - `addItemSchema` - Validation for item creation
63
+ - `updateItemSchema` - Validation for updates
64
+ - `linkItemSchema` - Validation for relationships
65
+
66
+ ## Documentation
67
+
68
+ - [DevSteps Documentation](https://devsteps.dev)
69
+ - [GitHub Repository](https://github.com/Schnick371/devsteps)
70
+ - [Issue Tracker](https://github.com/Schnick371/devsteps/issues)
71
+
72
+ ## License
73
+
74
+ Apache-2.0 © Thomas Hertel
@@ -0,0 +1,23 @@
1
+ import type { DevCrumbsConfig, EisenhowerQuadrant, ItemMetadata, ItemType, Priority } from '../schemas/index.js';
2
+ export interface AddItemArgs {
3
+ type: ItemType;
4
+ title: string;
5
+ description?: string;
6
+ category?: string;
7
+ priority?: Priority;
8
+ tags?: string[];
9
+ affected_paths?: string[];
10
+ assignee?: string;
11
+ eisenhower?: EisenhowerQuadrant;
12
+ }
13
+ export interface AddItemResult {
14
+ itemId: string;
15
+ metadata: ItemMetadata;
16
+ config: DevCrumbsConfig;
17
+ }
18
+ /**
19
+ * Core business logic for adding a new item to devcrumbs
20
+ * Pure function that handles all file I/O and validation
21
+ */
22
+ export declare function addItem(devcrumbsDir: string, args: AddItemArgs): Promise<AddItemResult>;
23
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/core/add.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EAEf,kBAAkB,EAClB,YAAY,EACZ,QAAQ,EACR,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CA8G7F"}
@@ -0,0 +1,102 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { TYPE_TO_DIRECTORY, generateItemId, getCurrentTimestamp } from '../utils/index.js';
4
+ /**
5
+ * Core business logic for adding a new item to devcrumbs
6
+ * Pure function that handles all file I/O and validation
7
+ */
8
+ export async function addItem(devcrumbsDir, args) {
9
+ // Check if initialized
10
+ if (!existsSync(devcrumbsDir)) {
11
+ throw new Error('Project not initialized. Run devcrumbs-init first.');
12
+ }
13
+ // Read config and index
14
+ const configPath = join(devcrumbsDir, 'config.json');
15
+ const indexPath = join(devcrumbsDir, 'index.json');
16
+ const config = JSON.parse(readFileSync(configPath, 'utf-8'));
17
+ const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
18
+ // Migration: Initialize counters if missing (for legacy projects)
19
+ if (!index.counters) {
20
+ index.counters = {};
21
+ // Calculate existing max IDs per type
22
+ for (const item of index.items) {
23
+ const match = item.id.match(/-(\d+)$/);
24
+ if (match) {
25
+ const num = Number.parseInt(match[1], 10);
26
+ index.counters[item.type] = Math.max(index.counters[item.type] || 0, num);
27
+ }
28
+ }
29
+ }
30
+ // Generate ID using global counter
31
+ const typeFolder = TYPE_TO_DIRECTORY[args.type];
32
+ const counter = (index.counters[args.type] || 0) + 1;
33
+ const itemId = generateItemId(args.type, counter);
34
+ // Check for duplicate ID (data integrity validation)
35
+ const existingIds = index.items.map((i) => i.id);
36
+ if (existingIds.includes(itemId)) {
37
+ throw new Error(`Duplicate ID detected: ${itemId}. Index may be corrupted or counter was reset. Please check .devcrumbs/index.json`);
38
+ }
39
+ // Increment counter
40
+ index.counters[args.type] = counter;
41
+ // Create metadata
42
+ const now = getCurrentTimestamp();
43
+ const metadata = {
44
+ id: itemId,
45
+ type: args.type,
46
+ category: args.category || 'general',
47
+ title: args.title,
48
+ status: 'draft',
49
+ priority: args.priority || 'medium',
50
+ eisenhower: args.eisenhower,
51
+ created: now,
52
+ updated: now,
53
+ author: args.assignee || config.settings.default_author,
54
+ assignee: args.assignee,
55
+ affected_paths: args.affected_paths || [],
56
+ linked_items: {
57
+ implements: [],
58
+ 'implemented-by': [],
59
+ 'tested-by': [],
60
+ tests: [],
61
+ blocks: [],
62
+ 'blocked-by': [],
63
+ 'relates-to': [],
64
+ 'depends-on': [],
65
+ 'required-by': [],
66
+ supersedes: [],
67
+ 'superseded-by': [],
68
+ },
69
+ tags: args.tags || [],
70
+ commits: [],
71
+ metadata: {},
72
+ };
73
+ // Save metadata
74
+ const itemDir = join(devcrumbsDir, typeFolder);
75
+ const metadataPath = join(itemDir, `${itemId}.json`);
76
+ const descriptionPath = join(itemDir, `${itemId}.md`);
77
+ writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
78
+ // Save description
79
+ const description = args.description || `# ${args.title}\n\n<!-- Add detailed description here -->\n`;
80
+ writeFileSync(descriptionPath, description);
81
+ // Update index
82
+ index.items.push({
83
+ id: itemId,
84
+ type: args.type,
85
+ title: args.title,
86
+ status: 'draft',
87
+ priority: args.priority || 'medium',
88
+ updated: now,
89
+ });
90
+ index.last_updated = now;
91
+ index.stats = index.stats || { total: 0, by_type: {}, by_status: {} };
92
+ index.stats.total = index.items.length;
93
+ index.stats.by_type[args.type] = (index.stats.by_type[args.type] || 0) + 1;
94
+ index.stats.by_status.draft = (index.stats.by_status.draft || 0) + 1;
95
+ writeFileSync(indexPath, JSON.stringify(index, null, 2));
96
+ return {
97
+ itemId,
98
+ metadata,
99
+ config,
100
+ };
101
+ }
102
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/core/add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { ItemStatus } from '../schemas/index.js';
2
+ export interface ArchiveItemResult {
3
+ itemId: string;
4
+ archivedAt: string;
5
+ originalStatus: ItemStatus;
6
+ }
7
+ /**
8
+ * Core business logic for archiving a single item
9
+ */
10
+ export declare function archiveItem(devcrumbsDir: string, itemId: string): Promise<ArchiveItemResult>;
11
+ export interface PurgeItemsArgs {
12
+ status?: ItemStatus[];
13
+ type?: string;
14
+ olderThan?: Date;
15
+ }
16
+ export interface PurgeItemsResult {
17
+ count: number;
18
+ archivedIds: string[];
19
+ }
20
+ /**
21
+ * Core business logic for bulk archiving items
22
+ */
23
+ export declare function purgeItems(devcrumbsDir: string, args?: PurgeItemsArgs): Promise<PurgeItemsResult>;
24
+ //# sourceMappingURL=archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAkB,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,UAAU,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA0ElG;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAC9B,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,gBAAgB,CAAC,CA6C3B"}
@@ -0,0 +1,109 @@
1
+ import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { TYPE_TO_DIRECTORY, getCurrentTimestamp, parseItemId } from '../utils/index.js';
4
+ /**
5
+ * Core business logic for archiving a single item
6
+ */
7
+ export async function archiveItem(devcrumbsDir, itemId) {
8
+ if (!existsSync(devcrumbsDir)) {
9
+ throw new Error('Project not initialized. Run devcrumbs-init first.');
10
+ }
11
+ const parsed = parseItemId(itemId);
12
+ if (!parsed) {
13
+ throw new Error(`Invalid item ID: ${itemId}`);
14
+ }
15
+ const typeFolder = TYPE_TO_DIRECTORY[parsed.type];
16
+ const metadataPath = join(devcrumbsDir, typeFolder, `${itemId}.json`);
17
+ const descriptionPath = join(devcrumbsDir, typeFolder, `${itemId}.md`);
18
+ if (!existsSync(metadataPath)) {
19
+ throw new Error(`Item not found: ${itemId}`);
20
+ }
21
+ // Read metadata
22
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
23
+ const originalStatus = metadata.status;
24
+ // Create archive directory if not exists
25
+ const archiveDir = join(devcrumbsDir, 'archive', typeFolder);
26
+ mkdirSync(archiveDir, { recursive: true });
27
+ // Move files to archive
28
+ const archiveMetadataPath = join(archiveDir, `${itemId}.json`);
29
+ const archiveDescriptionPath = join(archiveDir, `${itemId}.md`);
30
+ renameSync(metadataPath, archiveMetadataPath);
31
+ if (existsSync(descriptionPath)) {
32
+ renameSync(descriptionPath, archiveDescriptionPath);
33
+ }
34
+ // Update index
35
+ const indexPath = join(devcrumbsDir, 'index.json');
36
+ const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
37
+ // Remove from items
38
+ const itemIndex = index.items.findIndex((i) => i.id === itemId);
39
+ if (itemIndex !== -1) {
40
+ index.items.splice(itemIndex, 1);
41
+ }
42
+ // Add to archived_items
43
+ const archivedAt = getCurrentTimestamp();
44
+ index.archived_items = index.archived_items || [];
45
+ index.archived_items.push({
46
+ id: itemId,
47
+ type: parsed.type,
48
+ title: metadata.title,
49
+ archived_at: archivedAt,
50
+ original_status: originalStatus,
51
+ });
52
+ // Update stats
53
+ if (index.stats) {
54
+ index.stats.total = index.items.length;
55
+ index.stats.by_status[originalStatus] = Math.max((index.stats.by_status[originalStatus] || 1) - 1, 0);
56
+ index.stats.archived = (index.stats.archived || 0) + 1;
57
+ }
58
+ index.last_updated = archivedAt;
59
+ writeFileSync(indexPath, JSON.stringify(index, null, 2));
60
+ return {
61
+ itemId,
62
+ archivedAt,
63
+ originalStatus,
64
+ };
65
+ }
66
+ /**
67
+ * Core business logic for bulk archiving items
68
+ */
69
+ export async function purgeItems(devcrumbsDir, args = {}) {
70
+ if (!existsSync(devcrumbsDir)) {
71
+ throw new Error('Project not initialized. Run devcrumbs-init first.');
72
+ }
73
+ const indexPath = join(devcrumbsDir, 'index.json');
74
+ const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
75
+ // Find items to archive
76
+ let itemsToArchive = [...index.items];
77
+ // Filter by status (default: done, cancelled)
78
+ const statusFilter = args.status || ['done', 'cancelled'];
79
+ itemsToArchive = itemsToArchive.filter((i) => statusFilter.includes(i.status));
80
+ // Filter by type
81
+ if (args.type) {
82
+ itemsToArchive = itemsToArchive.filter((i) => i.type === args.type);
83
+ }
84
+ // Filter by date
85
+ if (args.olderThan) {
86
+ const cutoffDate = args.olderThan;
87
+ itemsToArchive = itemsToArchive.filter((i) => {
88
+ const updated = new Date(i.updated);
89
+ return updated < cutoffDate;
90
+ });
91
+ }
92
+ // Archive each item
93
+ const archivedIds = [];
94
+ for (const item of itemsToArchive) {
95
+ try {
96
+ await archiveItem(devcrumbsDir, item.id);
97
+ archivedIds.push(item.id);
98
+ }
99
+ catch (error) {
100
+ // Continue with next item on error
101
+ console.error(`Failed to archive ${item.id}:`, error);
102
+ }
103
+ }
104
+ return {
105
+ count: archivedIds.length,
106
+ archivedIds,
107
+ };
108
+ }
109
+ //# sourceMappingURL=archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { ItemMetadata } from '../schemas/index.js';
2
+ export interface BulkUpdateResult {
3
+ success: string[];
4
+ failed: Array<{
5
+ id: string;
6
+ error: string;
7
+ }>;
8
+ total: number;
9
+ }
10
+ /**
11
+ * Bulk update multiple items at once
12
+ * @param devcrumbsDir Path to .devcrumbs directory
13
+ * @param itemIds Array of item IDs to update
14
+ * @param updates Partial item metadata to apply to all items
15
+ * @returns Result with success and failure lists
16
+ */
17
+ export declare function bulkUpdateItems(devcrumbsDir: string, itemIds: string[], updates: Partial<ItemMetadata>): Promise<BulkUpdateResult>;
18
+ /**
19
+ * Bulk add tags to multiple items
20
+ * @param devcrumbsDir Path to .devcrumbs directory
21
+ * @param itemIds Array of item IDs
22
+ * @param tagsToAdd Tags to add
23
+ * @returns Result with success and failure lists
24
+ */
25
+ export declare function bulkAddTags(devcrumbsDir: string, itemIds: string[], tagsToAdd: string[]): Promise<BulkUpdateResult>;
26
+ /**
27
+ * Bulk remove tags from multiple items
28
+ * @param devcrumbsDir Path to .devcrumbs directory
29
+ * @param itemIds Array of item IDs
30
+ * @param tagsToRemove Tags to remove
31
+ * @returns Result with success and failure lists
32
+ */
33
+ export declare function bulkRemoveTags(devcrumbsDir: string, itemIds: string[], tagsToRemove: string[]): Promise<BulkUpdateResult>;
34
+ //# sourceMappingURL=bulk-update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-update.d.ts","sourceRoot":"","sources":["../../src/core/bulk-update.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,qBAAqB,CAAC;AAIpE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAuB3B;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,gBAAgB,CAAC,CAwD3B;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAmD3B"}
@@ -0,0 +1,141 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { getCurrentTimestamp } from '../utils/index.js';
4
+ import { updateItem } from './update.js';
5
+ /**
6
+ * Bulk update multiple items at once
7
+ * @param devcrumbsDir Path to .devcrumbs directory
8
+ * @param itemIds Array of item IDs to update
9
+ * @param updates Partial item metadata to apply to all items
10
+ * @returns Result with success and failure lists
11
+ */
12
+ export async function bulkUpdateItems(devcrumbsDir, itemIds, updates) {
13
+ const result = {
14
+ success: [],
15
+ failed: [],
16
+ total: itemIds.length,
17
+ };
18
+ for (const id of itemIds) {
19
+ try {
20
+ await updateItem(devcrumbsDir, {
21
+ id,
22
+ ...updates,
23
+ });
24
+ result.success.push(id);
25
+ }
26
+ catch (error) {
27
+ result.failed.push({
28
+ id,
29
+ error: error instanceof Error ? error.message : 'Unknown error',
30
+ });
31
+ }
32
+ }
33
+ return result;
34
+ }
35
+ /**
36
+ * Bulk add tags to multiple items
37
+ * @param devcrumbsDir Path to .devcrumbs directory
38
+ * @param itemIds Array of item IDs
39
+ * @param tagsToAdd Tags to add
40
+ * @returns Result with success and failure lists
41
+ */
42
+ export async function bulkAddTags(devcrumbsDir, itemIds, tagsToAdd) {
43
+ const result = {
44
+ success: [],
45
+ failed: [],
46
+ total: itemIds.length,
47
+ };
48
+ for (const id of itemIds) {
49
+ try {
50
+ const { type, folder } = await import('../utils/index.js').then((m) => ({
51
+ type: m.parseItemId(id)?.type,
52
+ folder: m.TYPE_TO_DIRECTORY[m.parseItemId(id)?.type || 'task'],
53
+ }));
54
+ if (!type) {
55
+ throw new Error(`Invalid item ID: ${id}`);
56
+ }
57
+ const metadataPath = join(devcrumbsDir, folder, `${id}.json`);
58
+ if (!existsSync(metadataPath)) {
59
+ throw new Error(`Item ${id} not found`);
60
+ }
61
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
62
+ // Add new tags (avoid duplicates)
63
+ const existingTags = new Set(metadata.tags);
64
+ for (const tag of tagsToAdd) {
65
+ existingTags.add(tag);
66
+ }
67
+ metadata.tags = Array.from(existingTags);
68
+ metadata.updated = getCurrentTimestamp();
69
+ writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
70
+ // Update index
71
+ const indexPath = join(devcrumbsDir, 'index.json');
72
+ const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
73
+ const itemIndex = index.items.findIndex((i) => i.id === id);
74
+ if (itemIndex >= 0) {
75
+ index.items[itemIndex].updated = metadata.updated;
76
+ }
77
+ index.last_updated = getCurrentTimestamp();
78
+ writeFileSync(indexPath, JSON.stringify(index, null, 2));
79
+ result.success.push(id);
80
+ }
81
+ catch (error) {
82
+ result.failed.push({
83
+ id,
84
+ error: error instanceof Error ? error.message : 'Unknown error',
85
+ });
86
+ }
87
+ }
88
+ return result;
89
+ }
90
+ /**
91
+ * Bulk remove tags from multiple items
92
+ * @param devcrumbsDir Path to .devcrumbs directory
93
+ * @param itemIds Array of item IDs
94
+ * @param tagsToRemove Tags to remove
95
+ * @returns Result with success and failure lists
96
+ */
97
+ export async function bulkRemoveTags(devcrumbsDir, itemIds, tagsToRemove) {
98
+ const result = {
99
+ success: [],
100
+ failed: [],
101
+ total: itemIds.length,
102
+ };
103
+ for (const id of itemIds) {
104
+ try {
105
+ const { type, folder } = await import('../utils/index.js').then((m) => ({
106
+ type: m.parseItemId(id)?.type,
107
+ folder: m.TYPE_TO_DIRECTORY[m.parseItemId(id)?.type || 'task'],
108
+ }));
109
+ if (!type) {
110
+ throw new Error(`Invalid item ID: ${id}`);
111
+ }
112
+ const metadataPath = join(devcrumbsDir, folder, `${id}.json`);
113
+ if (!existsSync(metadataPath)) {
114
+ throw new Error(`Item ${id} not found`);
115
+ }
116
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf-8'));
117
+ // Remove tags
118
+ metadata.tags = metadata.tags.filter((tag) => !tagsToRemove.includes(tag));
119
+ metadata.updated = getCurrentTimestamp();
120
+ writeFileSync(metadataPath, JSON.stringify(metadata, null, 2));
121
+ // Update index
122
+ const indexPath = join(devcrumbsDir, 'index.json');
123
+ const index = JSON.parse(readFileSync(indexPath, 'utf-8'));
124
+ const itemIndex = index.items.findIndex((i) => i.id === id);
125
+ if (itemIndex >= 0) {
126
+ index.items[itemIndex].updated = metadata.updated;
127
+ }
128
+ index.last_updated = getCurrentTimestamp();
129
+ writeFileSync(indexPath, JSON.stringify(index, null, 2));
130
+ result.success.push(id);
131
+ }
132
+ catch (error) {
133
+ result.failed.push({
134
+ id,
135
+ error: error instanceof Error ? error.message : 'Unknown error',
136
+ });
137
+ }
138
+ }
139
+ return result;
140
+ }
141
+ //# sourceMappingURL=bulk-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk-update.js","sourceRoot":"","sources":["../../src/core/bulk-update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { ContextLevel, QuickContext } from '../schemas/project.js';
2
+ interface PackageInfo {
3
+ name: string;
4
+ purpose: string;
5
+ dependencies: string[];
6
+ }
7
+ interface ItemCounts {
8
+ total: number;
9
+ by_type: Record<string, number>;
10
+ by_status: Record<string, number>;
11
+ }
12
+ interface RecentUpdate {
13
+ id: string;
14
+ type: string;
15
+ title: string;
16
+ updated: string;
17
+ }
18
+ interface ContextResponse {
19
+ context_level: ContextLevel;
20
+ tokens_used: number;
21
+ static_context?: unknown;
22
+ dynamic_context: {
23
+ packages: PackageInfo[];
24
+ active_items: ItemCounts;
25
+ recent_updates: RecentUpdate[];
26
+ };
27
+ suggestions?: string[];
28
+ }
29
+ /**
30
+ * Analyze packages from workspace (with caching)
31
+ */
32
+ export declare function analyzePackages(projectDir: string): Promise<PackageInfo[]>;
33
+ /**
34
+ * Get item counts from index (with caching)
35
+ */
36
+ export declare function getItemCounts(devcrumbsDir: string): Promise<ItemCounts>;
37
+ /**
38
+ * Get recent updates (last N days) (with caching)
39
+ */
40
+ export declare function getRecentUpdates(devcrumbsDir: string, days: number): Promise<RecentUpdate[]>;
41
+ /**
42
+ * Read PROJECT.md if exists (with caching)
43
+ */
44
+ export declare function readProjectMd(devcrumbsDir: string): Promise<QuickContext | null>;
45
+ /**
46
+ * Estimate token count (rough approximation: 1 token ≈ 4 chars)
47
+ */
48
+ export declare function estimateTokens(obj: unknown): number;
49
+ /**
50
+ * Get quick context
51
+ */
52
+ export declare function getQuickContext(projectDir: string, devcrumbsDir: string): Promise<ContextResponse>;
53
+ export {};
54
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/core/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGxE,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,UAAU,UAAU;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,eAAe;IACvB,aAAa,EAAE,YAAY,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE;QACf,QAAQ,EAAE,WAAW,EAAE,CAAC;QACxB,YAAY,EAAE,UAAU,CAAC;QACzB,cAAc,EAAE,YAAY,EAAE,CAAC;KAChC,CAAC;IACF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAyChF;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAiC7E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAsClG;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAkDtF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAGnD;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,eAAe,CAAC,CAoC1B"}