@schnick371/devsteps-shared 0.5.0 → 0.6.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/dist/core/add.d.ts +4 -4
- package/dist/core/add.d.ts.map +1 -1
- package/dist/core/add.js +8 -8
- package/dist/core/add.js.map +1 -1
- package/dist/core/archive.d.ts +2 -2
- package/dist/core/archive.d.ts.map +1 -1
- package/dist/core/archive.js +12 -12
- package/dist/core/archive.js.map +1 -1
- package/dist/core/bulk-update.d.ts +6 -6
- package/dist/core/bulk-update.d.ts.map +1 -1
- package/dist/core/bulk-update.js +11 -11
- package/dist/core/bulk-update.js.map +1 -1
- package/dist/core/context.d.ts +4 -4
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +14 -14
- package/dist/core/context.js.map +1 -1
- package/dist/core/get.d.ts +1 -1
- package/dist/core/get.d.ts.map +1 -1
- package/dist/core/get.js +5 -5
- package/dist/core/get.js.map +1 -1
- package/dist/core/list.d.ts +3 -3
- package/dist/core/list.d.ts.map +1 -1
- package/dist/core/list.js +7 -7
- package/dist/core/list.js.map +1 -1
- package/dist/core/update.d.ts +1 -1
- package/dist/core/update.d.ts.map +1 -1
- package/dist/core/update.js +7 -7
- package/dist/core/update.js.map +1 -1
- package/dist/schemas/index.d.ts +7 -7
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +5 -5
- package/dist/schemas/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/core/add.js.map +0 -1
- package/src/core/add.ts +0 -145
- package/src/core/archive.js.map +0 -1
- package/src/core/archive.ts +0 -153
- package/src/core/bulk-update.js.map +0 -1
- package/src/core/bulk-update.ts +0 -180
- package/src/core/context.js.map +0 -1
- package/src/core/context.ts +0 -269
- package/src/core/get.js.map +0 -1
- package/src/core/get.ts +0 -39
- package/src/core/index.js.map +0 -1
- package/src/core/index.ts +0 -26
- package/src/core/list.js.map +0 -1
- package/src/core/list.ts +0 -96
- package/src/core/update.js.map +0 -1
- package/src/core/update.ts +0 -154
- package/src/core/validation.ts +0 -252
- package/src/index.js +0 -21
- package/src/index.js.map +0 -1
- package/src/index.ts +0 -4
- package/src/schemas/index.js.map +0 -1
- package/src/schemas/index.ts +0 -226
- package/src/schemas/project.js.map +0 -1
- package/src/schemas/project.ts +0 -73
- package/src/schemas/relationships.ts +0 -48
- package/src/types/commands.js.map +0 -1
- package/src/types/commands.ts +0 -116
- package/src/types/index.js.map +0 -1
- package/src/types/index.ts +0 -13
- package/src/utils/cache.js.map +0 -1
- package/src/utils/cache.ts +0 -200
- package/src/utils/index.js.map +0 -1
- package/src/utils/index.ts +0 -170
package/src/schemas/project.ts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Schema for PROJECT.md metadata section
|
|
5
|
-
*/
|
|
6
|
-
export const ProjectMetadataSchema = z.object({
|
|
7
|
-
name: z.string(),
|
|
8
|
-
created: z.string().datetime(),
|
|
9
|
-
last_updated: z.string().datetime(),
|
|
10
|
-
version: z.string(),
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Schema for Quick Context (< 5K tokens target)
|
|
15
|
-
*/
|
|
16
|
-
export const QuickContextSchema = z.object({
|
|
17
|
-
tech_stack: z.record(z.string(), z.string()),
|
|
18
|
-
packages: z.array(
|
|
19
|
-
z.object({
|
|
20
|
-
name: z.string(),
|
|
21
|
-
purpose: z.string(),
|
|
22
|
-
dependencies: z.array(z.string()).optional(),
|
|
23
|
-
})
|
|
24
|
-
),
|
|
25
|
-
project_type: z.string(),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Schema for Standard Context (< 20K tokens target)
|
|
30
|
-
*/
|
|
31
|
-
export const StandardContextSchema = QuickContextSchema.extend({
|
|
32
|
-
architecture: z.string(),
|
|
33
|
-
design_decisions: z.array(
|
|
34
|
-
z.object({
|
|
35
|
-
title: z.string(),
|
|
36
|
-
decision: z.string(),
|
|
37
|
-
rationale: z.string(),
|
|
38
|
-
tradeoffs: z.string().optional(),
|
|
39
|
-
})
|
|
40
|
-
),
|
|
41
|
-
module_responsibilities: z.record(z.string(), z.string()),
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Schema for Deep Context (< 50K tokens target)
|
|
46
|
-
*/
|
|
47
|
-
export const DeepContextSchema = StandardContextSchema.extend({
|
|
48
|
-
coding_standards: z.string(),
|
|
49
|
-
testing_strategy: z.string(),
|
|
50
|
-
known_issues: z.array(z.string()).optional(),
|
|
51
|
-
technical_debt: z.array(z.string()).optional(),
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Complete PROJECT.md structure
|
|
56
|
-
*/
|
|
57
|
-
export const ProjectContextSchema = z.object({
|
|
58
|
-
metadata: ProjectMetadataSchema,
|
|
59
|
-
quick: QuickContextSchema,
|
|
60
|
-
standard: StandardContextSchema.optional(),
|
|
61
|
-
deep: DeepContextSchema.optional(),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
export type ProjectMetadata = z.infer<typeof ProjectMetadataSchema>;
|
|
65
|
-
export type QuickContext = z.infer<typeof QuickContextSchema>;
|
|
66
|
-
export type StandardContext = z.infer<typeof StandardContextSchema>;
|
|
67
|
-
export type DeepContext = z.infer<typeof DeepContextSchema>;
|
|
68
|
-
export type ProjectContext = z.infer<typeof ProjectContextSchema>;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Context level type
|
|
72
|
-
*/
|
|
73
|
-
export type ContextLevel = 'quick' | 'standard' | 'deep';
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Relationship type definitions
|
|
3
|
-
* Separates hierarchy relationships (strict validation) from flexible relationships (no validation)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Hierarchy relationships enforce parent-child rules
|
|
8
|
-
* - implements/implemented-by: Epic → Story → Task structure
|
|
9
|
-
*/
|
|
10
|
-
export const HIERARCHY_RELATIONSHIPS = ['implements', 'implemented-by'] as const;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Flexible relationships allow connections between any item types
|
|
14
|
-
* - relates-to: Generic association
|
|
15
|
-
* - blocks/blocked-by: Blocking dependencies
|
|
16
|
-
* - depends-on/required-by: Technical dependencies
|
|
17
|
-
* - tested-by/tests: Testing relationships
|
|
18
|
-
* - supersedes/superseded-by: Version/replacement tracking
|
|
19
|
-
*/
|
|
20
|
-
export const FLEXIBLE_RELATIONSHIPS = [
|
|
21
|
-
'relates-to',
|
|
22
|
-
'blocks',
|
|
23
|
-
'blocked-by',
|
|
24
|
-
'depends-on',
|
|
25
|
-
'required-by',
|
|
26
|
-
'tested-by',
|
|
27
|
-
'tests',
|
|
28
|
-
'supersedes',
|
|
29
|
-
'superseded-by',
|
|
30
|
-
] as const;
|
|
31
|
-
|
|
32
|
-
export type HierarchyRelation = (typeof HIERARCHY_RELATIONSHIPS)[number];
|
|
33
|
-
export type FlexibleRelation = (typeof FLEXIBLE_RELATIONSHIPS)[number];
|
|
34
|
-
export type RelationType = HierarchyRelation | FlexibleRelation;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Check if a relation type requires hierarchy validation
|
|
38
|
-
*/
|
|
39
|
-
export function isHierarchyRelation(relationType: string): relationType is HierarchyRelation {
|
|
40
|
-
return HIERARCHY_RELATIONSHIPS.includes(relationType as HierarchyRelation);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Check if a relation type is flexible (no validation)
|
|
45
|
-
*/
|
|
46
|
-
export function isFlexibleRelation(relationType: string): relationType is FlexibleRelation {
|
|
47
|
-
return FLEXIBLE_RELATIONSHIPS.includes(relationType as FlexibleRelation);
|
|
48
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["commands.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACU,QAAA,cAAc,GAA6B;IACtD,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;IACZ,GAAG,EAAE,aAAa;IAClB,IAAI,EAAE,SAAS;IACf,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,OAAO;IACd,IAAI,EAAE,MAAM;CACJ,CAAC"}
|
package/src/types/commands.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type { EisenhowerQuadrant, ItemType, Priority } from '../schemas/index.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Central type shortcuts mapping
|
|
5
|
-
*/
|
|
6
|
-
export const TYPE_SHORTCUTS: Record<string, ItemType> = {
|
|
7
|
-
epic: 'epic',
|
|
8
|
-
story: 'story',
|
|
9
|
-
task: 'task',
|
|
10
|
-
req: 'requirement',
|
|
11
|
-
feat: 'feature',
|
|
12
|
-
bug: 'bug',
|
|
13
|
-
spike: 'spike',
|
|
14
|
-
test: 'test',
|
|
15
|
-
} as const;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Command argument types - central source of truth
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
export interface AddItemCommandArgs {
|
|
22
|
-
type: string; // Will be mapped via TYPE_SHORTCUTS
|
|
23
|
-
title: string;
|
|
24
|
-
description?: string;
|
|
25
|
-
category?: string;
|
|
26
|
-
priority?: string;
|
|
27
|
-
eisenhower?: string;
|
|
28
|
-
tags?: string[];
|
|
29
|
-
assignee?: string;
|
|
30
|
-
paths?: string[];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface UpdateItemCommandArgs {
|
|
34
|
-
id: string;
|
|
35
|
-
status?: string;
|
|
36
|
-
priority?: string;
|
|
37
|
-
eisenhower?: string;
|
|
38
|
-
superseded_by?: string;
|
|
39
|
-
title?: string;
|
|
40
|
-
description?: string;
|
|
41
|
-
assignee?: string;
|
|
42
|
-
tags?: string[];
|
|
43
|
-
paths?: string[];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface ListItemsCommandArgs {
|
|
47
|
-
type?: string;
|
|
48
|
-
status?: string;
|
|
49
|
-
priority?: string;
|
|
50
|
-
eisenhower?: string;
|
|
51
|
-
assignee?: string;
|
|
52
|
-
tags?: string[];
|
|
53
|
-
archived?: boolean;
|
|
54
|
-
limit?: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface SearchItemsCommandArgs {
|
|
58
|
-
query: string;
|
|
59
|
-
type?: string;
|
|
60
|
-
limit?: string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface StatusCommandArgs {
|
|
64
|
-
detailed?: boolean;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface TraceCommandArgs {
|
|
68
|
-
id: string;
|
|
69
|
-
depth?: string;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface ExportCommandArgs {
|
|
73
|
-
format?: string;
|
|
74
|
-
output?: string;
|
|
75
|
-
types?: string[];
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export interface ArchiveCommandArgs {
|
|
79
|
-
id: string;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface PurgeCommandArgs {
|
|
83
|
-
status?: string[];
|
|
84
|
-
type?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Response types
|
|
89
|
-
*/
|
|
90
|
-
|
|
91
|
-
export interface CommandSuccessResponse {
|
|
92
|
-
success: true;
|
|
93
|
-
message: string;
|
|
94
|
-
[key: string]: unknown;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface CommandErrorResponse {
|
|
98
|
-
success: false;
|
|
99
|
-
error: string;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export type CommandResponse = CommandSuccessResponse | CommandErrorResponse;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Index item summary type (from index.json)
|
|
106
|
-
*/
|
|
107
|
-
export interface IndexItem {
|
|
108
|
-
id: string;
|
|
109
|
-
type: ItemType;
|
|
110
|
-
title: string;
|
|
111
|
-
status: string;
|
|
112
|
-
priority: Priority;
|
|
113
|
-
updated: string;
|
|
114
|
-
tags?: string[];
|
|
115
|
-
category?: string;
|
|
116
|
-
}
|
package/src/types/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAYA,gDAA8B"}
|
package/src/types/index.ts
DELETED
package/src/utils/cache.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["cache.ts"],"names":[],"mappings":"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"}
|
package/src/utils/cache.ts
DELETED
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
import { statSync } from 'node:fs';
|
|
2
|
-
|
|
3
|
-
interface CacheEntry<T> {
|
|
4
|
-
data: T;
|
|
5
|
-
timestamp: number;
|
|
6
|
-
mtime?: number; // for file-based invalidation
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface CacheStats {
|
|
10
|
-
size: number;
|
|
11
|
-
keys: string[];
|
|
12
|
-
hits: number;
|
|
13
|
-
misses: number;
|
|
14
|
-
hitRate: number;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Cache configuration
|
|
19
|
-
*/
|
|
20
|
-
export const CACHE_CONFIG = {
|
|
21
|
-
PROJECT_MD_TTL: 60 * 60 * 1000, // 1 hour
|
|
22
|
-
PACKAGE_ANALYSIS_TTL: 30 * 60 * 1000, // 30 minutes
|
|
23
|
-
ITEM_COUNTS_TTL: 5 * 60 * 1000, // 5 minutes
|
|
24
|
-
RECENT_UPDATES_TTL: 1 * 60 * 1000, // 1 minute
|
|
25
|
-
MAX_CACHE_SIZE: 1000, // Maximum number of cache entries
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Smart context cache with TTL and file-based invalidation
|
|
30
|
-
*/
|
|
31
|
-
export class ContextCache {
|
|
32
|
-
private cache = new Map<string, CacheEntry<unknown>>();
|
|
33
|
-
private hits = 0;
|
|
34
|
-
private misses = 0;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Get cached value
|
|
38
|
-
* @param key Cache key
|
|
39
|
-
* @param maxAge Maximum age in milliseconds
|
|
40
|
-
* @param filePath Optional file path for mtime-based invalidation
|
|
41
|
-
* @returns Cached value or null if invalid/expired
|
|
42
|
-
*/
|
|
43
|
-
get<T>(key: string, maxAge: number, filePath?: string): T | null {
|
|
44
|
-
const entry = this.cache.get(key);
|
|
45
|
-
|
|
46
|
-
if (!entry) {
|
|
47
|
-
this.misses++;
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Check file modification time
|
|
52
|
-
if (filePath && entry.mtime !== undefined) {
|
|
53
|
-
try {
|
|
54
|
-
const currentMtime = statSync(filePath).mtimeMs;
|
|
55
|
-
if (currentMtime > entry.mtime) {
|
|
56
|
-
this.cache.delete(key);
|
|
57
|
-
this.misses++;
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
} catch {
|
|
61
|
-
// File doesn't exist anymore, invalidate cache
|
|
62
|
-
this.cache.delete(key);
|
|
63
|
-
this.misses++;
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Check TTL
|
|
69
|
-
if (Date.now() - entry.timestamp > maxAge) {
|
|
70
|
-
this.cache.delete(key);
|
|
71
|
-
this.misses++;
|
|
72
|
-
return null;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
this.hits++;
|
|
76
|
-
return entry.data as T;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Set cached value
|
|
81
|
-
* @param key Cache key
|
|
82
|
-
* @param data Data to cache
|
|
83
|
-
* @param filePath Optional file path for mtime tracking
|
|
84
|
-
*/
|
|
85
|
-
set<T>(key: string, data: T, filePath?: string): void {
|
|
86
|
-
// Enforce max cache size (simple LRU: remove oldest)
|
|
87
|
-
if (this.cache.size >= CACHE_CONFIG.MAX_CACHE_SIZE) {
|
|
88
|
-
const firstKey = this.cache.keys().next().value;
|
|
89
|
-
if (firstKey) {
|
|
90
|
-
this.cache.delete(firstKey);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let mtime: number | undefined;
|
|
95
|
-
if (filePath) {
|
|
96
|
-
try {
|
|
97
|
-
mtime = statSync(filePath).mtimeMs;
|
|
98
|
-
} catch {
|
|
99
|
-
// File doesn't exist, don't track mtime
|
|
100
|
-
mtime = undefined;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
this.cache.set(key, {
|
|
105
|
-
data,
|
|
106
|
-
timestamp: Date.now(),
|
|
107
|
-
mtime,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Check if key exists and is valid
|
|
113
|
-
* @param key Cache key
|
|
114
|
-
* @param maxAge Maximum age in milliseconds
|
|
115
|
-
* @param filePath Optional file path for mtime-based invalidation
|
|
116
|
-
* @returns true if valid cached value exists
|
|
117
|
-
*/
|
|
118
|
-
has(key: string, maxAge: number, filePath?: string): boolean {
|
|
119
|
-
return this.get(key, maxAge, filePath) !== null;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Clear entire cache
|
|
124
|
-
*/
|
|
125
|
-
clear(): void {
|
|
126
|
-
this.cache.clear();
|
|
127
|
-
this.hits = 0;
|
|
128
|
-
this.misses = 0;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Clear specific cache key
|
|
133
|
-
* @param key Cache key to clear
|
|
134
|
-
*/
|
|
135
|
-
delete(key: string): boolean {
|
|
136
|
-
return this.cache.delete(key);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Clear cache entries matching pattern
|
|
141
|
-
* @param pattern Regex pattern to match keys
|
|
142
|
-
*/
|
|
143
|
-
clearPattern(pattern: RegExp): number {
|
|
144
|
-
let cleared = 0;
|
|
145
|
-
for (const key of this.cache.keys()) {
|
|
146
|
-
if (pattern.test(key)) {
|
|
147
|
-
this.cache.delete(key);
|
|
148
|
-
cleared++;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return cleared;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Get cache statistics
|
|
156
|
-
* @returns Cache statistics including hit rate
|
|
157
|
-
*/
|
|
158
|
-
stats(): CacheStats {
|
|
159
|
-
const total = this.hits + this.misses;
|
|
160
|
-
const hitRate = total > 0 ? this.hits / total : 0;
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
size: this.cache.size,
|
|
164
|
-
keys: Array.from(this.cache.keys()),
|
|
165
|
-
hits: this.hits,
|
|
166
|
-
misses: this.misses,
|
|
167
|
-
hitRate: Math.round(hitRate * 100) / 100,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Reset hit/miss counters
|
|
173
|
-
*/
|
|
174
|
-
resetStats(): void {
|
|
175
|
-
this.hits = 0;
|
|
176
|
-
this.misses = 0;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Global singleton instance
|
|
181
|
-
let globalCache: ContextCache | null = null;
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Get or create global cache instance
|
|
185
|
-
*/
|
|
186
|
-
export function getCache(): ContextCache {
|
|
187
|
-
if (!globalCache) {
|
|
188
|
-
globalCache = new ContextCache();
|
|
189
|
-
}
|
|
190
|
-
return globalCache;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Clear global cache
|
|
195
|
-
*/
|
|
196
|
-
export function clearGlobalCache(): void {
|
|
197
|
-
if (globalCache) {
|
|
198
|
-
globalCache.clear();
|
|
199
|
-
}
|
|
200
|
-
}
|
package/src/utils/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
package/src/utils/index.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import type { ItemType, Methodology } from '../schemas/index.js';
|
|
2
|
-
|
|
3
|
-
// Export cache utilities
|
|
4
|
-
export {
|
|
5
|
-
ContextCache,
|
|
6
|
-
CACHE_CONFIG,
|
|
7
|
-
getCache,
|
|
8
|
-
clearGlobalCache,
|
|
9
|
-
type CacheStats,
|
|
10
|
-
} from './cache.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Type to plural directory mapping
|
|
14
|
-
*/
|
|
15
|
-
export const TYPE_TO_DIRECTORY: Record<ItemType, string> = {
|
|
16
|
-
epic: 'epics',
|
|
17
|
-
story: 'stories',
|
|
18
|
-
task: 'tasks',
|
|
19
|
-
requirement: 'requirements',
|
|
20
|
-
feature: 'features',
|
|
21
|
-
bug: 'bugs',
|
|
22
|
-
spike: 'spikes',
|
|
23
|
-
test: 'tests',
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Get methodology configuration
|
|
28
|
-
*/
|
|
29
|
-
export function getMethodologyConfig(methodology: Methodology) {
|
|
30
|
-
const configs = {
|
|
31
|
-
scrum: {
|
|
32
|
-
item_types: ['epic', 'story', 'task', 'bug', 'spike', 'test'] as ItemType[],
|
|
33
|
-
item_prefixes: {
|
|
34
|
-
epic: 'EPIC',
|
|
35
|
-
story: 'STORY',
|
|
36
|
-
task: 'TASK',
|
|
37
|
-
bug: 'BUG',
|
|
38
|
-
spike: 'SPIKE',
|
|
39
|
-
test: 'TEST',
|
|
40
|
-
},
|
|
41
|
-
directories: ['epics', 'stories', 'tasks', 'bugs', 'spikes', 'tests'],
|
|
42
|
-
},
|
|
43
|
-
waterfall: {
|
|
44
|
-
item_types: ['requirement', 'feature', 'task', 'bug', 'test'] as ItemType[],
|
|
45
|
-
item_prefixes: {
|
|
46
|
-
requirement: 'REQ',
|
|
47
|
-
feature: 'FEAT',
|
|
48
|
-
task: 'TASK',
|
|
49
|
-
bug: 'BUG',
|
|
50
|
-
test: 'TEST',
|
|
51
|
-
},
|
|
52
|
-
directories: ['requirements', 'features', 'tasks', 'bugs', 'tests'],
|
|
53
|
-
},
|
|
54
|
-
hybrid: {
|
|
55
|
-
item_types: [
|
|
56
|
-
'epic',
|
|
57
|
-
'story',
|
|
58
|
-
'requirement',
|
|
59
|
-
'feature',
|
|
60
|
-
'task',
|
|
61
|
-
'bug',
|
|
62
|
-
'spike',
|
|
63
|
-
'test',
|
|
64
|
-
] as ItemType[],
|
|
65
|
-
item_prefixes: {
|
|
66
|
-
epic: 'EPIC',
|
|
67
|
-
story: 'STORY',
|
|
68
|
-
requirement: 'REQ',
|
|
69
|
-
feature: 'FEAT',
|
|
70
|
-
task: 'TASK',
|
|
71
|
-
bug: 'BUG',
|
|
72
|
-
spike: 'SPIKE',
|
|
73
|
-
test: 'TEST',
|
|
74
|
-
},
|
|
75
|
-
directories: [
|
|
76
|
-
'epics',
|
|
77
|
-
'stories',
|
|
78
|
-
'requirements',
|
|
79
|
-
'features',
|
|
80
|
-
'tasks',
|
|
81
|
-
'bugs',
|
|
82
|
-
'spikes',
|
|
83
|
-
'tests',
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
return configs[methodology];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Generates a new item ID with proper prefix and number
|
|
93
|
-
*/
|
|
94
|
-
export function generateItemId(
|
|
95
|
-
type: string,
|
|
96
|
-
counter: number,
|
|
97
|
-
prefixes?: Record<string, string>
|
|
98
|
-
): string {
|
|
99
|
-
const defaultPrefixes: Record<string, string> = {
|
|
100
|
-
epic: 'EPIC',
|
|
101
|
-
story: 'STORY',
|
|
102
|
-
task: 'TASK',
|
|
103
|
-
requirement: 'REQ',
|
|
104
|
-
feature: 'FEAT',
|
|
105
|
-
bug: 'BUG',
|
|
106
|
-
spike: 'SPIKE',
|
|
107
|
-
test: 'TEST',
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const prefixMap = prefixes || defaultPrefixes;
|
|
111
|
-
const prefix = prefixMap[type] || 'ITEM';
|
|
112
|
-
const paddedNumber = counter.toString().padStart(3, '0');
|
|
113
|
-
return `${prefix}-${paddedNumber}`;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Parses an item ID into type and number
|
|
118
|
-
*/
|
|
119
|
-
export function parseItemId(id: string): { type: ItemType; number: number } | null {
|
|
120
|
-
const match = id.match(/^(EPIC|STORY|TASK|REQ|FEAT|BUG|SPIKE|TEST)-(\d+)$/);
|
|
121
|
-
if (!match) return null;
|
|
122
|
-
|
|
123
|
-
const typeMap: Record<string, ItemType> = {
|
|
124
|
-
EPIC: 'epic',
|
|
125
|
-
STORY: 'story',
|
|
126
|
-
TASK: 'task',
|
|
127
|
-
REQ: 'requirement',
|
|
128
|
-
FEAT: 'feature',
|
|
129
|
-
BUG: 'bug',
|
|
130
|
-
SPIKE: 'spike',
|
|
131
|
-
TEST: 'test',
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
return {
|
|
135
|
-
type: typeMap[match[1]],
|
|
136
|
-
number: Number.parseInt(match[2], 10),
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Formats a date for display
|
|
142
|
-
*/
|
|
143
|
-
export function formatDate(date: string | Date): string {
|
|
144
|
-
const d = typeof date === 'string' ? new Date(date) : date;
|
|
145
|
-
return d.toISOString();
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Gets current timestamp in ISO format
|
|
150
|
-
*/
|
|
151
|
-
export function getCurrentTimestamp(): string {
|
|
152
|
-
return new Date().toISOString();
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Validates email format
|
|
157
|
-
*/
|
|
158
|
-
export function isValidEmail(email: string): boolean {
|
|
159
|
-
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Sanitizes a string for use in filenames
|
|
164
|
-
*/
|
|
165
|
-
export function sanitizeFilename(name: string): string {
|
|
166
|
-
return name
|
|
167
|
-
.toLowerCase()
|
|
168
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
169
|
-
.replace(/^-|-$/g, '');
|
|
170
|
-
}
|