@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.
Files changed (40) hide show
  1. package/output/package.json +8 -2
  2. package/output/source/common/artifacts.js +1 -1
  3. package/output/source/common/artifacts.test.js +11 -11
  4. package/output/source/common/errors.js +19 -19
  5. package/output/source/common/files.js +11 -11
  6. package/output/source/common/files.test.js +14 -14
  7. package/output/source/common/index.js +10 -10
  8. package/output/source/common/linter.js +27 -27
  9. package/output/source/common/linter.test.js +9 -9
  10. package/output/source/common/markdown.js +3 -3
  11. package/output/source/common/markdown.test.js +15 -15
  12. package/output/source/common/response.js +74 -74
  13. package/output/source/common/response.test.js +30 -30
  14. package/output/source/common/store.js +40 -40
  15. package/output/source/common/store.test.js +72 -72
  16. package/output/source/common/types.js +3 -3
  17. package/output/source/common/utils.js +8 -8
  18. package/output/source/index.js +16 -16
  19. package/output/source/index.test.js +64 -64
  20. package/output/source/prompts/index.js +3 -3
  21. package/output/source/prompts/quickStart.js +96 -96
  22. package/output/source/prompts/taskDiscovery.js +184 -184
  23. package/output/source/prompts/taskExecution.js +148 -148
  24. package/output/source/resources/designs.js +26 -26
  25. package/output/source/resources/designs.test.js +88 -88
  26. package/output/source/resources/governance.js +19 -19
  27. package/output/source/resources/index.js +2 -2
  28. package/output/source/resources/readme.js +7 -7
  29. package/output/source/resources/readme.test.js +113 -113
  30. package/output/source/resources/reports.js +10 -10
  31. package/output/source/resources/reports.test.js +83 -83
  32. package/output/source/tools/index.js +3 -3
  33. package/output/source/tools/project.js +191 -191
  34. package/output/source/tools/project.test.js +174 -173
  35. package/output/source/tools/roadmap.js +110 -95
  36. package/output/source/tools/roadmap.test.js +54 -46
  37. package/output/source/tools/task.js +305 -277
  38. package/output/source/tools/task.test.js +117 -110
  39. package/output/source/types.js +22 -22
  40. package/package.json +8 -2
