@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/README.md
CHANGED
|
@@ -1,15 +1,74 @@
|
|
|
1
1
|
# @schnick371/devsteps-shared
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Never Code Alone. Shared utilities and types for DevSteps packages.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Core package providing shared types, schemas, and utilities used across all DevSteps packages (CLI, MCP Server, VS Code Extension).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## Features
|
|
10
10
|
|
|
11
|
-
|
|
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
|
-
|
|
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"}
|
package/dist/core/add.js
ADDED
|
@@ -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"}
|