@popoverai/dotrequirements 0.26.2 → 0.27.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.
- package/README.md +13 -69
- package/dist/cli.js +19 -7
- package/dist/commands/ai-setup.d.ts +8 -2
- package/dist/commands/ai-setup.js +153 -347
- package/dist/commands/init.js +1 -1
- package/dist/commands/mcp.d.ts +8 -2
- package/dist/commands/mcp.js +17 -6
- package/dist/commands/review-test.d.ts +5 -1
- package/dist/commands/review-test.js +101 -7
- package/dist/commands/style-check.d.ts +1 -0
- package/dist/commands/style-check.js +137 -13
- package/dist/convex.d.ts +1 -3
- package/dist/convex.js +3 -3
- package/dist/requirements/cloud-ai.d.ts +21 -8
- package/dist/requirements/cloud-ai.js +10 -8
- package/dist/schema/parser-core.d.ts +13 -0
- package/dist/schema/parser-core.js +33 -9
- package/dist/templates/context-file-section.md +25 -22
- package/dist/utils/context-file.d.ts +7 -3
- package/dist/utils/context-file.js +10 -7
- package/dist/utils/project-settings.d.ts +1 -0
- package/dist/utils/project-settings.js +22 -0
- package/package.json +3 -5
- package/dist/mcp/convexClient.d.ts +0 -19
- package/dist/mcp/convexClient.js +0 -24
- package/dist/mcp/handlers/authoring.d.ts +0 -41
- package/dist/mcp/handlers/authoring.js +0 -113
- package/dist/mcp/handlers/debug.d.ts +0 -16
- package/dist/mcp/handlers/debug.js +0 -37
- package/dist/mcp/handlers/get.d.ts +0 -24
- package/dist/mcp/handlers/get.js +0 -69
- package/dist/mcp/handlers/index.d.ts +0 -28
- package/dist/mcp/handlers/index.js +0 -19
- package/dist/mcp/handlers/list.d.ts +0 -7
- package/dist/mcp/handlers/list.js +0 -43
- package/dist/mcp/handlers/push.d.ts +0 -26
- package/dist/mcp/handlers/push.js +0 -232
- package/dist/mcp/handlers/report.d.ts +0 -16
- package/dist/mcp/handlers/report.js +0 -134
- package/dist/mcp/handlers/review.d.ts +0 -52
- package/dist/mcp/handlers/review.js +0 -243
- package/dist/mcp/handlers/search.d.ts +0 -30
- package/dist/mcp/handlers/search.js +0 -58
- package/dist/mcp/handlers/test-mapping.d.ts +0 -39
- package/dist/mcp/handlers/test-mapping.js +0 -168
- package/dist/mcp/handlers/types.d.ts +0 -89
- package/dist/mcp/handlers/types.js +0 -52
- package/dist/mcp/index.d.ts +0 -45
- package/dist/mcp/index.js +0 -638
|
@@ -11,7 +11,8 @@ const PLATFORM_CONTEXT_FILES = {
|
|
|
11
11
|
cursor: "AGENTS.md",
|
|
12
12
|
codex: "AGENTS.md",
|
|
13
13
|
"github-copilot": "AGENTS.md",
|
|
14
|
-
|
|
14
|
+
// Antigravity 2.0 retired the GEMINI.md/.gemini conventions for AGENTS.md
|
|
15
|
+
antigravity: "AGENTS.md",
|
|
15
16
|
};
|
|
16
17
|
/**
|
|
17
18
|
* Get the appropriate context file name for a platform
|
|
@@ -20,10 +21,14 @@ export function getContextFileName(platform) {
|
|
|
20
21
|
return PLATFORM_CONTEXT_FILES[platform] ?? null;
|
|
21
22
|
}
|
|
22
23
|
/**
|
|
23
|
-
* Find the git root directory
|
|
24
|
+
* Find the git root directory.
|
|
25
|
+
*
|
|
26
|
+
* CONTEXT-FILE-6: in a worktree, .git is a FILE pointing at the main
|
|
27
|
+
* checkout — matching directories only would walk past it and resolve to
|
|
28
|
+
* the main checkout's root, landing the context file in the wrong tree.
|
|
24
29
|
*/
|
|
25
30
|
export async function findGitRoot() {
|
|
26
|
-
const gitDir = await findUp(".git", { type: "
|
|
31
|
+
const gitDir = await findUp(".git", { type: "both" });
|
|
27
32
|
return gitDir ? dirname(gitDir) : null;
|
|
28
33
|
}
|
|
29
34
|
/**
|
|
@@ -95,8 +100,8 @@ export async function getContextFilePath(platform) {
|
|
|
95
100
|
* Build a user-facing message explaining that context file installation
|
|
96
101
|
* was skipped because the current directory is not inside a git repository.
|
|
97
102
|
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
103
|
+
* Writing the platform's context file is the whole of setup now, so a missing
|
|
104
|
+
* git root means nothing was installed.
|
|
100
105
|
*/
|
|
101
106
|
export function buildNoGitRepoMessage(fileName) {
|
|
102
107
|
return [
|
|
@@ -106,8 +111,6 @@ export function buildNoGitRepoMessage(fileName) {
|
|
|
106
111
|
" To finish setup, either:",
|
|
107
112
|
" • run `git init` here, then re-run `dotreq ai-setup`, or",
|
|
108
113
|
" • `cd` into an existing project directory and run `dotreq ai-setup` there.",
|
|
109
|
-
"",
|
|
110
|
-
" Note: the MCP server itself was configured successfully — only the context file step was skipped.",
|
|
111
114
|
].join("\n");
|
|
112
115
|
}
|
|
113
116
|
//# sourceMappingURL=context-file.js.map
|
|
@@ -41,6 +41,7 @@ export interface ProjectInfo {
|
|
|
41
41
|
* Returns undefined if either is missing.
|
|
42
42
|
*/
|
|
43
43
|
export declare function getCredentialsFromEnv(): ProjectSettings | undefined;
|
|
44
|
+
export declare function setAuthFromEnv(enabled: boolean): void;
|
|
44
45
|
/**
|
|
45
46
|
* Find the project root by walking up from startDir looking for .requirements/ folder
|
|
46
47
|
* Returns the directory containing .requirements/, or undefined if not found
|
|
@@ -18,6 +18,19 @@ export function getCredentialsFromEnv() {
|
|
|
18
18
|
}
|
|
19
19
|
return undefined;
|
|
20
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* AUTHZ-6: explicit CI/CD credential injection. Set by the global
|
|
23
|
+
* --auth-from-env flag (cli.ts preAction hook); when enabled,
|
|
24
|
+
* getProjectCredentials reads DOTREQ_PROJECT_ID / DOTREQ_PROJECT_SECRET
|
|
25
|
+
* instead of file-based discovery. Without the flag those variables are
|
|
26
|
+
* ignored entirely — the explicit opt-in prevents credential conflicts
|
|
27
|
+
* between local and CI environments. (Previously the retired MCP server's
|
|
28
|
+
* --auth-from-env; ported to the CLI with identical semantics.)
|
|
29
|
+
*/
|
|
30
|
+
let authFromEnv = false;
|
|
31
|
+
export function setAuthFromEnv(enabled) {
|
|
32
|
+
authFromEnv = enabled;
|
|
33
|
+
}
|
|
21
34
|
/**
|
|
22
35
|
* Find the project root by walking up from startDir looking for .requirements/ folder
|
|
23
36
|
* Returns the directory containing .requirements/, or undefined if not found
|
|
@@ -157,6 +170,15 @@ export function getProjectInfo(startDir = process.cwd()) {
|
|
|
157
170
|
* Get project credentials, throwing helpful error if not available
|
|
158
171
|
*/
|
|
159
172
|
export function getProjectCredentials(startDir = process.cwd()) {
|
|
173
|
+
// AUTHZ-6.0 / 6.1: with the explicit flag, env credentials replace
|
|
174
|
+
// file-based discovery entirely
|
|
175
|
+
if (authFromEnv) {
|
|
176
|
+
const envCredentials = getCredentialsFromEnv();
|
|
177
|
+
if (!envCredentials) {
|
|
178
|
+
throw new Error("--auth-from-env requires both DOTREQ_PROJECT_ID and DOTREQ_PROJECT_SECRET environment variables to be set.");
|
|
179
|
+
}
|
|
180
|
+
return envCredentials;
|
|
181
|
+
}
|
|
160
182
|
const info = getProjectInfo(startDir);
|
|
161
183
|
if (!info) {
|
|
162
184
|
throw new Error('No dotrequirements project found. Run "dotrequirements init" to create one.');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popoverai/dotrequirements",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Requirements tracking CLI
|
|
3
|
+
"version": "0.27.0",
|
|
4
|
+
"description": "Requirements tracking CLI and test harness",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"dotrequirements": "./dist/cli.js",
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
".": "./dist/cli.js",
|
|
12
12
|
"./test": "./dist/harness/index.js",
|
|
13
13
|
"./schema": "./dist/schema/index.js",
|
|
14
|
-
"./schema/browser": "./dist/schema/browser.js"
|
|
15
|
-
"./mcp": "./dist/mcp/index.js"
|
|
14
|
+
"./schema/browser": "./dist/schema/browser.js"
|
|
16
15
|
},
|
|
17
16
|
"publishConfig": {
|
|
18
17
|
"access": "public"
|
|
@@ -34,7 +33,6 @@
|
|
|
34
33
|
"test-coverage",
|
|
35
34
|
"bdd",
|
|
36
35
|
"tdd",
|
|
37
|
-
"mcp",
|
|
38
36
|
"ai-assistant"
|
|
39
37
|
],
|
|
40
38
|
"author": "Will Raymer @Popover",
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Production Convex deployment URL
|
|
3
|
-
*/
|
|
4
|
-
export declare const CONVEX_URL = "https://data.dotrequirements.io";
|
|
5
|
-
/**
|
|
6
|
-
* Convex configuration for cloud operations
|
|
7
|
-
*/
|
|
8
|
-
interface ConvexConfig {
|
|
9
|
-
convexUrl: string;
|
|
10
|
-
projectId: string;
|
|
11
|
-
projectSecret: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Load Convex configuration from project settings.
|
|
15
|
-
* Returns null if credentials are not configured.
|
|
16
|
-
*/
|
|
17
|
-
export declare function loadConvexConfig(cwd?: string): ConvexConfig | null;
|
|
18
|
-
export {};
|
|
19
|
-
//# sourceMappingURL=convexClient.d.ts.map
|
package/dist/mcp/convexClient.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { getProjectCredentials } from "../utils/project-settings.js";
|
|
2
|
-
/**
|
|
3
|
-
* Production Convex deployment URL
|
|
4
|
-
*/
|
|
5
|
-
export const CONVEX_URL = "https://data.dotrequirements.io";
|
|
6
|
-
/**
|
|
7
|
-
* Load Convex configuration from project settings.
|
|
8
|
-
* Returns null if credentials are not configured.
|
|
9
|
-
*/
|
|
10
|
-
export function loadConvexConfig(cwd = process.cwd()) {
|
|
11
|
-
try {
|
|
12
|
-
const credentials = getProjectCredentials(cwd);
|
|
13
|
-
return {
|
|
14
|
-
convexUrl: CONVEX_URL,
|
|
15
|
-
projectId: credentials.projectId,
|
|
16
|
-
projectSecret: credentials.projectSecret,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
catch {
|
|
20
|
-
// Credentials not found or project not connected to cloud
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=convexClient.js.map
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authoring handlers for MCP tools
|
|
3
|
-
*
|
|
4
|
-
* Provides document creation and validation:
|
|
5
|
-
* - create_requirement_document: Generate requirements template with format guidance
|
|
6
|
-
* - validate_requirements: Validate requirements file syntax offline
|
|
7
|
-
*/
|
|
8
|
-
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
9
|
-
/**
|
|
10
|
-
* Arguments for create_requirement_document tool
|
|
11
|
-
*/
|
|
12
|
-
export interface CreateRequirementDocumentArgs {
|
|
13
|
-
filePath?: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Arguments for validate_requirements tool
|
|
17
|
-
*/
|
|
18
|
-
export interface ValidateRequirementsArgs {
|
|
19
|
-
filePath: string;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Handler for create_requirement_document tool
|
|
23
|
-
*
|
|
24
|
-
* Requirements covered:
|
|
25
|
-
* - MCP-AUTHOR-1.0: The template includes format guidance with code block examples
|
|
26
|
-
* - MCP-AUTHOR-1.1: The template includes style guidance (concrete examples, concise prose, testable conditions)
|
|
27
|
-
* - MCP-AUTHOR-1.2: When the project has requirementsStyleContext configured, it is included in the template
|
|
28
|
-
* - MCP-AUTHOR-1.3: When cloud credentials are unavailable, the template works without the custom context
|
|
29
|
-
*/
|
|
30
|
-
export declare function handleCreateRequirementDocument(args: CreateRequirementDocumentArgs, context: HandlerContext): Promise<ToolResponse>;
|
|
31
|
-
/**
|
|
32
|
-
* Handler for validate_requirements tool
|
|
33
|
-
*
|
|
34
|
-
* Requirements covered:
|
|
35
|
-
* - MCP-AUTHOR-2.1: When the file has valid syntax, the response confirms validation passed
|
|
36
|
-
* - MCP-AUTHOR-2.2: When the file has syntax errors, the response lists each error with location
|
|
37
|
-
* - MCP-AUTHOR-2.3: Validation does not require network access or cloud credentials
|
|
38
|
-
* - MCP-AUTHOR-2.4: When the file does not exist, an error is returned
|
|
39
|
-
*/
|
|
40
|
-
export declare function handleValidateRequirements(args: ValidateRequirementsArgs, context: HandlerContext): Promise<ToolResponse>;
|
|
41
|
-
//# sourceMappingURL=authoring.d.ts.map
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authoring handlers for MCP tools
|
|
3
|
-
*
|
|
4
|
-
* Provides document creation and validation:
|
|
5
|
-
* - create_requirement_document: Generate requirements template with format guidance
|
|
6
|
-
* - validate_requirements: Validate requirements file syntax offline
|
|
7
|
-
*/
|
|
8
|
-
import { existsSync } from "node:fs";
|
|
9
|
-
import { getProjectContext } from "../../requirements/cloud-ai.js";
|
|
10
|
-
import { generateStyleGuide, readLocalStyleGuide, } from "../../requirements/style-guide.js";
|
|
11
|
-
import { parseRequirementsFromFile, validateForPush, } from "../../schema/index.js";
|
|
12
|
-
import { CONVEX_URL } from "../convexClient.js";
|
|
13
|
-
import { errorResponse, resolveProjectFilePath, textResponse, } from "./types.js";
|
|
14
|
-
/**
|
|
15
|
-
* Handler for create_requirement_document tool
|
|
16
|
-
*
|
|
17
|
-
* Requirements covered:
|
|
18
|
-
* - MCP-AUTHOR-1.0: The template includes format guidance with code block examples
|
|
19
|
-
* - MCP-AUTHOR-1.1: The template includes style guidance (concrete examples, concise prose, testable conditions)
|
|
20
|
-
* - MCP-AUTHOR-1.2: When the project has requirementsStyleContext configured, it is included in the template
|
|
21
|
-
* - MCP-AUTHOR-1.3: When cloud credentials are unavailable, the template works without the custom context
|
|
22
|
-
*/
|
|
23
|
-
export async function handleCreateRequirementDocument(args, context) {
|
|
24
|
-
const { filePath = ".requirements/example.requirements.md" } = args;
|
|
25
|
-
// MCP-AUTHOR-1.3: Try to get requirements, but don't fail if no project is configured
|
|
26
|
-
let requirements = [];
|
|
27
|
-
try {
|
|
28
|
-
requirements = await context.getRequirements();
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// No project configured — discovered patterns will be empty
|
|
32
|
-
}
|
|
33
|
-
// MCP-AUTHOR-1.2: Try to fetch user-provided style context from cloud
|
|
34
|
-
let customStyleGuidance = null;
|
|
35
|
-
try {
|
|
36
|
-
const project = await context.getProjectFromDiscovery();
|
|
37
|
-
const contextData = await getProjectContext(project.projectId, project.projectSecret, CONVEX_URL);
|
|
38
|
-
customStyleGuidance = contextData?.requirementsStyleContext ?? null;
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
// MCP-AUTHOR-1.3: No credentials or cloud unavailable - continue without user context
|
|
42
|
-
}
|
|
43
|
-
const localStyleGuide = readLocalStyleGuide(context.workspaceRoot);
|
|
44
|
-
return textResponse(generateStyleGuide({
|
|
45
|
-
requirements,
|
|
46
|
-
customStyleGuidance,
|
|
47
|
-
filePath,
|
|
48
|
-
localStyleGuide,
|
|
49
|
-
}));
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Handler for validate_requirements tool
|
|
53
|
-
*
|
|
54
|
-
* Requirements covered:
|
|
55
|
-
* - MCP-AUTHOR-2.1: When the file has valid syntax, the response confirms validation passed
|
|
56
|
-
* - MCP-AUTHOR-2.2: When the file has syntax errors, the response lists each error with location
|
|
57
|
-
* - MCP-AUTHOR-2.3: Validation does not require network access or cloud credentials
|
|
58
|
-
* - MCP-AUTHOR-2.4: When the file does not exist, an error is returned
|
|
59
|
-
*/
|
|
60
|
-
export async function handleValidateRequirements(args, context) {
|
|
61
|
-
const { filePath } = args;
|
|
62
|
-
// #49: Resolve against the discovered project.path (matching push) with a
|
|
63
|
-
// workspaceRoot fallback. MCP-AUTHOR-2.3: validation stays offline — if
|
|
64
|
-
// discovery has no credentials it simply throws and we fall back to
|
|
65
|
-
// workspaceRoot resolution.
|
|
66
|
-
let projectPath;
|
|
67
|
-
try {
|
|
68
|
-
projectPath = (await context.getProjectFromDiscovery()).path;
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
projectPath = undefined;
|
|
72
|
-
}
|
|
73
|
-
const fullPath = resolveProjectFilePath(filePath, projectPath, context.workspaceRoot);
|
|
74
|
-
// MCP-AUTHOR-2.4: Check if file exists
|
|
75
|
-
if (!existsSync(fullPath)) {
|
|
76
|
-
return errorResponse(`File not found: ${filePath}`);
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
// MCP-AUTHOR-2.1 & MCP-AUTHOR-2.2: Parse and validate
|
|
80
|
-
const parsed = parseRequirementsFromFile(fullPath);
|
|
81
|
-
const reqCount = Object.keys(parsed.requirements).length;
|
|
82
|
-
// Check push readiness
|
|
83
|
-
const pushValidation = validateForPush(parsed.metadata);
|
|
84
|
-
let headline;
|
|
85
|
-
let pushDetails = "";
|
|
86
|
-
if (!pushValidation.valid) {
|
|
87
|
-
headline = `❌ \`${filePath}\` - Not push-ready\n- ${pushValidation.reason}`;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
const actionLabel = pushValidation.action === "create"
|
|
91
|
-
? "Will create new document"
|
|
92
|
-
: "Will update existing document";
|
|
93
|
-
headline = `✓ \`${filePath}\` - ${actionLabel}`;
|
|
94
|
-
if (pushValidation.warning) {
|
|
95
|
-
pushDetails = `\n- ⚠️ ${pushValidation.warning}`;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
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`);
|
|
99
|
-
}
|
|
100
|
-
catch (error) {
|
|
101
|
-
// MCP-AUTHOR-2.2: Syntax errors are returned with details
|
|
102
|
-
return {
|
|
103
|
-
content: [
|
|
104
|
-
{
|
|
105
|
-
type: "text",
|
|
106
|
-
text: `✗ Validation failed for \`${filePath}\`:\n\n${error instanceof Error ? error.message : String(error)}`,
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
isError: true,
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
//# sourceMappingURL=authoring.js.map
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* debug_mcp_environment handler
|
|
3
|
-
*
|
|
4
|
-
* Returns diagnostic information about the MCP server environment.
|
|
5
|
-
* Useful for debugging configuration issues.
|
|
6
|
-
*/
|
|
7
|
-
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
8
|
-
/**
|
|
9
|
-
* Arguments for debug_mcp_environment tool
|
|
10
|
-
*/
|
|
11
|
-
export type DebugMcpEnvironmentArgs = Record<string, never>;
|
|
12
|
-
/**
|
|
13
|
-
* Handler for debug_mcp_environment tool
|
|
14
|
-
*/
|
|
15
|
-
export declare function handleDebugMcpEnvironment(_args: DebugMcpEnvironmentArgs, context: HandlerContext): Promise<ToolResponse>;
|
|
16
|
-
//# sourceMappingURL=debug.d.ts.map
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* debug_mcp_environment handler
|
|
3
|
-
*
|
|
4
|
-
* Returns diagnostic information about the MCP server environment.
|
|
5
|
-
* Useful for debugging configuration issues.
|
|
6
|
-
*/
|
|
7
|
-
import { textResponse } from "./types.js";
|
|
8
|
-
/**
|
|
9
|
-
* Handler for debug_mcp_environment tool
|
|
10
|
-
*/
|
|
11
|
-
export async function handleDebugMcpEnvironment(_args, context) {
|
|
12
|
-
// Check for Antigravity-specific env vars
|
|
13
|
-
const antigravityVars = Object.entries(context.env)
|
|
14
|
-
.filter(([key]) => key.startsWith("GEMINI_") || key.startsWith("ANTIGRAVITY_"))
|
|
15
|
-
.map(([key, value]) => ` ${key}: ${value}`)
|
|
16
|
-
.join("\n");
|
|
17
|
-
// Show discovered projects from env vars
|
|
18
|
-
const projectList = Array.from(context.projectPaths.entries())
|
|
19
|
-
.map(([id, path]) => ` ${id}: ${path}`)
|
|
20
|
-
.join("\n");
|
|
21
|
-
const text = `# MCP Server Environment Debug Info
|
|
22
|
-
|
|
23
|
-
**process.cwd():** ${process.cwd()}
|
|
24
|
-
**WORKSPACE_ROOT:** ${context.workspaceRoot}
|
|
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
|
-
|
|
30
|
-
**Antigravity/Gemini env vars:**
|
|
31
|
-
${antigravityVars || "(none found)"}
|
|
32
|
-
|
|
33
|
-
**Projects from PROJ_* env vars:**
|
|
34
|
-
${projectList || "(none found)"}`;
|
|
35
|
-
return textResponse(text);
|
|
36
|
-
}
|
|
37
|
-
//# sourceMappingURL=debug.js.map
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* get_requirement handler
|
|
3
|
-
*
|
|
4
|
-
* Retrieves a specific requirement by ID with its full tree and test coverage.
|
|
5
|
-
*/
|
|
6
|
-
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
7
|
-
/**
|
|
8
|
-
* Arguments for get_requirement tool
|
|
9
|
-
*/
|
|
10
|
-
export interface GetRequirementArgs {
|
|
11
|
-
id: string;
|
|
12
|
-
projectId?: string;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Handler for get_requirement tool
|
|
16
|
-
*
|
|
17
|
-
* Requirements covered:
|
|
18
|
-
* - MCP-GET-1.0: When the ID matches a root requirement, the full tree is returned
|
|
19
|
-
* - MCP-GET-1.1: When the ID matches a child requirement, that subtree is returned
|
|
20
|
-
* - MCP-GET-1.2: When the ID does not exist, an error message is returned
|
|
21
|
-
* - MCP-GET-1.3: When a requirement is retrieved, test references are shown with file path and line number
|
|
22
|
-
*/
|
|
23
|
-
export declare function handleGetRequirement(args: GetRequirementArgs, context: HandlerContext): Promise<ToolResponse>;
|
|
24
|
-
//# sourceMappingURL=get.d.ts.map
|
package/dist/mcp/handlers/get.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* get_requirement handler
|
|
3
|
-
*
|
|
4
|
-
* Retrieves a specific requirement by ID with its full tree and test coverage.
|
|
5
|
-
*/
|
|
6
|
-
import { glob } from "glob";
|
|
7
|
-
import { formatRequirementTree } from "../../requirements/index.js";
|
|
8
|
-
import { findFilesWithRequirement, findTestCodeForRequirement, } from "../../requirements/testCodeExtractor.js";
|
|
9
|
-
import { textResponse } from "./types.js";
|
|
10
|
-
/**
|
|
11
|
-
* Handler for get_requirement tool
|
|
12
|
-
*
|
|
13
|
-
* Requirements covered:
|
|
14
|
-
* - MCP-GET-1.0: When the ID matches a root requirement, the full tree is returned
|
|
15
|
-
* - MCP-GET-1.1: When the ID matches a child requirement, that subtree is returned
|
|
16
|
-
* - MCP-GET-1.2: When the ID does not exist, an error message is returned
|
|
17
|
-
* - MCP-GET-1.3: When a requirement is retrieved, test references are shown with file path and line number
|
|
18
|
-
*/
|
|
19
|
-
export async function handleGetRequirement(args, context) {
|
|
20
|
-
const { id, projectId } = args;
|
|
21
|
-
const project = await context.getProjectFromDiscovery(projectId);
|
|
22
|
-
const requirements = await context.getRequirements(projectId);
|
|
23
|
-
// Get the tree starting from this ID.
|
|
24
|
-
// MCP-GET-1.0: Full tree for root requirement
|
|
25
|
-
// MCP-GET-1.1: Subtree for child requirement
|
|
26
|
-
//
|
|
27
|
-
// #46: Match the node itself plus all of its descendants by id prefix. The
|
|
28
|
-
// shared getRequirementTree only matches on rootId/id equality, which drops
|
|
29
|
-
// grandchildren (e.g. REQ-123.0.0) when a child id (REQ-123.0) is requested.
|
|
30
|
-
const tree = requirements.filter((r) => r.id === id || r.id.startsWith(`${id}.`));
|
|
31
|
-
// MCP-GET-1.2: Return error if not found
|
|
32
|
-
if (tree.length === 0) {
|
|
33
|
-
return textResponse(`Requirement "${id}" not found`);
|
|
34
|
-
}
|
|
35
|
-
const root = tree[0];
|
|
36
|
-
const formatted = formatRequirementTree(tree);
|
|
37
|
-
// MCP-GET-1.3: Find test files that reference this requirement
|
|
38
|
-
const testFiles = await glob("**/*.{test,spec}.{js,jsx,ts,tsx}", {
|
|
39
|
-
cwd: project.path,
|
|
40
|
-
absolute: true,
|
|
41
|
-
ignore: ["**/node_modules/**", "**/dist/**", "**/build/**"],
|
|
42
|
-
});
|
|
43
|
-
const matchingFiles = findFilesWithRequirement(testFiles, id);
|
|
44
|
-
const testCodeSections = [];
|
|
45
|
-
for (const file of matchingFiles) {
|
|
46
|
-
const testRefs = findTestCodeForRequirement(file, id);
|
|
47
|
-
// Deduplicate by removing nested blocks - keep only outermost blocks
|
|
48
|
-
const deduplicated = testRefs.filter((ref, i) => {
|
|
49
|
-
// Check if this ref is contained within any other ref
|
|
50
|
-
const isNested = testRefs.some((other, j) => {
|
|
51
|
-
if (i === j)
|
|
52
|
-
return false;
|
|
53
|
-
// other contains ref if it starts before or at the same line and ends after or at the same line
|
|
54
|
-
return (other.startLine <= ref.startLine &&
|
|
55
|
-
other.endLine >= ref.endLine &&
|
|
56
|
-
(other.startLine < ref.startLine || other.endLine > ref.endLine));
|
|
57
|
-
});
|
|
58
|
-
return !isNested;
|
|
59
|
-
});
|
|
60
|
-
for (const ref of deduplicated) {
|
|
61
|
-
testCodeSections.push(`**${ref.requirementId}** tested in \`${ref.file}:${ref.startLine}-${ref.endLine}\`:\n\n\`\`\`typescript\n${ref.code}\n\`\`\``);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
const testSection = testCodeSections.length > 0
|
|
65
|
-
? `\n\n## Test Coverage (${testCodeSections.length} reference(s)):\n\n${testCodeSections.join("\n\n---\n\n")}`
|
|
66
|
-
: "\n\n## Test Coverage\n\nNo tests found referencing this requirement.";
|
|
67
|
-
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}`);
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=get.js.map
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tool Handlers
|
|
3
|
-
*
|
|
4
|
-
* Each handler is a pure function that processes tool arguments
|
|
5
|
-
* and returns an MCP response. Handlers receive a context object
|
|
6
|
-
* that provides access to shared dependencies.
|
|
7
|
-
*/
|
|
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
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MCP Tool Handlers
|
|
3
|
-
*
|
|
4
|
-
* Each handler is a pure function that processes tool arguments
|
|
5
|
-
* and returns an MCP response. Handlers receive a context object
|
|
6
|
-
* that provides access to shared dependencies.
|
|
7
|
-
*/
|
|
8
|
-
export { handleCreateRequirementDocument, handleValidateRequirements, } from "./authoring.js";
|
|
9
|
-
// Handlers
|
|
10
|
-
export { handleDebugMcpEnvironment } from "./debug.js";
|
|
11
|
-
export { handleGetRequirement } from "./get.js";
|
|
12
|
-
export { handleList } from "./list.js";
|
|
13
|
-
export { handlePushRequirements } from "./push.js";
|
|
14
|
-
export { handleReport } from "./report.js";
|
|
15
|
-
export { handleReviewTest, handleStyleCheck } from "./review.js";
|
|
16
|
-
export { handleSearchRequirements } from "./search.js";
|
|
17
|
-
export { handleGetRequirementsByTest, handleGetTestsByRequirement, } from "./test-mapping.js";
|
|
18
|
-
export { errorResponse, textResponse } from "./types.js";
|
|
19
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
2
|
-
export interface ListArgs {
|
|
3
|
-
untested?: boolean;
|
|
4
|
-
projectId?: string;
|
|
5
|
-
}
|
|
6
|
-
export declare function handleList(args: ListArgs, context: HandlerContext): Promise<ToolResponse>;
|
|
7
|
-
//# sourceMappingURL=list.d.ts.map
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { getReferencedRequirementIds } from "../../requirements/grep.js";
|
|
2
|
-
import { textResponse } from "./types.js";
|
|
3
|
-
export async function handleList(args, context) {
|
|
4
|
-
const { untested = false, projectId } = args;
|
|
5
|
-
const project = await context.getProjectFromDiscovery(projectId);
|
|
6
|
-
const requirements = await context.getRequirements(projectId);
|
|
7
|
-
if (requirements.length === 0) {
|
|
8
|
-
return textResponse(`No requirements found in project: ${project.path}\n\nMake sure .requirements/ directory exists with Markdown files (*.requirements.md).`);
|
|
9
|
-
}
|
|
10
|
-
if (untested) {
|
|
11
|
-
return formatUntested(requirements, project.path);
|
|
12
|
-
}
|
|
13
|
-
return formatAll(requirements);
|
|
14
|
-
}
|
|
15
|
-
function formatAll(requirements) {
|
|
16
|
-
const grouped = new Map();
|
|
17
|
-
for (const req of requirements) {
|
|
18
|
-
const existing = grouped.get(req.rootId) || [];
|
|
19
|
-
existing.push(req);
|
|
20
|
-
grouped.set(req.rootId, existing);
|
|
21
|
-
}
|
|
22
|
-
const formatted = Array.from(grouped.entries())
|
|
23
|
-
.map(([rootId, reqs]) => {
|
|
24
|
-
const root = reqs.find((r) => r.path.length === 0);
|
|
25
|
-
const childCount = reqs.length - 1;
|
|
26
|
-
return `- **${rootId}**: ${root?.content || "(no content)"} (${childCount} children)`;
|
|
27
|
-
})
|
|
28
|
-
.join("\n");
|
|
29
|
-
return textResponse(`Found ${grouped.size} requirement(s) with ${requirements.length} total nodes:\n\n${formatted}`);
|
|
30
|
-
}
|
|
31
|
-
async function formatUntested(requirements, projectPath) {
|
|
32
|
-
const referencedIds = await getReferencedRequirementIds(projectPath);
|
|
33
|
-
const rootRequirements = requirements.filter((r) => r.path.length === 0);
|
|
34
|
-
const untested = rootRequirements.filter((r) => !referencedIds.has(r.id));
|
|
35
|
-
if (untested.length === 0) {
|
|
36
|
-
return textResponse(`All ${rootRequirements.length} requirement(s) have test references — coverage is complete.`);
|
|
37
|
-
}
|
|
38
|
-
const formatted = untested
|
|
39
|
-
.map((r) => `- **${r.id}**: ${r.content}`)
|
|
40
|
-
.join("\n");
|
|
41
|
-
return textResponse(`Found ${untested.length} untested requirement(s) out of ${rootRequirements.length} total:\n\n${formatted}`);
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=list.js.map
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Push handler for MCP tools
|
|
3
|
-
*
|
|
4
|
-
* Provides requirements push functionality:
|
|
5
|
-
* - push_requirements: Push local requirements to cloud
|
|
6
|
-
*/
|
|
7
|
-
import type { HandlerContext, ToolResponse } from "./types.js";
|
|
8
|
-
/**
|
|
9
|
-
* Arguments for push_requirements tool
|
|
10
|
-
*/
|
|
11
|
-
export interface PushRequirementsArgs {
|
|
12
|
-
filePath?: string;
|
|
13
|
-
confirmed?: boolean;
|
|
14
|
-
projectId?: string;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Handler for push_requirements tool
|
|
18
|
-
*
|
|
19
|
-
* Requirements covered:
|
|
20
|
-
* - MCP-PUSH-1.0: When not confirmed, no changes are made and a preview of creates/updates is returned
|
|
21
|
-
* - MCP-PUSH-1.1: When confirmed is true, the push executes and returns success message
|
|
22
|
-
* - MCP-PUSH-1.2: When credentials are missing or invalid, an error explains how to authenticate
|
|
23
|
-
* - MCP-PUSH-1.3: When filePath is provided, only that file is pushed (MCP-PUSH-1.3.0: missing file is an error)
|
|
24
|
-
*/
|
|
25
|
-
export declare function handlePushRequirements(args: PushRequirementsArgs, context: HandlerContext): Promise<ToolResponse>;
|
|
26
|
-
//# sourceMappingURL=push.d.ts.map
|