@projitive/mcp 1.0.7 → 1.1.1
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/README.md +3 -3
- package/output/package.json +4 -1
- package/output/source/{helpers/catch → common}/catch.js +6 -6
- package/output/source/{helpers/catch → common}/catch.test.js +6 -6
- package/output/source/common/confidence.js +231 -0
- package/output/source/common/confidence.test.js +205 -0
- package/output/source/common/errors.js +120 -0
- package/output/source/{helpers/files → common}/files.js +1 -1
- package/output/source/{helpers/files → common}/files.test.js +1 -1
- package/output/source/common/index.js +10 -0
- package/output/source/{helpers/linter/codes.js → common/linter.js} +13 -0
- package/output/source/{helpers/markdown → common}/markdown.test.js +1 -1
- package/output/source/{helpers/response → common}/response.test.js +1 -1
- package/output/source/common/types.js +7 -0
- package/output/source/common/utils.js +39 -0
- package/output/source/design-context.js +51 -500
- package/output/source/index.js +8 -193
- package/output/source/index.test.js +116 -0
- package/output/source/prompts/index.js +9 -0
- package/output/source/prompts/quickStart.js +94 -0
- package/output/source/prompts/taskDiscovery.js +190 -0
- package/output/source/prompts/taskExecution.js +161 -0
- package/output/source/resources/designs.js +108 -0
- package/output/source/resources/designs.test.js +154 -0
- package/output/source/resources/governance.js +40 -0
- package/output/source/resources/index.js +6 -0
- package/output/source/resources/readme.test.js +167 -0
- package/output/source/{reports.js → resources/reports.js} +5 -3
- package/output/source/resources/reports.test.js +149 -0
- package/output/source/tools/index.js +8 -0
- package/output/source/{projitive.js → tools/project.js} +6 -9
- package/output/source/tools/project.test.js +322 -0
- package/output/source/{roadmap.js → tools/roadmap.js} +4 -7
- package/output/source/tools/roadmap.test.js +103 -0
- package/output/source/{tasks.js → tools/task.js} +581 -27
- package/output/source/tools/task.test.js +473 -0
- package/output/source/types.js +67 -0
- package/package.json +4 -1
- package/output/source/designs.js +0 -38
- package/output/source/helpers/artifacts/index.js +0 -1
- package/output/source/helpers/catch/index.js +0 -1
- package/output/source/helpers/files/index.js +0 -1
- package/output/source/helpers/index.js +0 -6
- package/output/source/helpers/linter/index.js +0 -2
- package/output/source/helpers/linter/linter.js +0 -6
- package/output/source/helpers/markdown/index.js +0 -1
- package/output/source/helpers/response/index.js +0 -1
- package/output/source/projitive.test.js +0 -111
- package/output/source/roadmap.test.js +0 -11
- package/output/source/tasks.test.js +0 -152
- /package/output/source/{helpers/artifacts → common}/artifacts.js +0 -0
- /package/output/source/{helpers/artifacts → common}/artifacts.test.js +0 -0
- /package/output/source/{helpers/linter → common}/linter.test.js +0 -0
- /package/output/source/{helpers/markdown → common}/markdown.js +0 -0
- /package/output/source/{helpers/response → common}/response.js +0 -0
- /package/output/source/{readme.js → resources/readme.js} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Projitive unified error type definitions
|
|
2
|
+
export class ProjitiveError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
details;
|
|
5
|
+
constructor(message, code, details) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.details = details;
|
|
9
|
+
this.name = "ProjitiveError";
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
// Project related errors
|
|
13
|
+
export class ProjectError extends ProjitiveError {
|
|
14
|
+
constructor(message, code, details) {
|
|
15
|
+
super(message, code, details);
|
|
16
|
+
this.name = "ProjectError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class ProjectNotFoundError extends ProjectError {
|
|
20
|
+
constructor(inputPath) {
|
|
21
|
+
super(`Project not found at path: ${inputPath}`, "PROJECT_NOT_FOUND", {
|
|
22
|
+
inputPath,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class GovernanceRootNotFoundError extends ProjectError {
|
|
27
|
+
constructor(projectPath) {
|
|
28
|
+
super(`Governance root not found for project: ${projectPath}`, "GOVERNANCE_ROOT_NOT_FOUND", { projectPath });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// Task related errors
|
|
32
|
+
export class TaskError extends ProjitiveError {
|
|
33
|
+
constructor(message, code, details) {
|
|
34
|
+
super(message, code, details);
|
|
35
|
+
this.name = "TaskError";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class TaskNotFoundError extends TaskError {
|
|
39
|
+
constructor(taskId) {
|
|
40
|
+
super(`Task not found: ${taskId}`, "TASK_NOT_FOUND", { taskId });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class InvalidTaskIdError extends TaskError {
|
|
44
|
+
constructor(taskId) {
|
|
45
|
+
super(`Invalid task ID: ${taskId}`, "INVALID_TASK_ID", { taskId });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class TaskValidationError extends TaskError {
|
|
49
|
+
errors;
|
|
50
|
+
constructor(taskId, errors) {
|
|
51
|
+
super(`Task validation failed for ${taskId}: ${errors.join(", ")}`, "TASK_VALIDATION_FAILED", { taskId, errors });
|
|
52
|
+
this.errors = errors;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// File operation errors
|
|
56
|
+
export class FileError extends ProjitiveError {
|
|
57
|
+
filePath;
|
|
58
|
+
constructor(message, filePath, code, details) {
|
|
59
|
+
super(message, code || "FILE_ERROR", { filePath, ...details });
|
|
60
|
+
this.filePath = filePath;
|
|
61
|
+
this.name = "FileError";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export class FileNotFoundError extends FileError {
|
|
65
|
+
constructor(filePath) {
|
|
66
|
+
super(`File not found: ${filePath}`, filePath, "FILE_NOT_FOUND");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export class FileReadError extends FileError {
|
|
70
|
+
constructor(filePath, cause) {
|
|
71
|
+
super(`Failed to read file: ${filePath}`, filePath, "FILE_READ_ERROR", {
|
|
72
|
+
cause: cause?.message,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export class FileWriteError extends FileError {
|
|
77
|
+
constructor(filePath, cause) {
|
|
78
|
+
super(`Failed to write file: ${filePath}`, filePath, "FILE_WRITE_ERROR", {
|
|
79
|
+
cause: cause?.message,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Validation errors
|
|
84
|
+
export class ValidationError extends ProjitiveError {
|
|
85
|
+
errors;
|
|
86
|
+
constructor(message, errors = [], code) {
|
|
87
|
+
super(message, code || "VALIDATION_FAILED", { errors });
|
|
88
|
+
this.errors = errors;
|
|
89
|
+
this.name = "ValidationError";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export class ConfidenceScoreError extends ValidationError {
|
|
93
|
+
score;
|
|
94
|
+
constructor(message, score, errors = []) {
|
|
95
|
+
super(message, errors, "CONFIDENCE_SCORE_ERROR");
|
|
96
|
+
this.score = score;
|
|
97
|
+
this.score = score;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// MCP related errors
|
|
101
|
+
export class MCPError extends ProjitiveError {
|
|
102
|
+
constructor(message, code, details) {
|
|
103
|
+
super(message, code, details);
|
|
104
|
+
this.name = "MCPError";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export class ResourceNotFoundError extends MCPError {
|
|
108
|
+
constructor(resourceUri) {
|
|
109
|
+
super(`Resource not found: ${resourceUri}`, "RESOURCE_NOT_FOUND", {
|
|
110
|
+
resourceUri,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
export class PromptNotFoundError extends MCPError {
|
|
115
|
+
constructor(promptName) {
|
|
116
|
+
super(`Prompt not found: ${promptName}`, "PROMPT_NOT_FOUND", {
|
|
117
|
+
promptName,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { catchIt } from "
|
|
3
|
+
import { catchIt } from "./catch.js";
|
|
4
4
|
const FILE_ARTIFACTS = ["README.md", "roadmap.md", "tasks.md"];
|
|
5
5
|
const DIRECTORY_ARTIFACTS = ["designs", "reports", "hooks"];
|
|
6
6
|
async function fileLineCount(filePath) {
|
|
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { discoverGovernanceArtifacts } from
|
|
5
|
+
import { discoverGovernanceArtifacts } from './files.js';
|
|
6
6
|
const tempPaths = [];
|
|
7
7
|
async function createTempDir() {
|
|
8
8
|
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "projitive-mcp-test-"));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./errors.js";
|
|
2
|
+
export * from "./types.js";
|
|
3
|
+
export * from "./utils.js";
|
|
4
|
+
export * from "./markdown.js";
|
|
5
|
+
export * from "./files.js";
|
|
6
|
+
export * from "./response.js";
|
|
7
|
+
export * from "./confidence.js";
|
|
8
|
+
export * from "./catch.js";
|
|
9
|
+
export * from "./artifacts.js";
|
|
10
|
+
export * from "./linter.js";
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export function renderLintSuggestions(suggestions) {
|
|
2
|
+
return suggestions.map((item) => {
|
|
3
|
+
const suffix = item.fixHint ? ` ${item.fixHint}` : "";
|
|
4
|
+
return `- [${item.code}] ${item.message}${suffix}`;
|
|
5
|
+
});
|
|
6
|
+
}
|
|
1
7
|
export const TASK_LINT_CODES = {
|
|
2
8
|
DUPLICATE_ID: "TASK_DUPLICATE_ID",
|
|
3
9
|
IN_PROGRESS_OWNER_EMPTY: "TASK_IN_PROGRESS_OWNER_EMPTY",
|
|
@@ -11,6 +17,13 @@ export const TASK_LINT_CODES = {
|
|
|
11
17
|
FILTER_EMPTY: "TASK_FILTER_EMPTY",
|
|
12
18
|
CONTEXT_HOOK_HEAD_MISSING: "TASK_CONTEXT_HOOK_HEAD_MISSING",
|
|
13
19
|
CONTEXT_HOOK_FOOTER_MISSING: "TASK_CONTEXT_HOOK_FOOTER_MISSING",
|
|
20
|
+
// Spec v1.1.0 - Blocker Categorization
|
|
21
|
+
BLOCKED_WITHOUT_BLOCKER: "TASK_BLOCKED_WITHOUT_BLOCKER",
|
|
22
|
+
BLOCKER_TYPE_INVALID: "TASK_BLOCKER_TYPE_INVALID",
|
|
23
|
+
BLOCKER_DESCRIPTION_EMPTY: "TASK_BLOCKER_DESCRIPTION_EMPTY",
|
|
24
|
+
IN_PROGRESS_WITHOUT_SUBSTATE: "TASK_IN_PROGRESS_WITHOUT_SUBSTATE",
|
|
25
|
+
SUBSTATE_PHASE_INVALID: "TASK_SUBSTATE_PHASE_INVALID",
|
|
26
|
+
SUBSTATE_CONFIDENCE_INVALID: "TASK_SUBSTATE_CONFIDENCE_INVALID",
|
|
14
27
|
};
|
|
15
28
|
export const ROADMAP_LINT_CODES = {
|
|
16
29
|
IDS_EMPTY: "ROADMAP_IDS_EMPTY",
|
|
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
-
import { findTextReferences, readMarkdownSections } from
|
|
5
|
+
import { findTextReferences, readMarkdownSections } from './markdown.js';
|
|
6
6
|
const tempPaths = [];
|
|
7
7
|
async function createTempDir() {
|
|
8
8
|
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "projitive-mcp-test-"));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { asText, nextCallSection, renderErrorMarkdown, renderToolResponseMarkdown, summarySection, } from
|
|
2
|
+
import { asText, nextCallSection, renderErrorMarkdown, renderToolResponseMarkdown, summarySection, } from './response.js';
|
|
3
3
|
describe("response helpers", () => {
|
|
4
4
|
it("wraps markdown text as MCP text content", () => {
|
|
5
5
|
const result = asText("# hello");
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Common utility functions
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Safely read Markdown file content, return fallback if file doesn't exist or is empty
|
|
6
|
+
*/
|
|
7
|
+
export async function readMarkdownOrFallback(relativePath, fallbackTitle, repoRoot = process.cwd()) {
|
|
8
|
+
const absolutePath = path.resolve(repoRoot, relativePath);
|
|
9
|
+
try {
|
|
10
|
+
const content = await fs.readFile(absolutePath, "utf-8");
|
|
11
|
+
if (content.trim().length > 0) {
|
|
12
|
+
return content;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (error.code !== "ENOENT") {
|
|
17
|
+
console.error(`Failed to read file: ${absolutePath}`, error);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return [
|
|
21
|
+
`# ${fallbackTitle}`,
|
|
22
|
+
"",
|
|
23
|
+
`- file: ${relativePath}`,
|
|
24
|
+
"- status: missing-or-empty",
|
|
25
|
+
"- next: create this file or ensure it has readable markdown content",
|
|
26
|
+
].join("\n");
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Capitalize first letter
|
|
30
|
+
*/
|
|
31
|
+
export function capitalizeFirstLetter(str) {
|
|
32
|
+
return str.split(/[-_]/).map(part => part.charAt(0).toUpperCase() + part.slice(1)).join('');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Format title
|
|
36
|
+
*/
|
|
37
|
+
export function formatTitle(str) {
|
|
38
|
+
return str.split(/[-_]/).map(part => part.charAt(0).toUpperCase() + part.slice(1)).join(' ');
|
|
39
|
+
}
|