@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,252 @@
1
+ import type { ItemType, Methodology } from '../schemas/index.js';
2
+ import { isFlexibleRelation, isHierarchyRelation } from '../schemas/relationships.js';
3
+
4
+ /**
5
+ * Validation result with detailed error messaging
6
+ */
7
+ export interface ValidationResult {
8
+ valid: boolean;
9
+ error?: string;
10
+ suggestion?: string;
11
+ }
12
+
13
+ /**
14
+ * Minimal work item info needed for validation
15
+ */
16
+ export interface WorkItem {
17
+ id: string;
18
+ type: ItemType;
19
+ }
20
+
21
+ /**
22
+ * Validate relationship between two items based on methodology
23
+ * Only validates "implements" relationships - all other relations are flexible
24
+ *
25
+ * @param source - Item creating the relationship (child in hierarchy)
26
+ * @param target - Item being referenced (parent in hierarchy)
27
+ * @param relationType - Type of relationship
28
+ * @param methodology - Project methodology (scrum, waterfall, hybrid)
29
+ * @returns ValidationResult with valid flag and optional error/suggestion
30
+ */
31
+ export function validateRelationship(
32
+ source: WorkItem,
33
+ target: WorkItem,
34
+ relationType: string,
35
+ methodology: Methodology
36
+ ): ValidationResult {
37
+ // Flexible relationships always allowed
38
+ if (isFlexibleRelation(relationType)) {
39
+ return { valid: true };
40
+ }
41
+
42
+ // Only validate hierarchy relationships
43
+ if (!isHierarchyRelation(relationType)) {
44
+ return { valid: false, error: `Unknown relationship type: ${relationType}` };
45
+ }
46
+
47
+ // Only validate "implements" direction (implemented-by is automatic reverse)
48
+ if (relationType === 'implemented-by') {
49
+ return { valid: true }; // Reverse relationships auto-created, no validation needed
50
+ }
51
+
52
+ // Validate based on methodology
53
+ if (methodology === 'scrum') {
54
+ return validateScrumHierarchy(source, target);
55
+ }
56
+
57
+ if (methodology === 'waterfall') {
58
+ return validateWaterfallHierarchy(source, target);
59
+ }
60
+
61
+ if (methodology === 'hybrid') {
62
+ // Try Scrum rules first
63
+ const scrumResult = validateScrumHierarchy(source, target);
64
+ if (scrumResult.valid) {
65
+ return scrumResult;
66
+ }
67
+
68
+ // Try Waterfall rules
69
+ const waterfallResult = validateWaterfallHierarchy(source, target);
70
+ if (waterfallResult.valid) {
71
+ return waterfallResult;
72
+ }
73
+
74
+ // Neither worked - return Scrum error (more common)
75
+ return scrumResult;
76
+ }
77
+
78
+ return {
79
+ valid: false,
80
+ error: `Unknown methodology: ${methodology}`,
81
+ };
82
+ }
83
+
84
+ /**
85
+ * Validate Scrum hierarchy rules
86
+ * Epic → Story|Spike → Task
87
+ * Bug/Test can implement Epic or Story
88
+ */
89
+ function validateScrumHierarchy(source: WorkItem, target: WorkItem): ValidationResult {
90
+ const { type: sourceType } = source;
91
+ const { type: targetType } = target;
92
+
93
+ // Task → Story or Spike
94
+ if (sourceType === 'task') {
95
+ if (targetType === 'story' || targetType === 'spike') {
96
+ return { valid: true };
97
+ }
98
+ return {
99
+ valid: false,
100
+ error: 'Tasks can only implement Stories or Spikes in Scrum',
101
+ suggestion: `Change ${target.id} to a Story or create a Story first, then link Task → Story`,
102
+ };
103
+ }
104
+
105
+ // Story → Epic
106
+ if (sourceType === 'story') {
107
+ if (targetType === 'epic') {
108
+ return { valid: true };
109
+ }
110
+ return {
111
+ valid: false,
112
+ error: 'Stories can only implement Epics in Scrum',
113
+ suggestion: `Change ${target.id} to an Epic or create an Epic first, then link Story → Epic`,
114
+ };
115
+ }
116
+
117
+ // Spike → Epic
118
+ if (sourceType === 'spike') {
119
+ if (targetType === 'epic') {
120
+ return { valid: true };
121
+ }
122
+ return {
123
+ valid: false,
124
+ error: 'Spikes can only implement Epics in Scrum',
125
+ suggestion: `Change ${target.id} to an Epic or create an Epic first, then link Spike → Epic`,
126
+ };
127
+ }
128
+
129
+ // Bug → Epic or Story (flexible)
130
+ if (sourceType === 'bug') {
131
+ if (targetType === 'epic' || targetType === 'story') {
132
+ return { valid: true };
133
+ }
134
+ return {
135
+ valid: false,
136
+ error: 'Bugs can only implement Epics or Stories in Scrum',
137
+ suggestion: `Use "relates-to" for Bug → ${targetType} relationships, or create Epic/Story first`,
138
+ };
139
+ }
140
+
141
+ // Test → Epic or Story (flexible)
142
+ if (sourceType === 'test') {
143
+ if (targetType === 'epic' || targetType === 'story') {
144
+ return { valid: true };
145
+ }
146
+ return {
147
+ valid: false,
148
+ error: 'Tests can only implement Epics or Stories in Scrum',
149
+ suggestion: `Use "tested-by" relationship or create Epic/Story first`,
150
+ };
151
+ }
152
+
153
+ // Epic cannot implement anything (top-level)
154
+ if (sourceType === 'epic') {
155
+ return {
156
+ valid: false,
157
+ error: 'Epics are top-level items and cannot implement other items',
158
+ suggestion: 'Consider using "relates-to" to link Epics together',
159
+ };
160
+ }
161
+
162
+ return {
163
+ valid: false,
164
+ error: `Invalid Scrum relationship: ${sourceType} → ${targetType}`,
165
+ suggestion: 'Check Scrum hierarchy: Epic → Story|Spike → Task',
166
+ };
167
+ }
168
+
169
+ /**
170
+ * Validate Waterfall hierarchy rules
171
+ * Requirement → Feature|Spike → Task
172
+ * Bug/Test can implement Requirement or Feature
173
+ */
174
+ function validateWaterfallHierarchy(source: WorkItem, target: WorkItem): ValidationResult {
175
+ const { type: sourceType } = source;
176
+ const { type: targetType } = target;
177
+
178
+ // Task → Feature or Spike
179
+ if (sourceType === 'task') {
180
+ if (targetType === 'feature' || targetType === 'spike') {
181
+ return { valid: true };
182
+ }
183
+ return {
184
+ valid: false,
185
+ error: 'Tasks can only implement Features or Spikes in Waterfall',
186
+ suggestion: `Change ${target.id} to a Feature or create a Feature first, then link Task → Feature`,
187
+ };
188
+ }
189
+
190
+ // Feature → Requirement
191
+ if (sourceType === 'feature') {
192
+ if (targetType === 'requirement') {
193
+ return { valid: true };
194
+ }
195
+ return {
196
+ valid: false,
197
+ error: 'Features can only implement Requirements in Waterfall',
198
+ suggestion: `Change ${target.id} to a Requirement or create a Requirement first, then link Feature → Requirement`,
199
+ };
200
+ }
201
+
202
+ // Spike → Requirement
203
+ if (sourceType === 'spike') {
204
+ if (targetType === 'requirement') {
205
+ return { valid: true };
206
+ }
207
+ return {
208
+ valid: false,
209
+ error: 'Spikes can only implement Requirements in Waterfall',
210
+ suggestion: `Change ${target.id} to a Requirement or create a Requirement first, then link Spike → Requirement`,
211
+ };
212
+ }
213
+
214
+ // Bug → Requirement or Feature (flexible)
215
+ if (sourceType === 'bug') {
216
+ if (targetType === 'requirement' || targetType === 'feature') {
217
+ return { valid: true };
218
+ }
219
+ return {
220
+ valid: false,
221
+ error: 'Bugs can only implement Requirements or Features in Waterfall',
222
+ suggestion: `Use "relates-to" for Bug → ${targetType} relationships, or create Requirement/Feature first`,
223
+ };
224
+ }
225
+
226
+ // Test → Requirement or Feature (flexible)
227
+ if (sourceType === 'test') {
228
+ if (targetType === 'requirement' || targetType === 'feature') {
229
+ return { valid: true };
230
+ }
231
+ return {
232
+ valid: false,
233
+ error: 'Tests can only implement Requirements or Features in Waterfall',
234
+ suggestion: `Use "tested-by" relationship or create Requirement/Feature first`,
235
+ };
236
+ }
237
+
238
+ // Requirement cannot implement anything (top-level)
239
+ if (sourceType === 'requirement') {
240
+ return {
241
+ valid: false,
242
+ error: 'Requirements are top-level items and cannot implement other items',
243
+ suggestion: 'Consider using "relates-to" to link Requirements together',
244
+ };
245
+ }
246
+
247
+ return {
248
+ valid: false,
249
+ error: `Invalid Waterfall relationship: ${sourceType} → ${targetType}`,
250
+ suggestion: 'Check Waterfall hierarchy: Requirement → Feature|Spike → Task',
251
+ };
252
+ }
package/src/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types/index.js"), exports);
18
+ __exportStar(require("./schemas/index.js"), exports);
19
+ __exportStar(require("./utils/index.js"), exports);
20
+ __exportStar(require("./core/index.js"), exports);
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,qDAAmC;AACnC,mDAAiC;AACjC,kDAAgC"}
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './types/index.js';
2
+ export * from './schemas/index.js';
3
+ export * from './utils/index.js';
4
+ export * from './core/index.js';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,226 @@
1
+ import { z } from 'zod';
2
+
3
+ // Re-export project context schemas
4
+ export * from './project.js';
5
+ export * from './relationships.js';
6
+
7
+ /**
8
+ * Methodology types
9
+ */
10
+ export const Methodology = z.enum(['scrum', 'waterfall', 'hybrid']);
11
+ export type Methodology = z.infer<typeof Methodology>;
12
+
13
+ /**
14
+ * Item types in devcrumbs system
15
+ * Scrum: epic, story, task, bug, spike, test
16
+ * Waterfall: requirement, feature, task, bug, test
17
+ * Hybrid: all of the above
18
+ */
19
+ export const ItemType = z.enum([
20
+ 'epic',
21
+ 'story',
22
+ 'task',
23
+ 'requirement',
24
+ 'feature',
25
+ 'bug',
26
+ 'spike',
27
+ 'test',
28
+ ]);
29
+ export type ItemType = z.infer<typeof ItemType>;
30
+
31
+ /**
32
+ * Item status lifecycle
33
+ */
34
+ export const ItemStatus = z.enum([
35
+ 'draft',
36
+ 'planned',
37
+ 'in-progress',
38
+ 'review',
39
+ 'done',
40
+ 'obsolete',
41
+ 'blocked',
42
+ 'cancelled',
43
+ ]);
44
+ export type ItemStatus = z.infer<typeof ItemStatus>;
45
+
46
+ /**
47
+ * Priority levels
48
+ */
49
+ export const Priority = z.enum(['critical', 'high', 'medium', 'low']);
50
+ export type Priority = z.infer<typeof Priority>;
51
+
52
+ /**
53
+ * Eisenhower Matrix quadrants for prioritization
54
+ * Q1: Urgent + Important = Do First
55
+ * Q2: Not Urgent + Important = Schedule/Plan
56
+ * Q3: Urgent + Not Important = Delegate
57
+ * Q4: Not Urgent + Not Important = Eliminate/Later
58
+ */
59
+ export const EisenhowerQuadrant = z.enum([
60
+ 'urgent-important', // Q1: Do First
61
+ 'not-urgent-important', // Q2: Schedule
62
+ 'urgent-not-important', // Q3: Delegate
63
+ 'not-urgent-not-important', // Q4: Eliminate
64
+ ]);
65
+ export type EisenhowerQuadrant = z.infer<typeof EisenhowerQuadrant>;
66
+
67
+ /**
68
+ * Relationship types between items
69
+ */
70
+ export const RelationType = z.enum([
71
+ 'implements',
72
+ 'implemented-by',
73
+ 'tested-by',
74
+ 'tests',
75
+ 'blocks',
76
+ 'blocked-by',
77
+ 'relates-to',
78
+ 'depends-on',
79
+ 'required-by',
80
+ 'supersedes',
81
+ 'superseded-by',
82
+ ]);
83
+ export type RelationType = z.infer<typeof RelationType>;
84
+
85
+ /**
86
+ * Linked items structure
87
+ */
88
+ export const LinkedItems = z
89
+ .object({
90
+ implements: z.array(z.string()),
91
+ 'implemented-by': z.array(z.string()),
92
+ 'tested-by': z.array(z.string()),
93
+ tests: z.array(z.string()),
94
+ blocks: z.array(z.string()),
95
+ 'blocked-by': z.array(z.string()),
96
+ 'relates-to': z.array(z.string()),
97
+ 'depends-on': z.array(z.string()),
98
+ 'required-by': z.array(z.string()),
99
+ supersedes: z.array(z.string()),
100
+ 'superseded-by': z.array(z.string()),
101
+ })
102
+ .default({
103
+ implements: [],
104
+ 'implemented-by': [],
105
+ 'tested-by': [],
106
+ tests: [],
107
+ blocks: [],
108
+ 'blocked-by': [],
109
+ 'relates-to': [],
110
+ 'depends-on': [],
111
+ 'required-by': [],
112
+ supersedes: [],
113
+ 'superseded-by': [],
114
+ });
115
+ export type LinkedItems = z.infer<typeof LinkedItems>;
116
+
117
+ /**
118
+ * Git commit reference
119
+ */
120
+ export const GitCommit = z.object({
121
+ hash: z.string(),
122
+ message: z.string(),
123
+ author: z.string(),
124
+ timestamp: z.string(),
125
+ branch: z.string().optional(),
126
+ });
127
+ export type GitCommit = z.infer<typeof GitCommit>;
128
+
129
+ /**
130
+ * Core item schema - metadata stored as JSON
131
+ */
132
+ export const ItemMetadata = z.object({
133
+ id: z.string().regex(/^(EPIC|STORY|TASK|REQ|FEAT|BUG|SPIKE|TEST)-\d{3,}$/),
134
+ type: ItemType,
135
+ category: z.string().default('general'),
136
+ title: z.string().min(1).max(200),
137
+ status: ItemStatus.default('draft'),
138
+ priority: Priority.default('medium'),
139
+ eisenhower: EisenhowerQuadrant.optional(),
140
+ superseded_by: z.string().optional(),
141
+ created: z.string().datetime(),
142
+ updated: z.string().datetime(),
143
+ author: z.string().email().optional(),
144
+ assignee: z.string().email().optional(),
145
+ affected_paths: z.array(z.string()).default([]),
146
+ linked_items: LinkedItems,
147
+ tags: z.array(z.string()).default([]),
148
+ estimated_effort: z.string().optional(),
149
+ actual_effort: z.string().optional(),
150
+ commits: z.array(GitCommit).default([]),
151
+ metadata: z.record(z.string(), z.unknown()).default({}),
152
+ });
153
+ export type ItemMetadata = z.infer<typeof ItemMetadata>;
154
+
155
+ /**
156
+ * Configuration schema for .devcrumbs/config.json
157
+ */
158
+ export const DevCrumbsConfig = z.object({
159
+ version: z.string().default('0.1.0'),
160
+ project_name: z.string(),
161
+ project_id: z.string(),
162
+ created: z.string().datetime(),
163
+ updated: z.string().datetime(),
164
+ settings: z
165
+ .object({
166
+ methodology: Methodology.default('scrum'),
167
+ auto_increment: z.boolean(),
168
+ git_integration: z.boolean(),
169
+ default_author: z.string().email().optional(),
170
+ item_types: z.array(ItemType),
171
+ item_prefixes: z.record(z.string(), z.string()),
172
+ })
173
+ .default({
174
+ methodology: 'scrum',
175
+ auto_increment: true,
176
+ git_integration: true,
177
+ item_types: ['epic', 'story', 'task', 'bug', 'spike', 'test'],
178
+ item_prefixes: {
179
+ epic: 'EPIC',
180
+ story: 'STORY',
181
+ task: 'TASK',
182
+ bug: 'BUG',
183
+ spike: 'SPIKE',
184
+ test: 'TEST',
185
+ },
186
+ }),
187
+ });
188
+ export type DevCrumbsConfig = z.infer<typeof DevCrumbsConfig>;
189
+
190
+ /**
191
+ * Index schema for .devcrumbs/index.json
192
+ */
193
+ export const DevCrumbsIndex = z.object({
194
+ items: z.array(
195
+ z.object({
196
+ id: z.string(),
197
+ type: ItemType,
198
+ title: z.string(),
199
+ status: ItemStatus,
200
+ priority: Priority,
201
+ updated: z.string().datetime(),
202
+ })
203
+ ),
204
+ last_updated: z.string().datetime(),
205
+ counters: z.record(z.string(), z.number()).default({}),
206
+ archived_items: z
207
+ .array(
208
+ z.object({
209
+ id: z.string(),
210
+ type: ItemType,
211
+ title: z.string(),
212
+ archived_at: z.string().datetime(),
213
+ original_status: ItemStatus,
214
+ })
215
+ )
216
+ .default([]),
217
+ stats: z
218
+ .object({
219
+ total: z.number(),
220
+ by_type: z.record(z.string(), z.number()),
221
+ by_status: z.record(z.string(), z.number()),
222
+ archived: z.number().optional(),
223
+ })
224
+ .optional(),
225
+ });
226
+ export type DevCrumbsIndex = z.infer<typeof DevCrumbsIndex>;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["project.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB;;GAEG;AACU,QAAA,qBAAqB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACnC,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;CACpB,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,kBAAkB,GAAG,OAAC,CAAC,MAAM,CAAC;IACzC,UAAU,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC;IAC5C,QAAQ,EAAE,OAAC,CAAC,KAAK,CACf,OAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;QAChB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;QACnB,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;KAC7C,CAAC,CACH;IACD,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE;CACzB,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,qBAAqB,GAAG,0BAAkB,CAAC,MAAM,CAAC;IAC7D,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE;IACxB,gBAAgB,EAAE,OAAC,CAAC,KAAK,CACvB,OAAC,CAAC,MAAM,CAAC;QACP,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE;QACjB,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;QACpB,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE;QACrB,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACjC,CAAC,CACH;IACD,uBAAuB,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC;CAC1D,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,iBAAiB,GAAG,6BAAqB,CAAC,MAAM,CAAC;IAC5D,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,gBAAgB,EAAE,OAAC,CAAC,MAAM,EAAE;IAC5B,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC5C,cAAc,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,QAAQ,EAAE,6BAAqB;IAC/B,KAAK,EAAE,0BAAkB;IACzB,QAAQ,EAAE,6BAAqB,CAAC,QAAQ,EAAE;IAC1C,IAAI,EAAE,yBAAiB,CAAC,QAAQ,EAAE;CACnC,CAAC,CAAC"}
@@ -0,0 +1,73 @@
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';
@@ -0,0 +1,48 @@
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
+ }
@@ -0,0 +1 @@
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"}