@popoverai/dotrequirements 0.23.0 → 0.24.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 +169 -22
- package/dist/cli.js +121 -60
- package/dist/codebase-to-spec/budget.d.ts +53 -0
- package/dist/codebase-to-spec/budget.js +80 -0
- package/dist/codebase-to-spec/cache.d.ts +49 -0
- package/dist/codebase-to-spec/cache.js +54 -0
- package/dist/codebase-to-spec/claude.d.ts +69 -0
- package/dist/codebase-to-spec/claude.js +126 -0
- package/dist/codebase-to-spec/compose.d.ts +49 -0
- package/dist/codebase-to-spec/compose.js +124 -0
- package/dist/codebase-to-spec/edit-loop.d.ts +54 -0
- package/dist/codebase-to-spec/edit-loop.js +195 -0
- package/dist/codebase-to-spec/editor.d.ts +54 -0
- package/dist/codebase-to-spec/editor.js +74 -0
- package/dist/codebase-to-spec/exit-codes.d.ts +40 -0
- package/dist/codebase-to-spec/exit-codes.js +58 -0
- package/dist/codebase-to-spec/fan-out.d.ts +63 -0
- package/dist/codebase-to-spec/fan-out.js +215 -0
- package/dist/codebase-to-spec/interactive.d.ts +30 -0
- package/dist/codebase-to-spec/interactive.js +48 -0
- package/dist/codebase-to-spec/outline-review-loop.d.ts +51 -0
- package/dist/codebase-to-spec/outline-review-loop.js +187 -0
- package/dist/codebase-to-spec/pack.d.ts +51 -0
- package/dist/codebase-to-spec/pack.js +127 -0
- package/dist/codebase-to-spec/planner.d.ts +41 -0
- package/dist/codebase-to-spec/planner.js +76 -0
- package/dist/codebase-to-spec/present.d.ts +94 -0
- package/dist/codebase-to-spec/present.js +288 -0
- package/dist/codebase-to-spec/progress.d.ts +33 -0
- package/dist/codebase-to-spec/progress.js +28 -0
- package/dist/codebase-to-spec/prompts/editor.d.ts +13 -0
- package/dist/codebase-to-spec/prompts/editor.js +57 -0
- package/dist/codebase-to-spec/prompts/outline-reviewer.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/outline-reviewer.js +87 -0
- package/dist/codebase-to-spec/prompts/planner-initial.d.ts +11 -0
- package/dist/codebase-to-spec/prompts/planner-initial.js +125 -0
- package/dist/codebase-to-spec/prompts/planner-revise.d.ts +14 -0
- package/dist/codebase-to-spec/prompts/planner-revise.js +60 -0
- package/dist/codebase-to-spec/prompts/spec-reviewer.d.ts +16 -0
- package/dist/codebase-to-spec/prompts/spec-reviewer.js +96 -0
- package/dist/codebase-to-spec/prompts/specifier.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/specifier.js +100 -0
- package/dist/codebase-to-spec/prompts/style-check.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/style-check.js +78 -0
- package/dist/codebase-to-spec/schemas.d.ts +257 -0
- package/dist/codebase-to-spec/schemas.js +183 -0
- package/dist/codebase-to-spec/skill-install.d.ts +57 -0
- package/dist/codebase-to-spec/skill-install.js +79 -0
- package/dist/codebase-to-spec/slice.d.ts +49 -0
- package/dist/codebase-to-spec/slice.js +111 -0
- package/dist/codebase-to-spec/specifier.d.ts +60 -0
- package/dist/codebase-to-spec/specifier.js +79 -0
- package/dist/codebase-to-spec/style-check.d.ts +29 -0
- package/dist/codebase-to-spec/style-check.js +33 -0
- package/dist/codebase-to-spec/summary.d.ts +51 -0
- package/dist/codebase-to-spec/summary.js +183 -0
- package/dist/codebase-to-spec/validate.d.ts +46 -0
- package/dist/codebase-to-spec/validate.js +130 -0
- package/dist/commands/acceptance-test.d.ts +6 -0
- package/dist/commands/{browsertest.js → acceptance-test.js} +36 -29
- package/dist/commands/ai-setup.d.ts +5 -0
- package/dist/commands/ai-setup.js +441 -0
- package/dist/commands/codebase-to-spec/compose.d.ts +14 -0
- package/dist/commands/codebase-to-spec/compose.js +57 -0
- package/dist/commands/codebase-to-spec/edit-loop.d.ts +16 -0
- package/dist/commands/codebase-to-spec/edit-loop.js +83 -0
- package/dist/commands/codebase-to-spec/fan-out.d.ts +19 -0
- package/dist/commands/codebase-to-spec/fan-out.js +77 -0
- package/dist/commands/codebase-to-spec/index.d.ts +9 -0
- package/dist/commands/codebase-to-spec/index.js +135 -0
- package/dist/commands/codebase-to-spec/pack.d.ts +22 -0
- package/dist/commands/codebase-to-spec/pack.js +76 -0
- package/dist/commands/codebase-to-spec/plan-loop.d.ts +26 -0
- package/dist/commands/codebase-to-spec/plan-loop.js +105 -0
- package/dist/commands/codebase-to-spec/present.d.ts +21 -0
- package/dist/commands/codebase-to-spec/present.js +92 -0
- package/dist/commands/codebase-to-spec/run.d.ts +20 -0
- package/dist/commands/codebase-to-spec/run.js +85 -0
- package/dist/commands/codebase-to-spec/skill-install.d.ts +20 -0
- package/dist/commands/codebase-to-spec/skill-install.js +51 -0
- package/dist/commands/codebase-to-spec/specify-area.d.ts +18 -0
- package/dist/commands/codebase-to-spec/specify-area.js +82 -0
- package/dist/commands/codebase-to-spec/style-check.d.ts +15 -0
- package/dist/commands/codebase-to-spec/style-check.js +42 -0
- package/dist/commands/codebase-to-spec/validate.d.ts +18 -0
- package/dist/commands/codebase-to-spec/validate.js +38 -0
- package/dist/commands/create-requirement-document.d.ts +2 -0
- package/dist/commands/create-requirement-document.js +41 -0
- package/dist/commands/finalize.js +7 -7
- package/dist/commands/get.d.ts +2 -0
- package/dist/commands/get.js +55 -0
- package/dist/commands/init.js +132 -117
- package/dist/commands/link.js +27 -27
- package/dist/commands/list.d.ts +6 -0
- package/dist/commands/list.js +43 -0
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/prepare.js +4 -4
- package/dist/commands/pull.js +116 -121
- package/dist/commands/push.js +106 -112
- package/dist/commands/report.d.ts +6 -2
- package/dist/commands/report.js +177 -122
- package/dist/commands/requirements-for.d.ts +2 -0
- package/dist/commands/requirements-for.js +29 -0
- package/dist/commands/review-test.d.ts +2 -0
- package/dist/commands/review-test.js +75 -0
- package/dist/commands/search.d.ts +6 -0
- package/dist/commands/search.js +39 -0
- package/dist/commands/style-check.d.ts +7 -0
- package/dist/commands/style-check.js +75 -0
- package/dist/commands/tests-for.d.ts +2 -0
- package/dist/commands/tests-for.js +80 -0
- package/dist/commands/validate.d.ts +6 -0
- package/dist/commands/validate.js +72 -0
- package/dist/config.js +1 -1
- package/dist/convex.d.ts +34 -22
- package/dist/convex.js +38 -22
- package/dist/harness/cache.d.ts +1 -5
- package/dist/harness/cache.js +49 -59
- package/dist/harness/convexReporting.d.ts +1 -1
- package/dist/harness/convexReporting.js +9 -7
- package/dist/harness/coverageCache.js +3 -3
- package/dist/harness/finalize.js +59 -46
- package/dist/harness/index.d.ts +6 -7
- package/dist/harness/index.js +9 -10
- package/dist/harness/prepare.js +6 -5
- package/dist/harness/requirementsLoader.d.ts +2 -2
- package/dist/harness/requirementsLoader.js +13 -35
- package/dist/harness/tracking.js +18 -18
- package/dist/harness/types.d.ts +1 -1
- package/dist/mcp/convexClient.d.ts +0 -39
- package/dist/mcp/convexClient.js +2 -107
- package/dist/mcp/handlers/authoring.d.ts +1 -1
- package/dist/mcp/handlers/authoring.js +30 -234
- package/dist/mcp/handlers/debug.d.ts +2 -3
- package/dist/mcp/handlers/debug.js +10 -10
- package/dist/mcp/handlers/get.d.ts +1 -1
- package/dist/mcp/handlers/get.js +11 -10
- package/dist/mcp/handlers/index.d.ts +20 -20
- package/dist/mcp/handlers/index.js +10 -10
- package/dist/mcp/handlers/list.d.ts +4 -33
- package/dist/mcp/handlers/list.js +16 -38
- package/dist/mcp/handlers/push.d.ts +1 -1
- package/dist/mcp/handlers/push.js +28 -18
- package/dist/mcp/handlers/report.d.ts +16 -0
- package/dist/mcp/handlers/report.js +134 -0
- package/dist/mcp/handlers/review.d.ts +1 -1
- package/dist/mcp/handlers/review.js +40 -59
- package/dist/mcp/handlers/search.d.ts +1 -1
- package/dist/mcp/handlers/search.js +7 -9
- package/dist/mcp/handlers/test-mapping.d.ts +1 -1
- package/dist/mcp/handlers/test-mapping.js +14 -14
- package/dist/mcp/handlers/types.d.ts +3 -3
- package/dist/mcp/handlers/types.js +2 -2
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +147 -167
- package/dist/push/core.d.ts +2 -2
- package/dist/push/core.js +20 -20
- package/dist/push/index.d.ts +1 -1
- package/dist/push/index.js +2 -2
- package/dist/requirements/cloud-ai.d.ts +57 -0
- package/dist/requirements/cloud-ai.js +104 -0
- package/dist/requirements/cloud-coverage.d.ts +41 -0
- package/dist/requirements/cloud-coverage.js +60 -0
- package/dist/requirements/coverage.d.ts +45 -0
- package/dist/requirements/coverage.js +114 -0
- package/dist/{mcp → requirements}/grep.d.ts +10 -1
- package/dist/{mcp → requirements}/grep.js +89 -44
- package/dist/{mcp/requirements.d.ts → requirements/index.d.ts} +19 -3
- package/dist/{mcp/requirements.js → requirements/index.js} +54 -35
- package/dist/requirements/style-guide.d.ts +67 -0
- package/dist/requirements/style-guide.js +299 -0
- package/dist/{mcp → requirements}/testCodeExtractor.js +24 -26
- package/dist/schema/browser.d.ts +8 -8
- package/dist/schema/browser.js +13 -15
- package/dist/schema/builder.d.ts +1 -1
- package/dist/schema/builder.js +13 -44
- package/dist/schema/conversions.d.ts +2 -2
- package/dist/schema/conversions.js +11 -11
- package/dist/schema/index.d.ts +9 -9
- package/dist/schema/index.js +15 -15
- package/dist/schema/parser-core.d.ts +1 -1
- package/dist/schema/parser-core.js +23 -22
- package/dist/schema/parser.d.ts +3 -3
- package/dist/schema/parser.js +27 -31
- package/dist/schema/resolver.d.ts +1 -1
- package/dist/schema/resolver.js +9 -9
- package/dist/schema/scenario.d.ts +1 -1
- package/dist/schema/scenario.js +1 -1
- package/dist/schema/schemas.d.ts +3 -3
- package/dist/schema/schemas.js +41 -28
- package/dist/schema/test-schema.js +27 -27
- package/dist/templates/context-file-section.md +3 -2
- package/dist/templates/example-requirements.js +1 -1
- package/dist/templates/example-requirements.ts +3 -1
- package/dist/templates/requirements-readme.js +1 -1
- package/dist/templates/requirements-readme.ts +1 -1
- package/dist/templates/skills/codebase-to-spec/SKILL.md +118 -0
- package/dist/utils/brand.js +3 -3
- package/dist/utils/browser-launch.js +4 -4
- package/dist/utils/context-file.d.ts +1 -1
- package/dist/utils/context-file.js +26 -26
- package/dist/utils/env.js +7 -7
- package/dist/utils/gitignore.js +7 -7
- package/dist/utils/oauth-callback-server.d.ts +1 -1
- package/dist/utils/oauth-callback-server.js +27 -25
- package/dist/utils/oauth-flow.js +32 -29
- package/dist/utils/project-discovery.d.ts +3 -3
- package/dist/utils/project-discovery.js +18 -17
- package/dist/utils/project-name.js +8 -8
- package/dist/utils/project-selector.d.ts +1 -1
- package/dist/utils/project-selector.js +24 -21
- package/dist/utils/project-settings.d.ts +1 -1
- package/dist/utils/project-settings.js +24 -22
- package/dist/utils/templates.js +6 -6
- package/package.json +3 -2
- package/dist/commands/browsertest.d.ts +0 -6
- package/dist/commands/login.d.ts +0 -12
- package/dist/commands/login.js +0 -117
- package/dist/commands/logout.d.ts +0 -5
- package/dist/commands/logout.js +0 -17
- package/dist/commands/mcp-setup.d.ts +0 -5
- package/dist/commands/mcp-setup.js +0 -431
- package/dist/commands/test.d.ts +0 -6
- package/dist/commands/test.js +0 -78
- package/dist/mcp/handlers/coverage.d.ts +0 -44
- package/dist/mcp/handlers/coverage.js +0 -105
- package/dist/mcp/types.d.ts +0 -27
- package/dist/mcp/types.js +0 -2
- package/dist/utils/local-project.d.ts +0 -31
- package/dist/utils/local-project.js +0 -33
- package/dist/utils/token-refresh.d.ts +0 -24
- package/dist/utils/token-refresh.js +0 -69
- package/dist/utils/token-storage.d.ts +0 -31
- package/dist/utils/token-storage.js +0 -57
- /package/dist/{mcp → requirements}/testCodeExtractor.d.ts +0 -0
|
@@ -15,44 +15,5 @@ interface ConvexConfig {
|
|
|
15
15
|
* Returns null if credentials are not configured.
|
|
16
16
|
*/
|
|
17
17
|
export declare function loadConvexConfig(cwd?: string): ConvexConfig | null;
|
|
18
|
-
/**
|
|
19
|
-
* Query Convex for requirement coverage
|
|
20
|
-
*/
|
|
21
|
-
export declare function getRequirementCoverage(requirementKey: string, projectId: string, projectSecret: string, convexUrl: string): Promise<{
|
|
22
|
-
requirementKey: string;
|
|
23
|
-
lastTestedAt: number | null;
|
|
24
|
-
branch: string | null;
|
|
25
|
-
testFile: string | null;
|
|
26
|
-
testLine: number | null;
|
|
27
|
-
allBranches: Array<{
|
|
28
|
-
branch: string;
|
|
29
|
-
lastTestedAt: number;
|
|
30
|
-
testFile?: string;
|
|
31
|
-
testLine?: number;
|
|
32
|
-
}>;
|
|
33
|
-
}>;
|
|
34
|
-
/**
|
|
35
|
-
* Query Convex for project coverage summary
|
|
36
|
-
*/
|
|
37
|
-
export declare function getProjectCoverage(projectId: string, projectSecret: string, convexUrl: string, options?: {
|
|
38
|
-
branch?: string;
|
|
39
|
-
sinceTimestamp?: number;
|
|
40
|
-
}): Promise<{
|
|
41
|
-
tested: Array<{
|
|
42
|
-
requirementKey: string;
|
|
43
|
-
lastTestedAt: number;
|
|
44
|
-
branch: string;
|
|
45
|
-
testFile?: string;
|
|
46
|
-
testLine?: number;
|
|
47
|
-
}>;
|
|
48
|
-
untested: string[];
|
|
49
|
-
}>;
|
|
50
|
-
/**
|
|
51
|
-
* PROJ-CONTEXT-7: Query Convex for project context (AI style guidelines)
|
|
52
|
-
*/
|
|
53
|
-
export declare function getProjectContext(projectId: string, projectSecret: string, convexUrl: string): Promise<{
|
|
54
|
-
projectContext: string | null;
|
|
55
|
-
requirementsStyleContext: string | null;
|
|
56
|
-
} | null>;
|
|
57
18
|
export {};
|
|
58
19
|
//# sourceMappingURL=convexClient.d.ts.map
|
package/dist/mcp/convexClient.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { getProjectCredentials } from
|
|
1
|
+
import { getProjectCredentials } from "../utils/project-settings.js";
|
|
2
2
|
/**
|
|
3
3
|
* Production Convex deployment URL
|
|
4
4
|
*/
|
|
5
|
-
export const CONVEX_URL =
|
|
5
|
+
export const CONVEX_URL = "https://data.dotrequirements.io";
|
|
6
6
|
/**
|
|
7
7
|
* Load Convex configuration from project settings.
|
|
8
8
|
* Returns null if credentials are not configured.
|
|
@@ -21,109 +21,4 @@ export function loadConvexConfig(cwd = process.cwd()) {
|
|
|
21
21
|
return null;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Query Convex for requirement coverage
|
|
26
|
-
*/
|
|
27
|
-
export async function getRequirementCoverage(requirementKey, projectId, projectSecret, convexUrl) {
|
|
28
|
-
const response = await fetch(`${convexUrl}/api/query`, {
|
|
29
|
-
method: 'POST',
|
|
30
|
-
headers: { 'Content-Type': 'application/json' },
|
|
31
|
-
body: JSON.stringify({
|
|
32
|
-
path: 'testCoverage/queries:getRequirementCoverage',
|
|
33
|
-
args: {
|
|
34
|
-
projectAuth: {
|
|
35
|
-
projectSlug: projectId,
|
|
36
|
-
projectSecret,
|
|
37
|
-
},
|
|
38
|
-
target: {
|
|
39
|
-
type: 'project',
|
|
40
|
-
slug: projectId,
|
|
41
|
-
},
|
|
42
|
-
requirementKey,
|
|
43
|
-
},
|
|
44
|
-
format: 'json',
|
|
45
|
-
}),
|
|
46
|
-
});
|
|
47
|
-
if (!response.ok) {
|
|
48
|
-
throw new Error(`Failed to query coverage: ${response.statusText}`);
|
|
49
|
-
}
|
|
50
|
-
const json = await response.json();
|
|
51
|
-
if (json.status === 'error') {
|
|
52
|
-
throw new Error(`Convex query failed: ${json.errorMessage}`);
|
|
53
|
-
}
|
|
54
|
-
return json.value;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Query Convex for project coverage summary
|
|
58
|
-
*/
|
|
59
|
-
export async function getProjectCoverage(projectId, projectSecret, convexUrl, options) {
|
|
60
|
-
const response = await fetch(`${convexUrl}/api/query`, {
|
|
61
|
-
method: 'POST',
|
|
62
|
-
headers: { 'Content-Type': 'application/json' },
|
|
63
|
-
body: JSON.stringify({
|
|
64
|
-
path: 'testCoverage/queries:getProjectCoverage',
|
|
65
|
-
args: {
|
|
66
|
-
projectAuth: {
|
|
67
|
-
projectSlug: projectId,
|
|
68
|
-
projectSecret,
|
|
69
|
-
},
|
|
70
|
-
target: {
|
|
71
|
-
type: 'project',
|
|
72
|
-
slug: projectId,
|
|
73
|
-
},
|
|
74
|
-
branch: options?.branch,
|
|
75
|
-
sinceTimestamp: options?.sinceTimestamp,
|
|
76
|
-
},
|
|
77
|
-
format: 'json',
|
|
78
|
-
}),
|
|
79
|
-
});
|
|
80
|
-
if (!response.ok) {
|
|
81
|
-
throw new Error(`Failed to query coverage: ${response.statusText}`);
|
|
82
|
-
}
|
|
83
|
-
const json = await response.json();
|
|
84
|
-
if (json.status === 'error') {
|
|
85
|
-
throw new Error(`Convex query failed: ${json.errorMessage}`);
|
|
86
|
-
}
|
|
87
|
-
return json.value;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* PROJ-CONTEXT-7: Query Convex for project context (AI style guidelines)
|
|
91
|
-
*/
|
|
92
|
-
export async function getProjectContext(projectId, projectSecret, convexUrl) {
|
|
93
|
-
try {
|
|
94
|
-
const response = await fetch(`${convexUrl}/api/query`, {
|
|
95
|
-
method: 'POST',
|
|
96
|
-
headers: { 'Content-Type': 'application/json' },
|
|
97
|
-
body: JSON.stringify({
|
|
98
|
-
path: 'projects/queries:get',
|
|
99
|
-
args: {
|
|
100
|
-
projectAuth: {
|
|
101
|
-
projectSlug: projectId,
|
|
102
|
-
projectSecret,
|
|
103
|
-
},
|
|
104
|
-
target: {
|
|
105
|
-
type: 'project',
|
|
106
|
-
slug: projectId,
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
format: 'json',
|
|
110
|
-
}),
|
|
111
|
-
});
|
|
112
|
-
if (!response.ok) {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
const json = await response.json();
|
|
116
|
-
if (json.status === 'error' || !json.value) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
return {
|
|
120
|
-
projectContext: json.value.projectContext ?? null,
|
|
121
|
-
requirementsStyleContext: json.value.requirementsStyleContext ?? null,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
// Non-fatal: return null if query fails
|
|
126
|
-
return null;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
24
|
//# sourceMappingURL=convexClient.js.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* - create_requirement_document: Generate requirements template with format guidance
|
|
6
6
|
* - validate_requirements: Validate requirements file syntax offline
|
|
7
7
|
*/
|
|
8
|
-
import type { HandlerContext, ToolResponse } from
|
|
8
|
+
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
9
9
|
/**
|
|
10
10
|
* Arguments for create_requirement_document tool
|
|
11
11
|
*/
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
* - create_requirement_document: Generate requirements template with format guidance
|
|
6
6
|
* - validate_requirements: Validate requirements file syntax offline
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import { getProjectContext } from "../../requirements/cloud-ai.js";
|
|
11
|
+
import { generateStyleGuide, readLocalStyleGuide, } from "../../requirements/style-guide.js";
|
|
12
|
+
import { parseRequirementsFromFile, validateForPush, } from "../../schema/index.js";
|
|
13
|
+
import { CONVEX_URL } from "../convexClient.js";
|
|
14
|
+
import { errorResponse, textResponse } from "./types.js";
|
|
13
15
|
/**
|
|
14
16
|
* Handler for create_requirement_document tool
|
|
15
17
|
*
|
|
@@ -20,245 +22,32 @@ import { CONVEX_URL, getProjectContext, } from '../convexClient.js';
|
|
|
20
22
|
* - MCP-AUTHOR-1.3: When cloud credentials are unavailable, the template works without the custom context
|
|
21
23
|
*/
|
|
22
24
|
export async function handleCreateRequirementDocument(args, context) {
|
|
23
|
-
const { filePath =
|
|
24
|
-
//
|
|
25
|
-
// Try to get requirements, but don't fail if no project is configured
|
|
25
|
+
const { filePath = ".requirements/example.requirements.md" } = args;
|
|
26
|
+
// MCP-AUTHOR-1.3: Try to get requirements, but don't fail if no project is configured
|
|
26
27
|
let requirements = [];
|
|
27
28
|
try {
|
|
28
29
|
requirements = await context.getRequirements();
|
|
29
30
|
}
|
|
30
31
|
catch {
|
|
31
|
-
//
|
|
32
|
-
}
|
|
33
|
-
const labels = new Set();
|
|
34
|
-
const keyPrefixes = new Set();
|
|
35
|
-
for (const req of requirements) {
|
|
36
|
-
// Collect labels (empty string means unlabeled, so skip those)
|
|
37
|
-
if (req.label && req.label.trim()) {
|
|
38
|
-
labels.add(req.label);
|
|
39
|
-
}
|
|
40
|
-
// Collect requirement key prefixes (root IDs only)
|
|
41
|
-
// Extract prefix from keys like "AUTH-1" -> "AUTH", "LOGIN-FLOW-2" -> "LOGIN-FLOW"
|
|
42
|
-
if (req.path.length === 0 && req.id) {
|
|
43
|
-
const lastDashIndex = req.id.lastIndexOf('-');
|
|
44
|
-
if (lastDashIndex > 0) {
|
|
45
|
-
const prefix = req.id.substring(0, lastDashIndex);
|
|
46
|
-
keyPrefixes.add(prefix);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
const discoveredLabels = Array.from(labels).sort();
|
|
51
|
-
const discoveredPrefixes = Array.from(keyPrefixes).sort();
|
|
52
|
-
let labelGuidance = '';
|
|
53
|
-
let keyGuidance = '';
|
|
54
|
-
// Generate label guidance
|
|
55
|
-
if (discoveredLabels.length > 0) {
|
|
56
|
-
const labelList = discoveredLabels.slice(0, 10).map(l => `"${l}"`).join(', ');
|
|
57
|
-
const more = discoveredLabels.length > 10 ? ` (and ${discoveredLabels.length - 10} more)` : '';
|
|
58
|
-
labelGuidance = `**Existing labels in this codebase:** ${labelList}${more}
|
|
59
|
-
|
|
60
|
-
**Use these existing labels** to maintain consistency. If you're unsure which labels to use for a new requirement, ask the user.`;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
labelGuidance = `**No existing requirements found in this codebase.**
|
|
64
|
-
|
|
65
|
-
**Default to unlabeled requirements** (\`0. → content\`). If the user wants labels, ask them which format they prefer. Do not choose an opinionated framework like Given/When/Then without explicit user consent.`;
|
|
66
|
-
}
|
|
67
|
-
// Generate key guidance
|
|
68
|
-
if (discoveredPrefixes.length > 0) {
|
|
69
|
-
const prefixList = discoveredPrefixes.map(p => `"${p}"`).join(', ');
|
|
70
|
-
keyGuidance = `**Existing requirement key prefixes in this codebase:** ${prefixList}
|
|
71
|
-
|
|
72
|
-
**Match the existing pattern** when creating new requirement keys. Use the same domain prefixes and sequential numbering style.`;
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
keyGuidance = `**No existing requirements found in this codebase.**
|
|
76
|
-
|
|
77
|
-
**Use concise domain prefixes** like \`AUTH-1\`, \`LOGIN-1\`, etc. Start numbering at 1 and increment sequentially.`;
|
|
32
|
+
// No project configured — discovered patterns will be empty
|
|
78
33
|
}
|
|
79
34
|
// MCP-AUTHOR-1.2: Try to fetch user-provided style context from cloud
|
|
80
|
-
let
|
|
35
|
+
let customStyleGuidance = null;
|
|
81
36
|
try {
|
|
82
37
|
const project = await context.getProjectFromDiscovery();
|
|
83
38
|
const contextData = await getProjectContext(project.projectId, project.projectSecret, CONVEX_URL);
|
|
84
|
-
|
|
85
|
-
userStyleGuidance = `
|
|
86
|
-
|
|
87
|
-
## User-Provided Style Guidelines
|
|
88
|
-
|
|
89
|
-
The following style guidelines were provided by the project owner. When these conflict with the defaults above, prioritize the user's guidelines.
|
|
90
|
-
|
|
91
|
-
${contextData.requirementsStyleContext.trim()}`;
|
|
92
|
-
}
|
|
39
|
+
customStyleGuidance = contextData?.requirementsStyleContext ?? null;
|
|
93
40
|
}
|
|
94
41
|
catch {
|
|
95
42
|
// MCP-AUTHOR-1.3: No credentials or cloud unavailable - continue without user context
|
|
96
43
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# Example Requirements
|
|
105
|
-
|
|
106
|
-
This template demonstrates the dotrequirements Markdown format and style guidelines.
|
|
107
|
-
|
|
108
|
-
## Syntax Overview
|
|
109
|
-
|
|
110
|
-
**File naming:** Use \`*.requirements.md\` pattern (colocated: \`auth.requirements.md\` or centralized: \`.requirements/auth.requirements.md\`)
|
|
111
|
-
|
|
112
|
-
**Block format:**
|
|
113
|
-
\`\`\`dotrequirements
|
|
114
|
-
KEY: Root requirement content
|
|
115
|
-
0. → First criterion (unlabeled)
|
|
116
|
-
1. Label → Second criterion (with label)
|
|
117
|
-
1.0. → Nested criterion (unlabeled)
|
|
118
|
-
\`\`\`
|
|
119
|
-
|
|
120
|
-
- First line: \`KEY: content\` (requirement key and description)
|
|
121
|
-
- Criteria: \`position. Label → content\` or \`position. → content\` (unlabeled)
|
|
122
|
-
- Position: \`0\`, \`1\`, \`2\` (top-level) or \`0.0\`, \`1.0\` (nested) - defines hierarchy
|
|
123
|
-
- Delimiter: \`→\` or \`->\` separates optional label from content
|
|
124
|
-
|
|
125
|
-
## Requirement Keys: Concise and Sequential
|
|
126
|
-
|
|
127
|
-
${keyGuidance}
|
|
128
|
-
|
|
129
|
-
**Key format:** \`DOMAIN-FEATURE-N\` where N is sequential (1, 2, 3...)
|
|
130
|
-
|
|
131
|
-
**Best practices:**
|
|
132
|
-
1. **Concise domains** - Use short, clear prefixes
|
|
133
|
-
- ✅ \`AUTHZ-1\` (authorization)
|
|
134
|
-
- ✅ \`AUTH-1\` (authentication)
|
|
135
|
-
- ❌ \`AUTHORIZATION-1\` (too verbose)
|
|
136
|
-
- ❌ \`REQ-IDENTITY-ACCESS-AUTHZ-1\` (too nested)
|
|
137
|
-
|
|
138
|
-
2. **Sequential, 1-indexed numbering** - Start at 1, no padding
|
|
139
|
-
- ✅ \`LOGIN-1\`, \`LOGIN-2\`, \`LOGIN-3\`
|
|
140
|
-
- ❌ \`LOGIN-0\` (don't use 0-indexing for requirement IDs)
|
|
141
|
-
- ❌ \`LOGIN-001\` (no zero-padding)
|
|
142
|
-
|
|
143
|
-
3. **Unique across project** - Each key must be unique in the entire project
|
|
144
|
-
|
|
145
|
-
4. **Match existing patterns** - Check existing requirements first and follow their convention
|
|
146
|
-
|
|
147
|
-
## Labels: Match Your Codebase or Ask the User
|
|
148
|
-
|
|
149
|
-
${labelGuidance}
|
|
150
|
-
|
|
151
|
-
## Style Principles for Requirements
|
|
152
|
-
|
|
153
|
-
**1. Use Concrete Examples**: Replace vague language with specific, testable conditions.
|
|
154
|
-
- ❌ "users can log in" or "works properly"
|
|
155
|
-
- ✅ "When a registered user provides valid credentials, they are authenticated"
|
|
156
|
-
|
|
157
|
-
**2. Write Natural, Concise Prose**: Avoid terseness and verbosity. Use declarative style (not "should").
|
|
158
|
-
- ❌ "registered user with valid credentials is authenticated" (too terse)
|
|
159
|
-
- ❌ "A registered user, whose account was created on Tuesday and whose life story is as follows..." (too verbose)
|
|
160
|
-
- ✅ "When a registered user provides valid credentials, they are authenticated"
|
|
161
|
-
|
|
162
|
-
**3. Keep Arrange/Act/Assert in Mind**: Well-written requirements describe preconditions, trigger, and result.
|
|
163
|
-
- ✅ "When [preconditions:] a registered user [trigger:] provides valid credentials, [result:] they are authenticated"
|
|
164
|
-
|
|
165
|
-
**4. Be Framework Neutral**: Don't prescribe Given/When/Then vs AC vs other formats - focus on content quality.
|
|
166
|
-
|
|
167
|
-
**5. Use Named Personas**: Establish personas in parent requirements, reuse in children.
|
|
168
|
-
- ✅ Parent: "A registered user, Jamie, can log in normally" → Child: "When Jamie provides valid credentials, they are authenticated"
|
|
169
|
-
|
|
170
|
-
**6. Use User-Centric Language**: Describe user experience, not technical internals.
|
|
171
|
-
- ❌ "they are redirected to app.dotrequirements.io/redirect/dashboard"
|
|
172
|
-
- ✅ "they are automatically brought to the dashboard"
|
|
173
|
-
|
|
174
|
-
**7. Single Action Per Requirement**: Don't chain multiple actions with "and then".
|
|
175
|
-
- ❌ "When Robin provides credentials, requests an OTP, then provides the OTP..."
|
|
176
|
-
- ✅ Break into separate requirements for each action
|
|
177
|
-
|
|
178
|
-
**8. Each Requirement Should Be Independent**: Requirements within a block should be independently testable. If they share preconditions or form a sequence, either nest them or restate context.
|
|
179
|
-
- ❌ "0. → When Jordan submits signup, an account is created" / "1. → Welcome email is sent" / "2. → Dashboard appears"
|
|
180
|
-
- ✅ Option A: Restate context - "1. → When Jordan submits signup, a welcome email is sent"
|
|
181
|
-
- ✅ Option B: Use nesting - "0. When → Jordan submits signup" / " 0.0. Then → an account is created"
|
|
182
|
-
- Test: Can you understand what's being tested by reading just one requirement, or do you need to read its siblings?
|
|
183
|
-
|
|
184
|
-
**9. Focus on Behavior, Not Design**: Describe what happens, not UI specifics.
|
|
185
|
-
- ❌ "enters valid credentials into two single-line input fields and presses a green button"
|
|
186
|
-
- ✅ "provides valid credentials"
|
|
187
|
-
|
|
188
|
-
**10. Focus on Outcomes, Not Implementation**: User perspective, even for technical requirements.
|
|
189
|
-
- ❌ "When the app requests that Twilio send Casey an OTP from /email/POST endpoint..."
|
|
190
|
-
- ✅ "When Casey requests an email OTP..."
|
|
191
|
-
- Note: Even technical requirements can be user-centric: "95 percent of users experience under 1 second of delay"
|
|
192
|
-
|
|
193
|
-
**11. Decompose Large Requirements**: If it can't be validated with a single test, break it down.
|
|
194
|
-
${userStyleGuidance}
|
|
195
|
-
|
|
196
|
-
## Example Requirements
|
|
197
|
-
|
|
198
|
-
**Unlabeled (recommended default):**
|
|
199
|
-
\`\`\`dotrequirements
|
|
200
|
-
AUTH-LOGIN-1: A registered user, Jamie, can log in to their account
|
|
201
|
-
0. → When Jamie provides their registered email and correct password, they are authenticated and brought to their dashboard
|
|
202
|
-
1. → When Jamie provides an incorrect password, they see an error message and remain on the login page
|
|
203
|
-
2. → When Jamie's account has been deactivated, they see a message explaining their account status
|
|
204
|
-
\`\`\`
|
|
205
|
-
|
|
206
|
-
**With labels (example only - DO NOT use opinionated formats like Given/When/Then without asking the user first):**
|
|
207
|
-
\`\`\`dotrequirements
|
|
208
|
-
PAYMENT-REFUND-1: A customer, Alex, receives a refund after returning an item
|
|
209
|
-
0. Given → Alex purchased a laptop from the store 10 days ago
|
|
210
|
-
1. Given → Alex initiates a return through their order history
|
|
211
|
-
2. When → Alex's returned laptop is received and inspected at the warehouse
|
|
212
|
-
3. Then → Alex receives a refund to their original payment method within 5 business days
|
|
213
|
-
4. Then → Alex receives an email confirmation with the refund amount and expected timeline
|
|
214
|
-
\`\`\`
|
|
215
|
-
|
|
216
|
-
## Referencing Requirements in Tests
|
|
217
|
-
|
|
218
|
-
**Use \`requirement()\` as the test description** - it returns a string:
|
|
219
|
-
|
|
220
|
-
\`\`\`typescript
|
|
221
|
-
import { describe, it, expect } from 'vitest';
|
|
222
|
-
import { requirement } from '@popoverai/dotrequirements/test';
|
|
223
|
-
|
|
224
|
-
describe(requirement('AUTH-LOGIN-1'), () => {
|
|
225
|
-
describe(requirement('AUTH-LOGIN-1.given'), () => {
|
|
226
|
-
// Arrange: Create Jamie's account
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
describe(requirement('AUTH-LOGIN-1.when'), () => {
|
|
230
|
-
// Act: Submit login with valid credentials
|
|
231
|
-
|
|
232
|
-
it(requirement('AUTH-LOGIN-1.then'), () => {
|
|
233
|
-
// Assert: Jamie is authenticated
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
\`\`\`
|
|
238
|
-
|
|
239
|
-
**Test Style Principles:**
|
|
240
|
-
|
|
241
|
-
**1. Use requirement() AS the description**: Don't put requirement() inside test body or in comments.
|
|
242
|
-
- ✅ \`test(requirement('AUTH-LOGIN-1'), () => { /* test code */ })\`
|
|
243
|
-
- ✅ \`it(requirement('LOGIN-1.then'), () => { /* assert */ })\`
|
|
244
|
-
- ❌ \`test("user can log in", () => { requirement('AUTH-LOGIN-1'); /* test code */ })\`
|
|
245
|
-
- ❌ \`// LOGIN-1: User can log in\` (comment instead of using requirement() as description)
|
|
246
|
-
|
|
247
|
-
**2. Comments describe the TEST, not the requirement**: Don't copy requirement text verbatim.
|
|
248
|
-
- ✅ \`describe(requirement('REQ-1.0'), () => { // registered user, valid credentials\`
|
|
249
|
-
- ❌ \`describe(requirement('REQ-1.0'), () => { // 0. When a registered user provides valid credentials, they are authenticated\` (verbatim copy is a red flag)
|
|
250
|
-
- Note: Comments should reflect what the test actually does, not just repeat what the requirement says
|
|
251
|
-
|
|
252
|
-
**3. Structure tests to match requirements**: Nest describe/it blocks for structured requirements.
|
|
253
|
-
- ✅ For structured requirements: \`describe(requirement('LOGIN-1.given'))\` nested with \`describe(requirement('LOGIN-1.when'))\` and \`it(requirement('LOGIN-1.then'))\`
|
|
254
|
-
- ✅ For simple requirements: \`test(requirement('AUTH-LOGIN-1'), () => { /* arrange, act, assert all in one */ })\`
|
|
255
|
-
|
|
256
|
-
**Path formats:**
|
|
257
|
-
- \`requirement('AUTH-LOGIN-1')\` - root requirement
|
|
258
|
-
- \`requirement('AUTH-LOGIN-1.0')\` - by numeric position
|
|
259
|
-
- \`requirement('AUTH-LOGIN-1.given')\` - by label (case-insensitive)
|
|
260
|
-
- \`requirement('AUTH-LOGIN-1.given#1')\` - disambiguate duplicate labels`;
|
|
261
|
-
return textResponse(`# Requirements File Template\n\nHere's a comprehensive template for \`${filePath}\` with format and style guidance:\n\n\`\`\`markdown\n${template}\`\`\`\n\n## Next Steps\n\n1. **Create file**: Use Write tool to create \`${filePath}\` based on this template\n2. **Refine style** (optional): Call \`style_check\` for AI feedback on style and best practices\n3. **Validate syntax**: Call \`validate_requirements\` to verify format is correct\n4. **Push to Convex**: Call \`push_requirements\` to sync requirements to data layer\n\n**Note**: Requirements files can be colocated with code (\`src/auth.requirements.md\`) or centralized in \`.requirements/\` directory.`);
|
|
44
|
+
const localStyleGuide = readLocalStyleGuide(context.workspaceRoot);
|
|
45
|
+
return textResponse(generateStyleGuide({
|
|
46
|
+
requirements,
|
|
47
|
+
customStyleGuidance,
|
|
48
|
+
filePath,
|
|
49
|
+
localStyleGuide,
|
|
50
|
+
}));
|
|
262
51
|
}
|
|
263
52
|
/**
|
|
264
53
|
* Handler for validate_requirements tool
|
|
@@ -284,23 +73,30 @@ export async function handleValidateRequirements(args, context) {
|
|
|
284
73
|
// Check push readiness
|
|
285
74
|
const pushValidation = validateForPush(parsed.metadata);
|
|
286
75
|
let headline;
|
|
287
|
-
let pushDetails =
|
|
76
|
+
let pushDetails = "";
|
|
288
77
|
if (!pushValidation.valid) {
|
|
289
78
|
headline = `❌ \`${filePath}\` - Not push-ready\n- ${pushValidation.reason}`;
|
|
290
79
|
}
|
|
291
80
|
else {
|
|
292
|
-
const actionLabel = pushValidation.action ===
|
|
81
|
+
const actionLabel = pushValidation.action === "create"
|
|
82
|
+
? "Will create new document"
|
|
83
|
+
: "Will update existing document";
|
|
293
84
|
headline = `✓ \`${filePath}\` - ${actionLabel}`;
|
|
294
85
|
if (pushValidation.warning) {
|
|
295
86
|
pushDetails = `\n- ⚠️ ${pushValidation.warning}`;
|
|
296
87
|
}
|
|
297
88
|
}
|
|
298
|
-
return textResponse(`${headline}${pushDetails}\n\n**Metadata:**\n- Version: ${parsed.metadata.version ??
|
|
89
|
+
return textResponse(`${headline}${pushDetails}\n\n**Metadata:**\n- Version: ${parsed.metadata.version ?? "(none)"}\n- Document: ${parsed.metadata.document?.title || "(none)"}\n- Document ID: ${parsed.metadata.document?.id || "(none)"}\n\n**Requirements:** ${reqCount} root requirement(s) found`);
|
|
299
90
|
}
|
|
300
91
|
catch (error) {
|
|
301
92
|
// MCP-AUTHOR-2.1: Syntax errors are returned with details
|
|
302
93
|
return {
|
|
303
|
-
content: [
|
|
94
|
+
content: [
|
|
95
|
+
{
|
|
96
|
+
type: "text",
|
|
97
|
+
text: `✗ Validation failed for \`${filePath}\`:\n\n${error instanceof Error ? error.message : String(error)}`,
|
|
98
|
+
},
|
|
99
|
+
],
|
|
304
100
|
isError: true,
|
|
305
101
|
};
|
|
306
102
|
}
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
* Returns diagnostic information about the MCP server environment.
|
|
5
5
|
* Useful for debugging configuration issues.
|
|
6
6
|
*/
|
|
7
|
-
import type { HandlerContext, ToolResponse } from
|
|
7
|
+
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
8
8
|
/**
|
|
9
9
|
* Arguments for debug_mcp_environment tool
|
|
10
10
|
*/
|
|
11
|
-
export
|
|
12
|
-
}
|
|
11
|
+
export type DebugMcpEnvironmentArgs = Record<string, never>;
|
|
13
12
|
/**
|
|
14
13
|
* Handler for debug_mcp_environment tool
|
|
15
14
|
*/
|
|
@@ -4,34 +4,34 @@
|
|
|
4
4
|
* Returns diagnostic information about the MCP server environment.
|
|
5
5
|
* Useful for debugging configuration issues.
|
|
6
6
|
*/
|
|
7
|
-
import { textResponse } from
|
|
7
|
+
import { textResponse } from "./types.js";
|
|
8
8
|
/**
|
|
9
9
|
* Handler for debug_mcp_environment tool
|
|
10
10
|
*/
|
|
11
11
|
export async function handleDebugMcpEnvironment(_args, context) {
|
|
12
12
|
// Check for Antigravity-specific env vars
|
|
13
13
|
const antigravityVars = Object.entries(context.env)
|
|
14
|
-
.filter(([key]) => key.startsWith(
|
|
14
|
+
.filter(([key]) => key.startsWith("GEMINI_") || key.startsWith("ANTIGRAVITY_"))
|
|
15
15
|
.map(([key, value]) => ` ${key}: ${value}`)
|
|
16
|
-
.join(
|
|
16
|
+
.join("\n");
|
|
17
17
|
// Show discovered projects from env vars
|
|
18
18
|
const projectList = Array.from(context.projectPaths.entries())
|
|
19
19
|
.map(([id, path]) => ` ${id}: ${path}`)
|
|
20
|
-
.join(
|
|
20
|
+
.join("\n");
|
|
21
21
|
const text = `# MCP Server Environment Debug Info
|
|
22
22
|
|
|
23
23
|
**process.cwd():** ${process.cwd()}
|
|
24
24
|
**WORKSPACE_ROOT:** ${context.workspaceRoot}
|
|
25
|
-
**REQUIREMENTS_DIR env:** ${context.env.REQUIREMENTS_DIR ||
|
|
26
|
-
**HOME:** ${context.env.HOME ||
|
|
27
|
-
**PWD:** ${context.env.PWD ||
|
|
28
|
-
**OLDPWD:** ${context.env.OLDPWD ||
|
|
25
|
+
**REQUIREMENTS_DIR env:** ${context.env.REQUIREMENTS_DIR || "(not set)"}
|
|
26
|
+
**HOME:** ${context.env.HOME || "(not set)"}
|
|
27
|
+
**PWD:** ${context.env.PWD || "(not set)"}
|
|
28
|
+
**OLDPWD:** ${context.env.OLDPWD || "(not set)"}
|
|
29
29
|
|
|
30
30
|
**Antigravity/Gemini env vars:**
|
|
31
|
-
${antigravityVars ||
|
|
31
|
+
${antigravityVars || "(none found)"}
|
|
32
32
|
|
|
33
33
|
**Projects from PROJ_* env vars:**
|
|
34
|
-
${projectList ||
|
|
34
|
+
${projectList || "(none found)"}`;
|
|
35
35
|
return textResponse(text);
|
|
36
36
|
}
|
|
37
37
|
//# sourceMappingURL=debug.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Retrieves a specific requirement by ID with its full tree and test coverage.
|
|
5
5
|
*/
|
|
6
|
-
import type { HandlerContext, ToolResponse } from
|
|
6
|
+
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
7
7
|
/**
|
|
8
8
|
* Arguments for get_requirement tool
|
|
9
9
|
*/
|
package/dist/mcp/handlers/get.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Retrieves a specific requirement by ID with its full tree and test coverage.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { glob } from "glob";
|
|
7
|
+
import { formatRequirementTree, getRequirementTree, } from "../../requirements/index.js";
|
|
8
|
+
import { findFilesWithRequirement, findTestCodeForRequirement, } from "../../requirements/testCodeExtractor.js";
|
|
9
|
+
import { textResponse } from "./types.js";
|
|
10
10
|
/**
|
|
11
11
|
* Handler for get_requirement tool
|
|
12
12
|
*
|
|
@@ -31,10 +31,10 @@ export async function handleGetRequirement(args, context) {
|
|
|
31
31
|
const root = tree[0];
|
|
32
32
|
const formatted = formatRequirementTree(tree);
|
|
33
33
|
// MCP-GET-1.3: Find test files that reference this requirement
|
|
34
|
-
const testFiles = await glob(
|
|
34
|
+
const testFiles = await glob("**/*.{test,spec}.{js,jsx,ts,tsx}", {
|
|
35
35
|
cwd: project.path,
|
|
36
36
|
absolute: true,
|
|
37
|
-
ignore: [
|
|
37
|
+
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
|
|
38
38
|
});
|
|
39
39
|
const matchingFiles = findFilesWithRequirement(testFiles, id);
|
|
40
40
|
const testCodeSections = [];
|
|
@@ -47,8 +47,9 @@ export async function handleGetRequirement(args, context) {
|
|
|
47
47
|
if (i === j)
|
|
48
48
|
return false;
|
|
49
49
|
// other contains ref if it starts before or at the same line and ends after or at the same line
|
|
50
|
-
return other.startLine <= ref.startLine &&
|
|
51
|
-
|
|
50
|
+
return (other.startLine <= ref.startLine &&
|
|
51
|
+
other.endLine >= ref.endLine &&
|
|
52
|
+
(other.startLine < ref.startLine || other.endLine > ref.endLine));
|
|
52
53
|
});
|
|
53
54
|
return !isNested;
|
|
54
55
|
});
|
|
@@ -57,8 +58,8 @@ export async function handleGetRequirement(args, context) {
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
const testSection = testCodeSections.length > 0
|
|
60
|
-
? `\n\n## Test Coverage (${testCodeSections.length} reference(s)):\n\n${testCodeSections.join(
|
|
61
|
-
:
|
|
61
|
+
? `\n\n## Test Coverage (${testCodeSections.length} reference(s)):\n\n${testCodeSections.join("\n\n---\n\n")}`
|
|
62
|
+
: "\n\n## Test Coverage\n\nNo tests found referencing this requirement.";
|
|
62
63
|
return textResponse(`# ${id}\n\n**Document:** ${root.documentTitle}\n**Source:** ${root.sourceFile}\n\n## Requirement Tree (${tree.length} node(s)):\n\n\`\`\`\n${formatted}\n\`\`\`${testSection}`);
|
|
63
64
|
}
|
|
64
65
|
//# sourceMappingURL=get.js.map
|
|
@@ -5,24 +5,24 @@
|
|
|
5
5
|
* and returns an MCP response. Handlers receive a context object
|
|
6
6
|
* that provides access to shared dependencies.
|
|
7
7
|
*/
|
|
8
|
-
export type {
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export
|
|
12
|
-
export {
|
|
13
|
-
export
|
|
14
|
-
export {
|
|
15
|
-
export
|
|
16
|
-
export {
|
|
17
|
-
export
|
|
18
|
-
export {
|
|
19
|
-
export
|
|
20
|
-
export {
|
|
21
|
-
export
|
|
22
|
-
export {
|
|
23
|
-
export
|
|
24
|
-
export {
|
|
25
|
-
export
|
|
26
|
-
export {
|
|
27
|
-
export
|
|
8
|
+
export type { CreateRequirementDocumentArgs, ValidateRequirementsArgs, } from "./authoring.js";
|
|
9
|
+
export { handleCreateRequirementDocument, handleValidateRequirements, } from "./authoring.js";
|
|
10
|
+
export type { DebugMcpEnvironmentArgs } from "./debug.js";
|
|
11
|
+
export { handleDebugMcpEnvironment } from "./debug.js";
|
|
12
|
+
export type { GetRequirementArgs } from "./get.js";
|
|
13
|
+
export { handleGetRequirement } from "./get.js";
|
|
14
|
+
export type { ListArgs } from "./list.js";
|
|
15
|
+
export { handleList } from "./list.js";
|
|
16
|
+
export type { PushRequirementsArgs } from "./push.js";
|
|
17
|
+
export { handlePushRequirements } from "./push.js";
|
|
18
|
+
export type { ReportArgs } from "./report.js";
|
|
19
|
+
export { handleReport } from "./report.js";
|
|
20
|
+
export type { ReviewTestArgs, StyleCheckArgs } from "./review.js";
|
|
21
|
+
export { handleReviewTest, handleStyleCheck } from "./review.js";
|
|
22
|
+
export type { SearchRequirementsArgs } from "./search.js";
|
|
23
|
+
export { handleSearchRequirements } from "./search.js";
|
|
24
|
+
export type { GetRequirementsByTestArgs, GetTestsByRequirementArgs, } from "./test-mapping.js";
|
|
25
|
+
export { handleGetRequirementsByTest, handleGetTestsByRequirement, } from "./test-mapping.js";
|
|
26
|
+
export type { HandlerContext, ToolContentItem, ToolHandler, ToolResponse, } from "./types.js";
|
|
27
|
+
export { errorResponse, textResponse } from "./types.js";
|
|
28
28
|
//# sourceMappingURL=index.d.ts.map
|