@projitive/mcp 2.0.3 → 2.0.4
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/output/package.json +8 -2
- package/output/source/common/artifacts.js +1 -1
- package/output/source/common/artifacts.test.js +11 -11
- package/output/source/common/errors.js +19 -19
- package/output/source/common/files.js +11 -11
- package/output/source/common/files.test.js +14 -14
- package/output/source/common/index.js +10 -10
- package/output/source/common/linter.js +27 -27
- package/output/source/common/linter.test.js +9 -9
- package/output/source/common/markdown.js +3 -3
- package/output/source/common/markdown.test.js +15 -15
- package/output/source/common/response.js +74 -74
- package/output/source/common/response.test.js +30 -30
- package/output/source/common/store.js +40 -40
- package/output/source/common/store.test.js +72 -72
- package/output/source/common/types.js +3 -3
- package/output/source/common/utils.js +8 -8
- package/output/source/index.js +16 -16
- package/output/source/index.test.js +64 -64
- package/output/source/prompts/index.js +3 -3
- package/output/source/prompts/quickStart.js +96 -96
- package/output/source/prompts/taskDiscovery.js +184 -184
- package/output/source/prompts/taskExecution.js +148 -148
- package/output/source/resources/designs.js +26 -26
- package/output/source/resources/designs.test.js +88 -88
- package/output/source/resources/governance.js +19 -19
- package/output/source/resources/index.js +2 -2
- package/output/source/resources/readme.js +7 -7
- package/output/source/resources/readme.test.js +113 -113
- package/output/source/resources/reports.js +10 -10
- package/output/source/resources/reports.test.js +83 -83
- package/output/source/tools/index.js +3 -3
- package/output/source/tools/project.js +191 -191
- package/output/source/tools/project.test.js +174 -173
- package/output/source/tools/roadmap.js +110 -95
- package/output/source/tools/roadmap.test.js +54 -46
- package/output/source/tools/task.js +305 -277
- package/output/source/tools/task.test.js +117 -110
- package/output/source/types.js +22 -22
- package/package.json +8 -2
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { isValidRoadmapId } from
|
|
2
|
-
import { isValidTaskId } from
|
|
1
|
+
import { isValidRoadmapId } from '../tools/roadmap.js';
|
|
2
|
+
import { isValidTaskId } from '../tools/task.js';
|
|
3
3
|
export function parseReportMetadata(markdown) {
|
|
4
4
|
const lines = markdown.split(/\r?\n/);
|
|
5
5
|
const metadata = {};
|
|
6
6
|
for (const line of lines) {
|
|
7
7
|
// Remove markdown bold markers (**)
|
|
8
|
-
const cleanLine = line.replace(/\*\*/g,
|
|
9
|
-
const [rawKey, ...rawValue] = cleanLine.split(
|
|
8
|
+
const cleanLine = line.replace(/\*\*/g, '');
|
|
9
|
+
const [rawKey, ...rawValue] = cleanLine.split(':');
|
|
10
10
|
if (!rawKey || rawValue.length === 0) {
|
|
11
11
|
continue;
|
|
12
12
|
}
|
|
13
13
|
const key = rawKey.trim().toLowerCase();
|
|
14
|
-
const value = rawValue.join(
|
|
15
|
-
if (key ===
|
|
14
|
+
const value = rawValue.join(':').trim();
|
|
15
|
+
if (key === 'task')
|
|
16
16
|
metadata.task = value;
|
|
17
|
-
if (key ===
|
|
17
|
+
if (key === 'roadmap')
|
|
18
18
|
metadata.roadmap = value;
|
|
19
|
-
if (key ===
|
|
19
|
+
if (key === 'owner')
|
|
20
20
|
metadata.owner = value;
|
|
21
|
-
if (key ===
|
|
21
|
+
if (key === 'date')
|
|
22
22
|
metadata.date = value;
|
|
23
23
|
}
|
|
24
24
|
return metadata;
|
|
@@ -26,7 +26,7 @@ export function parseReportMetadata(markdown) {
|
|
|
26
26
|
export function validateReportMetadata(metadata) {
|
|
27
27
|
const errors = [];
|
|
28
28
|
if (!metadata.task) {
|
|
29
|
-
errors.push(
|
|
29
|
+
errors.push('Missing Task metadata');
|
|
30
30
|
}
|
|
31
31
|
else if (!isValidTaskId(metadata.task)) {
|
|
32
32
|
errors.push(`Invalid Task metadata format: ${metadata.task}`);
|
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import { describe, expect, it } from
|
|
2
|
-
import { parseReportMetadata, validateReportMetadata, } from
|
|
3
|
-
describe(
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { parseReportMetadata, validateReportMetadata, } from './reports.js';
|
|
3
|
+
describe('reports module', () => {
|
|
4
|
+
describe('parseReportMetadata', () => {
|
|
5
|
+
it('parses task metadata from markdown', () => {
|
|
6
6
|
const markdown = [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
].join(
|
|
7
|
+
'# Task Report',
|
|
8
|
+
'',
|
|
9
|
+
'**Task:** TASK-0001',
|
|
10
|
+
'**Owner:** ai-copilot',
|
|
11
|
+
'**Date:** 2026-02-22',
|
|
12
|
+
'',
|
|
13
|
+
'Some content here',
|
|
14
|
+
].join('\n');
|
|
15
15
|
const metadata = parseReportMetadata(markdown);
|
|
16
|
-
expect(metadata.task).toBe(
|
|
17
|
-
expect(metadata.owner).toBe(
|
|
18
|
-
expect(metadata.date).toBe(
|
|
16
|
+
expect(metadata.task).toBe('TASK-0001');
|
|
17
|
+
expect(metadata.owner).toBe('ai-copilot');
|
|
18
|
+
expect(metadata.date).toBe('2026-02-22');
|
|
19
19
|
});
|
|
20
|
-
it(
|
|
20
|
+
it('parses roadmap metadata from markdown', () => {
|
|
21
21
|
const markdown = [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
].join(
|
|
22
|
+
'# Roadmap Report',
|
|
23
|
+
'',
|
|
24
|
+
'**Roadmap:** ROADMAP-0001',
|
|
25
|
+
'',
|
|
26
|
+
'Some content here',
|
|
27
|
+
].join('\n');
|
|
28
28
|
const metadata = parseReportMetadata(markdown);
|
|
29
|
-
expect(metadata.roadmap).toBe(
|
|
29
|
+
expect(metadata.roadmap).toBe('ROADMAP-0001');
|
|
30
30
|
});
|
|
31
|
-
it(
|
|
31
|
+
it('returns empty object for markdown without metadata', () => {
|
|
32
32
|
const markdown = [
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
].join(
|
|
33
|
+
'# Simple Report',
|
|
34
|
+
'',
|
|
35
|
+
'No metadata here',
|
|
36
|
+
].join('\n');
|
|
37
37
|
const metadata = parseReportMetadata(markdown);
|
|
38
38
|
expect(metadata).toEqual({});
|
|
39
39
|
});
|
|
40
|
-
it(
|
|
41
|
-
const metadata = parseReportMetadata(
|
|
40
|
+
it('handles empty string', () => {
|
|
41
|
+
const metadata = parseReportMetadata('');
|
|
42
42
|
expect(metadata).toEqual({});
|
|
43
43
|
});
|
|
44
|
-
it(
|
|
44
|
+
it('handles malformed metadata lines', () => {
|
|
45
45
|
const markdown = [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
].join(
|
|
46
|
+
'# Report',
|
|
47
|
+
'',
|
|
48
|
+
'Task without colon',
|
|
49
|
+
'Not a metadata line',
|
|
50
|
+
':',
|
|
51
|
+
'Task:',
|
|
52
|
+
].join('\n');
|
|
53
53
|
const metadata = parseReportMetadata(markdown);
|
|
54
54
|
expect(metadata).toBeDefined();
|
|
55
55
|
});
|
|
56
|
-
it(
|
|
56
|
+
it('parses metadata in different formats', () => {
|
|
57
57
|
const markdown = [
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
].join(
|
|
58
|
+
'Task: TASK-0001',
|
|
59
|
+
'task: TASK-0002',
|
|
60
|
+
'TASK: TASK-0003',
|
|
61
|
+
' task : TASK-0004 ',
|
|
62
|
+
].join('\n');
|
|
63
63
|
const metadata = parseReportMetadata(markdown);
|
|
64
64
|
expect(metadata.task).toBeDefined();
|
|
65
65
|
});
|
|
66
66
|
});
|
|
67
|
-
describe(
|
|
68
|
-
it(
|
|
67
|
+
describe('validateReportMetadata', () => {
|
|
68
|
+
it('validates correct task metadata', () => {
|
|
69
69
|
const metadata = {
|
|
70
|
-
task:
|
|
71
|
-
owner:
|
|
72
|
-
date:
|
|
70
|
+
task: 'TASK-0001',
|
|
71
|
+
owner: 'ai-copilot',
|
|
72
|
+
date: '2026-02-22',
|
|
73
73
|
};
|
|
74
74
|
const result = validateReportMetadata(metadata);
|
|
75
75
|
expect(result.ok).toBe(true);
|
|
76
76
|
expect(result.errors).toEqual([]);
|
|
77
77
|
});
|
|
78
|
-
it(
|
|
78
|
+
it('rejects missing task metadata', () => {
|
|
79
79
|
const metadata = {
|
|
80
|
-
owner:
|
|
80
|
+
owner: 'ai-copilot',
|
|
81
81
|
};
|
|
82
82
|
const result = validateReportMetadata(metadata);
|
|
83
83
|
expect(result.ok).toBe(false);
|
|
84
|
-
expect(result.errors).toContain(
|
|
84
|
+
expect(result.errors).toContain('Missing Task metadata');
|
|
85
85
|
});
|
|
86
|
-
it(
|
|
86
|
+
it('rejects invalid task ID format', () => {
|
|
87
87
|
const metadata = {
|
|
88
|
-
task:
|
|
88
|
+
task: 'invalid-format',
|
|
89
89
|
};
|
|
90
90
|
const result = validateReportMetadata(metadata);
|
|
91
91
|
expect(result.ok).toBe(false);
|
|
92
|
-
expect(result.errors.some((e) => e.includes(
|
|
92
|
+
expect(result.errors.some((e) => e.includes('Invalid Task'))).toBe(true);
|
|
93
93
|
});
|
|
94
|
-
it(
|
|
94
|
+
it('validates optional roadmap metadata', () => {
|
|
95
95
|
const metadata = {
|
|
96
|
-
task:
|
|
97
|
-
roadmap:
|
|
96
|
+
task: 'TASK-0001',
|
|
97
|
+
roadmap: 'ROADMAP-0001',
|
|
98
98
|
};
|
|
99
99
|
const result = validateReportMetadata(metadata);
|
|
100
100
|
expect(result.ok).toBe(true);
|
|
101
101
|
});
|
|
102
|
-
it(
|
|
102
|
+
it('rejects invalid roadmap ID format', () => {
|
|
103
103
|
const metadata = {
|
|
104
|
-
task:
|
|
105
|
-
roadmap:
|
|
104
|
+
task: 'TASK-0001',
|
|
105
|
+
roadmap: 'invalid-roadmap',
|
|
106
106
|
};
|
|
107
107
|
const result = validateReportMetadata(metadata);
|
|
108
108
|
expect(result.ok).toBe(false);
|
|
109
|
-
expect(result.errors.some((e) => e.includes(
|
|
109
|
+
expect(result.errors.some((e) => e.includes('Invalid Roadmap'))).toBe(true);
|
|
110
110
|
});
|
|
111
|
-
it(
|
|
111
|
+
it('handles empty metadata object', () => {
|
|
112
112
|
const metadata = {};
|
|
113
113
|
const result = validateReportMetadata(metadata);
|
|
114
114
|
expect(result.ok).toBe(false);
|
|
115
115
|
expect(result.errors.length).toBeGreaterThan(0);
|
|
116
116
|
});
|
|
117
|
-
it(
|
|
117
|
+
it('collects multiple validation errors', () => {
|
|
118
118
|
const metadata = {
|
|
119
|
-
task:
|
|
120
|
-
roadmap:
|
|
119
|
+
task: 'invalid-task',
|
|
120
|
+
roadmap: 'invalid-roadmap',
|
|
121
121
|
};
|
|
122
122
|
const result = validateReportMetadata(metadata);
|
|
123
123
|
expect(result.ok).toBe(false);
|
|
124
124
|
expect(result.errors.length).toBeGreaterThan(1);
|
|
125
125
|
});
|
|
126
126
|
});
|
|
127
|
-
describe(
|
|
128
|
-
it(
|
|
127
|
+
describe('integration', () => {
|
|
128
|
+
it('parses and validates complete report metadata', () => {
|
|
129
129
|
const markdown = [
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
].join(
|
|
130
|
+
'# Task Completion Report',
|
|
131
|
+
'',
|
|
132
|
+
'**Task:** TASK-0001',
|
|
133
|
+
'**Roadmap:** ROADMAP-0002',
|
|
134
|
+
'**Owner:** ai-copilot',
|
|
135
|
+
'**Date:** 2026-02-22',
|
|
136
|
+
'',
|
|
137
|
+
'## Summary',
|
|
138
|
+
'Task completed successfully',
|
|
139
|
+
].join('\n');
|
|
140
140
|
const metadata = parseReportMetadata(markdown);
|
|
141
141
|
const validation = validateReportMetadata(metadata);
|
|
142
|
-
expect(metadata.task).toBe(
|
|
143
|
-
expect(metadata.roadmap).toBe(
|
|
144
|
-
expect(metadata.owner).toBe(
|
|
145
|
-
expect(metadata.date).toBe(
|
|
142
|
+
expect(metadata.task).toBe('TASK-0001');
|
|
143
|
+
expect(metadata.roadmap).toBe('ROADMAP-0002');
|
|
144
|
+
expect(metadata.owner).toBe('ai-copilot');
|
|
145
|
+
expect(metadata.date).toBe('2026-02-22');
|
|
146
146
|
expect(validation.ok).toBe(true);
|
|
147
147
|
});
|
|
148
148
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { registerProjectTools } from
|
|
2
|
-
import { registerTaskTools } from
|
|
3
|
-
import { registerRoadmapTools } from
|
|
1
|
+
import { registerProjectTools } from './project.js';
|
|
2
|
+
import { registerTaskTools } from './task.js';
|
|
3
|
+
import { registerRoadmapTools } from './roadmap.js';
|
|
4
4
|
export function registerTools(server) {
|
|
5
5
|
registerProjectTools(server);
|
|
6
6
|
registerTaskTools(server);
|