pi-harness-runtime 0.10.26 → 0.10.27

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 (92) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/package.json +1 -1
  3. package/packages/architecture-generator/dist/adr.d.ts +15 -0
  4. package/packages/architecture-generator/dist/adr.d.ts.map +1 -0
  5. package/packages/architecture-generator/dist/adr.js +42 -0
  6. package/packages/architecture-generator/dist/adr.js.map +1 -0
  7. package/packages/architecture-generator/dist/index.d.ts +9 -0
  8. package/packages/architecture-generator/dist/index.d.ts.map +1 -0
  9. package/packages/architecture-generator/dist/index.js +9 -0
  10. package/packages/architecture-generator/dist/index.js.map +1 -0
  11. package/packages/architecture-generator/dist/mermaid.d.ts +30 -0
  12. package/packages/architecture-generator/dist/mermaid.d.ts.map +1 -0
  13. package/packages/architecture-generator/dist/mermaid.js +58 -0
  14. package/packages/architecture-generator/dist/mermaid.js.map +1 -0
  15. package/packages/architecture-generator/dist/types.d.ts +30 -0
  16. package/packages/architecture-generator/dist/types.d.ts.map +1 -0
  17. package/packages/architecture-generator/dist/types.js +7 -0
  18. package/packages/architecture-generator/dist/types.js.map +1 -0
  19. package/packages/architecture-generator/src/adr.ts +51 -0
  20. package/packages/architecture-generator/src/index.ts +9 -0
  21. package/packages/architecture-generator/src/mermaid.ts +82 -0
  22. package/packages/architecture-generator/src/types.ts +30 -0
  23. package/packages/knowledge-graph/dist/graph-extractor.d.ts +27 -0
  24. package/packages/knowledge-graph/dist/graph-extractor.d.ts.map +1 -0
  25. package/packages/knowledge-graph/dist/graph-extractor.js +285 -0
  26. package/packages/knowledge-graph/dist/graph-extractor.js.map +1 -0
  27. package/packages/knowledge-graph/dist/index.d.ts +27 -0
  28. package/packages/knowledge-graph/dist/index.d.ts.map +1 -0
  29. package/packages/knowledge-graph/dist/index.js +27 -0
  30. package/packages/knowledge-graph/dist/index.js.map +1 -0
  31. package/packages/knowledge-graph/dist/mcp-client.d.ts +38 -0
  32. package/packages/knowledge-graph/dist/mcp-client.d.ts.map +1 -0
  33. package/packages/knowledge-graph/dist/mcp-client.js +157 -0
  34. package/packages/knowledge-graph/dist/mcp-client.js.map +1 -0
  35. package/packages/knowledge-graph/dist/provenance-linker.d.ts +19 -0
  36. package/packages/knowledge-graph/dist/provenance-linker.d.ts.map +1 -0
  37. package/packages/knowledge-graph/dist/provenance-linker.js +92 -0
  38. package/packages/knowledge-graph/dist/provenance-linker.js.map +1 -0
  39. package/packages/knowledge-graph/dist/types.d.ts +53 -0
  40. package/packages/knowledge-graph/dist/types.d.ts.map +1 -0
  41. package/packages/knowledge-graph/dist/types.js +7 -0
  42. package/packages/knowledge-graph/dist/types.js.map +1 -0
  43. package/packages/knowledge-graph/src/graph-extractor.ts +355 -0
  44. package/packages/knowledge-graph/src/index.ts +27 -0
  45. package/packages/knowledge-graph/src/mcp-client.ts +246 -0
  46. package/packages/knowledge-graph/src/provenance-linker.ts +105 -0
  47. package/packages/knowledge-graph/src/types.ts +86 -0
  48. package/packages/milestone-manager/dist/engine.d.ts +27 -0
  49. package/packages/milestone-manager/dist/engine.d.ts.map +1 -0
  50. package/packages/milestone-manager/dist/engine.js +80 -0
  51. package/packages/milestone-manager/dist/engine.js.map +1 -0
  52. package/packages/milestone-manager/dist/index.d.ts +6 -0
  53. package/packages/milestone-manager/dist/index.d.ts.map +1 -0
  54. package/packages/milestone-manager/dist/index.js +6 -0
  55. package/packages/milestone-manager/dist/index.js.map +1 -0
  56. package/packages/milestone-manager/dist/types.d.ts +25 -0
  57. package/packages/milestone-manager/dist/types.d.ts.map +1 -0
  58. package/packages/milestone-manager/dist/types.js +7 -0
  59. package/packages/milestone-manager/dist/types.js.map +1 -0
  60. package/packages/milestone-manager/src/engine.ts +113 -0
  61. package/packages/milestone-manager/src/index.ts +6 -0
  62. package/packages/milestone-manager/src/types.ts +28 -0
  63. package/packages/project-bootstrap/dist/bootstrap.d.ts +23 -0
  64. package/packages/project-bootstrap/dist/bootstrap.d.ts.map +1 -0
  65. package/packages/project-bootstrap/dist/bootstrap.js +136 -0
  66. package/packages/project-bootstrap/dist/bootstrap.js.map +1 -0
  67. package/packages/project-bootstrap/dist/frappe.d.ts +8 -0
  68. package/packages/project-bootstrap/dist/frappe.d.ts.map +1 -0
  69. package/packages/project-bootstrap/dist/frappe.js +82 -0
  70. package/packages/project-bootstrap/dist/frappe.js.map +1 -0
  71. package/packages/project-bootstrap/dist/index.d.ts +27 -0
  72. package/packages/project-bootstrap/dist/index.d.ts.map +1 -0
  73. package/packages/project-bootstrap/dist/index.js +27 -0
  74. package/packages/project-bootstrap/dist/index.js.map +1 -0
  75. package/packages/project-bootstrap/dist/minimal.d.ts +8 -0
  76. package/packages/project-bootstrap/dist/minimal.d.ts.map +1 -0
  77. package/packages/project-bootstrap/dist/minimal.js +35 -0
  78. package/packages/project-bootstrap/dist/minimal.js.map +1 -0
  79. package/packages/project-bootstrap/dist/types.d.ts +61 -0
  80. package/packages/project-bootstrap/dist/types.d.ts.map +1 -0
  81. package/packages/project-bootstrap/dist/types.js +7 -0
  82. package/packages/project-bootstrap/dist/types.js.map +1 -0
  83. package/packages/project-bootstrap/dist/typescript.d.ts +8 -0
  84. package/packages/project-bootstrap/dist/typescript.d.ts.map +1 -0
  85. package/packages/project-bootstrap/dist/typescript.js +103 -0
  86. package/packages/project-bootstrap/dist/typescript.js.map +1 -0
  87. package/packages/project-bootstrap/src/bootstrap.ts +181 -0
  88. package/packages/project-bootstrap/src/frappe.ts +103 -0
  89. package/packages/project-bootstrap/src/index.ts +27 -0
  90. package/packages/project-bootstrap/src/minimal.ts +45 -0
  91. package/packages/project-bootstrap/src/types.ts +66 -0
  92. package/packages/project-bootstrap/src/typescript.ts +123 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Knowledge Graph - RFC-0106
