@popoverai/dotrequirements 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +478 -0
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.js +82 -0
  4. package/dist/commands/init.d.ts +6 -0
  5. package/dist/commands/init.js +355 -0
  6. package/dist/commands/link.d.ts +15 -0
  7. package/dist/commands/link.js +156 -0
  8. package/dist/commands/login.d.ts +12 -0
  9. package/dist/commands/login.js +117 -0
  10. package/dist/commands/logout.d.ts +5 -0
  11. package/dist/commands/logout.js +17 -0
  12. package/dist/commands/mcp-setup.d.ts +5 -0
  13. package/dist/commands/mcp-setup.js +367 -0
  14. package/dist/commands/mcp.d.ts +6 -0
  15. package/dist/commands/mcp.js +10 -0
  16. package/dist/commands/pull.d.ts +7 -0
  17. package/dist/commands/pull.js +171 -0
  18. package/dist/commands/push.d.ts +11 -0
  19. package/dist/commands/push.js +310 -0
  20. package/dist/commands/test.d.ts +6 -0
  21. package/dist/commands/test.js +78 -0
  22. package/dist/config.d.ts +5 -0
  23. package/dist/config.js +16 -0
  24. package/dist/convex.d.ts +56 -0
  25. package/dist/convex.js +58 -0
  26. package/dist/harness/cache.d.ts +135 -0
  27. package/dist/harness/cache.js +342 -0
  28. package/dist/harness/convexReporting.d.ts +15 -0
  29. package/dist/harness/convexReporting.js +136 -0
  30. package/dist/harness/coverageCache.d.ts +30 -0
  31. package/dist/harness/coverageCache.js +70 -0
  32. package/dist/harness/finalize.d.ts +48 -0
  33. package/dist/harness/finalize.js +299 -0
  34. package/dist/harness/index.d.ts +70 -0
  35. package/dist/harness/index.js +103 -0
  36. package/dist/harness/localReporting.d.ts +6 -0
  37. package/dist/harness/localReporting.js +49 -0
  38. package/dist/harness/prepare.d.ts +41 -0
  39. package/dist/harness/prepare.js +83 -0
  40. package/dist/harness/requirementsLoader.d.ts +45 -0
  41. package/dist/harness/requirementsLoader.js +201 -0
  42. package/dist/harness/tracking.d.ts +49 -0
  43. package/dist/harness/tracking.js +179 -0
  44. package/dist/harness/types.d.ts +12 -0
  45. package/dist/harness/types.js +6 -0
  46. package/dist/mcp/convexClient.d.ts +43 -0
  47. package/dist/mcp/convexClient.js +101 -0
  48. package/dist/mcp/grep.d.ts +24 -0
  49. package/dist/mcp/grep.js +261 -0
  50. package/dist/mcp/index.d.ts +3 -0
  51. package/dist/mcp/index.js +1758 -0
  52. package/dist/mcp/requirements.d.ts +47 -0
  53. package/dist/mcp/requirements.js +141 -0
  54. package/dist/mcp/testCodeExtractor.d.ts +22 -0
  55. package/dist/mcp/testCodeExtractor.js +152 -0
  56. package/dist/mcp/types.d.ts +27 -0
  57. package/dist/mcp/types.js +2 -0
  58. package/dist/schema/browser.d.ts +12 -0
  59. package/dist/schema/browser.js +24 -0
  60. package/dist/schema/builder.d.ts +25 -0
  61. package/dist/schema/builder.js +125 -0
  62. package/dist/schema/conversions.d.ts +69 -0
  63. package/dist/schema/conversions.js +201 -0
  64. package/dist/schema/index.d.ts +14 -0
  65. package/dist/schema/index.js +24 -0
  66. package/dist/schema/parser-core.d.ts +61 -0
  67. package/dist/schema/parser-core.js +247 -0
  68. package/dist/schema/parser.d.ts +44 -0
  69. package/dist/schema/parser.js +295 -0
  70. package/dist/schema/resolver.d.ts +66 -0
  71. package/dist/schema/resolver.js +185 -0
  72. package/dist/schema/schemas.d.ts +312 -0
  73. package/dist/schema/schemas.js +258 -0
  74. package/dist/schema/test-schema.d.ts +5 -0
  75. package/dist/schema/test-schema.js +81 -0
  76. package/dist/templates/antigravity-gemini.md +3 -0
  77. package/dist/templates/antigravity-overview-rule.md +3 -0
  78. package/dist/templates/antigravity-test-rule.md +3 -0
  79. package/dist/templates/behavioral-core.md +25 -0
  80. package/dist/templates/claude-code-overview-skill.md +6 -0
  81. package/dist/templates/claude-code-skill.md +6 -0
  82. package/dist/templates/claude-code-test-skill.md +6 -0
  83. package/dist/templates/codex-agents.md +3 -0
  84. package/dist/templates/codex-overview-agents.md +3 -0
  85. package/dist/templates/codex-test-agents.md +3 -0
  86. package/dist/templates/cursor-overview-rule.mdc +5 -0
  87. package/dist/templates/cursor-rule.mdc +5 -0
  88. package/dist/templates/cursor-test-rule.mdc +5 -0
  89. package/dist/templates/example-requirements.d.ts +8 -0
  90. package/dist/templates/example-requirements.js +88 -0
  91. package/dist/templates/example-requirements.ts +88 -0
  92. package/dist/templates/overview-core.md +27 -0
  93. package/dist/templates/requirements-readme.d.ts +5 -0
  94. package/dist/templates/requirements-readme.js +31 -0
  95. package/dist/templates/requirements-readme.ts +30 -0
  96. package/dist/templates/test-writing-core.md +72 -0
  97. package/dist/utils/brand.d.ts +5 -0
  98. package/dist/utils/brand.js +8 -0
  99. package/dist/utils/browser-launch.d.ts +19 -0
  100. package/dist/utils/browser-launch.js +36 -0
  101. package/dist/utils/detect-existing-project.d.ts +5 -0
  102. package/dist/utils/detect-existing-project.js +34 -0
  103. package/dist/utils/env.d.ts +19 -0
  104. package/dist/utils/env.js +56 -0
  105. package/dist/utils/gitignore.d.ts +7 -0
  106. package/dist/utils/gitignore.js +29 -0
  107. package/dist/utils/local-project.d.ts +31 -0
  108. package/dist/utils/local-project.js +33 -0
  109. package/dist/utils/oauth-callback-server.d.ts +28 -0
  110. package/dist/utils/oauth-callback-server.js +156 -0
  111. package/dist/utils/oauth-flow.d.ts +22 -0
  112. package/dist/utils/oauth-flow.js +120 -0
  113. package/dist/utils/project-discovery.d.ts +57 -0
  114. package/dist/utils/project-discovery.js +146 -0
  115. package/dist/utils/project-name.d.ts +8 -0
  116. package/dist/utils/project-name.js +48 -0
  117. package/dist/utils/project-selector.d.ts +25 -0
  118. package/dist/utils/project-selector.js +69 -0
  119. package/dist/utils/prompts.d.ts +33 -0
  120. package/dist/utils/prompts.js +60 -0
  121. package/dist/utils/templates.d.ts +29 -0
  122. package/dist/utils/templates.js +67 -0
  123. package/dist/utils/token-refresh.d.ts +24 -0
  124. package/dist/utils/token-refresh.js +69 -0
  125. package/dist/utils/token-storage.d.ts +31 -0
  126. package/dist/utils/token-storage.js +57 -0
  127. package/package.json +82 -0
