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,371 @@
1
+ import { access, readdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { writeAuditLog } from "../audit/auditLog.js";
4
+ import { EngiMcpError } from "../mcp/errors.js";
5
+ import { assertAbsoluteRoot, isDeniedPathForRoot, resolveSafePath } from "../project/pathSafety.js";
6
+ import { assertNoGitConflictMarkers, assertProjectWritable } from "../project/writeGuards.js";
7
+ import { atomicWrite } from "../utils/atomicWrite.js";
8
+ import { parseFrontmatter, serializeDocument } from "./frontmatter.js";
9
+ import { parseHeadings } from "./headings.js";
10
+ import { patchSection } from "./sectionPatch.js";
11
+ import { loadTemplate } from "./templates.js";
12
+ const ignoredDirectories = new Set([".git", ".engimcp", "node_modules", "dist", "templates"]);
13
+ const relationFields = [
14
+ "depends_on",
15
+ "impacts",
16
+ "satisfies",
17
+ "verified_by",
18
+ "verifies",
19
+ "decided_by",
20
+ "updates",
21
+ "supersedes",
22
+ "relates_to",
23
+ "blocks",
24
+ "derives_from"
25
+ ];
26
+ export async function discoverMarkdownDocuments(rootInput) {
27
+ const root = assertAbsoluteRoot(rootInput);
28
+ const documents = [];
29
+ async function walk(directory) {
30
+ const entries = await readdir(directory, { withFileTypes: true });
31
+ for (const entry of entries) {
32
+ if (entry.isDirectory()) {
33
+ if (!ignoredDirectories.has(entry.name)) {
34
+ await walk(path.join(directory, entry.name));
35
+ }
36
+ continue;
37
+ }
38
+ if (!entry.isFile() || !entry.name.endsWith(".md")) {
39
+ continue;
40
+ }
41
+ const absolutePath = path.join(directory, entry.name);
42
+ const relativePath = path.relative(root, absolutePath);
43
+ if (await isDeniedPathForRoot(root, relativePath)) {
44
+ continue;
45
+ }
46
+ const content = await readFile(absolutePath, "utf8");
47
+ const frontmatter = parseFrontmatter(content);
48
+ const data = frontmatter.data ?? {};
49
+ documents.push({
50
+ id: data.id,
51
+ path: relativePath,
52
+ absolutePath,
53
+ kind: data.kind,
54
+ status: data.status,
55
+ version: data.version,
56
+ title: typeof data.title === "string" ? data.title : undefined,
57
+ summary: typeof data.summary === "string" ? data.summary : undefined,
58
+ frontmatter: data,
59
+ headings: parseHeadings(frontmatter.body),
60
+ frontmatterError: frontmatter.error
61
+ });
62
+ }
63
+ }
64
+ await walk(root);
65
+ return documents;
66
+ }
67
+ export async function buildDocumentRegistry(root) {
68
+ const documents = await discoverMarkdownDocuments(root);
69
+ const byId = new Map();
70
+ const byPath = new Map();
71
+ for (const document of documents) {
72
+ if (document.id && !byId.has(document.id)) {
73
+ byId.set(document.id, document);
74
+ }
75
+ byPath.set(document.path, document);
76
+ }
77
+ return { documents, byId, byPath };
78
+ }
79
+ export async function readDocument(root, input) {
80
+ const registry = await buildDocumentRegistry(root);
81
+ const document = resolveDocument(registry, input);
82
+ const content = await readFile(await resolveSafePath(root, document.path), "utf8");
83
+ const parsed = parseFrontmatter(content);
84
+ const mode = input.mode ?? "full";
85
+ const result = {
86
+ id: document.id,
87
+ path: document.path,
88
+ frontmatter: parsed.data ?? {},
89
+ links: extractFrontmatterLinks(parsed.data ?? {})
90
+ };
91
+ if (mode === "frontmatter") {
92
+ return result;
93
+ }
94
+ if (mode === "headings") {
95
+ return {
96
+ ...result,
97
+ headings: parseHeadings(parsed.body).map(formatHeading)
98
+ };
99
+ }
100
+ if (mode === "summary") {
101
+ return {
102
+ ...result,
103
+ content: document.summary ?? firstParagraph(parsed.body)
104
+ };
105
+ }
106
+ if (mode === "section") {
107
+ if (!input.heading_path || input.heading_path.length === 0) {
108
+ throw new EngiMcpError("INVALID_HEADING_PATH", "heading_path is required for section mode.");
109
+ }
110
+ return {
111
+ ...result,
112
+ content: readSection(parsed.body, input.heading_path)
113
+ };
114
+ }
115
+ return {
116
+ ...result,
117
+ content: content,
118
+ headings: parseHeadings(parsed.body).map(formatHeading)
119
+ };
120
+ }
121
+ export async function createDocument(input) {
122
+ const root = path.resolve(input.root);
123
+ await assertProjectWritable(root);
124
+ const targetPath = await resolveSafePath(root, input.path);
125
+ const templateContent = await loadTemplate(root, input.template, input.kind);
126
+ const parsed = parseFrontmatter(templateContent);
127
+ const frontmatter = {
128
+ ...(parsed.data ?? {}),
129
+ ...(input.frontmatter ?? {}),
130
+ id: input.id,
131
+ kind: input.kind
132
+ };
133
+ const body = parsed.body.replace(/^# .*(?:\r?\n|$)/, `# ${input.title}\n`);
134
+ const content = serializeDocument(frontmatter, body);
135
+ try {
136
+ await access(targetPath);
137
+ throw new EngiMcpError("DOCUMENT_EXISTS", `Document already exists: ${input.path}`);
138
+ }
139
+ catch (error) {
140
+ if (error instanceof EngiMcpError) {
141
+ throw error;
142
+ }
143
+ }
144
+ if (input.dry_run) {
145
+ return {
146
+ ok: true,
147
+ changed: true,
148
+ path: input.path,
149
+ id: input.id,
150
+ diff_summary: "dry run: document would be created",
151
+ content
152
+ };
153
+ }
154
+ await atomicWrite(targetPath, content);
155
+ const auditId = await writeAuditLog({
156
+ root,
157
+ tool: "engi_doc_create",
158
+ target: input.id,
159
+ operation: "create",
160
+ result: "ok",
161
+ diff_summary: "document created"
162
+ });
163
+ return {
164
+ ok: true,
165
+ changed: true,
166
+ path: input.path,
167
+ id: input.id,
168
+ diff_summary: "document created",
169
+ audit_id: auditId
170
+ };
171
+ }
172
+ export async function patchDocumentFrontmatter(input) {
173
+ const root = path.resolve(input.root);
174
+ await assertProjectWritable(root);
175
+ const registry = await buildDocumentRegistry(root);
176
+ const document = resolveDocument(registry, { id: input.id });
177
+ const original = await readFile(document.absolutePath, "utf8");
178
+ assertNoGitConflictMarkers(original, document.path);
179
+ const parsed = parseFrontmatter(original);
180
+ if (parsed.error) {
181
+ throw new EngiMcpError("BROKEN_FRONTMATTER", parsed.error);
182
+ }
183
+ const nextContent = serializeDocument({ ...(parsed.data ?? {}), ...input.patch }, parsed.body);
184
+ const diffSummary = summarizeLineDiff(original, nextContent);
185
+ if (input.dry_run) {
186
+ return {
187
+ ok: true,
188
+ changed: nextContent !== original,
189
+ path: document.path,
190
+ id: document.id,
191
+ diff_summary: diffSummary,
192
+ content: nextContent
193
+ };
194
+ }
195
+ await atomicWrite(document.absolutePath, nextContent);
196
+ const auditId = await writeAuditLog({
197
+ root,
198
+ tool: "engi_frontmatter_patch",
199
+ target: input.id,
200
+ operation: "frontmatter_patch",
201
+ result: "ok",
202
+ diff_summary: diffSummary
203
+ });
204
+ return {
205
+ ok: true,
206
+ changed: nextContent !== original,
207
+ path: document.path,
208
+ id: document.id,
209
+ diff_summary: diffSummary,
210
+ audit_id: auditId
211
+ };
212
+ }
213
+ export async function patchDocumentSection(input) {
214
+ const root = path.resolve(input.root);
215
+ await assertProjectWritable(root);
216
+ const registry = await buildDocumentRegistry(root);
217
+ const document = resolveDocument(registry, { id: input.id });
218
+ const original = await readFile(document.absolutePath, "utf8");
219
+ assertNoGitConflictMarkers(original, document.path);
220
+ const parsed = parseFrontmatter(original);
221
+ if (parsed.error) {
222
+ throw new EngiMcpError("BROKEN_FRONTMATTER", parsed.error);
223
+ }
224
+ const nextBody = patchSection(parsed.body, {
225
+ headingPath: input.heading_path,
226
+ operation: input.operation,
227
+ content: input.content
228
+ });
229
+ const nextContent = serializeDocument(parsed.data ?? {}, nextBody);
230
+ const diffSummary = summarizeLineDiff(original, nextContent);
231
+ if (input.dry_run) {
232
+ return {
233
+ ok: true,
234
+ changed: nextContent !== original,
235
+ path: document.path,
236
+ id: document.id,
237
+ diff_summary: diffSummary,
238
+ content: nextContent
239
+ };
240
+ }
241
+ await atomicWrite(document.absolutePath, nextContent);
242
+ const auditId = await writeAuditLog({
243
+ root,
244
+ tool: "engi_doc_patch_section",
245
+ target: input.id,
246
+ operation: input.operation,
247
+ result: "ok",
248
+ diff_summary: diffSummary
249
+ });
250
+ return {
251
+ ok: true,
252
+ changed: nextContent !== original,
253
+ path: document.path,
254
+ id: document.id,
255
+ diff_summary: diffSummary,
256
+ audit_id: auditId
257
+ };
258
+ }
259
+ export async function addDocumentRelationship(input) {
260
+ const root = path.resolve(input.root);
261
+ const registry = await buildDocumentRegistry(root);
262
+ const document = resolveDocument(registry, { id: input.id });
263
+ const current = document.frontmatter[input.relation_type];
264
+ const existing = Array.isArray(current)
265
+ ? current.filter((item) => typeof item === "string")
266
+ : typeof current === "string"
267
+ ? [current]
268
+ : [];
269
+ const next = existing.includes(input.target_id) ? existing : [...existing, input.target_id];
270
+ return patchDocumentFrontmatter({
271
+ root,
272
+ id: input.id,
273
+ patch: {
274
+ [input.relation_type]: next
275
+ },
276
+ dry_run: input.dry_run
277
+ });
278
+ }
279
+ export function extractFrontmatterLinks(frontmatter) {
280
+ return relationFields.flatMap((field) => {
281
+ const value = frontmatter[field];
282
+ if (Array.isArray(value)) {
283
+ return value.filter((item) => typeof item === "string");
284
+ }
285
+ return typeof value === "string" ? [value] : [];
286
+ });
287
+ }
288
+ function resolveDocument(registry, input) {
289
+ if (input.id) {
290
+ const document = registry.byId.get(input.id);
291
+ if (!document) {
292
+ throw new EngiMcpError("DOCUMENT_NOT_FOUND", `Document id not found: ${input.id}`);
293
+ }
294
+ return document;
295
+ }
296
+ if (input.path) {
297
+ const normalizedPath = path.normalize(input.path);
298
+ const document = registry.byPath.get(normalizedPath);
299
+ if (!document) {
300
+ throw new EngiMcpError("DOCUMENT_NOT_FOUND", `Document path not found: ${input.path}`);
301
+ }
302
+ return document;
303
+ }
304
+ if (input.kind) {
305
+ const matches = registry.documents
306
+ .filter((document) => document.kind === input.kind)
307
+ .sort((left, right) => left.path.localeCompare(right.path));
308
+ if (matches.length === 0) {
309
+ throw new EngiMcpError("DOCUMENT_NOT_FOUND", `Document kind not found: ${input.kind}`);
310
+ }
311
+ return matches[0];
312
+ }
313
+ throw new EngiMcpError("DOCUMENT_SELECTOR_REQUIRED", "Provide document id, path, or kind.");
314
+ }
315
+ function formatHeading(heading) {
316
+ return `${"#".repeat(heading.level)} ${heading.text}`;
317
+ }
318
+ function firstParagraph(markdown) {
319
+ return (markdown
320
+ .split(/\r?\n\r?\n/)
321
+ .map((part) => part.trim())
322
+ .find((part) => part.length > 0 && !part.startsWith("#")) ?? "");
323
+ }
324
+ function readSection(markdown, headingPath) {
325
+ const lines = markdown.split(/\r?\n/);
326
+ let searchFrom = 0;
327
+ let currentStart = -1;
328
+ let currentLevel = 0;
329
+ for (const heading of headingPath) {
330
+ let found = false;
331
+ for (let index = searchFrom; index < lines.length; index += 1) {
332
+ const match = lines[index]?.match(/^(#{1,6})\s+(.*)$/);
333
+ if (!match) {
334
+ continue;
335
+ }
336
+ const level = match[1].length;
337
+ if (currentLevel > 0 && level <= currentLevel) {
338
+ break;
339
+ }
340
+ if (match[2].trim() === heading) {
341
+ currentStart = index;
342
+ currentLevel = level;
343
+ searchFrom = index + 1;
344
+ found = true;
345
+ break;
346
+ }
347
+ }
348
+ if (!found) {
349
+ throw new EngiMcpError("SECTION_NOT_FOUND", `Section not found: ${heading}`);
350
+ }
351
+ }
352
+ let end = lines.length;
353
+ for (let index = currentStart + 1; index < lines.length; index += 1) {
354
+ const match = lines[index]?.match(/^(#{1,6})\s+/);
355
+ if (match && match[1].length <= currentLevel) {
356
+ end = index;
357
+ break;
358
+ }
359
+ }
360
+ return lines.slice(currentStart, end).join("\n");
361
+ }
362
+ function summarizeLineDiff(before, after) {
363
+ if (before === after) {
364
+ return "no changes";
365
+ }
366
+ const beforeLineCount = before.split(/\r?\n/).length;
367
+ const afterLineCount = after.split(/\r?\n/).length;
368
+ const delta = afterLineCount - beforeLineCount;
369
+ return delta === 0 ? "content changed" : `${Math.abs(delta)} line count delta`;
370
+ }
371
+ //# sourceMappingURL=documentService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"documentService.js","sourceRoot":"","sources":["../../src/documents/documentService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface FrontmatterData {
2
+ id?: string;
3
+ kind?: string;
4
+ status?: string;
5
+ version?: string;
6
+ [key: string]: unknown;
7
+ }
8
+ export interface ParsedFrontmatter {
9
+ data?: FrontmatterData;
10
+ body: string;
11
+ error?: string;
12
+ }
13
+ export declare function parseFrontmatter(content: string): ParsedFrontmatter;
14
+ export declare function serializeDocument(frontmatter: Record<string, unknown>, body: string): string;
@@ -0,0 +1,30 @@
1
+ import { parse } from "yaml";
2
+ import { stringify } from "yaml";
3
+ export function parseFrontmatter(content) {
4
+ if (!content.startsWith("---\n")) {
5
+ return { body: content };
6
+ }
7
+ const closingDelimiter = content.match(/\n---\s*(?:\r?\n|$)/);
8
+ if (!closingDelimiter?.index) {
9
+ return {
10
+ body: content,
11
+ error: "Missing closing frontmatter delimiter."
12
+ };
13
+ }
14
+ const raw = content.slice(4, closingDelimiter.index);
15
+ const body = content.slice(closingDelimiter.index + closingDelimiter[0].length);
16
+ try {
17
+ const parsed = parse(raw);
18
+ return { data: parsed ?? {}, body };
19
+ }
20
+ catch (error) {
21
+ return {
22
+ body,
23
+ error: error instanceof Error ? error.message : String(error)
24
+ };
25
+ }
26
+ }
27
+ export function serializeDocument(frontmatter, body) {
28
+ return `---\n${stringify(frontmatter).trimEnd()}\n---\n\n${body.trimStart()}`;
29
+ }
30
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../src/documents/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAgBjC,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC9D,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC;QAC7B,OAAO;YACL,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,wCAAwC;SAChD,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAEhF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAA2B,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI;YACJ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,WAAoC,EAAE,IAAY;IAClF,OAAO,QAAQ,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,YAAY,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;AAChF,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface Heading {
2
+ level: number;
3
+ text: string;
4
+ line: number;
5
+ }
6
+ export declare function parseHeadings(markdown: string): Heading[];
@@ -0,0 +1,15 @@
1
+ export function parseHeadings(markdown) {
2
+ return markdown
3
+ .split(/\r?\n/)
4
+ .map((line, index) => ({ line, index }))
5
+ .filter(({ line }) => /^#{1,6}\s+/.test(line))
6
+ .map(({ line, index }) => {
7
+ const marker = line.match(/^#{1,6}/)?.[0] ?? "#";
8
+ return {
9
+ level: marker.length,
10
+ text: line.slice(marker.length).trim(),
11
+ line: index + 1
12
+ };
13
+ });
14
+ }
15
+ //# sourceMappingURL=headings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headings.js","sourceRoot":"","sources":["../../src/documents/headings.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,QAAQ;SACZ,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;SACvC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAC7C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;QACjD,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE;YACtC,IAAI,EAAE,KAAK,GAAG,CAAC;SAChB,CAAC;IACJ,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { parseFrontmatter } from "./frontmatter.js";
2
+ export { parseHeadings } from "./headings.js";
@@ -0,0 +1,3 @@
1
+ export { parseFrontmatter } from "./frontmatter.js";
2
+ export { parseHeadings } from "./headings.js";
3
+ //# sourceMappingURL=markdownParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownParser.js","sourceRoot":"","sources":["../../src/documents/markdownParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type SectionPatchOperation = "replace" | "append" | "prepend" | "insert_after";
2
+ export interface SectionPatchInput {
3
+ headingPath: string[];
4
+ operation: SectionPatchOperation;
5
+ content: string;
6
+ }
7
+ export declare function patchSection(markdown: string, input: SectionPatchInput): string;
@@ -0,0 +1,73 @@
1
+ import { EngiMcpError } from "../mcp/errors.js";
2
+ export function patchSection(markdown, input) {
3
+ const lines = markdown.split(/\r?\n/);
4
+ const range = findSectionRange(lines, input.headingPath);
5
+ const existing = lines.slice(range.start, range.end).join("\n");
6
+ const nextSection = applyOperation(existing, input);
7
+ return [
8
+ ...lines.slice(0, range.start),
9
+ ...nextSection.split(/\r?\n/),
10
+ ...lines.slice(range.end)
11
+ ].join("\n");
12
+ }
13
+ function applyOperation(existing, input) {
14
+ if (input.operation === "replace") {
15
+ return input.content.trimEnd();
16
+ }
17
+ if (input.operation === "append") {
18
+ return `${existing.trimEnd()}\n\n${input.content.trimEnd()}`;
19
+ }
20
+ if (input.operation === "prepend") {
21
+ const [heading, ...body] = existing.split(/\r?\n/);
22
+ return `${heading}\n\n${input.content.trimEnd()}\n${body.join("\n").trimStart()}`;
23
+ }
24
+ return `${existing.trimEnd()}\n\n${input.content.trimEnd()}`;
25
+ }
26
+ function findSectionRange(lines, headingPath) {
27
+ if (headingPath.length === 0) {
28
+ throw new EngiMcpError("INVALID_HEADING_PATH", "Heading path must not be empty.");
29
+ }
30
+ let searchFrom = 0;
31
+ let current;
32
+ for (const heading of headingPath) {
33
+ current = findNextHeading(lines, heading, searchFrom, current?.level);
34
+ searchFrom = current.start + 1;
35
+ }
36
+ if (!current) {
37
+ throw new EngiMcpError("SECTION_NOT_FOUND", "Section not found.");
38
+ }
39
+ return {
40
+ ...current,
41
+ end: findSectionEnd(lines, current.start, current.level)
42
+ };
43
+ }
44
+ function findNextHeading(lines, text, start, parentLevel) {
45
+ for (let index = start; index < lines.length; index += 1) {
46
+ const match = lines[index]?.match(/^(#{1,6})\s+(.*)$/);
47
+ if (!match) {
48
+ continue;
49
+ }
50
+ const level = match[1].length;
51
+ if (parentLevel !== undefined && level <= parentLevel) {
52
+ break;
53
+ }
54
+ if (match[2].trim() === text) {
55
+ return {
56
+ start: index,
57
+ end: lines.length,
58
+ level
59
+ };
60
+ }
61
+ }
62
+ throw new EngiMcpError("SECTION_NOT_FOUND", `Section not found: ${text}`);
63
+ }
64
+ function findSectionEnd(lines, start, level) {
65
+ for (let index = start + 1; index < lines.length; index += 1) {
66
+ const match = lines[index]?.match(/^(#{1,6})\s+/);
67
+ if (match && match[1].length <= level) {
68
+ return index;
69
+ }
70
+ }
71
+ return lines.length;
72
+ }
73
+ //# sourceMappingURL=sectionPatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectionPatch.js","sourceRoot":"","sources":["../../src/documents/sectionPatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function loadTemplate(root: string, template: string, kind: string): Promise<string>;
@@ -0,0 +1,62 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ const builtInTemplates = {
4
+ design_doc: `---
5
+ id: DOC-EXAMPLE
6
+ kind: design_doc
7
+ status: draft
8
+ version: 0.1.0
9
+ ---
10
+
11
+ # Document Title
12
+
13
+ ## Purpose
14
+
15
+ ## Requirements
16
+
17
+ ## Current Solution
18
+
19
+ ## Calculations / Arguments
20
+
21
+ ## Risks
22
+
23
+ ## Related Documents
24
+ `,
25
+ requirement: `---
26
+ id: FR-000
27
+ kind: requirement
28
+ status: draft
29
+ version: 0.1.0
30
+ ---
31
+
32
+ # Requirement Title
33
+ `,
34
+ edr: `---
35
+ id: EDR-0000
36
+ kind: decision
37
+ status: proposed
38
+ version: 0.1.0
39
+ ---
40
+
41
+ # Decision Title
42
+ `,
43
+ task: `---
44
+ id: TASK-0000
45
+ kind: task
46
+ status: todo
47
+ version: 0.1.0
48
+ ---
49
+
50
+ # Task Title
51
+ `
52
+ };
53
+ export async function loadTemplate(root, template, kind) {
54
+ const localTemplatePath = path.join(root, "templates", `${template}.md`);
55
+ try {
56
+ return await readFile(localTemplatePath, "utf8");
57
+ }
58
+ catch {
59
+ return builtInTemplates[template] ?? builtInTemplates[kind] ?? builtInTemplates.design_doc;
60
+ }
61
+ }
62
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/documents/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,gBAAgB,GAA2B;IAC/C,UAAU,EAAE;;;;;;;;;;;;;;;;;;;;CAoBb;IACC,WAAW,EAAE;;;;;;;;CAQd;IACC,GAAG,EAAE;;;;;;;;CAQN;IACC,IAAI,EAAE;;;;;;;;CAQP;CACA,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,QAAgB,EAAE,IAAY;IAC7E,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;IAEzE,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,UAAU,CAAC;IAC7F,CAAC;AACH,CAAC"}