@projitive/mcp 2.1.1 → 2.1.2
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@projitive/mcp",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Projitive MCP Server for project and task discovery/update",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "",
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"publishConfig": {
|
|
13
13
|
"access": "public"
|
|
14
14
|
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/yinxulai/projitive"
|
|
18
|
+
},
|
|
15
19
|
"scripts": {
|
|
16
20
|
"test": "vitest run",
|
|
17
21
|
"test:coverage": "vitest run --coverage",
|
|
@@ -47,7 +47,8 @@ export function registerTaskExecutionPrompt(server) {
|
|
|
47
47
|
'- If status is MISSING/INCOMPLETE, complete it before any implementation',
|
|
48
48
|
'',
|
|
49
49
|
'### Pre-Execution Research Brief (Mandatory Gate)',
|
|
50
|
-
'- Fixed file name: `designs/research/<TASK-ID>.implementation-research.md`',
|
|
50
|
+
'- Fixed file name (relative to governanceDir): `designs/research/<TASK-ID>.implementation-research.md`',
|
|
51
|
+
'- Absolute location: `<governanceDir>/designs/research/<TASK-ID>.implementation-research.md`',
|
|
51
52
|
'- Required sections:',
|
|
52
53
|
' - `## Design Guidelines and Specs`',
|
|
53
54
|
' - `## Code Architecture and Implementation Findings`',
|
|
@@ -224,7 +225,7 @@ export function registerTaskExecutionPrompt(server) {
|
|
|
224
225
|
'',
|
|
225
226
|
'6. **Pre-execution research brief is mandatory**',
|
|
226
227
|
' - `TODO -> IN_PROGRESS` is not allowed until research brief is READY',
|
|
227
|
-
' - Always read
|
|
228
|
+
' - Always read `<governanceDir>/designs/research/<TASK-ID>.implementation-research.md` before implementation',
|
|
228
229
|
].join('\n');
|
|
229
230
|
return asUserPrompt(text);
|
|
230
231
|
});
|
|
@@ -11,7 +11,8 @@ describe('taskExecution prompt', () => {
|
|
|
11
11
|
expect(text).toContain('1) Run taskContext(projectPath="/workspace/app", taskId="TASK-0007").');
|
|
12
12
|
expect(text).toContain('Every status transition must have report evidence');
|
|
13
13
|
expect(text).toContain('Pre-Execution Research Brief (Mandatory Gate)');
|
|
14
|
-
expect(text).toContain('designs/research/<TASK-ID>.implementation-research.md');
|
|
14
|
+
expect(text).toContain('Fixed file name (relative to governanceDir): `designs/research/<TASK-ID>.implementation-research.md`');
|
|
15
|
+
expect(text).toContain('Always read `<governanceDir>/designs/research/<TASK-ID>.implementation-research.md` before implementation');
|
|
15
16
|
});
|
|
16
17
|
it('falls back to taskNext when task is not provided', async () => {
|
|
17
18
|
const server = { registerPrompt: vi.fn() };
|
|
@@ -285,9 +285,6 @@ function normalizeTaskLink(link) {
|
|
|
285
285
|
const withoutDotPrefix = slashNormalized.replace(/^\.\//, '');
|
|
286
286
|
return withoutDotPrefix.replace(/^\/+/, '');
|
|
287
287
|
}
|
|
288
|
-
function resolveTaskLinkPath(projectPath, link) {
|
|
289
|
-
return path.join(projectPath, link);
|
|
290
|
-
}
|
|
291
288
|
function taskResearchBriefRelativePath(taskId) {
|
|
292
289
|
return `${TASK_RESEARCH_DIR}/${taskId}${TASK_RESEARCH_FILE_SUFFIX}`;
|
|
293
290
|
}
|
|
@@ -317,9 +314,8 @@ function renderTaskResearchBriefTemplate(task) {
|
|
|
317
314
|
];
|
|
318
315
|
}
|
|
319
316
|
async function inspectTaskResearchBrief(governanceDir, task) {
|
|
320
|
-
const projectPath = toProjectPath(governanceDir);
|
|
321
317
|
const relativePath = taskResearchBriefRelativePath(task.id);
|
|
322
|
-
const absolutePath =
|
|
318
|
+
const absolutePath = path.join(governanceDir, relativePath);
|
|
323
319
|
const exists = await fs.access(absolutePath).then(() => true).catch(() => false);
|
|
324
320
|
return { relativePath, absolutePath, exists, ready: exists };
|
|
325
321
|
}
|
|
@@ -327,8 +323,8 @@ function collectTaskResearchBriefLintSuggestions(state) {
|
|
|
327
323
|
if (!state.exists) {
|
|
328
324
|
return [{
|
|
329
325
|
code: TASK_LINT_CODES.RESEARCH_BRIEF_MISSING,
|
|
330
|
-
message: `Pre-execution research brief missing: ${state.relativePath}.`,
|
|
331
|
-
fixHint: 'Create the file and fill required sections before implementation.',
|
|
326
|
+
message: `Pre-execution research brief missing under governanceDir: ${state.relativePath}.`,
|
|
327
|
+
fixHint: 'Create the file under governanceDir and fill required sections before implementation.',
|
|
332
328
|
}];
|
|
333
329
|
}
|
|
334
330
|
return [];
|
|
@@ -357,14 +353,14 @@ function collectProjectContextDocsLintSuggestions(state) {
|
|
|
357
353
|
suggestions.push({
|
|
358
354
|
code: PROJECT_LINT_CODES.ARCHITECTURE_DOC_MISSING,
|
|
359
355
|
message: 'Project context is missing architecture design documentation.',
|
|
360
|
-
fixHint: `Add required file: ${CORE_ARCHITECTURE_DOC_FILE}.`,
|
|
356
|
+
fixHint: `Add required file under governanceDir: ${CORE_ARCHITECTURE_DOC_FILE}.`,
|
|
361
357
|
});
|
|
362
358
|
}
|
|
363
359
|
if (state.missingStyleDocs) {
|
|
364
360
|
suggestions.push({
|
|
365
361
|
code: PROJECT_LINT_CODES.STYLE_DOC_MISSING,
|
|
366
362
|
message: 'Project context is missing design style documentation.',
|
|
367
|
-
fixHint: `Add required file: ${CORE_STYLE_DOC_FILE}.`,
|
|
363
|
+
fixHint: `Add required file under governanceDir: ${CORE_STYLE_DOC_FILE}.`,
|
|
368
364
|
});
|
|
369
365
|
}
|
|
370
366
|
return suggestions;
|
|
@@ -1109,10 +1105,10 @@ export function registerTaskTools(server) {
|
|
|
1109
1105
|
? [
|
|
1110
1106
|
'- Project context docs are incomplete. Complete missing project architecture/style docs before deep implementation.',
|
|
1111
1107
|
...(data.projectContextDocsState.missingArchitectureDocs
|
|
1112
|
-
? [`- Missing architecture design doc: create required file ${CORE_ARCHITECTURE_DOC_FILE}.`]
|
|
1108
|
+
? [`- Missing architecture design doc: create required file under governanceDir: ${CORE_ARCHITECTURE_DOC_FILE}.`]
|
|
1113
1109
|
: []),
|
|
1114
1110
|
...(data.projectContextDocsState.missingStyleDocs
|
|
1115
|
-
? [`- Missing design style doc: create required file ${CORE_STYLE_DOC_FILE}.`]
|
|
1111
|
+
? [`- Missing design style doc: create required file under governanceDir: ${CORE_STYLE_DOC_FILE}.`]
|
|
1116
1112
|
: []),
|
|
1117
1113
|
]
|
|
1118
1114
|
: []),
|
|
@@ -1235,11 +1231,11 @@ export function registerTaskTools(server) {
|
|
|
1235
1231
|
`- architecture docs: ${projectContextDocsState.architectureDocs.length > 0 ? 'found' : 'missing'}`,
|
|
1236
1232
|
...(projectContextDocsState.architectureDocs.length > 0
|
|
1237
1233
|
? projectContextDocsState.architectureDocs.map((item) => `- architecture: ${item}`)
|
|
1238
|
-
: [`- architecture: add required file ${CORE_ARCHITECTURE_DOC_FILE}.`]),
|
|
1234
|
+
: [`- architecture: add required file under governanceDir: ${CORE_ARCHITECTURE_DOC_FILE}.`]),
|
|
1239
1235
|
`- design style docs: ${projectContextDocsState.styleDocs.length > 0 ? 'found' : 'missing'}`,
|
|
1240
1236
|
...(projectContextDocsState.styleDocs.length > 0
|
|
1241
1237
|
? projectContextDocsState.styleDocs.map((item) => `- style: ${item}`)
|
|
1242
|
-
: [`- style: add required file ${CORE_STYLE_DOC_FILE}.`]),
|
|
1238
|
+
: [`- style: add required file under governanceDir: ${CORE_STYLE_DOC_FILE}.`]),
|
|
1243
1239
|
'',
|
|
1244
1240
|
'### Related Artifacts',
|
|
1245
1241
|
...(relatedArtifacts.length > 0 ? relatedArtifacts.map((file) => `- ${file}`) : ['- (none)']),
|
|
@@ -1256,22 +1252,22 @@ export function registerTaskTools(server) {
|
|
|
1256
1252
|
...(!researchBriefState.ready
|
|
1257
1253
|
? [
|
|
1258
1254
|
'- Pre-execution gate is NOT satisfied. Complete research brief first, then proceed with implementation.',
|
|
1259
|
-
`- Create or update ${researchBriefState.relativePath} with design guidelines + code architecture findings before code changes.`,
|
|
1255
|
+
`- Create or update ${researchBriefState.relativePath} under governanceDir with design guidelines + code architecture findings before code changes.`,
|
|
1260
1256
|
'- Include exact file/line locations in the brief (for example path/to/file.ts#L120).',
|
|
1261
1257
|
'- Re-run taskContext after writing the brief and confirm researchBriefStatus becomes READY.',
|
|
1262
1258
|
]
|
|
1263
1259
|
: [
|
|
1264
1260
|
'- Pre-execution gate satisfied. Read the research brief first, then continue implementation.',
|
|
1265
|
-
`- Must read ${researchBriefState.relativePath} before any task execution changes.`,
|
|
1261
|
+
`- Must read ${researchBriefState.relativePath} under governanceDir before any task execution changes.`,
|
|
1266
1262
|
]),
|
|
1267
1263
|
...(!projectContextDocsState.ready
|
|
1268
1264
|
? [
|
|
1269
1265
|
'- Project context docs gate is NOT satisfied. Complete missing project architecture/style docs first.',
|
|
1270
1266
|
...(projectContextDocsState.missingArchitectureDocs
|
|
1271
|
-
? [`- Missing architecture design doc. Add required file ${CORE_ARCHITECTURE_DOC_FILE} and include architecture boundaries and module responsibilities.`]
|
|
1267
|
+
? [`- Missing architecture design doc. Add required file under governanceDir: ${CORE_ARCHITECTURE_DOC_FILE} and include architecture boundaries and module responsibilities.`]
|
|
1272
1268
|
: []),
|
|
1273
1269
|
...(projectContextDocsState.missingStyleDocs
|
|
1274
|
-
? [`- Missing design style doc. Add required file ${CORE_STYLE_DOC_FILE} and include style language, tokens/themes, and UI consistency rules.`]
|
|
1270
|
+
? [`- Missing design style doc. Add required file under governanceDir: ${CORE_STYLE_DOC_FILE} and include style language, tokens/themes, and UI consistency rules.`]
|
|
1275
1271
|
: []),
|
|
1276
1272
|
'- Re-run taskContext and confirm both architectureDocsStatus/styleDocsStatus are READY.',
|
|
1277
1273
|
]
|
|
@@ -1414,7 +1410,7 @@ export function registerTaskTools(server) {
|
|
|
1414
1410
|
guidance: ({ updates, originalStatus }) => [
|
|
1415
1411
|
'Task updated successfully and tasks.md has been synced. Run `taskContext` to verify the changes.',
|
|
1416
1412
|
...(updates.status === 'IN_PROGRESS' && originalStatus === 'TODO'
|
|
1417
|
-
? ['- Ensure pre-execution research brief exists before deep implementation.']
|
|
1413
|
+
? ['- Ensure pre-execution research brief exists under governanceDir before deep implementation.']
|
|
1418
1414
|
: []),
|
|
1419
1415
|
...(updates.status === 'DONE'
|
|
1420
1416
|
? ['- Verify evidence links are attached and reflect completed work.']
|
|
@@ -313,14 +313,14 @@ describe('tasks module', () => {
|
|
|
313
313
|
await fs.rm(projectRoot, { recursive: true, force: true });
|
|
314
314
|
});
|
|
315
315
|
it('taskUpdate allows TODO -> IN_PROGRESS when research brief is ready', async () => {
|
|
316
|
-
const { projectRoot, dbPath } = await createGovernanceWorkspace();
|
|
316
|
+
const { projectRoot, governanceDir, dbPath } = await createGovernanceWorkspace();
|
|
317
317
|
await replaceRoadmapsInStore(dbPath, [
|
|
318
318
|
{ id: 'ROADMAP-0001', title: 'Bootstrap', status: 'active', updatedAt: '2026-03-14T00:00:00.000Z' },
|
|
319
319
|
]);
|
|
320
320
|
await saveTasks(dbPath, [
|
|
321
321
|
normalizeTask({ id: 'TASK-0001', title: 'gate test pass', status: 'TODO', roadmapRefs: ['ROADMAP-0001'] }),
|
|
322
322
|
]);
|
|
323
|
-
const researchDir = path.join(
|
|
323
|
+
const researchDir = path.join(governanceDir, 'designs', 'research');
|
|
324
324
|
await fs.mkdir(researchDir, { recursive: true });
|
|
325
325
|
await fs.writeFile(path.join(researchDir, 'TASK-0001.implementation-research.md'), [
|
|
326
326
|
'# TASK-0001 Implementation Research Brief',
|
|
@@ -404,8 +404,8 @@ describe('tasks module', () => {
|
|
|
404
404
|
const contextResult = await taskContext({ projectPath: projectRoot, taskId: 'TASK-0001' });
|
|
405
405
|
expect(contextResult.content[0].text).toContain('architectureDocsStatus: MISSING');
|
|
406
406
|
expect(contextResult.content[0].text).toContain('styleDocsStatus: MISSING');
|
|
407
|
-
expect(contextResult.content[0].text).toContain('add required file designs/core/architecture.md');
|
|
408
|
-
expect(contextResult.content[0].text).toContain('add required file designs/core/style-guide.md');
|
|
407
|
+
expect(contextResult.content[0].text).toContain('add required file under governanceDir: designs/core/architecture.md');
|
|
408
|
+
expect(contextResult.content[0].text).toContain('add required file under governanceDir: designs/core/style-guide.md');
|
|
409
409
|
await fs.rm(projectRoot, { recursive: true, force: true });
|
|
410
410
|
});
|
|
411
411
|
it('taskUpdate allows IN_PROGRESS -> DONE with lint guidance when conformance fails', async () => {
|
|
@@ -423,7 +423,7 @@ describe('tasks module', () => {
|
|
|
423
423
|
links: [],
|
|
424
424
|
}),
|
|
425
425
|
]);
|
|
426
|
-
const researchDir = path.join(
|
|
426
|
+
const researchDir = path.join(governanceDir, 'designs', 'research');
|
|
427
427
|
await fs.mkdir(researchDir, { recursive: true });
|
|
428
428
|
await fs.writeFile(path.join(researchDir, 'TASK-0001.implementation-research.md'), [
|
|
429
429
|
'# TASK-0001 Implementation Research Brief',
|
|
@@ -467,7 +467,7 @@ describe('tasks module', () => {
|
|
|
467
467
|
links: ['README.md'],
|
|
468
468
|
}),
|
|
469
469
|
]);
|
|
470
|
-
const researchDir = path.join(
|
|
470
|
+
const researchDir = path.join(governanceDir, 'designs', 'research');
|
|
471
471
|
await fs.mkdir(researchDir, { recursive: true });
|
|
472
472
|
await fs.writeFile(path.join(researchDir, 'TASK-0001.implementation-research.md'), [
|
|
473
473
|
'# TASK-0001 Implementation Research Brief',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@projitive/mcp",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Projitive MCP Server for project and task discovery/update",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "",
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"publishConfig": {
|
|
13
13
|
"access": "public"
|
|
14
14
|
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/yinxulai/projitive"
|
|
18
|
+
},
|
|
15
19
|
"scripts": {
|
|
16
20
|
"test": "vitest run",
|
|
17
21
|
"test:coverage": "vitest run --coverage",
|