@@ -0,0 +1,69 @@
1
+ import { promptChoice } from './prompts.js';
2
+ import { api } from '../convex.js';
3
+ /**
4
+ * Prompt user to select a team from their available teams.
5
+ * Returns the team ID, or null if user cancels.
6
+ */
7
+ export async function selectTeam(client) {
8
+ console.log('Fetching your teams...\n');
9
+ const teams = await client.query(api.teams.queries.listForUserWithUsage);
10
+ if (teams.length === 0) {
11
+ console.log('You are not a member of any teams.');
12
+ console.log('To create a team, visit: https://app.dotrequirements.io/teams/new\n');
13
+ return null;
14
+ }
15
+ const teamChoices = teams.map((team) => {
16
+ const limitDisplay = team.projectLimit === -1
17
+ ? 'unlimited'
18
+ : `${team.projectCount}/${team.projectLimit}`;
19
+ return {
20
+ title: `${team.name} (${team.tierName} - ${limitDisplay} projects)`,
21
+ value: team.teamId,
22
+ };
23
+ });
24
+ const selectedTeamId = await promptChoice('Select a team:', teamChoices);
25
+ return selectedTeamId ?? null;
26
+ }
27
+ /**
28
+ * Prompt user to select a project from a team.
29
+ * Returns the selected project info, or null if user cancels or no projects exist.
30
+ */
31
+ export async function selectProject(client, teamId) {
32
+ console.log('\nFetching projects...\n');
33
+ const projectsWithSecrets = await client.query(api.projectSecrets.queries.listOwnSecretsForTeam, { target: { type: 'team', id: teamId } });
34
+ if (projectsWithSecrets.length === 0) {
35
+ console.log('No projects found in this team.');
36
+ console.log('Use "dotrequirements init" to create a new project.\n');
37
+ return null;
38
+ }
39
+ const projectChoices = projectsWithSecrets.map((project) => ({
40
+ title: project.projectSlug
41
+ ? `${project.projectName} (${project.projectSlug})`
42
+ : project.projectName,
43
+ value: project.projectId,
44
+ }));
45
+ const selectedProjectId = await promptChoice('Select a project:', projectChoices);
46
+ if (!selectedProjectId) {
47
+ return null;
48
+ }
49
+ const selectedProject = projectsWithSecrets.find((p) => p.projectId === selectedProjectId);
50
+ if (!selectedProject) {
51
+ return null;
52
+ }
53
+ return {
54
+ projectId: selectedProject.projectId,
55
+ projectName: selectedProject.projectName,
56
+ projectSlug: selectedProject.projectSlug,
57
+ };
58
+ }
59
+ /**
60
+ * Get or create a user-scoped secret for a project.
61
+ * Returns the secret and whether it was newly created.
62
+ */
63
+ export async function getOrCreateProjectSecret(client, projectId) {
64
+ const result = await client.mutation(api.projectSecrets.mutations.ensureOwnSecret, {
65
+ target: { type: 'project', id: projectId },
66
+ });
67
+ return result;
68
+ }
69
+ //# sourceMappingURL=project-selector.js.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Interactive prompt utilities for the CLI.
3
+ * Uses the prompts library for user interaction.
4
+ */
5
+ /**
6
+ * Prompt the user to choose from a list of options.
7
+ * Returns the selected value.
8
+ */
9
+ export declare function promptChoice<T extends string>(message: string, choices: Array<{
10
+ title: string;
11
+ value: T;
12
+ description?: string;
13
+ disabled?: boolean;
14
+ }>): Promise<T | undefined>;
15
+ /**
16
+ * Prompt the user for text input.
17
+ * Returns the entered text or undefined if cancelled.
18
+ */
19
+ export declare function promptText(message: string, options?: {
20
+ initial?: string;
21
+ validate?: (value: string) => boolean | string;
22
+ }): Promise<string | undefined>;
23
+ /**
24
+ * Prompt the user for confirmation (yes/no).
25
+ * Returns true if confirmed, false otherwise.
26
+ */
27
+ export declare function promptConfirm(message: string, initial?: boolean): Promise<boolean>;
28
+ /**
29
+ * Prompt for password/secret input (hidden).
30
+ * Returns the entered secret or undefined if cancelled.
31
+ */
32
+ export declare function promptSecret(message: string): Promise<string | undefined>;
33
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Interactive prompt utilities for the CLI.
3
+ * Uses the prompts library for user interaction.
4
+ */
5
+ import prompts from "prompts";
6
+ /**
7
+ * Prompt the user to choose from a list of options.
8
+ * Returns the selected value.
9
+ */
10
+ export async function promptChoice(message, choices) {
11
+ const response = await prompts({
12
+ type: "select",
13
+ name: "value",
14
+ message,
15
+ choices,
16
+ initial: 0,
17
+ });
18
+ return response.value;
19
+ }
20
+ /**
21
+ * Prompt the user for text input.
22
+ * Returns the entered text or undefined if cancelled.
23
+ */
24
+ export async function promptText(message, options) {
25
+ const response = await prompts({
26
+ type: "text",
27
+ name: "value",
28
+ message,
29
+ initial: options?.initial,
30
+ validate: options?.validate,
31
+ });
32
+ return response.value;
33
+ }
34
+ /**
35
+ * Prompt the user for confirmation (yes/no).
36
+ * Returns true if confirmed, false otherwise.
37
+ */
38
+ export async function promptConfirm(message, initial = false) {
39
+ const response = await prompts({
40
+ type: "confirm",
41
+ name: "value",
42
+ message,
43
+ initial,
44
+ });
45
+ // If user cancels (Ctrl+C), treat as false
46
+ return response.value ?? false;
47
+ }
48
+ /**
49
+ * Prompt for password/secret input (hidden).
50
+ * Returns the entered secret or undefined if cancelled.
51
+ */
52
+ export async function promptSecret(message) {
53
+ const response = await prompts({
54
+ type: "password",
55
+ name: "value",
56
+ message,
57
+ });
58
+ return response.value;
59
+ }
60
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Load a template file and replace placeholders
3
+ */
4
+ export declare function loadTemplate(templateName: string, replacements?: Record<string, string>): string;
5
+ /**
6
+ * Load the behavioral core content (requirements capture guidance)
7
+ */
8
+ export declare function loadBehavioralCore(): string;
9
+ /**
10
+ * Load the test writing core content
11
+ */
12
+ export declare function loadTestWritingCore(): string;
13
+ /**
14
+ * Load the overview core content
15
+ */
16
+ export declare function loadOverviewCore(): string;
17
+ /**
18
+ * Load the requirements skill template with core content injected
19
+ */
20
+ export declare function loadPlatformTemplate(templateName: string): string;
21
+ /**
22
+ * Load the test writing skill template with core content injected
23
+ */
24
+ export declare function loadTestWritingTemplate(templateName: string): string;
25
+ /**
26
+ * Load the overview skill template with core content injected
27
+ */
28
+ export declare function loadOverviewTemplate(templateName: string): string;
29
+ //# sourceMappingURL=templates.d.ts.map
@@ -0,0 +1,67 @@
1
+ import { readFileSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ /**
5
+ * Get the templates directory path
6
+ */
7
+ function getTemplatesDir() {
8
+ // In production (compiled), templates are in dist/templates
9
+ // In development, they're in src/templates
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ // Go up from utils/ to src/ or dist/, then into templates/
13
+ return join(__dirname, '..', 'templates');
14
+ }
15
+ /**
16
+ * Load a template file and replace placeholders
17
+ */
18
+ export function loadTemplate(templateName, replacements = {}) {
19
+ const templatesDir = getTemplatesDir();
20
+ const templatePath = join(templatesDir, templateName);
21
+ let content = readFileSync(templatePath, 'utf-8');
22
+ // Replace placeholders
23
+ for (const [key, value] of Object.entries(replacements)) {
24
+ content = content.replace(new RegExp(`{{${key}}}`, 'g'), value);
25
+ }
26
+ return content;
27
+ }
28
+ /**
29
+ * Load the behavioral core content (requirements capture guidance)
30
+ */
31
+ export function loadBehavioralCore() {
32
+ return loadTemplate('behavioral-core.md');
33
+ }
34
+ /**
35
+ * Load the test writing core content
36
+ */
37
+ export function loadTestWritingCore() {
38
+ return loadTemplate('test-writing-core.md');
39
+ }
40
+ /**
41
+ * Load the overview core content
42
+ */
43
+ export function loadOverviewCore() {
44
+ return loadTemplate('overview-core.md');
45
+ }
46
+ /**
47
+ * Load the requirements skill template with core content injected
48
+ */
49
+ export function loadPlatformTemplate(templateName) {
50
+ const behavioralCore = loadBehavioralCore();
51
+ return loadTemplate(templateName, { BEHAVIORAL_CORE: behavioralCore });
52
+ }
53
+ /**
54
+ * Load the test writing skill template with core content injected
55
+ */
56
+ export function loadTestWritingTemplate(templateName) {
57
+ const testWritingCore = loadTestWritingCore();
58
+ return loadTemplate(templateName, { TEST_WRITING_CORE: testWritingCore });
59
+ }
60
+ /**
61
+ * Load the overview skill template with core content injected
62
+ */
63
+ export function loadOverviewTemplate(templateName) {
64
+ const overviewCore = loadOverviewCore();
65
+ return loadTemplate(templateName, { OVERVIEW_CORE: overviewCore });
66
+ }
67
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Token refresh utilities for maintaining long-lived CLI sessions.
3
+ *
4
+ * WorkOS access tokens expire after 5 minutes, but refresh tokens can be used
5
+ * to obtain new access/refresh token pairs. Refresh tokens are single-use and
6
+ * get rotated on each refresh.
7
+ */
8
+ /**
9
+ * Get a valid access token, refreshing if needed.
10
+ *
11
+ * This function should be called before making any authenticated Convex requests.
12
+ * It checks if the current access token is expired and refreshes it if necessary.
13
+ *
14
+ * Returns null if no tokens are stored (user needs to login).
15
+ */
16
+ export declare function getValidAccessToken(): Promise<string | null>;
17
+ /**
18
+ * Ensure user is authenticated with a valid access token.
19
+ *
20
+ * Throws an error if not logged in or if token refresh fails.
21
+ * Use this at the start of commands that require authentication.
22
+ */
23
+ export declare function requireAuth(): Promise<string>;
24
+ //# sourceMappingURL=token-refresh.d.ts.map
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Token refresh utilities for maintaining long-lived CLI sessions.
3
+ *
4
+ * WorkOS access tokens expire after 5 minutes, but refresh tokens can be used
5
+ * to obtain new access/refresh token pairs. Refresh tokens are single-use and
6
+ * get rotated on each refresh.
7
+ */
8
+ import { ConvexHttpClient } from 'convex/browser';
9
+ import { getTokens, storeTokens, areTokensExpired } from './token-storage.js';
10
+ import { getConvexUrl } from '../config.js';
11
+ import { api } from '../convex.js';
12
+ /**
13
+ * Get a valid access token, refreshing if needed.
14
+ *
15
+ * This function should be called before making any authenticated Convex requests.
16
+ * It checks if the current access token is expired and refreshes it if necessary.
17
+ *
18
+ * Returns null if no tokens are stored (user needs to login).
19
+ */
20
+ export async function getValidAccessToken() {
21
+ const tokens = await getTokens();
22
+ if (!tokens) {
23
+ return null; // Not logged in
24
+ }
25
+ // If tokens are still valid, return current access token
26
+ if (!areTokensExpired(tokens)) {
27
+ return tokens.accessToken;
28
+ }
29
+ // Tokens expired, refresh them
30
+ try {
31
+ console.log('Access token expired, refreshing...');
32
+ // Refresh tokens via Convex action (server-side WorkOS call)
33
+ const client = new ConvexHttpClient(getConvexUrl());
34
+ const result = await client.action(api.lib.authActions.refreshAccessToken, {
35
+ refreshToken: tokens.refreshToken,
36
+ });
37
+ if (!result.success) {
38
+ throw new Error(`Token refresh failed: ${result.error}`);
39
+ }
40
+ const { accessToken, refreshToken, expiresAt } = result;
41
+ // Store new tokens (IMPORTANT: refresh token is single-use, must update)
42
+ await storeTokens({
43
+ accessToken,
44
+ refreshToken, // New refresh token from response
45
+ expiresAt,
46
+ });
47
+ console.log('✓ Token refreshed successfully');
48
+ return accessToken;
49
+ }
50
+ catch (error) {
51
+ console.error('Failed to refresh access token:', error);
52
+ console.log('Please run "dotrequirements login" to re-authenticate.');
53
+ return null;
54
+ }
55
+ }
56
+ /**
57
+ * Ensure user is authenticated with a valid access token.
58
+ *
59
+ * Throws an error if not logged in or if token refresh fails.
60
+ * Use this at the start of commands that require authentication.
61
+ */
62
+ export async function requireAuth() {
63
+ const accessToken = await getValidAccessToken();
64
+ if (!accessToken) {
65
+ throw new Error('Not authenticated. Please run "dotrequirements login" first.');
66
+ }
67
+ return accessToken;
68
+ }
69
+ //# sourceMappingURL=token-refresh.js.map
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Token storage utilities for OAuth access tokens and refresh tokens.
3
+ *
4
+ * Uses file-based storage at ~/.dotrequirements/tokens.json with restricted permissions.
5
+ */
6
+ export interface StoredTokens {
7
+ accessToken: string;
8
+ refreshToken: string;
9
+ expiresAt: number;
10
+ }
11
+ /**
12
+ * Store tokens in file storage with restricted permissions
13
+ */
14
+ export declare function storeTokens(tokens: StoredTokens): Promise<void>;
15
+ /**
16
+ * Retrieve stored tokens from file
17
+ */
18
+ export declare function getTokens(): Promise<StoredTokens | null>;
19
+ /**
20
+ * Delete stored tokens
21
+ */
22
+ export declare function deleteTokens(): Promise<void>;
23
+ /**
24
+ * Check if tokens are expired
25
+ */
26
+ export declare function areTokensExpired(tokens: StoredTokens): boolean;
27
+ /**
28
+ * Check if tokens exist and are valid
29
+ */
30
+ export declare function hasValidTokens(): Promise<boolean>;
31
+ //# sourceMappingURL=token-storage.d.ts.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Token storage utilities for OAuth access tokens and refresh tokens.
3
+ *
4
+ * Uses file-based storage at ~/.dotrequirements/tokens.json with restricted permissions.
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ import * as os from 'os';
9
+ const TOKEN_DIR = path.join(os.homedir(), '.dotrequirements');
10
+ const TOKEN_FILE = path.join(TOKEN_DIR, 'tokens.json');
11
+ /**
12
+ * Store tokens in file storage with restricted permissions
13
+ */
14
+ export async function storeTokens(tokens) {
15
+ if (!fs.existsSync(TOKEN_DIR)) {
16
+ fs.mkdirSync(TOKEN_DIR, { recursive: true, mode: 0o700 });
17
+ }
18
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify(tokens, null, 2), { mode: 0o600 });
19
+ }
20
+ /**
21
+ * Retrieve stored tokens from file
22
+ */
23
+ export async function getTokens() {
24
+ if (fs.existsSync(TOKEN_FILE)) {
25
+ try {
26
+ const content = fs.readFileSync(TOKEN_FILE, 'utf-8');
27
+ return JSON.parse(content);
28
+ }
29
+ catch (error) {
30
+ console.error('Failed to read stored tokens:', error);
31
+ return null;
32
+ }
33
+ }
34
+ return null;
35
+ }
36
+ /**
37
+ * Delete stored tokens
38
+ */
39
+ export async function deleteTokens() {
40
+ if (fs.existsSync(TOKEN_FILE)) {
41
+ fs.unlinkSync(TOKEN_FILE);
42
+ }
43
+ }
44
+ /**
45
+ * Check if tokens are expired
46
+ */
47
+ export function areTokensExpired(tokens) {
48
+ return Date.now() >= tokens.expiresAt;
49
+ }
50
+ /**
51
+ * Check if tokens exist and are valid
52
+ */
53
+ export async function hasValidTokens() {
54
+ const tokens = await getTokens();
55
+ return tokens !== null && !areTokensExpired(tokens);
56
+ }
57
+ //# sourceMappingURL=token-storage.js.map
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@popoverai/dotrequirements",
3
+ "version": "0.11.0",
4
+ "description": "Requirements tracking CLI, test harness, and MCP server",
5
+ "type": "module",
6
+ "bin": {
7
+ "dotrequirements": "./dist/cli.js",
8
+ "dotreq": "./dist/cli.js"
9
+ },
10
+ "exports": {
11
+ ".": "./dist/cli.js",
12
+ "./test": "./dist/harness/index.js",
13
+ "./schema": "./dist/schema/index.js",
14
+ "./schema/browser": "./dist/schema/browser.js",
15
+ "./mcp": "./dist/mcp/index.js"
16
+ },
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc && cp -r src/templates/* dist/templates/",
22
+ "dev": "tsc --watch",
23
+ "pull": "node dist/cli.js pull",
24
+ "test": "vitest",
25
+ "test:run": "vitest run",
26
+ "test:coverage": "vitest run --coverage",
27
+ "prepublish:check": "git diff-index --quiet HEAD || (echo 'Error: Uncommitted changes detected. Commit or stash them first.' && exit 1)",
28
+ "publish:patch": "pnpm prepublish:check && npm version patch && pnpm build && npm publish && git push && git push --tags",
29
+ "publish:minor": "pnpm prepublish:check && npm version minor && pnpm build && npm publish && git push && git push --tags",
30
+ "publish:major": "pnpm prepublish:check && npm version major && pnpm build && npm publish && git push && git push --tags"
31
+ },
32
+ "keywords": [
33
+ "requirements",
34
+ "testing",
35
+ "test-coverage",
36
+ "bdd",
37
+ "tdd",
38
+ "mcp",
39
+ "ai-assistant"
40
+ ],
41
+ "author": "Will Raymer @Popover",
42
+ "license": "MIT",
43
+ "homepage": "https://dotrequirements.io",
44
+ "bugs": {
45
+ "email": "support@popover.ca"
46
+ },
47
+ "engines": {
48
+ "node": ">=18"
49
+ },
50
+ "dependencies": {
51
+ "@babel/parser": "^7.28.5",
52
+ "@babel/traverse": "^7.28.5",
53
+ "@babel/types": "^7.28.5",
54
+ "@modelcontextprotocol/sdk": "^1.0.0",
55
+ "@types/prompts": "^2.4.9",
56
+ "@workos-inc/node": "^7.77.0",
57
+ "chalk": "^5.6.2",
58
+ "commander": "^12.1.0",
59
+ "convex": "^1.29.3",
60
+ "find-up": "^8.0.0",
61
+ "glob": "^11.0.0",
62
+ "open": "^11.0.0",
63
+ "prompts": "^2.4.2",
64
+ "uuid": "^13.0.0",
65
+ "yaml": "^2.8.1",
66
+ "zod": "^3.25.76",
67
+ "zod-validation-error": "^5.0.0"
68
+ },
69
+ "devDependencies": {
70
+ "@types/babel__traverse": "^7.28.0",
71
+ "@types/node": "^20",
72
+ "@types/uuid": "^11.0.0",
73
+ "typescript": "^5",
74
+ "vitest": "^4.0.0"
75
+ },
76
+ "files": [
77
+ "dist",
78
+ "!dist/**/*.map",
79
+ "!dist/**/*.js.map",
80
+ "!dist/**/*.d.ts.map"
81
+ ]
82
+ }