engimcp 1.0.0

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 (134) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE +21 -0
  3. package/README.md +345 -0
  4. package/dist/audit/auditLog.d.ts +9 -0
  5. package/dist/audit/auditLog.js +20 -0
  6. package/dist/audit/auditLog.js.map +1 -0
  7. package/dist/bom/bomService.d.ts +23 -0
  8. package/dist/bom/bomService.js +44 -0
  9. package/dist/bom/bomService.js.map +1 -0
  10. package/dist/config/projectConfig.d.ts +16 -0
  11. package/dist/config/projectConfig.js +16 -0
  12. package/dist/config/projectConfig.js.map +1 -0
  13. package/dist/config/schema.d.ts +16 -0
  14. package/dist/config/schema.js +21 -0
  15. package/dist/config/schema.js.map +1 -0
  16. package/dist/context/contextPack.d.ts +31 -0
  17. package/dist/context/contextPack.js +142 -0
  18. package/dist/context/contextPack.js.map +1 -0
  19. package/dist/context/tokenBudget.d.ts +1 -0
  20. package/dist/context/tokenBudget.js +4 -0
  21. package/dist/context/tokenBudget.js.map +1 -0
  22. package/dist/decisions/decisionService.d.ts +21 -0
  23. package/dist/decisions/decisionService.js +62 -0
  24. package/dist/decisions/decisionService.js.map +1 -0
  25. package/dist/dev/smokeProjectStatus.d.ts +1 -0
  26. package/dist/dev/smokeProjectStatus.js +9 -0
  27. package/dist/dev/smokeProjectStatus.js.map +1 -0
  28. package/dist/documents/documentService.d.ts +83 -0
  29. package/dist/documents/documentService.js +371 -0
  30. package/dist/documents/documentService.js.map +1 -0
  31. package/dist/documents/frontmatter.d.ts +14 -0
  32. package/dist/documents/frontmatter.js +30 -0
  33. package/dist/documents/frontmatter.js.map +1 -0
  34. package/dist/documents/headings.d.ts +6 -0
  35. package/dist/documents/headings.js +15 -0
  36. package/dist/documents/headings.js.map +1 -0
  37. package/dist/documents/markdownParser.d.ts +2 -0
  38. package/dist/documents/markdownParser.js +3 -0
  39. package/dist/documents/markdownParser.js.map +1 -0
  40. package/dist/documents/sectionPatch.d.ts +7 -0
  41. package/dist/documents/sectionPatch.js +73 -0
  42. package/dist/documents/sectionPatch.js.map +1 -0
  43. package/dist/documents/templates.d.ts +1 -0
  44. package/dist/documents/templates.js +62 -0
  45. package/dist/documents/templates.js.map +1 -0
  46. package/dist/filesystem/filesystemService.d.ts +168 -0
  47. package/dist/filesystem/filesystemService.js +606 -0
  48. package/dist/filesystem/filesystemService.js.map +1 -0
  49. package/dist/git/gitAdapter.d.ts +25 -0
  50. package/dist/git/gitAdapter.js +99 -0
  51. package/dist/git/gitAdapter.js.map +1 -0
  52. package/dist/graph/graphBuilder.d.ts +27 -0
  53. package/dist/graph/graphBuilder.js +126 -0
  54. package/dist/graph/graphBuilder.js.map +1 -0
  55. package/dist/graph/impact.d.ts +18 -0
  56. package/dist/graph/impact.js +53 -0
  57. package/dist/graph/impact.js.map +1 -0
  58. package/dist/graph/relations.d.ts +7 -0
  59. package/dist/graph/relations.js +28 -0
  60. package/dist/graph/relations.js.map +1 -0
  61. package/dist/index.d.ts +2 -0
  62. package/dist/index.js +16 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/mcp/errors.d.ts +5 -0
  65. package/dist/mcp/errors.js +11 -0
  66. package/dist/mcp/errors.js.map +1 -0
  67. package/dist/mcp/prompts.d.ts +2 -0
  68. package/dist/mcp/prompts.js +39 -0
  69. package/dist/mcp/prompts.js.map +1 -0
  70. package/dist/mcp/resources.d.ts +2 -0
  71. package/dist/mcp/resources.js +36 -0
  72. package/dist/mcp/resources.js.map +1 -0
  73. package/dist/mcp/tools.d.ts +2 -0
  74. package/dist/mcp/tools.js +431 -0
  75. package/dist/mcp/tools.js.map +1 -0
  76. package/dist/project/pathSafety.d.ts +6 -0
  77. package/dist/project/pathSafety.js +137 -0
  78. package/dist/project/pathSafety.js.map +1 -0
  79. package/dist/project/projectInit.d.ts +11 -0
  80. package/dist/project/projectInit.js +81 -0
  81. package/dist/project/projectInit.js.map +1 -0
  82. package/dist/project/projectService.d.ts +36 -0
  83. package/dist/project/projectService.js +60 -0
  84. package/dist/project/projectService.js.map +1 -0
  85. package/dist/project/writeGuards.d.ts +3 -0
  86. package/dist/project/writeGuards.js +46 -0
  87. package/dist/project/writeGuards.js.map +1 -0
  88. package/dist/requirements/requirementService.d.ts +19 -0
  89. package/dist/requirements/requirementService.js +72 -0
  90. package/dist/requirements/requirementService.js.map +1 -0
  91. package/dist/runtime/options.d.ts +7 -0
  92. package/dist/runtime/options.js +34 -0
  93. package/dist/runtime/options.js.map +1 -0
  94. package/dist/search/ftsIndex.d.ts +29 -0
  95. package/dist/search/ftsIndex.js +96 -0
  96. package/dist/search/ftsIndex.js.map +1 -0
  97. package/dist/search/searchService.d.ts +20 -0
  98. package/dist/search/searchService.js +17 -0
  99. package/dist/search/searchService.js.map +1 -0
  100. package/dist/server.d.ts +2 -0
  101. package/dist/server.js +16 -0
  102. package/dist/server.js.map +1 -0
  103. package/dist/storage/sqlite.d.ts +15 -0
  104. package/dist/storage/sqlite.js +80 -0
  105. package/dist/storage/sqlite.js.map +1 -0
  106. package/dist/tasks/taskService.d.ts +17 -0
  107. package/dist/tasks/taskService.js +57 -0
  108. package/dist/tasks/taskService.js.map +1 -0
  109. package/dist/utils/atomicWrite.d.ts +1 -0
  110. package/dist/utils/atomicWrite.js +10 -0
  111. package/dist/utils/atomicWrite.js.map +1 -0
  112. package/dist/utils/errors.d.ts +1 -0
  113. package/dist/utils/errors.js +2 -0
  114. package/dist/utils/errors.js.map +1 -0
  115. package/dist/utils/ids.d.ts +3 -0
  116. package/dist/utils/ids.js +25 -0
  117. package/dist/utils/ids.js.map +1 -0
  118. package/dist/validation/checks.d.ts +1 -0
  119. package/dist/validation/checks.js +2 -0
  120. package/dist/validation/checks.js.map +1 -0
  121. package/dist/validation/validator.d.ts +18 -0
  122. package/dist/validation/validator.js +131 -0
  123. package/dist/validation/validator.js.map +1 -0
  124. package/dist/verification/testReportService.d.ts +19 -0
  125. package/dist/verification/testReportService.js +42 -0
  126. package/dist/verification/testReportService.js.map +1 -0
  127. package/dist/version.d.ts +1 -0
  128. package/dist/version.js +2 -0
  129. package/dist/version.js.map +1 -0
  130. package/package.json +49 -0
  131. package/templates/design_doc.md +24 -0
  132. package/templates/edr.md +58 -0
  133. package/templates/requirement.md +30 -0
  134. package/templates/task.md +22 -0
