@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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@projitive/mcp",
3
- "version": "2.1.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 `designs/research/<TASK-ID>.implementation-research.md` before implementation',
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 = resolveTaskLinkPath(projectPath, relativePath);
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(projectRoot, 'designs', 'research');
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(projectRoot, 'designs', 'research');
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(projectRoot, 'designs', 'research');
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.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",