@popoverai/dotrequirements 0.22.0 → 0.24.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 +173 -23
- package/dist/cli.js +121 -61
- 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-apply.d.ts +12 -0
- package/dist/codebase-to-spec/prompts/planner-apply.js +32 -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/acceptance-test.js +212 -0
- package/dist/commands/ai-setup.d.ts +5 -0
- package/dist/commands/ai-setup.js +441 -0
- package/dist/commands/browsertest.d.ts +0 -1
- package/dist/commands/browsertest.js +51 -26
- 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-setup.js +159 -149
- 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/test.js +53 -59
- 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/grep.d.ts +1 -1
- package/dist/mcp/grep.js +87 -42
- package/dist/mcp/handlers/authoring.d.ts +1 -1
- package/dist/mcp/handlers/authoring.js +30 -234
- package/dist/mcp/handlers/coverage.d.ts +1 -1
- package/dist/mcp/handlers/coverage.js +13 -15
- 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 +156 -178
- package/dist/mcp/requirements.d.ts +2 -2
- package/dist/mcp/requirements.js +30 -30
- package/dist/mcp/testCodeExtractor.js +24 -26
- package/dist/mcp/types.d.ts +1 -1
- 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/requirements/grep.d.ts +33 -0
- package/dist/requirements/grep.js +306 -0
- package/dist/requirements/index.d.ts +73 -0
- package/dist/requirements/index.js +174 -0
- package/dist/requirements/style-guide.d.ts +67 -0
- package/dist/requirements/style-guide.js +299 -0
- package/dist/requirements/testCodeExtractor.d.ts +22 -0
- package/dist/requirements/testCodeExtractor.js +150 -0
- package/dist/schema/browser.d.ts +8 -6
- package/dist/schema/browser.js +14 -14
- 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 -7
- package/dist/schema/index.js +15 -13
- 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 +91 -0
- package/dist/schema/scenario.js +82 -0
- 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 +5 -4
- package/dist/utils/project-settings.js +28 -20
- package/dist/utils/templates.js +6 -6
- package/package.json +2 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getReferencedRequirementIds } from "../requirements/grep.js";
|
|
2
|
+
import { loadAllRequirements, } from "../requirements/index.js";
|
|
3
|
+
export async function listCommand(options) {
|
|
4
|
+
const workspaceRoot = process.cwd();
|
|
5
|
+
const { flattened } = await loadAllRequirements(workspaceRoot);
|
|
6
|
+
if (flattened.length === 0) {
|
|
7
|
+
console.log("No requirements found. Make sure .requirements/ directory exists with *.requirements.md files.");
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const rootRequirements = flattened.filter((r) => r.path.length === 0);
|
|
11
|
+
if (options.untested) {
|
|
12
|
+
// CLI-FIND-LIST-2: filter to roots with no requirement() references
|
|
13
|
+
const referencedIds = await getReferencedRequirementIds(workspaceRoot);
|
|
14
|
+
const untested = rootRequirements.filter((r) => !referencedIds.has(r.id));
|
|
15
|
+
// CLI-FIND-LIST-2.2: full coverage → say so explicitly
|
|
16
|
+
if (untested.length === 0) {
|
|
17
|
+
console.log(`All ${rootRequirements.length} requirement(s) have test references.`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// CLI-FIND-LIST-2.1: count of untested + total
|
|
21
|
+
console.log(`Found ${untested.length} untested requirement(s) out of ${rootRequirements.length} total:\n`);
|
|
22
|
+
for (const r of untested) {
|
|
23
|
+
console.log(` ${r.id}: ${r.content}`);
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// CLI-FIND-LIST-1: list all roots
|
|
28
|
+
const grouped = new Map();
|
|
29
|
+
for (const req of flattened) {
|
|
30
|
+
const existing = grouped.get(req.rootId) || [];
|
|
31
|
+
existing.push(req);
|
|
32
|
+
grouped.set(req.rootId, existing);
|
|
33
|
+
}
|
|
34
|
+
// CLI-FIND-LIST-1.1: totals
|
|
35
|
+
console.log(`Found ${grouped.size} requirement(s) with ${flattened.length} total nodes:\n`);
|
|
36
|
+
// CLI-FIND-LIST-1.0: each root with ID, content, child count
|
|
37
|
+
for (const [rootId, reqs] of grouped) {
|
|
38
|
+
const root = reqs.find((r) => r.path.length === 0);
|
|
39
|
+
const childCount = reqs.length - 1;
|
|
40
|
+
console.log(` ${rootId}: ${root?.content || "(no content)"} (${childCount} children)`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { execSync } from
|
|
2
|
-
import {
|
|
3
|
-
import { homedir } from
|
|
4
|
-
import { join } from
|
|
5
|
-
import prompts from
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import prompts from "prompts";
|
|
6
|
+
import { brand } from "../utils/brand.js";
|
|
7
|
+
import { appendOrUpdateSection, buildNoGitRepoMessage, findDotrequirementsSection, findGitRoot, getContextFileName, } from "../utils/context-file.js";
|
|
8
|
+
import { loadTemplate } from "../utils/templates.js";
|
|
9
9
|
/**
|
|
10
10
|
* Load the context file section template
|
|
11
11
|
*/
|
|
12
12
|
function loadContextFileSection() {
|
|
13
|
-
return loadTemplate(
|
|
13
|
+
return loadTemplate("context-file-section.md");
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* Install workflow guidance to the appropriate context file for a platform
|
|
@@ -23,7 +23,7 @@ async function installContextFileSection(platform) {
|
|
|
23
23
|
}
|
|
24
24
|
const gitRoot = await findGitRoot();
|
|
25
25
|
if (!gitRoot) {
|
|
26
|
-
console.log(
|
|
26
|
+
console.log(`\n${buildNoGitRepoMessage(fileName)}\n`);
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const contextFilePath = join(gitRoot, fileName);
|
|
@@ -31,40 +31,48 @@ async function installContextFileSection(platform) {
|
|
|
31
31
|
// Check if file exists and has existing section
|
|
32
32
|
let existingSection = null;
|
|
33
33
|
if (existsSync(contextFilePath)) {
|
|
34
|
-
const content = readFileSync(contextFilePath,
|
|
34
|
+
const content = readFileSync(contextFilePath, "utf-8");
|
|
35
35
|
const section = findDotrequirementsSection(content);
|
|
36
36
|
if (section) {
|
|
37
37
|
existingSection = section.content;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
// Prompt user
|
|
41
|
-
const action = existingSection
|
|
41
|
+
const action = existingSection
|
|
42
|
+
? "Update"
|
|
43
|
+
: existsSync(contextFilePath)
|
|
44
|
+
? "Add to"
|
|
45
|
+
: "Create";
|
|
42
46
|
const response = await prompts({
|
|
43
|
-
type:
|
|
44
|
-
name:
|
|
47
|
+
type: "confirm",
|
|
48
|
+
name: "install",
|
|
45
49
|
message: `${action} ${fileName} with dotrequirements workflow guidance?`,
|
|
46
50
|
initial: true,
|
|
47
51
|
});
|
|
48
52
|
if (!response.install) {
|
|
49
|
-
console.log(
|
|
53
|
+
console.log("");
|
|
50
54
|
return;
|
|
51
55
|
}
|
|
52
56
|
// If updating, show what will change
|
|
53
57
|
if (existingSection) {
|
|
54
58
|
const confirmUpdate = await prompts({
|
|
55
|
-
type:
|
|
56
|
-
name:
|
|
57
|
-
message:
|
|
59
|
+
type: "confirm",
|
|
60
|
+
name: "confirm",
|
|
61
|
+
message: "Existing dotrequirements section found. Replace it?",
|
|
58
62
|
initial: true,
|
|
59
63
|
});
|
|
60
64
|
if (!confirmUpdate.confirm) {
|
|
61
|
-
console.log(
|
|
65
|
+
console.log(" Skipped.\n");
|
|
62
66
|
return;
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
69
|
try {
|
|
66
70
|
const result = appendOrUpdateSection(contextFilePath, sectionContent);
|
|
67
|
-
const actionVerb = result.action ===
|
|
71
|
+
const actionVerb = result.action === "created"
|
|
72
|
+
? "Created"
|
|
73
|
+
: result.action === "appended"
|
|
74
|
+
? "Added to"
|
|
75
|
+
: "Updated";
|
|
68
76
|
console.log(`✅ ${actionVerb} ${contextFilePath}\n`);
|
|
69
77
|
}
|
|
70
78
|
catch (error) {
|
|
@@ -79,71 +87,72 @@ export async function mcpSetupCommand() {
|
|
|
79
87
|
console.log(`🔧 Setting up ${brand} MCP server\n`);
|
|
80
88
|
// Interactive client selector
|
|
81
89
|
const response = await prompts({
|
|
82
|
-
type:
|
|
83
|
-
name:
|
|
84
|
-
message:
|
|
90
|
+
type: "select",
|
|
91
|
+
name: "client",
|
|
92
|
+
message: "Which AI assistant are you using?",
|
|
85
93
|
choices: [
|
|
86
|
-
{ title:
|
|
87
|
-
{ title:
|
|
88
|
-
{ title:
|
|
89
|
-
{ title:
|
|
90
|
-
{ title:
|
|
91
|
-
{ title:
|
|
92
|
-
{ title:
|
|
94
|
+
{ title: "Claude Code", value: "claude-code" },
|
|
95
|
+
{ title: "Claude Desktop", value: "claude-desktop" },
|
|
96
|
+
{ title: "Cursor", value: "cursor" },
|
|
97
|
+
{ title: "Google Antigravity", value: "antigravity" },
|
|
98
|
+
{ title: "OpenAI Codex", value: "codex" },
|
|
99
|
+
{ title: "GitHub Copilot", value: "github-copilot" },
|
|
100
|
+
{ title: "Other (custom path)", value: "other" },
|
|
93
101
|
],
|
|
94
102
|
initial: 0,
|
|
95
103
|
});
|
|
96
104
|
if (!response.client) {
|
|
97
|
-
console.log(
|
|
105
|
+
console.log("\nSetup cancelled.");
|
|
98
106
|
return;
|
|
99
107
|
}
|
|
100
108
|
switch (response.client) {
|
|
101
|
-
case
|
|
109
|
+
case "claude-code":
|
|
102
110
|
await setupClaudeCode();
|
|
103
111
|
break;
|
|
104
|
-
case
|
|
112
|
+
case "claude-desktop":
|
|
105
113
|
await setupClaudeDesktop();
|
|
106
114
|
break;
|
|
107
|
-
case
|
|
115
|
+
case "cursor":
|
|
108
116
|
await setupCursor();
|
|
109
117
|
break;
|
|
110
|
-
case
|
|
118
|
+
case "antigravity":
|
|
111
119
|
await setupAntigravity();
|
|
112
120
|
break;
|
|
113
|
-
case
|
|
121
|
+
case "codex":
|
|
114
122
|
await setupCodex();
|
|
115
123
|
break;
|
|
116
|
-
case
|
|
124
|
+
case "github-copilot":
|
|
117
125
|
await setupGitHubCopilot();
|
|
118
126
|
break;
|
|
119
|
-
case
|
|
127
|
+
case "other":
|
|
120
128
|
await setupOther();
|
|
121
129
|
break;
|
|
122
130
|
default:
|
|
123
131
|
console.log(`\n❌ ${response.client} is not yet supported.`);
|
|
124
|
-
console.log(
|
|
132
|
+
console.log("Please refer to the documentation for manual setup.");
|
|
125
133
|
}
|
|
126
134
|
}
|
|
127
135
|
async function setupClaudeCode() {
|
|
128
|
-
console.log(
|
|
136
|
+
console.log("\n📦 Configuring MCP for Claude Code...\n");
|
|
129
137
|
const command = `claude mcp add-json dotrequirements '{"type":"stdio","command":"npx","args":["-y","@popoverai/dotrequirements","mcp"]}'`;
|
|
130
138
|
let mcpConfigured = false;
|
|
131
139
|
try {
|
|
132
|
-
execSync(command, { stdio:
|
|
133
|
-
console.log(
|
|
140
|
+
execSync(command, { stdio: "pipe" });
|
|
141
|
+
console.log("✅ MCP configured successfully for Claude Code!");
|
|
134
142
|
mcpConfigured = true;
|
|
135
143
|
}
|
|
136
144
|
catch (error) {
|
|
137
|
-
const
|
|
138
|
-
const
|
|
145
|
+
const execError = error;
|
|
146
|
+
const stderr = execError.stderr?.toString() || "";
|
|
147
|
+
const errorMessage = execError.message || "";
|
|
139
148
|
const combinedError = stderr + errorMessage;
|
|
140
|
-
if (combinedError.includes(
|
|
141
|
-
console.log(
|
|
149
|
+
if (combinedError.includes("already exists")) {
|
|
150
|
+
console.log("✅ MCP server already configured for Claude Code");
|
|
142
151
|
mcpConfigured = true;
|
|
143
152
|
}
|
|
144
153
|
else {
|
|
145
|
-
console.error(
|
|
146
|
-
console.log(
|
|
154
|
+
console.error("❌ Failed to configure MCP automatically.");
|
|
155
|
+
console.log("\nYou can manually run:");
|
|
147
156
|
console.log(` ${command}`);
|
|
148
157
|
if (stderr) {
|
|
149
158
|
console.log(`\nError: ${stderr}`);
|
|
@@ -151,75 +160,75 @@ async function setupClaudeCode() {
|
|
|
151
160
|
}
|
|
152
161
|
}
|
|
153
162
|
if (mcpConfigured) {
|
|
154
|
-
console.log(
|
|
155
|
-
console.log(
|
|
156
|
-
await installContextFileSection(
|
|
163
|
+
console.log("\n⚠️ Important: Restart Claude Code for changes to take effect.");
|
|
164
|
+
console.log("\nYou can now ask your AI assistant to help write requirements!\n");
|
|
165
|
+
await installContextFileSection("claude-code");
|
|
157
166
|
}
|
|
158
167
|
}
|
|
159
168
|
async function setupClaudeDesktop() {
|
|
160
|
-
console.log(
|
|
169
|
+
console.log("\n📦 Configuring MCP for Claude Desktop...\n");
|
|
161
170
|
// Determine config path based on OS
|
|
162
171
|
const platform = process.platform;
|
|
163
172
|
let configPath;
|
|
164
173
|
let configDir;
|
|
165
|
-
if (platform ===
|
|
166
|
-
configDir = join(homedir(),
|
|
167
|
-
configPath = join(configDir,
|
|
174
|
+
if (platform === "darwin") {
|
|
175
|
+
configDir = join(homedir(), "Library", "Application Support", "Claude");
|
|
176
|
+
configPath = join(configDir, "claude_desktop_config.json");
|
|
168
177
|
}
|
|
169
|
-
else if (platform ===
|
|
170
|
-
const appData = process.env.APPDATA || join(homedir(),
|
|
171
|
-
configDir = join(appData,
|
|
172
|
-
configPath = join(configDir,
|
|
178
|
+
else if (platform === "win32") {
|
|
179
|
+
const appData = process.env.APPDATA || join(homedir(), "AppData", "Roaming");
|
|
180
|
+
configDir = join(appData, "Claude");
|
|
181
|
+
configPath = join(configDir, "claude_desktop_config.json");
|
|
173
182
|
}
|
|
174
183
|
else {
|
|
175
|
-
console.error(
|
|
176
|
-
console.log(
|
|
184
|
+
console.error("❌ Claude Desktop is only supported on macOS and Windows.");
|
|
185
|
+
console.log("\nFor Linux, please manually configure the MCP server.");
|
|
177
186
|
return;
|
|
178
187
|
}
|
|
179
188
|
const mcpServerConfig = {
|
|
180
|
-
command:
|
|
181
|
-
args: [
|
|
189
|
+
command: "npx",
|
|
190
|
+
args: ["-y", "@popoverai/dotrequirements", "mcp"],
|
|
182
191
|
env: {
|
|
183
192
|
REQUIREMENTS_DIR: process.cwd(),
|
|
184
193
|
},
|
|
185
194
|
};
|
|
186
195
|
try {
|
|
187
196
|
if (!existsSync(configDir)) {
|
|
188
|
-
console.log(
|
|
197
|
+
console.log("Creating Claude Desktop config directory...");
|
|
189
198
|
mkdirSync(configDir, { recursive: true });
|
|
190
199
|
}
|
|
191
200
|
let config = {};
|
|
192
201
|
if (existsSync(configPath)) {
|
|
193
202
|
try {
|
|
194
|
-
const existingContent = readFileSync(configPath,
|
|
203
|
+
const existingContent = readFileSync(configPath, "utf-8");
|
|
195
204
|
if (existingContent.trim()) {
|
|
196
205
|
config = JSON.parse(existingContent);
|
|
197
206
|
}
|
|
198
207
|
}
|
|
199
208
|
catch (parseError) {
|
|
200
|
-
console.log(
|
|
209
|
+
console.log("⚠️ Existing config file is invalid, creating fresh config...");
|
|
201
210
|
config = {};
|
|
202
211
|
}
|
|
203
212
|
}
|
|
204
213
|
if (!config.mcpServers) {
|
|
205
214
|
config.mcpServers = {};
|
|
206
215
|
}
|
|
207
|
-
config.mcpServers
|
|
208
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2),
|
|
216
|
+
config.mcpServers.dotrequirements = mcpServerConfig;
|
|
217
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
209
218
|
console.log(`✅ MCP configured successfully!`);
|
|
210
219
|
console.log(` Config file: ${configPath}`);
|
|
211
220
|
console.log(` REQUIREMENTS_DIR: ${process.cwd()}\n`);
|
|
212
|
-
console.log(
|
|
213
|
-
console.log(
|
|
214
|
-
console.log(
|
|
221
|
+
console.log("⚠️ Important: Quit and restart Claude Desktop for changes to take effect.");
|
|
222
|
+
console.log(" (Cmd+Q on macOS, not just close the window)\n");
|
|
223
|
+
console.log("You can now ask Claude Desktop to help write requirements!\n");
|
|
215
224
|
// Claude Desktop doesn't use skills like Claude Code, so we skip that step
|
|
216
225
|
}
|
|
217
226
|
catch (error) {
|
|
218
|
-
console.error(
|
|
227
|
+
console.error("❌ Failed to configure MCP automatically.");
|
|
219
228
|
console.log(`\nError: ${error instanceof Error ? error.message : String(error)}`);
|
|
220
|
-
console.log(
|
|
229
|
+
console.log("\nYou can manually edit the config file at:");
|
|
221
230
|
console.log(` ${configPath}\n`);
|
|
222
|
-
console.log(
|
|
231
|
+
console.log("Add the following configuration:");
|
|
223
232
|
const manualConfig = {
|
|
224
233
|
mcpServers: {
|
|
225
234
|
dotrequirements: mcpServerConfig,
|
|
@@ -229,48 +238,48 @@ async function setupClaudeDesktop() {
|
|
|
229
238
|
}
|
|
230
239
|
}
|
|
231
240
|
async function setupCursor() {
|
|
232
|
-
console.log(
|
|
233
|
-
const configPath = join(process.cwd(),
|
|
234
|
-
const configDir = join(process.cwd(),
|
|
241
|
+
console.log("\n📦 Configuring MCP for Cursor (project-specific)...\n");
|
|
242
|
+
const configPath = join(process.cwd(), ".cursor", "mcp.json");
|
|
243
|
+
const configDir = join(process.cwd(), ".cursor");
|
|
235
244
|
const mcpServerConfig = {
|
|
236
|
-
command:
|
|
237
|
-
args: [
|
|
245
|
+
command: "npx",
|
|
246
|
+
args: ["-y", "@popoverai/dotrequirements", "mcp"],
|
|
238
247
|
};
|
|
239
248
|
try {
|
|
240
249
|
if (!existsSync(configDir)) {
|
|
241
|
-
console.log(
|
|
250
|
+
console.log("Creating Cursor config directory...");
|
|
242
251
|
mkdirSync(configDir, { recursive: true });
|
|
243
252
|
}
|
|
244
253
|
let config = {};
|
|
245
254
|
if (existsSync(configPath)) {
|
|
246
255
|
try {
|
|
247
|
-
const existingContent = readFileSync(configPath,
|
|
256
|
+
const existingContent = readFileSync(configPath, "utf-8");
|
|
248
257
|
if (existingContent.trim()) {
|
|
249
258
|
config = JSON.parse(existingContent);
|
|
250
259
|
}
|
|
251
260
|
}
|
|
252
261
|
catch (parseError) {
|
|
253
|
-
console.log(
|
|
262
|
+
console.log("⚠️ Existing config file is invalid, creating fresh config...");
|
|
254
263
|
config = {};
|
|
255
264
|
}
|
|
256
265
|
}
|
|
257
266
|
if (!config.mcpServers) {
|
|
258
267
|
config.mcpServers = {};
|
|
259
268
|
}
|
|
260
|
-
config.mcpServers
|
|
261
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2),
|
|
269
|
+
config.mcpServers.dotrequirements = mcpServerConfig;
|
|
270
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
262
271
|
console.log(`✅ MCP configured successfully!`);
|
|
263
272
|
console.log(` Config file: ${configPath}\n`);
|
|
264
|
-
console.log(
|
|
265
|
-
console.log(
|
|
266
|
-
await installContextFileSection(
|
|
273
|
+
console.log("⚠️ Important: Reload or restart Cursor for changes to take effect.");
|
|
274
|
+
console.log("\nYou can now ask your AI assistant to help write requirements!\n");
|
|
275
|
+
await installContextFileSection("cursor");
|
|
267
276
|
}
|
|
268
277
|
catch (error) {
|
|
269
|
-
console.error(
|
|
278
|
+
console.error("❌ Failed to configure MCP automatically.");
|
|
270
279
|
console.log(`\nError: ${error instanceof Error ? error.message : String(error)}`);
|
|
271
|
-
console.log(
|
|
280
|
+
console.log("\nYou can manually edit the config file at:");
|
|
272
281
|
console.log(` ${configPath}\n`);
|
|
273
|
-
console.log(
|
|
282
|
+
console.log("Add the following configuration:");
|
|
274
283
|
const manualConfig = {
|
|
275
284
|
mcpServers: {
|
|
276
285
|
dotrequirements: mcpServerConfig,
|
|
@@ -280,21 +289,21 @@ async function setupCursor() {
|
|
|
280
289
|
}
|
|
281
290
|
}
|
|
282
291
|
async function setupAntigravity() {
|
|
283
|
-
console.log(
|
|
284
|
-
const configPath = join(homedir(),
|
|
285
|
-
const configDir = join(homedir(),
|
|
292
|
+
console.log("\n📦 Configuring MCP for Google Antigravity...\n");
|
|
293
|
+
const configPath = join(homedir(), ".gemini", "antigravity", "mcp_config.json");
|
|
294
|
+
const configDir = join(homedir(), ".gemini", "antigravity");
|
|
286
295
|
// Check if we're in a dotrequirements project directory
|
|
287
|
-
const envLocalPath = join(process.cwd(),
|
|
296
|
+
const envLocalPath = join(process.cwd(), ".env.local");
|
|
288
297
|
let projectId = null;
|
|
289
298
|
let projectPath = null;
|
|
290
299
|
if (existsSync(envLocalPath)) {
|
|
291
300
|
try {
|
|
292
|
-
const envContent = readFileSync(envLocalPath,
|
|
293
|
-
const lines = envContent.split(
|
|
301
|
+
const envContent = readFileSync(envLocalPath, "utf-8");
|
|
302
|
+
const lines = envContent.split("\n");
|
|
294
303
|
for (const line of lines) {
|
|
295
304
|
const trimmed = line.trim();
|
|
296
|
-
if (trimmed.startsWith(
|
|
297
|
-
projectId = trimmed.split(
|
|
305
|
+
if (trimmed.startsWith("DOTREQUIREMENTS_PROJECT_ID=")) {
|
|
306
|
+
projectId = trimmed.split("=")[1]?.trim().replace(/['"]/g, "");
|
|
298
307
|
projectPath = process.cwd();
|
|
299
308
|
break;
|
|
300
309
|
}
|
|
@@ -306,33 +315,34 @@ async function setupAntigravity() {
|
|
|
306
315
|
}
|
|
307
316
|
try {
|
|
308
317
|
if (!existsSync(configDir)) {
|
|
309
|
-
console.log(
|
|
318
|
+
console.log("Creating Antigravity config directory...");
|
|
310
319
|
mkdirSync(configDir, { recursive: true });
|
|
311
320
|
}
|
|
312
321
|
let config = {};
|
|
313
322
|
if (existsSync(configPath)) {
|
|
314
323
|
try {
|
|
315
|
-
const existingContent = readFileSync(configPath,
|
|
324
|
+
const existingContent = readFileSync(configPath, "utf-8");
|
|
316
325
|
if (existingContent.trim()) {
|
|
317
326
|
config = JSON.parse(existingContent);
|
|
318
327
|
}
|
|
319
328
|
}
|
|
320
329
|
catch (parseError) {
|
|
321
|
-
console.log(
|
|
330
|
+
console.log("⚠️ Existing config file is invalid, creating fresh config...");
|
|
322
331
|
config = {};
|
|
323
332
|
}
|
|
324
333
|
}
|
|
325
334
|
if (!config.mcpServers) {
|
|
326
335
|
config.mcpServers = {};
|
|
327
336
|
}
|
|
328
|
-
if (!config.mcpServers
|
|
329
|
-
config.mcpServers
|
|
330
|
-
command:
|
|
331
|
-
args: [
|
|
337
|
+
if (!config.mcpServers.dotrequirements) {
|
|
338
|
+
config.mcpServers.dotrequirements = {
|
|
339
|
+
command: "npx",
|
|
340
|
+
args: ["-y", "@popoverai/dotrequirements", "mcp"],
|
|
332
341
|
env: {},
|
|
333
342
|
};
|
|
334
343
|
}
|
|
335
|
-
|
|
344
|
+
// biome-ignore lint/suspicious/noExplicitAny: `config` is parsed JSON from a user-owned MCP config file; its shape isn't ours to type fully. We only need the `env` bag, which we narrow ad-hoc here.
|
|
345
|
+
const dotreqServer = config.mcpServers.dotrequirements;
|
|
336
346
|
if (!dotreqServer.env) {
|
|
337
347
|
dotreqServer.env = {};
|
|
338
348
|
}
|
|
@@ -344,86 +354,86 @@ async function setupAntigravity() {
|
|
|
344
354
|
}
|
|
345
355
|
else {
|
|
346
356
|
console.log(`ℹ️ Not in a ${brand} project directory (no .env.local with DOTREQUIREMENTS_PROJECT_ID found)`);
|
|
347
|
-
console.log(
|
|
357
|
+
console.log(" Setting up global MCP server only.\n");
|
|
348
358
|
}
|
|
349
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2),
|
|
359
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
350
360
|
console.log(`✅ MCP configured successfully!`);
|
|
351
361
|
console.log(` Config file: ${configPath}\n`);
|
|
352
|
-
console.log(
|
|
353
|
-
console.log(
|
|
362
|
+
console.log("⚠️ Important: Reload or restart Google Antigravity for changes to take effect.");
|
|
363
|
+
console.log("\nYou can now ask your AI assistant to help write requirements!");
|
|
354
364
|
if (projectId) {
|
|
355
365
|
console.log(`\n💡 To add more projects, run \`dotreq mcp-setup\` from each project directory.\n`);
|
|
356
366
|
}
|
|
357
367
|
else {
|
|
358
|
-
console.log(
|
|
368
|
+
console.log("");
|
|
359
369
|
}
|
|
360
|
-
await installContextFileSection(
|
|
370
|
+
await installContextFileSection("antigravity");
|
|
361
371
|
}
|
|
362
372
|
catch (error) {
|
|
363
|
-
console.error(
|
|
373
|
+
console.error("❌ Failed to configure MCP automatically.");
|
|
364
374
|
console.log(`\nError: ${error instanceof Error ? error.message : String(error)}`);
|
|
365
|
-
console.log(
|
|
375
|
+
console.log("\nYou can manually edit the config file at:");
|
|
366
376
|
console.log(` ${configPath}`);
|
|
367
377
|
}
|
|
368
378
|
}
|
|
369
379
|
async function setupCodex() {
|
|
370
|
-
console.log(
|
|
380
|
+
console.log("\n📦 Configuring MCP for OpenAI Codex...\n");
|
|
371
381
|
const command = `codex mcp add dotrequirements -- npx -y @popoverai/dotrequirements mcp`;
|
|
372
382
|
try {
|
|
373
|
-
execSync(command, { stdio:
|
|
374
|
-
console.log(
|
|
375
|
-
console.log(
|
|
376
|
-
console.log(
|
|
377
|
-
await installContextFileSection(
|
|
383
|
+
execSync(command, { stdio: "inherit" });
|
|
384
|
+
console.log("\n✅ MCP configured successfully for Codex!");
|
|
385
|
+
console.log("\n⚠️ Important: Restart Codex for changes to take effect.");
|
|
386
|
+
console.log("\nYou can now ask your AI assistant to help write requirements!\n");
|
|
387
|
+
await installContextFileSection("codex");
|
|
378
388
|
}
|
|
379
389
|
catch (error) {
|
|
380
|
-
console.error(
|
|
381
|
-
console.log(
|
|
390
|
+
console.error("\n❌ Failed to configure MCP automatically.");
|
|
391
|
+
console.log("\nYou can manually run:");
|
|
382
392
|
console.log(` ${command}`);
|
|
383
|
-
console.log(
|
|
384
|
-
console.log(
|
|
393
|
+
console.log("\nOr manually edit ~/.codex/config.toml and add:");
|
|
394
|
+
console.log("[mcp_servers.dotrequirements]");
|
|
385
395
|
console.log('command = "npx"');
|
|
386
396
|
console.log('args = ["-y", "@popoverai/dotrequirements", "mcp"]');
|
|
387
397
|
}
|
|
388
398
|
}
|
|
389
399
|
async function setupGitHubCopilot() {
|
|
390
|
-
console.log(
|
|
391
|
-
console.log(
|
|
392
|
-
console.log(
|
|
393
|
-
console.log(
|
|
394
|
-
await installContextFileSection(
|
|
400
|
+
console.log("\n📦 Configuring skills for GitHub Copilot...\n");
|
|
401
|
+
console.log("ℹ️ GitHub Copilot discovers MCP servers from your IDE configuration.");
|
|
402
|
+
console.log(" Please configure the MCP server in VS Code settings or GitHub settings.\n");
|
|
403
|
+
console.log(" MCP server command: npx -y @popoverai/dotrequirements mcp\n");
|
|
404
|
+
await installContextFileSection("github-copilot");
|
|
395
405
|
}
|
|
396
406
|
async function setupOther() {
|
|
397
|
-
console.log(
|
|
398
|
-
console.log(
|
|
399
|
-
console.log(
|
|
400
|
-
console.log(
|
|
401
|
-
console.log(
|
|
402
|
-
console.log(
|
|
407
|
+
console.log("\n📦 Custom Context File Setup\n");
|
|
408
|
+
console.log("ℹ️ Workflow guidance is added to a context file at your project root.");
|
|
409
|
+
console.log(" Common file names by platform:");
|
|
410
|
+
console.log(" - CLAUDE.md (Claude Code)");
|
|
411
|
+
console.log(" - AGENTS.md (Cursor, Codex, GitHub Copilot)");
|
|
412
|
+
console.log(" - GEMINI.md (Antigravity)\n");
|
|
403
413
|
const response = await prompts({
|
|
404
|
-
type:
|
|
405
|
-
name:
|
|
406
|
-
message:
|
|
414
|
+
type: "select",
|
|
415
|
+
name: "file",
|
|
416
|
+
message: "Which context file should we update?",
|
|
407
417
|
choices: [
|
|
408
|
-
{ title:
|
|
409
|
-
{ title:
|
|
410
|
-
{ title:
|
|
418
|
+
{ title: "AGENTS.md (most compatible)", value: "AGENTS.md" },
|
|
419
|
+
{ title: "CLAUDE.md", value: "CLAUDE.md" },
|
|
420
|
+
{ title: "GEMINI.md", value: "GEMINI.md" },
|
|
411
421
|
],
|
|
412
422
|
initial: 0,
|
|
413
423
|
});
|
|
414
424
|
if (!response.file) {
|
|
415
|
-
console.log(
|
|
425
|
+
console.log("\nSetup cancelled.");
|
|
416
426
|
return;
|
|
417
427
|
}
|
|
418
|
-
console.log(
|
|
419
|
-
console.log(
|
|
420
|
-
console.log(
|
|
421
|
-
console.log(
|
|
428
|
+
console.log("\n📝 MCP Server Setup\n");
|
|
429
|
+
console.log("Configure your AI assistant to run the MCP server:");
|
|
430
|
+
console.log(" Command: npx");
|
|
431
|
+
console.log(" Args: -y @popoverai/dotrequirements mcp\n");
|
|
422
432
|
// Determine platform based on file choice for the install function
|
|
423
433
|
const platformMap = {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
434
|
+
"CLAUDE.md": "claude-code",
|
|
435
|
+
"AGENTS.md": "cursor", // Any AGENTS.md platform works
|
|
436
|
+
"GEMINI.md": "antigravity",
|
|
427
437
|
};
|
|
428
438
|
const platform = platformMap[response.file];
|
|
429
439
|
await installContextFileSection(platform);
|
package/dist/commands/mcp.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
export async function mcpCommand() {
|
|
6
6
|
// Import and start the MCP server
|
|
7
7
|
// The server handles stdio transport and runs until process termination
|
|
8
|
-
const { main } = await import(
|
|
8
|
+
const { main } = await import("../mcp/index.js");
|
|
9
9
|
await main();
|
|
10
10
|
}
|
|
11
11
|
//# sourceMappingURL=mcp.js.map
|
package/dist/commands/prepare.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { prepare } from
|
|
1
|
+
import { prepare } from "../harness/prepare.js";
|
|
2
2
|
export async function prepareCommand(options) {
|
|
3
3
|
const result = prepare({
|
|
4
4
|
cwd: process.cwd(),
|
|
@@ -12,9 +12,9 @@ export async function prepareCommand(options) {
|
|
|
12
12
|
console.log(` - ${err.file}: ${err.error}`);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
console.log(
|
|
16
|
-
console.log(
|
|
17
|
-
console.log('\nRun your tests, then run "dotrequirements finalize" to generate coverage report.');
|
|
15
|
+
console.log("\nCache written to .requirements/.cache/lookup.json");
|
|
16
|
+
console.log("Tracking initialized at .requirements/.cache/tracking.jsonl");
|
|
17
|
+
console.log('\nRun your tests, then run "dotrequirements harness finalize" to generate coverage report.');
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=prepare.js.map
|