@popoverai/dotrequirements 0.23.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +169 -22
  2. package/dist/cli.js +121 -60
  3. package/dist/codebase-to-spec/budget.d.ts +53 -0
  4. package/dist/codebase-to-spec/budget.js +80 -0
  5. package/dist/codebase-to-spec/cache.d.ts +49 -0
  6. package/dist/codebase-to-spec/cache.js +54 -0
  7. package/dist/codebase-to-spec/claude.d.ts +69 -0
  8. package/dist/codebase-to-spec/claude.js +126 -0
  9. package/dist/codebase-to-spec/compose.d.ts +49 -0
  10. package/dist/codebase-to-spec/compose.js +124 -0
  11. package/dist/codebase-to-spec/edit-loop.d.ts +54 -0
  12. package/dist/codebase-to-spec/edit-loop.js +195 -0
  13. package/dist/codebase-to-spec/editor.d.ts +54 -0
  14. package/dist/codebase-to-spec/editor.js +74 -0
  15. package/dist/codebase-to-spec/exit-codes.d.ts +40 -0
  16. package/dist/codebase-to-spec/exit-codes.js +58 -0
  17. package/dist/codebase-to-spec/fan-out.d.ts +63 -0
  18. package/dist/codebase-to-spec/fan-out.js +215 -0
  19. package/dist/codebase-to-spec/interactive.d.ts +30 -0
  20. package/dist/codebase-to-spec/interactive.js +48 -0
  21. package/dist/codebase-to-spec/outline-review-loop.d.ts +51 -0
  22. package/dist/codebase-to-spec/outline-review-loop.js +187 -0
  23. package/dist/codebase-to-spec/pack.d.ts +51 -0
  24. package/dist/codebase-to-spec/pack.js +127 -0
  25. package/dist/codebase-to-spec/planner.d.ts +41 -0
  26. package/dist/codebase-to-spec/planner.js +76 -0
  27. package/dist/codebase-to-spec/present.d.ts +94 -0
  28. package/dist/codebase-to-spec/present.js +288 -0
  29. package/dist/codebase-to-spec/progress.d.ts +33 -0
  30. package/dist/codebase-to-spec/progress.js +28 -0
  31. package/dist/codebase-to-spec/prompts/editor.d.ts +13 -0
  32. package/dist/codebase-to-spec/prompts/editor.js +57 -0
  33. package/dist/codebase-to-spec/prompts/outline-reviewer.d.ts +12 -0
  34. package/dist/codebase-to-spec/prompts/outline-reviewer.js +87 -0
  35. package/dist/codebase-to-spec/prompts/planner-initial.d.ts +11 -0
  36. package/dist/codebase-to-spec/prompts/planner-initial.js +125 -0
  37. package/dist/codebase-to-spec/prompts/planner-revise.d.ts +14 -0
  38. package/dist/codebase-to-spec/prompts/planner-revise.js +60 -0
  39. package/dist/codebase-to-spec/prompts/spec-reviewer.d.ts +16 -0
  40. package/dist/codebase-to-spec/prompts/spec-reviewer.js +96 -0
  41. package/dist/codebase-to-spec/prompts/specifier.d.ts +12 -0
  42. package/dist/codebase-to-spec/prompts/specifier.js +100 -0
  43. package/dist/codebase-to-spec/prompts/style-check.d.ts +12 -0
  44. package/dist/codebase-to-spec/prompts/style-check.js +78 -0
  45. package/dist/codebase-to-spec/schemas.d.ts +257 -0
  46. package/dist/codebase-to-spec/schemas.js +183 -0
  47. package/dist/codebase-to-spec/skill-install.d.ts +57 -0
  48. package/dist/codebase-to-spec/skill-install.js +79 -0
  49. package/dist/codebase-to-spec/slice.d.ts +49 -0
  50. package/dist/codebase-to-spec/slice.js +111 -0
  51. package/dist/codebase-to-spec/specifier.d.ts +60 -0
  52. package/dist/codebase-to-spec/specifier.js +79 -0
  53. package/dist/codebase-to-spec/style-check.d.ts +29 -0
  54. package/dist/codebase-to-spec/style-check.js +33 -0
  55. package/dist/codebase-to-spec/summary.d.ts +51 -0
  56. package/dist/codebase-to-spec/summary.js +183 -0
  57. package/dist/codebase-to-spec/validate.d.ts +46 -0
  58. package/dist/codebase-to-spec/validate.js +130 -0
  59. package/dist/commands/acceptance-test.d.ts +6 -0
  60. package/dist/commands/{browsertest.js → acceptance-test.js} +36 -29
  61. package/dist/commands/ai-setup.d.ts +5 -0
  62. package/dist/commands/ai-setup.js +441 -0
  63. package/dist/commands/codebase-to-spec/compose.d.ts +14 -0
  64. package/dist/commands/codebase-to-spec/compose.js +57 -0
  65. package/dist/commands/codebase-to-spec/edit-loop.d.ts +16 -0
  66. package/dist/commands/codebase-to-spec/edit-loop.js +83 -0
  67. package/dist/commands/codebase-to-spec/fan-out.d.ts +19 -0
  68. package/dist/commands/codebase-to-spec/fan-out.js +77 -0
  69. package/dist/commands/codebase-to-spec/index.d.ts +9 -0
  70. package/dist/commands/codebase-to-spec/index.js +135 -0
  71. package/dist/commands/codebase-to-spec/pack.d.ts +22 -0
  72. package/dist/commands/codebase-to-spec/pack.js +76 -0
  73. package/dist/commands/codebase-to-spec/plan-loop.d.ts +26 -0
  74. package/dist/commands/codebase-to-spec/plan-loop.js +105 -0
  75. package/dist/commands/codebase-to-spec/present.d.ts +21 -0
  76. package/dist/commands/codebase-to-spec/present.js +92 -0
  77. package/dist/commands/codebase-to-spec/run.d.ts +20 -0
  78. package/dist/commands/codebase-to-spec/run.js +85 -0
  79. package/dist/commands/codebase-to-spec/skill-install.d.ts +20 -0
  80. package/dist/commands/codebase-to-spec/skill-install.js +51 -0
  81. package/dist/commands/codebase-to-spec/specify-area.d.ts +18 -0
  82. package/dist/commands/codebase-to-spec/specify-area.js +82 -0
  83. package/dist/commands/codebase-to-spec/style-check.d.ts +15 -0
  84. package/dist/commands/codebase-to-spec/style-check.js +42 -0
  85. package/dist/commands/codebase-to-spec/validate.d.ts +18 -0
  86. package/dist/commands/codebase-to-spec/validate.js +38 -0
  87. package/dist/commands/create-requirement-document.d.ts +2 -0
  88. package/dist/commands/create-requirement-document.js +41 -0
  89. package/dist/commands/finalize.js +7 -7
  90. package/dist/commands/get.d.ts +2 -0
  91. package/dist/commands/get.js +55 -0
  92. package/dist/commands/init.js +132 -117
  93. package/dist/commands/link.js +27 -27
  94. package/dist/commands/list.d.ts +6 -0
  95. package/dist/commands/list.js +43 -0
  96. package/dist/commands/mcp.js +1 -1
  97. package/dist/commands/prepare.js +4 -4
  98. package/dist/commands/pull.js +116 -121
  99. package/dist/commands/push.js +106 -112
  100. package/dist/commands/report.d.ts +6 -2
  101. package/dist/commands/report.js +177 -122
  102. package/dist/commands/requirements-for.d.ts +2 -0
  103. package/dist/commands/requirements-for.js +29 -0
  104. package/dist/commands/review-test.d.ts +2 -0
  105. package/dist/commands/review-test.js +75 -0
  106. package/dist/commands/search.d.ts +6 -0
  107. package/dist/commands/search.js +39 -0
  108. package/dist/commands/style-check.d.ts +7 -0
  109. package/dist/commands/style-check.js +75 -0
  110. package/dist/commands/tests-for.d.ts +2 -0
  111. package/dist/commands/tests-for.js +80 -0
  112. package/dist/commands/validate.d.ts +6 -0
  113. package/dist/commands/validate.js +72 -0
  114. package/dist/config.js +1 -1
  115. package/dist/convex.d.ts +34 -22
  116. package/dist/convex.js +38 -22
  117. package/dist/harness/cache.d.ts +1 -5
  118. package/dist/harness/cache.js +49 -59
  119. package/dist/harness/convexReporting.d.ts +1 -1
  120. package/dist/harness/convexReporting.js +9 -7
  121. package/dist/harness/coverageCache.js +3 -3
  122. package/dist/harness/finalize.js +59 -46
  123. package/dist/harness/index.d.ts +6 -7
  124. package/dist/harness/index.js +9 -10
  125. package/dist/harness/prepare.js +6 -5
  126. package/dist/harness/requirementsLoader.d.ts +2 -2
  127. package/dist/harness/requirementsLoader.js +13 -35
  128. package/dist/harness/tracking.js +18 -18
  129. package/dist/harness/types.d.ts +1 -1
  130. package/dist/mcp/convexClient.d.ts +0 -39
  131. package/dist/mcp/convexClient.js +2 -107
  132. package/dist/mcp/handlers/authoring.d.ts +1 -1
  133. package/dist/mcp/handlers/authoring.js +30 -234
  134. package/dist/mcp/handlers/debug.d.ts +2 -3
  135. package/dist/mcp/handlers/debug.js +10 -10
  136. package/dist/mcp/handlers/get.d.ts +1 -1
  137. package/dist/mcp/handlers/get.js +11 -10
  138. package/dist/mcp/handlers/index.d.ts +20 -20
  139. package/dist/mcp/handlers/index.js +10 -10
  140. package/dist/mcp/handlers/list.d.ts +4 -33
  141. package/dist/mcp/handlers/list.js +16 -38
  142. package/dist/mcp/handlers/push.d.ts +1 -1
  143. package/dist/mcp/handlers/push.js +28 -18
  144. package/dist/mcp/handlers/report.d.ts +16 -0
  145. package/dist/mcp/handlers/report.js +134 -0
  146. package/dist/mcp/handlers/review.d.ts +1 -1
  147. package/dist/mcp/handlers/review.js +40 -59
  148. package/dist/mcp/handlers/search.d.ts +1 -1
  149. package/dist/mcp/handlers/search.js +7 -9
  150. package/dist/mcp/handlers/test-mapping.d.ts +1 -1
  151. package/dist/mcp/handlers/test-mapping.js +14 -14
  152. package/dist/mcp/handlers/types.d.ts +3 -3
  153. package/dist/mcp/handlers/types.js +2 -2
  154. package/dist/mcp/index.d.ts +1 -1
  155. package/dist/mcp/index.js +147 -167
  156. package/dist/push/core.d.ts +2 -2
  157. package/dist/push/core.js +20 -20
  158. package/dist/push/index.d.ts +1 -1
  159. package/dist/push/index.js +2 -2
  160. package/dist/requirements/cloud-ai.d.ts +57 -0
  161. package/dist/requirements/cloud-ai.js +104 -0
  162. package/dist/requirements/cloud-coverage.d.ts +41 -0
  163. package/dist/requirements/cloud-coverage.js +60 -0
  164. package/dist/requirements/coverage.d.ts +45 -0
  165. package/dist/requirements/coverage.js +114 -0
  166. package/dist/{mcp → requirements}/grep.d.ts +10 -1
  167. package/dist/{mcp → requirements}/grep.js +89 -44
  168. package/dist/{mcp/requirements.d.ts → requirements/index.d.ts} +19 -3
  169. package/dist/{mcp/requirements.js → requirements/index.js} +54 -35
  170. package/dist/requirements/style-guide.d.ts +67 -0
  171. package/dist/requirements/style-guide.js +299 -0
  172. package/dist/{mcp → requirements}/testCodeExtractor.js +24 -26
  173. package/dist/schema/browser.d.ts +8 -8
  174. package/dist/schema/browser.js +13 -15
  175. package/dist/schema/builder.d.ts +1 -1
  176. package/dist/schema/builder.js +13 -44
  177. package/dist/schema/conversions.d.ts +2 -2
  178. package/dist/schema/conversions.js +11 -11
  179. package/dist/schema/index.d.ts +9 -9
  180. package/dist/schema/index.js +15 -15
  181. package/dist/schema/parser-core.d.ts +1 -1
  182. package/dist/schema/parser-core.js +23 -22
  183. package/dist/schema/parser.d.ts +3 -3
  184. package/dist/schema/parser.js +27 -31
  185. package/dist/schema/resolver.d.ts +1 -1
  186. package/dist/schema/resolver.js +9 -9
  187. package/dist/schema/scenario.d.ts +1 -1
  188. package/dist/schema/scenario.js +1 -1
  189. package/dist/schema/schemas.d.ts +3 -3
  190. package/dist/schema/schemas.js +41 -28
  191. package/dist/schema/test-schema.js +27 -27
  192. package/dist/templates/context-file-section.md +3 -2
  193. package/dist/templates/example-requirements.js +1 -1
  194. package/dist/templates/example-requirements.ts +3 -1
  195. package/dist/templates/requirements-readme.js +1 -1
  196. package/dist/templates/requirements-readme.ts +1 -1
  197. package/dist/templates/skills/codebase-to-spec/SKILL.md +118 -0
  198. package/dist/utils/brand.js +3 -3
  199. package/dist/utils/browser-launch.js +4 -4
  200. package/dist/utils/context-file.d.ts +1 -1
  201. package/dist/utils/context-file.js +26 -26
  202. package/dist/utils/env.js +7 -7
  203. package/dist/utils/gitignore.js +7 -7
  204. package/dist/utils/oauth-callback-server.d.ts +1 -1
  205. package/dist/utils/oauth-callback-server.js +27 -25
  206. package/dist/utils/oauth-flow.js +32 -29
  207. package/dist/utils/project-discovery.d.ts +3 -3
  208. package/dist/utils/project-discovery.js +18 -17
  209. package/dist/utils/project-name.js +8 -8
  210. package/dist/utils/project-selector.d.ts +1 -1
  211. package/dist/utils/project-selector.js +24 -21
  212. package/dist/utils/project-settings.d.ts +1 -1
  213. package/dist/utils/project-settings.js +24 -22
  214. package/dist/utils/templates.js +6 -6
  215. package/package.json +3 -2
  216. package/dist/commands/browsertest.d.ts +0 -6
  217. package/dist/commands/login.d.ts +0 -12
  218. package/dist/commands/login.js +0 -117
  219. package/dist/commands/logout.d.ts +0 -5
  220. package/dist/commands/logout.js +0 -17
  221. package/dist/commands/mcp-setup.d.ts +0 -5
  222. package/dist/commands/mcp-setup.js +0 -431
  223. package/dist/commands/test.d.ts +0 -6
  224. package/dist/commands/test.js +0 -78
  225. package/dist/mcp/handlers/coverage.d.ts +0 -44
  226. package/dist/mcp/handlers/coverage.js +0 -105
  227. package/dist/mcp/types.d.ts +0 -27
  228. package/dist/mcp/types.js +0 -2
  229. package/dist/utils/local-project.d.ts +0 -31
  230. package/dist/utils/local-project.js +0 -33
  231. package/dist/utils/token-refresh.d.ts +0 -24
  232. package/dist/utils/token-refresh.js +0 -69
  233. package/dist/utils/token-storage.d.ts +0 -31
  234. package/dist/utils/token-storage.js +0 -57
  235. /package/dist/{mcp → requirements}/testCodeExtractor.d.ts +0 -0