3
+ *
4
+ * MCP tools for knowledge graph queries.
5
+ */
6
+
7
+ import type {
8
+ KnowledgeNode,
9
+ KnowledgeEdge,
10
+ KnowledgeGraph,
11
+ SearchOptions,
12
+ SearchResult,
13
+ TencentDBConfig,
14
+ } from "./types.js";
15
+
16
+ /**
17
+ * Sync graph to TencentDB Knowledge Service
18
+ */
19
+ export async function syncGraphToKnowledgeService(
20
+ graph: KnowledgeGraph,
21
+ config: TencentDBConfig,
22
+ ): Promise<{ synced: number; errors: string[] }> {
23
+ const response = await fetch(
24
+ `${config.knowledgeUrl}/v3/knowledge/graph/sync`,
25
+ {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/json",
29
+ "x-tdai-user-key": config.userKey,
30
+ "x-tdai-service-id": config.serviceId,
31
+ },
32
+ body: JSON.stringify({
33
+ nodes: graph.nodes.map((n) => ({
34
+ id: n.id,
35
+ type: n.type,
36
+ ...n.data,
37
+ })),
38
+ edges: graph.edges.map((e) => ({
39
+ from: e.from,
40
+ to: e.to,
41
+ type: e.type,
42
+ })),
43
+ }),
44
+ },
45
+ );
46
+
47
+ if (!response.ok) {
48
+ const error = await response.text();
49
+ return { synced: 0, errors: [error] };
50
+ }
51
+
52
+ return { synced: graph.nodes.length, errors: [] };
53
+ }
54
+
55
+ /**
56
+ * Search knowledge graph
57
+ */
58
+ export async function searchGraph(
59
+ query: string,
60
+ config: TencentDBConfig,
61
+ options: SearchOptions = {},
62
+ ): Promise<SearchResult[]> {
63
+ const limit = options.limit ?? 10;
64
+
65
+ const response = await fetch(
66
+ `${config.knowledgeUrl}/v3/knowledge/graph/search`,
67
+ {
68
+ method: "POST",
69
+ headers: {
70
+ "Content-Type": "application/json",
71
+ "x-tdai-user-key": config.userKey,
72
+ "x-tdai-service-id": config.serviceId,
73
+ },
74
+ body: JSON.stringify({
75
+ query,
76
+ limit,
77
+ type: options.type,
78
+ tags: options.tags,
79
+ }),
80
+ },
81
+ );
82
+
83
+ if (!response.ok) {
84
+ throw new Error(`Search failed: ${response.statusText}`);
85
+ }
86
+
87
+ const data = (await response.json()) as {
88
+ results: Array<{
89
+ id: string;
90
+ type: string;
91
+ title: string;
92
+ description?: string;
93
+ tags: string[];
94
+ score: number;
95
+ }>;
96
+ };
97
+
98
+ return data.results.map((r) => ({
99
+ node: {
100
+ id: r.id,
101
+ type: r.type as KnowledgeNode["type"],
102
+ data: {
103
+ title: r.title,
104
+ description: r.description,
105
+ tags: r.tags,
106
+ },
107
+ },
108
+ score: r.score,
109
+ }));
110
+ }
111
+
112
+ /**
113
+ * Query graph by relationship type
114
+ */
115
+ export async function queryRelationships(
116
+ config: TencentDBConfig,
117
+ options: {
118
+ type?: KnowledgeEdge["type"];
119
+ from?: string;
120
+ to?: string;
121
+ },
122
+ ): Promise<KnowledgeEdge[]> {
123
+ const response = await fetch(
124
+ `${config.knowledgeUrl}/v3/knowledge/graph/query`,
125
+ {
126
+ method: "POST",
127
+ headers: {
128
+ "Content-Type": "application/json",
129
+ "x-tdai-user-key": config.userKey,
130
+ "x-tdai-service-id": config.serviceId,
131
+ },
132
+ body: JSON.stringify(options),
133
+ },
134
+ );
135
+
136
+ if (!response.ok) {
137
+ throw new Error(`Query failed: ${response.statusText}`);
138
+ }
139
+
140
+ const data = (await response.json()) as {
141
+ edges: Array<{
142
+ from: string;
143
+ to: string;
144
+ type: string;
145
+ }>;
146
+ };
147
+
148
+ return data.edges.map((e) => ({
149
+ from: e.from,
150
+ to: e.to,
151
+ type: e.type as KnowledgeEdge["type"],
152
+ }));
153
+ }
154
+
155
+ /**
156
+ * Get a specific node by ID
157
+ */
158
+ export async function getNode(
159
+ nodeId: string,
160
+ config: TencentDBConfig,
161
+ ): Promise<KnowledgeNode | null> {
162
+ const response = await fetch(
163
+ `${config.knowledgeUrl}/v3/knowledge/graph/node/${encodeURIComponent(nodeId)}`,
164
+ {
165
+ headers: {
166
+ "x-tdai-user-key": config.userKey,
167
+ "x-tdai-service-id": config.serviceId,
168
+ },
169
+ },
170
+ );
171
+
172
+ if (response.status === 404) {
173
+ return null;
174
+ }
175
+
176
+ if (!response.ok) {
177
+ throw new Error(`Get node failed: ${response.statusText}`);
178
+ }
179
+
180
+ const data = (await response.json()) as {
181
+ id: string;
182
+ type: string;
183
+ title: string;
184
+ description?: string;
185
+ tags: string[];
186
+ source?: string;
187
+ };
188
+
189
+ return {
190
+ id: data.id,
191
+ type: data.type as KnowledgeNode["type"],
192
+ data: {
193
+ title: data.title,
194
+ description: data.description,
195
+ tags: data.tags,
196
+ source: data.source,
197
+ },
198
+ };
199
+ }
200
+
201
+ /**
202
+ * Find skills that implement a specific RFC
203
+ */
204
+ export async function findByRFC(
205
+ rfcId: string,
206
+ config: TencentDBConfig,
207
+ ): Promise<KnowledgeNode[]> {
208
+ const edges = await queryRelationships(config, {
209
+ type: "implements",
210
+ to: rfcId.startsWith("rfc:") ? rfcId : `rfc:${rfcId}`,
211
+ });
212
+
213
+ const nodes: KnowledgeNode[] = [];
214
+ for (const edge of edges) {
215
+ const node = await getNode(edge.from, config);
216
+ if (node) {
217
+ nodes.push(node);
218
+ }
219
+ }
220
+
221
+ return nodes;
222
+ }
223
+
224
+ /**
225
+ * Find related skills
226
+ */
227
+ export async function findRelated(
228
+ skillId: string,
229
+ config: TencentDBConfig,
230
+ maxResults = 5,
231
+ ): Promise<KnowledgeNode[]> {
232
+ const edges = await queryRelationships(config, {
233
+ type: "related_to",
234
+ from: skillId.startsWith("skill:") ? skillId : `skill:${skillId}`,
235
+ });
236
+
237
+ const nodes: KnowledgeNode[] = [];
238
+ for (const edge of edges.slice(0, maxResults)) {
239
+ const node = await getNode(edge.to, config);
240
+ if (node) {
241
+ nodes.push(node);
242
+ }
243
+ }
244
+
245
+ return nodes;
246
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Knowledge Graph - RFC-0106
3
+ *
4
+ * Provenance linking between skills, RFCs, and implementations.
5
+ */
6
+
7
+ import type { KnowledgeNode, KnowledgeEdge, KnowledgeGraph } from "./types.js";
8
+
9
+ /**
10
+ * Build provenance edges based on metadata
11
+ */
12
+ export function buildProvenanceEdges(graph: KnowledgeGraph): KnowledgeEdge[] {
13
+ const edges: KnowledgeEdge[] = [];
14
+ const nodeMap = new Map(graph.nodes.map((n) => [n.id, n]));
15
+
16
+ for (const node of graph.nodes) {
17
+ if (node.type === "skill" && node.data.tags.includes("implements")) {
18
+ // Link to RFCs found in tags
19
+ const rfcTag = node.data.tags.find((t) => t.startsWith("rfc-"));
20
+ if (rfcTag) {
21
+ edges.push({
22
+ from: node.id,
23
+ to: `rfc:${rfcTag.toUpperCase()}`,
24
+ type: "implements",
25
+ metadata: { source: "tag:implements" },
26
+ });
27
+ }
28
+ }
29
+
30
+ // Implementation -> documents -> RFC
31
+ if (node.type === "implementation") {
32
+ const rfcMatch = node.id.match(/implementation:RFC-(\d+)/i);
33
+ if (rfcMatch) {
34
+ edges.push({
35
+ from: node.id,
36
+ to: `rfc:RFC-${rfcMatch[1].padStart(4, "0")}`,
37
+ type: "documents",
38
+ metadata: { source: "id:parsing" },
39
+ });
40
+ }
41
+ }
42
+ }
43
+
44
+ return edges;
45
+ }
46
+
47
+ /**
48
+ * Infer additional edges from content analysis
49
+ */
50
+ export function inferRelationships(graph: KnowledgeGraph): KnowledgeEdge[] {
51
+ const edges: KnowledgeEdge[] = [];
52
+
53
+ // Group skills by shared tags
54
+ const tagGroups = new Map<string, KnowledgeNode[]>();
55
+ for (const node of graph.nodes) {
56
+ if (node.type !== "skill") continue;
57
+ for (const tag of node.data.tags) {
58
+ if (!tagGroups.has(tag)) {
59
+ tagGroups.set(tag, []);
60
+ }
61
+ tagGroups.get(tag)!.push(node);
62
+ }
63
+ }
64
+
65
+ // Skills sharing 3+ tags are related
66
+ for (const [, nodes] of tagGroups) {
67
+ if (nodes.length < 2) continue;
68
+
69
+ for (let i = 0; i < nodes.length; i++) {
70
+ for (let j = i + 1; j < nodes.length; j++) {
71
+ const sharedTags = nodes[i].data.tags.filter((t) =>
72
+ nodes[j].data.tags.includes(t),
73
+ );
74
+ if (sharedTags.length >= 3) {
75
+ edges.push({
76
+ from: nodes[i].id,
77
+ to: nodes[j].id,
78
+ type: "related_to",
79
+ metadata: {
80
+ source: "inferred:shared-tags",
81
+ confidence:
82
+ sharedTags.length /
83
+ Math.max(nodes[i].data.tags.length, nodes[j].data.tags.length),
84
+ },
85
+ });
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ return edges;
92
+ }
93
+
94
+ /**
95
+ * Complete graph with all provenance links
96
+ */
97
+ export function completeGraph(graph: KnowledgeGraph): KnowledgeGraph {
98
+ const provenanceEdges = buildProvenanceEdges(graph);
99
+ const inferredEdges = inferRelationships(graph);
100
+
101
+ return {
102
+ nodes: graph.nodes,
103
+ edges: [...graph.edges, ...provenanceEdges, ...inferredEdges],
104
+ };
105
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Knowledge Graph - RFC-0106
3
+ *
4
+ * Typed definitions for knowledge graph nodes and edges.
5
+ */
6
+
7
+ // --- Node Types ---
8
+
9
+ export type KnowledgeNodeType =
10
+ | "skill" // SKILL.md entry
11
+ | "rfc" // RFC document
12
+ | "implementation" // IMPLEMENTATION/* entry
13
+ | "concept" // Abstract concept
14
+ | "api" // API endpoint
15
+ | "cli" // CLI command
16
+ | "pattern" // Code pattern
17
+ | "workflow"; // Workflow/SOP
18
+
19
+ export interface KnowledgeNode {
20
+ id: string; // e.g., "skill:frappe-custom-field-lifecycle"
21
+ type: KnowledgeNodeType;
22
+ data: {
23
+ title: string;
24
+ description?: string;
25
+ tags: string[];
26
+ source?: string; // File path
27
+ url?: string; // RFC/IMPLEMENTATION URL
28
+ };
29
+ }
30
+
31
+ // --- Edge Types ---
32
+
33
+ export type KnowledgeEdgeType =
34
+ | "implements" // Skill implements RFC
35
+ | "depends_on" // Skill A depends on Skill B
36
+ | "supersedes" // New version replaces old
37
+ | "related_to" // General relationship
38
+ | "authored_by" // Author attribution
39
+ | "documents" // RFC/Impl documents a skill
40
+ | "references"; // RFC references implementation
41
+
42
+ export interface KnowledgeEdge {
43
+ from: string; // Node ID
44
+ to: string; // Node ID
45
+ type: KnowledgeEdgeType;
46
+ metadata?: {
47
+ confidence?: number; // 0-1
48
+ source?: string; // How was this edge discovered
49
+ };
50
+ }
51
+
52
+ // --- Graph ---
53
+
54
+ export interface KnowledgeGraph {
55
+ nodes: KnowledgeNode[];
56
+ edges: KnowledgeEdge[];
57
+ }
58
+
59
+ export interface ProvenanceData {
60
+ implements?: string; // RFC number (e.g., "RFC-0106")
61
+ related_implementation?: string; // IMPLEMENTATION path
62
+ author?: string;
63
+ version?: string;
64
+ }
65
+
66
+ // --- Search ---
67
+
68
+ export interface SearchResult {
69
+ node: KnowledgeNode;
70
+ score: number;
71
+ highlights?: string[];
72
+ }
73
+
74
+ export interface SearchOptions {
75
+ limit?: number;
76
+ type?: KnowledgeNodeType;
77
+ tags?: string[];
78
+ }
79
+
80
+ // --- Config ---
81
+
82
+ export interface TencentDBConfig {
83
+ knowledgeUrl: string; // http://{host}:8424
84
+ userKey: string;
85
+ serviceId: string;
86
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Milestone Manager - RFC-0075
3
+ *
4
+ * Track milestones and calculate status.
5
+ */
6
+ import type { Milestone, MilestoneStatus, MilestoneManagerOptions } from "./types.js";
7
+ /**
8
+ * Calculate milestone status based on progress and time
9
+ */
10
+ export declare function calculateMilestoneStatus(milestone: Milestone, options?: MilestoneManagerOptions): MilestoneStatus;
11
+ /**
12
+ * Milestone Manager
13
+ */
14
+ export declare class MilestoneManager {
15
+ private milestones;
16
+ private options;
17
+ constructor(options?: MilestoneManagerOptions);
18
+ addMilestone(milestone: Milestone): void;
19
+ removeMilestone(id: string): void;
20
+ getMilestone(id: string): Milestone | undefined;
21
+ listMilestones(): Milestone[];
22
+ updateMilestone(id: string, update: Partial<Milestone>): void;
23
+ getStatus(id: string): MilestoneStatus | undefined;
24
+ getAtRiskMilestones(): Milestone[];
25
+ getMissedMilestones(): Milestone[];
26
+ }
27
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACX,SAAS,EACT,eAAe,EACf,uBAAuB,EACvB,MAAM,YAAY,CAAC;AAOpB;;GAEG;AACH,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,uBAA4B,GACnC,eAAe,CAmCjB;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,OAAO,CAA0B;IAEzC,YAAY,OAAO,GAAE,uBAA4B,EAEhD;IAED,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,CAEvC;IAED,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAEhC;IAED,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAE9C;IAED,cAAc,IAAI,SAAS,EAAE,CAE5B;IAED,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAK5D;IAED,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAKjD;IAED,mBAAmB,IAAI,SAAS,EAAE,CAIjC;IAED,mBAAmB,IAAI,SAAS,EAAE,CAIjC;CACD"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Milestone Manager - RFC-0075
3
+ *
4
+ * Track milestones and calculate status.
5
+ */
6
+ const DEFAULT_OPTIONS = {
7
+ atRiskThreshold: 80,
8
+ missedThreshold: 0,
9
+ };
10
+ /**
11
+ * Calculate milestone status based on progress and time
12
+ */
13
+ export function calculateMilestoneStatus(milestone, options = {}) {
14
+ const opts = { ...DEFAULT_OPTIONS, ...options };
15
+ const totalItems = milestone.items.length;
16
+ const completedItems = milestone.completedItems;
17
+ if (completedItems >= totalItems) {
18
+ return "completed";
19
+ }
20
+ // Check if past target date
21
+ const targetDate = new Date(milestone.targetDate);
22
+ const today = new Date();
23
+ const daysPast = Math.floor((today.getTime() - targetDate.getTime()) / (1000 * 60 * 60 * 24));
24
+ if (opts.missedThreshold && daysPast > opts.missedThreshold) {
25
+ return "missed";
26
+ }
27
+ // Check progress percentage
28
+ const progressPct = totalItems > 0 ? (completedItems / totalItems) * 100 : 0;
29
+ // Calculate expected progress based on time
30
+ const startDate = new Date(milestone.targetDate);
31
+ startDate.setDate(startDate.getDate() - 14); // Assume 2-week sprints
32
+ const totalDays = 14;
33
+ const daysElapsed = Math.max(0, Math.min(totalDays, totalDays - daysPast));
34
+ const expectedPct = (daysElapsed / totalDays) * 100;
35
+ if (progressPct < expectedPct * (1 - opts.atRiskThreshold / 100)) {
36
+ return "at-risk";
37
+ }
38
+ return "on-track";
39
+ }
40
+ /**
41
+ * Milestone Manager
42
+ */
43
+ export class MilestoneManager {
44
+ milestones = new Map();
45
+ options;
46
+ constructor(options = {}) {
47
+ this.options = { ...DEFAULT_OPTIONS, ...options };
48
+ }
49
+ addMilestone(milestone) {
50
+ this.milestones.set(milestone.id, milestone);
51
+ }
52
+ removeMilestone(id) {
53
+ this.milestones.delete(id);
54
+ }
55
+ getMilestone(id) {
56
+ return this.milestones.get(id);
57
+ }
58
+ listMilestones() {
59
+ return [...this.milestones.values()];
60
+ }
61
+ updateMilestone(id, update) {
62
+ const milestone = this.milestones.get(id);
63
+ if (milestone) {
64
+ this.milestones.set(id, { ...milestone, ...update });
65
+ }
66
+ }
67
+ getStatus(id) {
68
+ const milestone = this.milestones.get(id);
69
+ return milestone
70
+ ? calculateMilestoneStatus(milestone, this.options)
71
+ : undefined;
72
+ }
73
+ getAtRiskMilestones() {
74
+ return this.listMilestones().filter((m) => calculateMilestoneStatus(m, this.options) === "at-risk");
75
+ }
76
+ getMissedMilestones() {
77
+ return this.listMilestones().filter((m) => calculateMilestoneStatus(m, this.options) === "missed");
78
+ }
79
+ }
80
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Milestone Manager - RFC-0075
3
+ */
4
+ export * from "./types.js";
5
+ export * from "./engine.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Milestone Manager - RFC-0075
3
+ */
4
+ export * from "./types.js";
5
+ export * from "./engine.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Milestone Manager - RFC-0075
3
+ *
4
+ * Track milestones against progress and alert when items are at risk.
5
+ */
6
+ export type MilestoneStatus = "on-track" | "at-risk" | "missed" | "completed";
7
+ export interface Milestone {
8
+ id: string;
9
+ title: string;
10
+ targetDate: string;
11
+ description?: string;
12
+ items: string[];
13
+ status: MilestoneStatus;
14
+ completedItems: number;
15
+ }
16
+ export interface MilestoneManagerOptions {
17
+ atRiskThreshold?: number;
18
+ missedThreshold?: number;
19
+ }
20
+ export interface MilestoneUpdate {
21
+ itemId: string;
22
+ status: "added" | "completed" | "removed";
23
+ milestoneId: string;
24
+ }
25
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE9E,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Milestone Manager - RFC-0075
3
+ *
4
+ * Track milestones against progress and alert when items are at risk.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}