@@ -1,11 +1,11 @@
1
- import { z } from "zod";
1
+ import { z } from 'zod';
2
2
  function asUserPrompt(text) {
3
3
  return {
4
4
  messages: [
5
5
  {
6
- role: "user",
6
+ role: 'user',
7
7
  content: {
8
- type: "text",
8
+ type: 'text',
9
9
  text,
10
10
  },
11
11
  },
@@ -13,9 +13,9 @@ function asUserPrompt(text) {
13
13
  };
14
14
  }
15
15
  export function registerTaskExecutionPrompt(server) {
16
- server.registerPrompt("taskExecution", {
17
- title: "Task Execution",
18
- description: "Primary execution prompt: select one task, execute, and verify evidence consistency",
16
+ server.registerPrompt('taskExecution', {
17
+ title: 'Task Execution',
18
+ description: 'Primary execution prompt: select one task, execute, and verify evidence consistency',
19
19
  argsSchema: {
20
20
  projectPath: z.string().optional(),
21
21
  taskId: z.string().optional(),
@@ -23,150 +23,150 @@ export function registerTaskExecutionPrompt(server) {
23
23
  }, async ({ projectPath, taskId }) => {
24
24
  const taskEntry = taskId && projectPath
25
25
  ? `1) Run taskContext(projectPath="${projectPath}", taskId="${taskId}").`
26
- : "1) Run taskNext().";
26
+ : '1) Run taskNext().';
27
27
  const text = [
28
- "# Execute Task Workflow",
29
- "",
30
- "You are a Projitive task execution assistant. Here is the complete workflow:",
31
- "",
32
- "## Step 1: Get the Task",
33
- "",
28
+ '# Execute Task Workflow',
29
+ '',
30
+ 'You are a Projitive task execution assistant. Here is the complete workflow:',
31
+ '',
32
+ '## Step 1: Get the Task',
33
+ '',
34
34
  taskEntry,
35
- "",
36
- "## Step 2: Understand the Task",
37
- "",
38
- "After getting task context, read carefully:",
39
- "",
40
- "### Suggested Read Order",
41
- "Read each file in order:",
42
- "- Note content and location of each file",
43
- "- Understand task background and motivation",
44
- "- Identify task acceptance criteria",
45
- "- Look for related design decisions",
46
- "",
47
- "### Evidence",
48
- "- Candidate Files - Related file list",
49
- "- Reference Locations - Where TASK/ROADMAP IDs appear",
50
- "",
51
- "### Lint Suggestions",
52
- "Resolve any warnings before starting task execution.",
53
- "",
54
- "## Step 3: Execute the Task",
55
- "",
56
- "### Status Management",
57
- "",
58
- "| Current Status | Next Step | Description |",
59
- "|----------------|-----------|-------------|",
60
- "| TODO | \u2192 IN_PROGRESS | When starting execution |",
61
- "| IN_PROGRESS | \u2192 DONE | When task is complete |",
62
- "| IN_PROGRESS | \u2192 BLOCKED | When blocked |",
63
- "| BLOCKED | \u2192 TODO | When blocker is resolved |",
64
- "",
65
- "### Execution Steps",
66
- "",
67
- "1. **Prepare (if status is TODO)",
68
- " - Call `taskUpdate()` to change status to IN_PROGRESS",
69
- " - Set owner (if empty)",
70
- " - Fill subState (optional, Spec v1.1.0)",
71
- "",
72
- "2. **Execute task content**",
73
- " - Prefer MCP tool writes for governance store (`taskUpdate` / `roadmapUpdate`)",
74
- " - .projitive (task table) - Update task status and metadata",
75
- " - designs/*.md - Add or update design documents",
76
- " - reports/*.md - Create execution reports",
77
- " - .projitive (roadmap table) - Update roadmap (if needed)",
78
- " - taskCreate/taskUpdate/roadmapCreate/roadmapUpdate auto-sync corresponding markdown views",
79
- "",
80
- "3. **Create execution report**",
81
- " - Create new report file in reports/ directory",
82
- " - Record what changes were made",
83
- " - Record why changes were made",
84
- " - Record verification results",
85
- "",
86
- "4. **Complete task (if status is IN_PROGRESS)",
87
- " - Confirm all acceptance criteria are met",
88
- " - Call `taskUpdate()` to change status to DONE",
89
- " - Update updatedAt timestamp",
90
- "",
91
- "## Step 4: Verify Changes",
92
- "",
93
- "After execution:",
94
- "",
95
- "1. **Re-run taskContext()",
96
- " - Confirm task status updated correctly",
97
- " - Confirm updatedAt timestamp updated",
98
- "",
99
- "2. **Check reference consistency",
100
- " - Confirm all TASK/ROADMAP IDs still valid",
101
- " - Confirm no broken links in Reference Locations",
102
- "",
103
- "3. **Check Lint Suggestions",
104
- " - Confirm no new warnings",
105
- " - If there are warnings, resolve them first",
106
- "",
107
- "4. **Continue to next task (optional)",
108
- " - Call `taskNext()` for next task",
109
- " - Repeat above workflow",
110
- "",
111
- "## Autonomous Progress Rules",
112
- "",
113
- "- Keep WIP small: drive one task to DONE before starting another unless blocker requires branching.",
114
- "- Prefer unblock-first execution: if one small task unlocks multiple tasks, do it first.",
115
- "- Avoid churn: do not repeatedly flip status without producing new evidence.",
116
- "- Every loop should leave one durable artifact update (task status, report, or roadmap progress).",
117
- "",
118
- "## Special Cases",
119
- "",
120
- "### Case 1: Encountered a blocker",
121
- "",
122
- "If unable to continue task execution:",
123
- "1. Call `taskUpdate()` to change status to BLOCKED",
124
- "2. Fill blocker field (Spec v1.1.0):",
125
- " - type: Blocker type (dependency/missing-info/technical-debt/other)",
126
- " - description: Blocker description",
127
- " - relatedLinks: Related links (optional)",
128
- "3. Create a new TODO task via `taskCreate()` to resolve blocker",
129
- "",
130
- "### Case 2: No actionable tasks",
131
- "",
132
- "If taskNext() returns empty:",
133
- "1. Call `projectContext()` to recheck project state",
134
- "2. Analyze active roadmap milestones and find smallest executable slices",
135
- "2.5 If roadmap milestones are missing, create them via `roadmapCreate()`",
136
- "3. Read design documents in designs/ directory to find delivery gaps",
137
- "4. Create 1-3 new TODO tasks via `taskCreate()` only if each task has clear done condition and evidence output",
138
- "5. Re-run `taskNext()` and continue",
139
- "",
140
- "### Case 3: Need to initialize governance",
141
- "",
142
- "If .projitive directory does not exist:",
143
- "1. Call `projectInit(projectPath=\"<project-dir>\")`",
144
- "2. Then restart",
145
- "",
146
- "## Hard Rules (NEVER violate)",
147
- "",
148
- "1. **NEVER modify TASK/ROADMAP IDs**",
149
- " - Keep them immutable once assigned",
150
- " - If you need to reference, keep them as-is",
151
- "",
152
- "2. **Every status transition must have report evidence**",
153
- " - TODO \u2192 IN_PROGRESS: Report not required",
154
- " - IN_PROGRESS \u2192 DONE: Report REQUIRED",
155
- " - IN_PROGRESS \u2192 BLOCKED: Report recommended to explain blocker",
156
- "",
157
- "3. **Governance-store-first writes only**",
158
- " - tasks.md/roadmap.md are generated views, not authoritative source",
159
- " - Use taskUpdate/roadmapUpdate as primary write path",
160
- "",
161
- "4. **Always verify after updates**",
162
- " - After every taskUpdate() call",
163
- " - Re-run taskContext()",
164
- " - Confirm reference consistency",
165
- "",
166
- "5. **Keep updatedAt in sync**",
167
- " - Every time you update a task",
168
- " - Must update updatedAt to current time (ISO 8601 format)",
169
- ].join("\n");
35
+ '',
36
+ '## Step 2: Understand the Task',
37
+ '',
38
+ 'After getting task context, read carefully:',
39
+ '',
40
+ '### Suggested Read Order',
41
+ 'Read each file in order:',
42
+ '- Note content and location of each file',
43
+ '- Understand task background and motivation',
44
+ '- Identify task acceptance criteria',
45
+ '- Look for related design decisions',
46
+ '',
47
+ '### Evidence',
48
+ '- Candidate Files - Related file list',
49
+ '- Reference Locations - Where TASK/ROADMAP IDs appear',
50
+ '',
51
+ '### Lint Suggestions',
52
+ 'Resolve any warnings before starting task execution.',
53
+ '',
54
+ '## Step 3: Execute the Task',
55
+ '',
56
+ '### Status Management',
57
+ '',
58
+ '| Current Status | Next Step | Description |',
59
+ '|----------------|-----------|-------------|',
60
+ '| TODO | \u2192 IN_PROGRESS | When starting execution |',
61
+ '| IN_PROGRESS | \u2192 DONE | When task is complete |',
62
+ '| IN_PROGRESS | \u2192 BLOCKED | When blocked |',
63
+ '| BLOCKED | \u2192 TODO | When blocker is resolved |',
64
+ '',
65
+ '### Execution Steps',
66
+ '',
67
+ '1. **Prepare (if status is TODO)',
68
+ ' - Call `taskUpdate()` to change status to IN_PROGRESS',
69
+ ' - Set owner (if empty)',
70
+ ' - Fill subState (optional, Spec v1.1.0)',
71
+ '',
72
+ '2. **Execute task content**',
73
+ ' - Prefer MCP tool writes for governance store (`taskUpdate` / `roadmapUpdate`)',
74
+ ' - .projitive (task table) - Update task status and metadata',
75
+ ' - designs/*.md - Add or update design documents',
76
+ ' - reports/*.md - Create execution reports',
77
+ ' - .projitive (roadmap table) - Update roadmap (if needed)',
78
+ ' - taskCreate/taskUpdate/roadmapCreate/roadmapUpdate auto-sync corresponding markdown views',
79
+ '',
80
+ '3. **Create execution report**',
81
+ ' - Create new report file in reports/ directory',
82
+ ' - Record what changes were made',
83
+ ' - Record why changes were made',
84
+ ' - Record verification results',
85
+ '',
86
+ '4. **Complete task (if status is IN_PROGRESS)',
87
+ ' - Confirm all acceptance criteria are met',
88
+ ' - Call `taskUpdate()` to change status to DONE',
89
+ ' - Update updatedAt timestamp',
90
+ '',
91
+ '## Step 4: Verify Changes',
92
+ '',
93
+ 'After execution:',
94
+ '',
95
+ '1. **Re-run taskContext()',
96
+ ' - Confirm task status updated correctly',
97
+ ' - Confirm updatedAt timestamp updated',
98
+ '',
99
+ '2. **Check reference consistency',
100
+ ' - Confirm all TASK/ROADMAP IDs still valid',
101
+ ' - Confirm no broken links in Reference Locations',
102
+ '',
103
+ '3. **Check Lint Suggestions',
104
+ ' - Confirm no new warnings',
105
+ ' - If there are warnings, resolve them first',
106
+ '',
107
+ '4. **Continue to next task (optional)',
108
+ ' - Call `taskNext()` for next task',
109
+ ' - Repeat above workflow',
110
+ '',
111
+ '## Autonomous Progress Rules',
112
+ '',
113
+ '- Keep WIP small: drive one task to DONE before starting another unless blocker requires branching.',
114
+ '- Prefer unblock-first execution: if one small task unlocks multiple tasks, do it first.',
115
+ '- Avoid churn: do not repeatedly flip status without producing new evidence.',
116
+ '- Every loop should leave one durable artifact update (task status, report, or roadmap progress).',
117
+ '',
118
+ '## Special Cases',
119
+ '',
120
+ '### Case 1: Encountered a blocker',
121
+ '',
122
+ 'If unable to continue task execution:',
123
+ '1. Call `taskUpdate()` to change status to BLOCKED',
124
+ '2. Fill blocker field (Spec v1.1.0):',
125
+ ' - type: Blocker type (dependency/missing-info/technical-debt/other)',
126
+ ' - description: Blocker description',
127
+ ' - relatedLinks: Related links (optional)',
128
+ '3. Create a new TODO task via `taskCreate()` to resolve blocker',
129
+ '',
130
+ '### Case 2: No actionable tasks',
131
+ '',
132
+ 'If taskNext() returns empty:',
133
+ '1. Call `projectContext()` to recheck project state',
134
+ '2. Analyze active roadmap milestones and find smallest executable slices',
135
+ '2.5 If roadmap milestones are missing, create them via `roadmapCreate()`',
136
+ '3. Read design documents in designs/ directory to find delivery gaps',
137
+ '4. Create 1-3 new TODO tasks via `taskCreate()` only if each task has clear done condition and evidence output',
138
+ '5. Re-run `taskNext()` and continue',
139
+ '',
140
+ '### Case 3: Need to initialize governance',
141
+ '',
142
+ 'If .projitive directory does not exist:',
143
+ '1. Call `projectInit(projectPath="<project-dir>")`',
144
+ '2. Then restart',
145
+ '',
146
+ '## Hard Rules (NEVER violate)',
147
+ '',
148
+ '1. **NEVER modify TASK/ROADMAP IDs**',
149
+ ' - Keep them immutable once assigned',
150
+ ' - If you need to reference, keep them as-is',
151
+ '',
152
+ '2. **Every status transition must have report evidence**',
153
+ ' - TODO \u2192 IN_PROGRESS: Report not required',
154
+ ' - IN_PROGRESS \u2192 DONE: Report REQUIRED',
155
+ ' - IN_PROGRESS \u2192 BLOCKED: Report recommended to explain blocker',
156
+ '',
157
+ '3. **Governance-store-first writes only**',
158
+ ' - tasks.md/roadmap.md are generated views, not authoritative source',
159
+ ' - Use taskUpdate/roadmapUpdate as primary write path',
160
+ '',
161
+ '4. **Always verify after updates**',
162
+ ' - After every taskUpdate() call',
163
+ ' - Re-run taskContext()',
164
+ ' - Confirm reference consistency',
165
+ '',
166
+ '5. **Keep updatedAt in sync**',
167
+ ' - Every time you update a task',
168
+ ' - Must update updatedAt to current time (ISO 8601 format)',
169
+ ].join('\n');
170
170
  return asUserPrompt(text);
171
171
  });
172
172
  }
@@ -1,28 +1,28 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { isValidRoadmapId } from "../tools/roadmap.js";
4
- import { isValidTaskId } from "../tools/task.js";
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { isValidRoadmapId } from '../tools/roadmap.js';
4
+ import { isValidTaskId } from '../tools/task.js';
5
5
  export function parseDesignMetadata(markdown) {
6
6
  const lines = markdown.split(/\r?\n/);
7
7
  const metadata = {};
8
8
  for (const line of lines) {
9
9
  // Remove markdown bold markers (**)
10
- const cleanLine = line.replace(/\*\*/g, "");
11
- const [rawKey, ...rawValue] = cleanLine.split(":");
10
+ const cleanLine = line.replace(/\*\*/g, '');
11
+ const [rawKey, ...rawValue] = cleanLine.split(':');
12
12
  if (!rawKey || rawValue.length === 0) {
13
13
  continue;
14
14
  }
15
15
  const key = rawKey.trim().toLowerCase();
16
- const value = rawValue.join(":").trim();
17
- if (key === "task")
16
+ const value = rawValue.join(':').trim();
17
+ if (key === 'task')
18
18
  metadata.task = value;
19
- if (key === "roadmap")
19
+ if (key === 'roadmap')
20
20
  metadata.roadmap = value;
21
- if (key === "owner")
21
+ if (key === 'owner')
22
22
  metadata.owner = value;
23
- if (key === "status")
23
+ if (key === 'status')
24
24
  metadata.status = value;
25
- if (key === "last updated")
25
+ if (key === 'last updated')
26
26
  metadata.lastUpdated = value;
27
27
  }
28
28
  return metadata;
@@ -30,7 +30,7 @@ export function parseDesignMetadata(markdown) {
30
30
  export function validateDesignMetadata(metadata) {
31
31
  const errors = [];
32
32
  if (!metadata.task) {
33
- errors.push("Missing Task metadata");
33
+ errors.push('Missing Task metadata');
34
34
  }
35
35
  else if (!isValidTaskId(metadata.task)) {
36
36
  errors.push(`Invalid Task metadata format: ${metadata.task}`);
@@ -49,7 +49,7 @@ async function findAllMarkdownFiles(dir) {
49
49
  if (entry.isDirectory()) {
50
50
  await walk(fullPath, path.join(relativeBase, entry.name));
51
51
  }
52
- else if (entry.isFile() && entry.name.endsWith(".md")) {
52
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
53
53
  result.push({
54
54
  filePath: fullPath,
55
55
  relativePath: path.join(relativeBase, entry.name),
@@ -57,11 +57,11 @@ async function findAllMarkdownFiles(dir) {
57
57
  }
58
58
  }
59
59
  }
60
- await walk(dir, "");
60
+ await walk(dir, '');
61
61
  return result;
62
62
  }
63
63
  export async function registerDesignFilesResources(server, repoRoot) {
64
- const designsDir = path.join(repoRoot, ".projitive", "designs");
64
+ const designsDir = path.join(repoRoot, '.projitive', 'designs');
65
65
  try {
66
66
  // Check if design documents directory exists
67
67
  await fs.access(designsDir);
@@ -72,13 +72,13 @@ export async function registerDesignFilesResources(server, repoRoot) {
72
72
  // Generate designId from relative path, replace path separators with '-'
73
73
  const designId = relativePath
74
74
  .slice(0, -3) // Remove .md suffix
75
- .replace(/[\\/]/g, "-"); // Replace path separators with '-'
76
- const content = await fs.readFile(filePath, "utf-8");
75
+ .replace(/[\\/]/g, '-'); // Replace path separators with '-'
76
+ const content = await fs.readFile(filePath, 'utf-8');
77
77
  // Register resource
78
78
  server.registerResource(`design-${designId}`, `projitive://designs/${designId}`, {
79
79
  title: designId,
80
80
  description: `Design document: ${relativePath}`,
81
- mimeType: "text/markdown",
81
+ mimeType: 'text/markdown',
82
82
  }, async () => ({
83
83
  contents: [
84
84
  {
@@ -89,18 +89,18 @@ export async function registerDesignFilesResources(server, repoRoot) {
89
89
  }));
90
90
  }
91
91
  }
92
- catch (error) {
92
+ catch {
93
93
  // If design documents directory doesn't exist, register a default resource
94
94
  console.warn(`Designs directory not found at ${designsDir}, registering default design resource`);
95
- server.registerResource("designs", "projitive://designs", {
96
- title: "Designs",
97
- description: "Design documents directory",
98
- mimeType: "text/markdown",
95
+ server.registerResource('designs', 'projitive://designs', {
96
+ title: 'Designs',
97
+ description: 'Design documents directory',
98
+ mimeType: 'text/markdown',
99
99
  }, async () => ({
100
100
  contents: [
101
101
  {
102
- uri: "projitive://designs",
103
- text: `# Designs Directory\n\nDesign documents not found. Please create design files in .projitive/designs/ directory.`,
102
+ uri: 'projitive://designs',
103
+ text: '# Designs Directory\n\nDesign documents not found. Please create design files in .projitive/designs/ directory.',
104
104
  },
105
105
  ],
106
106
  }));