@@ -1,7 +1,7 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- const REQUIREMENTS_DIR = '.requirements';
4
- const SETTINGS_FILE = 'project-settings.json';
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ const REQUIREMENTS_DIR = ".requirements";
4
+ const SETTINGS_FILE = "project-settings.json";
5
5
  /**
6
6
  * Get project credentials from environment variables.
7
7
  * Used in CI/CD environments where credentials are passed via env vars
@@ -27,14 +27,16 @@ export function findProjectRoot(startDir = process.cwd()) {
27
27
  const root = path.parse(currentDir).root;
28
28
  while (currentDir !== root) {
29
29
  const requirementsDir = path.join(currentDir, REQUIREMENTS_DIR);
30
- if (fs.existsSync(requirementsDir) && fs.statSync(requirementsDir).isDirectory()) {
30
+ if (fs.existsSync(requirementsDir) &&
31
+ fs.statSync(requirementsDir).isDirectory()) {
31
32
  return currentDir;
32
33
  }
33
34
  currentDir = path.dirname(currentDir);
34
35
  }
35
36
  // Check root directory as well
36
37
  const rootRequirementsDir = path.join(root, REQUIREMENTS_DIR);
37
- if (fs.existsSync(rootRequirementsDir) && fs.statSync(rootRequirementsDir).isDirectory()) {
38
+ if (fs.existsSync(rootRequirementsDir) &&
39
+ fs.statSync(rootRequirementsDir).isDirectory()) {
38
40
  return root;
39
41
  }
40
42
  return undefined;
@@ -50,7 +52,7 @@ export function readProjectSettings(projectRoot) {
50
52
  }
51
53
  let content;
52
54
  try {
53
- content = fs.readFileSync(settingsPath, 'utf-8');
55
+ content = fs.readFileSync(settingsPath, "utf-8");
54
56
  }
55
57
  catch (err) {
56
58
  throw new Error(`Could not read project-settings.json: ${err.message}`);
@@ -62,11 +64,11 @@ export function readProjectSettings(projectRoot) {
62
64
  catch (err) {
63
65
  throw new Error(`project-settings.json is invalid: ${err.message}`);
64
66
  }
65
- if (typeof parsed !== 'object' ||
67
+ if (typeof parsed !== "object" ||
66
68
  parsed === null ||
67
- typeof parsed.projectId !== 'string' ||
68
- typeof parsed.projectSecret !== 'string') {
69
- throw new Error('project-settings.json is invalid: missing projectId or projectSecret');
69
+ typeof parsed.projectId !== "string" ||
70
+ typeof parsed.projectSecret !== "string") {
71
+ throw new Error("project-settings.json is invalid: missing projectId or projectSecret");
70
72
  }
71
73
  const record = parsed;
72
74
  const settings = {
@@ -74,28 +76,28 @@ export function readProjectSettings(projectRoot) {
74
76
  projectSecret: record.projectSecret,
75
77
  };
76
78
  // Optional fields
77
- if (typeof record.defaultURL === 'string') {
79
+ if (typeof record.defaultURL === "string") {
78
80
  settings.defaultURL = record.defaultURL;
79
81
  }
80
- if (typeof record.browserTest === 'object' && record.browserTest !== null) {
82
+ if (typeof record.browserTest === "object" && record.browserTest !== null) {
81
83
  const bt = record.browserTest;
82
84
  settings.browserTest = {};
83
- if (typeof bt.modelName === 'string') {
85
+ if (typeof bt.modelName === "string") {
84
86
  settings.browserTest.modelName = bt.modelName;
85
87
  }
86
- if (typeof bt.modelApiKey === 'string') {
88
+ if (typeof bt.modelApiKey === "string") {
87
89
  settings.browserTest.modelApiKey = bt.modelApiKey;
88
90
  }
89
- if (typeof bt.geminiApiKey === 'string') {
91
+ if (typeof bt.geminiApiKey === "string") {
90
92
  settings.browserTest.geminiApiKey = bt.geminiApiKey;
91
93
  }
92
- if (typeof bt.vercelBypassSecret === 'string') {
94
+ if (typeof bt.vercelBypassSecret === "string") {
93
95
  settings.browserTest.vercelBypassSecret = bt.vercelBypassSecret;
94
96
  }
95
- if (typeof bt.browserbaseApiKey === 'string') {
97
+ if (typeof bt.browserbaseApiKey === "string") {
96
98
  settings.browserTest.browserbaseApiKey = bt.browserbaseApiKey;
97
99
  }
98
- if (typeof bt.browserbaseProjectId === 'string') {
100
+ if (typeof bt.browserbaseProjectId === "string") {
99
101
  settings.browserTest.browserbaseProjectId = bt.browserbaseProjectId;
100
102
  }
101
103
  }
@@ -112,8 +114,8 @@ export function writeProjectSettings(projectRoot, settings) {
112
114
  if (!fs.existsSync(requirementsDir)) {
113
115
  fs.mkdirSync(requirementsDir, { recursive: true });
114
116
  }
115
- const content = JSON.stringify(settings, null, 2) + '\n';
116
- fs.writeFileSync(settingsPath, content, 'utf-8');
117
+ const content = `${JSON.stringify(settings, null, 2)}\n`;
118
+ fs.writeFileSync(settingsPath, content, "utf-8");
117
119
  }
118
120
  /**
119
121
  * Get project info including status and credentials
@@ -134,7 +136,7 @@ export function getProjectInfo(startDir = process.cwd()) {
134
136
  }
135
137
  return {
136
138
  rootPath,
137
- status: credentials ? 'cloud-connected' : 'local-only',
139
+ status: credentials ? "cloud-connected" : "local-only",
138
140
  credentials,
139
141
  };
140
142
  }
@@ -1,6 +1,6 @@
1
- import { readFileSync } from 'fs';
2
- import { join, dirname } from 'path';
3
- import { fileURLToPath } from 'url';
1
+ import { readFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
4
  /**
5
5
  * Get the templates directory path
6
6
  */