@@ -0,0 +1,99 @@
1
+ import { execFile } from "node:child_process";
2
+ import { cp, mkdir, readdir } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { assertAbsoluteRoot, isDeniedPathForRoot, resolveSafePath } from "../project/pathSafety.js";
6
+ import { assertProjectWritable } from "../project/writeGuards.js";
7
+ const execFileAsync = promisify(execFile);
8
+ export async function getGitStatus(root) {
9
+ try {
10
+ await execFileAsync("git", ["-C", root, "rev-parse", "--is-inside-work-tree"]);
11
+ const [{ stdout: statusStdout }, diffSummary] = await Promise.all([
12
+ execFileAsync("git", ["-C", root, "status", "--short", "--untracked-files=all"]),
13
+ getDiffSummary(root)
14
+ ]);
15
+ const files = parseStatusFiles(statusStdout);
16
+ return {
17
+ is_git_repo: true,
18
+ dirty: files.length > 0,
19
+ summary: files.length === 0 ? "clean" : `${files.length} changed`,
20
+ files,
21
+ diff_summary: diffSummary
22
+ };
23
+ }
24
+ catch {
25
+ return {
26
+ is_git_repo: false,
27
+ dirty: false,
28
+ summary: "not a git repository"
29
+ };
30
+ }
31
+ }
32
+ export async function createProjectSnapshot(rootInput) {
33
+ const root = assertAbsoluteRoot(rootInput);
34
+ await assertProjectWritable(root);
35
+ const snapshotId = new Date().toISOString().replace(/[-:.TZ]/g, "");
36
+ const snapshotRelativePath = `.engimcp/snapshots/${snapshotId}`;
37
+ const snapshotPath = await resolveSafePath(root, snapshotRelativePath);
38
+ const entries = await readdir(root, { withFileTypes: true });
39
+ const copiedPaths = [];
40
+ await mkdir(snapshotPath, { recursive: true });
41
+ for (const entry of entries) {
42
+ if (shouldSkipSnapshotEntry(entry.name)) {
43
+ continue;
44
+ }
45
+ const source = path.join(root, entry.name);
46
+ const destination = path.join(snapshotPath, entry.name);
47
+ await cp(source, destination, {
48
+ recursive: true,
49
+ filter: async (sourcePath) => {
50
+ const relativePath = path.relative(root, sourcePath);
51
+ return relativePath === "" || !(await isDeniedPathForRoot(root, relativePath));
52
+ }
53
+ });
54
+ copiedPaths.push(entry.name);
55
+ }
56
+ return {
57
+ ok: true,
58
+ path: snapshotRelativePath,
59
+ copied_paths: copiedPaths.sort()
60
+ };
61
+ }
62
+ export async function createGitCommit(rootInput, message) {
63
+ const root = assertAbsoluteRoot(rootInput);
64
+ await assertProjectWritable(root);
65
+ const before = await getGitStatus(root);
66
+ if (!before.is_git_repo) {
67
+ throw new Error("Project root is not a Git repository.");
68
+ }
69
+ if (!before.dirty) {
70
+ throw new Error("No Git changes to commit.");
71
+ }
72
+ await execFileAsync("git", ["-C", root, "add", "."]);
73
+ await execFileAsync("git", ["-C", root, "commit", "-m", message]);
74
+ const { stdout } = await execFileAsync("git", ["-C", root, "rev-parse", "HEAD"]);
75
+ return {
76
+ ok: true,
77
+ commit: stdout.trim(),
78
+ message,
79
+ files: before.files ?? []
80
+ };
81
+ }
82
+ async function getDiffSummary(root) {
83
+ const { stdout } = await execFileAsync("git", ["-C", root, "diff", "--stat"]);
84
+ return stdout.trim();
85
+ }
86
+ function parseStatusFiles(stdout) {
87
+ return stdout
88
+ .trim()
89
+ .split(/\r?\n/)
90
+ .filter(Boolean)
91
+ .map((line) => ({
92
+ status: line.slice(0, 2).trim(),
93
+ path: (line[2] === " " ? line.slice(3) : line.slice(2)).trim()
94
+ }));
95
+ }
96
+ function shouldSkipSnapshotEntry(name) {
97
+ return name === ".git" || name === ".engimcp" || name === "node_modules" || name === "dist";
98
+ }
99
+ //# sourceMappingURL=gitAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gitAdapter.js","sourceRoot":"","sources":["../../src/git/gitAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type RelationType } from "./relations.js";
2
+ export interface GraphNode {
3
+ id: string;
4
+ path: string;
5
+ kind?: string;
6
+ status?: string;
7
+ }
8
+ export interface GraphEdge {
9
+ source_id: string;
10
+ relation_type: RelationType;
11
+ target_id: string;
12
+ source_path: string;
13
+ }
14
+ export interface ProjectGraph {
15
+ nodes: GraphNode[];
16
+ edges: GraphEdge[];
17
+ }
18
+ export interface GraphQueryInput {
19
+ root: string;
20
+ id: string;
21
+ direction?: "outgoing" | "incoming" | "both";
22
+ depth?: number;
23
+ relation_types?: RelationType[];
24
+ }
25
+ export declare function buildGraph(rootInput: string): Promise<ProjectGraph>;
26
+ export declare function queryGraph(input: GraphQueryInput): Promise<ProjectGraph>;
27
+ export declare function findDependencyCycles(graph: ProjectGraph): string[][];
@@ -0,0 +1,126 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { parseFrontmatter } from "../documents/frontmatter.js";
3
+ import { buildDocumentRegistry } from "../documents/documentService.js";
4
+ import { assertAbsoluteRoot } from "../project/pathSafety.js";
5
+ import { extractRelations } from "./relations.js";
6
+ export async function buildGraph(rootInput) {
7
+ const root = assertAbsoluteRoot(rootInput);
8
+ const registry = await buildDocumentRegistry(root);
9
+ const nodes = registry.documents
10
+ .filter((document) => document.id)
11
+ .map((document) => ({
12
+ id: document.id,
13
+ path: document.path,
14
+ kind: document.kind,
15
+ status: document.status
16
+ }));
17
+ const edges = (await Promise.all(registry.documents.map(async (document) => {
18
+ if (!document.id) {
19
+ return [];
20
+ }
21
+ const content = await readFile(document.absolutePath, "utf8");
22
+ const parsed = parseFrontmatter(content);
23
+ const frontmatterEdges = extractRelations(document.frontmatter).map((relation) => ({
24
+ source_id: document.id,
25
+ relation_type: relation.relation_type,
26
+ target_id: relation.target_id,
27
+ source_path: document.path
28
+ }));
29
+ const inlineEdges = extractInlineLinkTargets(parsed.body, registry.byId).map((targetId) => ({
30
+ source_id: document.id,
31
+ relation_type: "relates_to",
32
+ target_id: targetId,
33
+ source_path: document.path
34
+ }));
35
+ return [...frontmatterEdges, ...inlineEdges];
36
+ }))).flat();
37
+ return { nodes, edges: dedupeEdges(edges) };
38
+ }
39
+ export async function queryGraph(input) {
40
+ const graph = await buildGraph(input.root);
41
+ const direction = input.direction ?? "both";
42
+ const maxDepth = input.depth ?? 1;
43
+ const relationTypes = input.relation_types ? new Set(input.relation_types) : undefined;
44
+ const visited = new Set([input.id]);
45
+ const frontier = [{ id: input.id, depth: 0 }];
46
+ const selectedEdges = [];
47
+ while (frontier.length > 0) {
48
+ const current = frontier.shift();
49
+ if (!current || current.depth >= maxDepth) {
50
+ continue;
51
+ }
52
+ const edges = graph.edges.filter((edge) => {
53
+ if (relationTypes && !relationTypes.has(edge.relation_type)) {
54
+ return false;
55
+ }
56
+ if (direction === "outgoing") {
57
+ return edge.source_id === current.id;
58
+ }
59
+ if (direction === "incoming") {
60
+ return edge.target_id === current.id;
61
+ }
62
+ return edge.source_id === current.id || edge.target_id === current.id;
63
+ });
64
+ for (const edge of edges) {
65
+ selectedEdges.push(edge);
66
+ const nextId = edge.source_id === current.id ? edge.target_id : edge.source_id;
67
+ if (!visited.has(nextId)) {
68
+ visited.add(nextId);
69
+ frontier.push({ id: nextId, depth: current.depth + 1 });
70
+ }
71
+ }
72
+ }
73
+ return {
74
+ nodes: graph.nodes.filter((node) => visited.has(node.id)),
75
+ edges: dedupeEdges(selectedEdges)
76
+ };
77
+ }
78
+ export function findDependencyCycles(graph) {
79
+ const dependencyEdges = graph.edges.filter((edge) => edge.relation_type === "depends_on");
80
+ const adjacency = new Map();
81
+ const cycles = [];
82
+ for (const edge of dependencyEdges) {
83
+ adjacency.set(edge.source_id, [...(adjacency.get(edge.source_id) ?? []), edge.target_id]);
84
+ }
85
+ function visit(node, stack) {
86
+ if (stack.includes(node)) {
87
+ cycles.push([...stack.slice(stack.indexOf(node)), node]);
88
+ return;
89
+ }
90
+ for (const next of adjacency.get(node) ?? []) {
91
+ visit(next, [...stack, node]);
92
+ }
93
+ }
94
+ for (const node of adjacency.keys()) {
95
+ visit(node, []);
96
+ }
97
+ return cycles;
98
+ }
99
+ function dedupeEdges(edges) {
100
+ const seen = new Set();
101
+ return edges.filter((edge) => {
102
+ const key = `${edge.source_id}:${edge.relation_type}:${edge.target_id}`;
103
+ if (seen.has(key)) {
104
+ return false;
105
+ }
106
+ seen.add(key);
107
+ return true;
108
+ });
109
+ }
110
+ function extractInlineLinkTargets(markdown, byId) {
111
+ const targets = new Set();
112
+ for (const match of markdown.matchAll(/\[\[([A-Za-z0-9_.:-]+)(?:\|[^\]]+)?\]\]/g)) {
113
+ const target = match[1];
114
+ if (target && byId.has(target)) {
115
+ targets.add(target);
116
+ }
117
+ }
118
+ for (const match of markdown.matchAll(/\[[^\]]+\]\(([^)#\s]+)(?:#[^)]+)?\)/g)) {
119
+ const target = match[1];
120
+ if (target && byId.has(target)) {
121
+ targets.add(target);
122
+ }
123
+ }
124
+ return [...targets];
125
+ }
126
+ //# sourceMappingURL=graphBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphBuilder.js","sourceRoot":"","sources":["../../src/graph/graphBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface ImpactAnalyzeInput {
2
+ root: string;
3
+ changed_ids: string[];
4
+ change_description?: string;
5
+ depth?: number;
6
+ }
7
+ export interface ImpactItem {
8
+ id: string;
9
+ path?: string;
10
+ reason: string;
11
+ severity: "low" | "medium" | "high";
12
+ }
13
+ export interface ImpactAnalyzeResult {
14
+ impact: ImpactItem[];
15
+ recommended_reads: string[];
16
+ recommended_actions: string[];
17
+ }
18
+ export declare function analyzeImpact(input: ImpactAnalyzeInput): Promise<ImpactAnalyzeResult>;
@@ -0,0 +1,53 @@
1
+ import { buildGraph } from "./graphBuilder.js";
2
+ export async function analyzeImpact(input) {
3
+ const graph = await buildGraph(input.root);
4
+ const maxDepth = input.depth ?? 2;
5
+ const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
6
+ const impact = new Map();
7
+ const frontier = input.changed_ids.map((id) => ({ id, depth: 0, via: "changed input" }));
8
+ const visited = new Set(input.changed_ids);
9
+ while (frontier.length > 0) {
10
+ const current = frontier.shift();
11
+ if (!current || current.depth >= maxDepth) {
12
+ continue;
13
+ }
14
+ for (const edge of impactEdges(graph.edges, current.id)) {
15
+ const nextId = edge.source_id === current.id ? edge.target_id : edge.source_id;
16
+ if (visited.has(nextId)) {
17
+ continue;
18
+ }
19
+ visited.add(nextId);
20
+ frontier.push({ id: nextId, depth: current.depth + 1, via: edge.relation_type });
21
+ impact.set(nextId, {
22
+ id: nextId,
23
+ path: nodeById.get(nextId)?.path,
24
+ reason: `${nextId} is connected to ${current.id} via ${edge.relation_type}`,
25
+ severity: current.depth === 0 ? "medium" : "low"
26
+ });
27
+ }
28
+ }
29
+ return {
30
+ impact: [...impact.values()],
31
+ recommended_reads: [...impact.keys()],
32
+ recommended_actions: [
33
+ "review_impacted_documents",
34
+ "update_related_calculations",
35
+ "run_validation"
36
+ ]
37
+ };
38
+ }
39
+ function impactEdges(edges, id) {
40
+ return edges.filter((edge) => {
41
+ if (edge.relation_type === "impacts" && edge.source_id === id) {
42
+ return true;
43
+ }
44
+ if (edge.relation_type === "impacts" && edge.target_id === id) {
45
+ return true;
46
+ }
47
+ if (edge.relation_type === "depends_on" && edge.target_id === id) {
48
+ return true;
49
+ }
50
+ return false;
51
+ });
52
+ }
53
+ //# sourceMappingURL=impact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.js","sourceRoot":"","sources":["../../src/graph/impact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const relationTypes: readonly ["depends_on", "impacts", "satisfies", "verified_by", "verifies", "decided_by", "updates", "supersedes", "relates_to", "blocks", "derives_from"];
2
+ export type RelationType = (typeof relationTypes)[number];
3
+ export declare function isRelationType(value: string): value is RelationType;
4
+ export declare function extractRelations(frontmatter: Record<string, unknown>): Array<{
5
+ relation_type: RelationType;
6
+ target_id: string;
7
+ }>;
@@ -0,0 +1,28 @@
1
+ export const relationTypes = [
2
+ "depends_on",
3
+ "impacts",
4
+ "satisfies",
5
+ "verified_by",
6
+ "verifies",
7
+ "decided_by",
8
+ "updates",
9
+ "supersedes",
10
+ "relates_to",
11
+ "blocks",
12
+ "derives_from"
13
+ ];
14
+ export function isRelationType(value) {
15
+ return relationTypes.includes(value);
16
+ }
17
+ export function extractRelations(frontmatter) {
18
+ return relationTypes.flatMap((relationType) => {
19
+ const value = frontmatter[relationType];
20
+ if (Array.isArray(value)) {
21
+ return value
22
+ .filter((item) => typeof item === "string")
23
+ .map((target_id) => ({ relation_type: relationType, target_id }));
24
+ }
25
+ return typeof value === "string" ? [{ relation_type: relationType, target_id: value }] : [];
26
+ });
27
+ }
28
+ //# sourceMappingURL=relations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/graph/relations.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,YAAY;IACZ,SAAS;IACT,WAAW;IACX,aAAa;IACb,UAAU;IACV,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,YAAY;IACZ,QAAQ;IACR,cAAc;CACN,CAAC;AAIX,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAQ,aAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,WAAoC;IAInE,OAAO,aAAa,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK;iBACT,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC;iBAC1D,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { configureRuntimeOptions, parseRuntimeOptions } from "./runtime/options.js";
4
+ import { createServer } from "./server.js";
5
+ async function main() {
6
+ configureRuntimeOptions(parseRuntimeOptions(process.argv.slice(2)));
7
+ const server = createServer();
8
+ const transport = new StdioServerTransport();
9
+ await server.connect(transport);
10
+ }
11
+ main().catch((error) => {
12
+ const message = error instanceof Error ? (error.stack ?? error.message) : String(error);
13
+ console.error(message);
14
+ process.exitCode = 1;
15
+ });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,uBAAuB,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare class EngiMcpError extends Error {
2
+ readonly code: string;
3
+ readonly hint?: string | undefined;
4
+ constructor(code: string, message: string, hint?: string | undefined);
5
+ }
@@ -0,0 +1,11 @@
1
+ export class EngiMcpError extends Error {
2
+ code;
3
+ hint;
4
+ constructor(code, message, hint) {
5
+ super(message);
6
+ this.code = code;
7
+ this.hint = hint;
8
+ this.name = "EngiMcpError";
9
+ }
10
+ }
11
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/mcp/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,YAAa,SAAQ,KAAK;IAEnB;IAEA;IAHlB,YACkB,IAAY,EAC5B,OAAe,EACC,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJC,SAAI,GAAJ,IAAI,CAAQ;QAEZ,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerPrompts(server: McpServer): void;
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ export function registerPrompts(server) {
3
+ server.prompt("start_engineering_session", "Prepare an agent for an EngiMCP session.", () => ({
4
+ messages: [
5
+ {
6
+ role: "user",
7
+ content: {
8
+ type: "text",
9
+ text: "Read project status, validation summary, active context, and open tasks before making changes."
10
+ }
11
+ }
12
+ ]
13
+ }));
14
+ server.prompt("change_impact_review", "Review the impact of an engineering change.", {
15
+ change_description: z.string()
16
+ }, ({ change_description }) => ({
17
+ messages: [
18
+ {
19
+ role: "user",
20
+ content: {
21
+ type: "text",
22
+ text: `Analyze this change: ${change_description}. Run impact analysis, build a context pack, explain affected documents, and propose a minimal edit plan.`
23
+ }
24
+ }
25
+ ]
26
+ }));
27
+ server.prompt("create_engineering_decision", "Create an EDR draft.", () => ({
28
+ messages: [
29
+ {
30
+ role: "user",
31
+ content: {
32
+ type: "text",
33
+ text: "Create an Engineering Decision Record with context, problem, options, decision, consequences, affected requirements, affected documents, and open questions."
34
+ }
35
+ }
36
+ ]
37
+ }));
38
+ }
39
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,MAAM,CAAC,2BAA2B,EAAE,0CAA0C,EAAE,GAAG,EAAE,CAAC,CAAC;QAC5F,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,gGAAgG;iBACvG;aACF;SACF;KACF,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,MAAM,CACX,sBAAsB,EACtB,6CAA6C,EAC7C;QACE,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE;KAC/B,EACD,CAAC,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3B,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,wBAAwB,kBAAkB,2GAA2G;iBAC5J;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,MAAM,CAAC,6BAA6B,EAAE,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1E,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,8JAA8J;iBACrK;aACF;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerResources(server: McpServer): void;
@@ -0,0 +1,36 @@
1
+ import { getProjectMap, getProjectStatus } from "../project/projectService.js";
2
+ import { validateProject } from "../validation/validator.js";
3
+ export function registerResources(server) {
4
+ server.resource("project-status", "engi://project/status", async (uri) => ({
5
+ contents: [
6
+ {
7
+ uri: uri.href,
8
+ mimeType: "application/json",
9
+ text: JSON.stringify(await getProjectStatus({
10
+ root: process.cwd(),
11
+ include_validation_summary: true,
12
+ include_git_status: true
13
+ }), null, 2)
14
+ }
15
+ ]
16
+ }));
17
+ server.resource("project-map", "engi://project/map", async (uri) => ({
18
+ contents: [
19
+ {
20
+ uri: uri.href,
21
+ mimeType: "application/json",
22
+ text: JSON.stringify(await getProjectMap({ root: process.cwd() }), null, 2)
23
+ }
24
+ ]
25
+ }));
26
+ server.resource("validation-summary", "engi://validation/summary", async (uri) => ({
27
+ contents: [
28
+ {
29
+ uri: uri.href,
30
+ mimeType: "application/json",
31
+ text: JSON.stringify(await validateProject({ root: process.cwd() }), null, 2)
32
+ }
33
+ ]
34
+ }));
35
+ }
36
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,uBAAuB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACzE,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,MAAM,gBAAgB,CAAC;oBACrB,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE;oBACnB,0BAA0B,EAAE,IAAI;oBAChC,kBAAkB,EAAE,IAAI;iBACzB,CAAC,EACF,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACnE,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;aAC5E;SACF;KACF,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,2BAA2B,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACjF,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,GAAG,CAAC,IAAI;gBACb,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,eAAe,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;aAC9E;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerTools(server: McpServer): void;