@@ -10,7 +10,7 @@ function getTemplatesDir() {
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = dirname(__filename);
12
12
  // Go up from utils/ to src/ or dist/, then into templates/
13
- return join(__dirname, '..', 'templates');
13
+ return join(__dirname, "..", "templates");
14
14
  }
15
15
  /**
16
16
  * Load a template file and replace placeholders
@@ -18,10 +18,10 @@ function getTemplatesDir() {
18
18
  export function loadTemplate(templateName, replacements = {}) {
19
19
  const templatesDir = getTemplatesDir();
20
20
  const templatePath = join(templatesDir, templateName);
21
- let content = readFileSync(templatePath, 'utf-8');
21
+ let content = readFileSync(templatePath, "utf-8");
22
22
  // Replace placeholders
23
23
  for (const [key, value] of Object.entries(replacements)) {
24
- content = content.replace(new RegExp(`{{${key}}}`, 'g'), value);
24
+ content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
25
25
  }
26
26
  return content;
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popoverai/dotrequirements",
3
- "version": "0.23.0",
3
+ "version": "0.24.1",
4
4
  "description": "Requirements tracking CLI, test harness, and MCP server",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  "license": "MIT",
43
43
  "homepage": "https://dotrequirements.io",
44
44
  "bugs": {
45
- "email": "support@popover.ca"
45
+ "email": "support@dotrequirements.io"
46
46
  },
47
47
  "engines": {
48
48
  "node": ">=18"
@@ -61,6 +61,7 @@
61
61
  "glob": "^11.0.0",
62
62
  "open": "^11.0.0",
63
63
  "prompts": "^2.4.2",
64
+ "repomix": "^1.14.0",
64
65
  "uuid": "^13.0.0",
65
66
  "yaml": "^2.8.1",
66
67
  "zod": "^3.25.76",
@@ -1,6 +0,0 @@
1
- interface BrowserTestOptions {
2
- json?: boolean;
3
- }
4
- export declare function browserTestCommand(requirementKey: string, url: string | undefined, options: BrowserTestOptions): Promise<void>;
5
- export {};
6
- //# sourceMappingURL=browsertest.d.ts.map
@@ -1,12 +0,0 @@
1
- /**
2
- * Login command - authenticate with WorkOS and manage project credentials.
3
- *
4
- * Implements:
5
- * - LOGIN-1: CLI OAuth implementation
6
- * - LOGIN-2: Upgrade from placeholder to real credentials
7
- * - LOGIN-3: Refresh existing project credentials
8
- * - LOGIN-4: Already logged in detection
9
- * - LOGIN-6: Handle missing .env.local
10
- */
11
- export declare function loginCommand(): Promise<void>;
12
- //# sourceMappingURL=login.d.ts.map
@@ -1,117 +0,0 @@
1
- /**
2
- * Login command - authenticate with WorkOS and manage project credentials.
3
- *
4
- * Implements:
5
- * - LOGIN-1: CLI OAuth implementation
6
- * - LOGIN-2: Upgrade from placeholder to real credentials
7
- * - LOGIN-3: Refresh existing project credentials
8
- * - LOGIN-4: Already logged in detection
9
- * - LOGIN-6: Handle missing .env.local
10
- */
11
- import { executeOAuthFlow } from '../utils/oauth-flow.js';
12
- import { getConvexUrl } from '../config.js';
13
- import { hasValidTokens } from '../utils/token-storage.js';
14
- import { isLocalOnlyProject } from '../utils/local-project.js';
15
- import * as fs from 'fs';
16
- import { ConvexHttpClient } from 'convex/browser';
17
- import { findUp } from 'find-up';
18
- import { brand } from '../utils/brand.js';
19
- export async function loginCommand() {
20
- console.log(`Logging in to ${brand}...\n`);
21
- // LOGIN-4: Check if already logged in
22
- if (await hasValidTokens()) {
23
- console.log('✓ Already logged in');
24
- console.log('Run "dotrequirements logout" to log in as a different user.');
25
- return;
26
- }
27
- // LOGIN-1: Execute OAuth flow
28
- const result = await executeOAuthFlow();
29
- console.log('\n✓ Logged in successfully!');
30
- // LOGIN-6: Check if there's a .env.local in the current directory
31
- const envPath = await findUp('.env.local');
32
- if (envPath) {
33
- await handleExistingProject(envPath, result.accessToken);
34
- }
35
- else {
36
- // LOGIN-6.1: No project in current directory
37
- console.log('\nNo project found in this directory.');
38
- console.log('Run "dotrequirements init" to create a new project in the current directory.');
39
- }
40
- }
41
- /**
42
- * Handle existing project based on credential type (placeholder vs real)
43
- */
44
- async function handleExistingProject(envPath, accessToken) {
45
- try {
46
- // Read .env.local to get project ID and secret
47
- const envContent = fs.readFileSync(envPath, 'utf-8');
48
- const projectIdMatch = envContent.match(/DOTREQUIREMENTS_PROJECT_ID=(.+)/);
49
- const secretMatch = envContent.match(/DOTREQUIREMENTS_PROJECT_SECRET=(.+)/);
50
- if (!projectIdMatch || !secretMatch) {
51
- console.log('\n.env.local found but missing project credentials.');
52
- return;
53
- }
54
- const projectId = projectIdMatch[1].trim();
55
- const projectSecret = secretMatch[1].trim();
56
- const convexUrl = getConvexUrl();
57
- const client = new ConvexHttpClient(convexUrl);
58
- client.setAuth(accessToken);
59
- // LOGIN-2: Check if placeholder credentials
60
- if (isLocalOnlyProject(projectId)) {
61
- await upgradeFromPlaceholder(envPath, envContent, client);
62
- }
63
- else {
64
- // LOGIN-3: Refresh existing project credentials
65
- await refreshCredentials(envPath, envContent, projectId, client);
66
- }
67
- }
68
- catch (error) {
69
- console.error('\nFailed to update project credentials:');
70
- console.error(error instanceof Error ? error.message : String(error));
71
- console.log('\nYour authentication was successful.');
72
- console.log('You can continue using the project with its existing credentials.');
73
- }
74
- }
75
- /**
76
- * LOGIN-2: Upgrade from placeholder credentials to real project
77
- */
78
- async function upgradeFromPlaceholder(envPath, envContent, client) {
79
- console.log('\nUpgrading from local-only mode to cloud access...');
80
- // LOGIN-2.0, LOGIN-2.1: Create team and project
81
- const result = await client.mutation('lib/authMutations:createProjectForAuthenticatedUser', {});
82
- if (!result.success) {
83
- throw new Error(result.error || 'Unknown error');
84
- }
85
- console.log('✓ Created new project in your team');
86
- // LOGIN-2.3: Update .env.local with real credentials
87
- const updatedEnv = envContent
88
- .replace(/DOTREQUIREMENTS_PROJECT_ID=.+/, `DOTREQUIREMENTS_PROJECT_ID=${result.projectId}`)
89
- .replace(/DOTREQUIREMENTS_PROJECT_SECRET=.+/, `DOTREQUIREMENTS_PROJECT_SECRET=${result.projectSecret}`);
90
- fs.writeFileSync(envPath, updatedEnv);
91
- console.log('✓ Updated .env.local with cloud credentials');
92
- // LOGIN-2.4: Display next steps
93
- console.log('\nYour project is now connected to the cloud!');
94
- console.log('Run "dotrequirements push" to sync your requirements.');
95
- }
96
- /**
97
- * LOGIN-3: Refresh existing project credentials
98
- */
99
- async function refreshCredentials(envPath, envContent, projectId, client) {
100
- console.log('\nRefreshing your project credentials...');
101
- // LOGIN-3.0: Verify access and generate new secret
102
- const result = await client.mutation('lib/authMutations:refreshProjectSecret', {
103
- projectId: projectId, // Cast to Id<"projects">
104
- });
105
- if (!result.success) {
106
- // LOGIN-3.4: User doesn't have access
107
- throw new Error(result.error || 'Unknown error');
108
- }
109
- // LOGIN-3.2: Update .env.local with new secret
110
- const updatedEnv = envContent.replace(/DOTREQUIREMENTS_PROJECT_SECRET=.+/, `DOTREQUIREMENTS_PROJECT_SECRET=${result.projectSecret}`);
111
- fs.writeFileSync(envPath, updatedEnv);
112
- // LOGIN-3.3: Confirm access extended
113
- const expiryDate = new Date(result.expiresAt).toLocaleDateString();
114
- console.log(`✓ Access extended until ${expiryDate}`);
115
- console.log('✓ Updated .env.local with new credentials');
116
- }
117
- //# sourceMappingURL=login.js.map
@@ -1,5 +0,0 @@
1
- /**
2
- * Logout command - clear stored authentication tokens.
3
- */
4
- export declare function logoutCommand(): Promise<void>;
5
- //# sourceMappingURL=logout.d.ts.map
@@ -1,17 +0,0 @@
1
- /**
2
- * Logout command - clear stored authentication tokens.
3
- */
4
- import { deleteTokens, hasValidTokens } from '../utils/token-storage.js';
5
- export async function logoutCommand() {
6
- const wasLoggedIn = await hasValidTokens();
7
- await deleteTokens();
8
- if (wasLoggedIn) {
9
- console.log('Logged out successfully.');
10
- }
11
- else {
12
- console.log('No active session found.');
13
- }
14
- console.log('\nYour project credentials in .env.local are unchanged.');
15
- console.log('Run "dotrequirements login" to authenticate again.');
16
- }
17
- //# sourceMappingURL=logout.js.map
@@ -1,5 +0,0 @@
1
- /**
2
- * MCP setup command - configures the MCP server for AI assistants
3
- */
4
- export declare function mcpSetupCommand(): Promise<void>;
5
- //# sourceMappingURL=mcp-setup.d.ts.map