@popoverai/dotrequirements 0.24.0 → 0.24.2
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 +4 -3
- package/dist/cli.js +0 -0
- package/dist/codebase-to-spec/claude.d.ts +1 -0
- package/dist/codebase-to-spec/claude.js +9 -0
- package/dist/codebase-to-spec/pack.d.ts +16 -0
- package/dist/codebase-to-spec/pack.js +17 -3
- package/dist/codebase-to-spec/present.d.ts +8 -1
- package/dist/codebase-to-spec/present.js +7 -4
- package/dist/codebase-to-spec/progress.d.ts +6 -0
- package/dist/codebase-to-spec/progress.js +34 -0
- package/dist/codebase-to-spec/prompts/outline-reviewer.d.ts +1 -1
- package/dist/codebase-to-spec/prompts/outline-reviewer.js +3 -1
- package/dist/codebase-to-spec/prompts/planner-initial.d.ts +1 -1
- package/dist/codebase-to-spec/prompts/planner-initial.js +4 -0
- package/dist/codebase-to-spec/prompts/planner-revise.d.ts +1 -1
- package/dist/codebase-to-spec/prompts/planner-revise.js +2 -2
- package/dist/codebase-to-spec/prompts/spec-reviewer.d.ts +1 -1
- package/dist/codebase-to-spec/prompts/spec-reviewer.js +6 -1
- package/dist/codebase-to-spec/prompts/specifier.d.ts +1 -1
- package/dist/codebase-to-spec/prompts/specifier.js +6 -4
- package/dist/codebase-to-spec/prompts/style-check.d.ts +10 -2
- package/dist/codebase-to-spec/prompts/style-check.js +76 -46
- package/dist/codebase-to-spec/schemas.d.ts +85 -1
- package/dist/codebase-to-spec/schemas.js +25 -1
- package/dist/codebase-to-spec/specifier.js +6 -0
- package/dist/commands/codebase-to-spec/index.js +13 -0
- package/dist/commands/codebase-to-spec/pack.d.ts +6 -0
- package/dist/commands/codebase-to-spec/pack.js +1 -0
- package/dist/commands/codebase-to-spec/present.d.ts +5 -0
- package/dist/commands/codebase-to-spec/present.js +6 -1
- package/dist/commands/codebase-to-spec/run.js +1 -0
- package/package.json +5 -6
- package/dist/codebase-to-spec/prompts/planner-apply.d.ts +0 -12
- package/dist/codebase-to-spec/prompts/planner-apply.js +0 -32
- package/dist/commands/browsertest.d.ts +0 -6
- package/dist/commands/browsertest.js +0 -212
- package/dist/commands/login.d.ts +0 -12
- package/dist/commands/login.js +0 -117
- package/dist/commands/logout.d.ts +0 -5
- package/dist/commands/logout.js +0 -17
- package/dist/commands/mcp-setup.d.ts +0 -5
- package/dist/commands/mcp-setup.js +0 -441
- package/dist/commands/test.d.ts +0 -6
- package/dist/commands/test.js +0 -72
- package/dist/mcp/grep.d.ts +0 -24
- package/dist/mcp/grep.js +0 -306
- package/dist/mcp/handlers/coverage.d.ts +0 -44
- package/dist/mcp/handlers/coverage.js +0 -103
- package/dist/mcp/requirements.d.ts +0 -57
- package/dist/mcp/requirements.js +0 -155
- package/dist/mcp/testCodeExtractor.d.ts +0 -22
- package/dist/mcp/testCodeExtractor.js +0 -150
- package/dist/mcp/types.d.ts +0 -27
- package/dist/mcp/types.js +0 -2
- package/dist/utils/local-project.d.ts +0 -31
- package/dist/utils/local-project.js +0 -33
- package/dist/utils/token-refresh.d.ts +0 -24
- package/dist/utils/token-refresh.js +0 -69
- package/dist/utils/token-storage.d.ts +0 -31
- package/dist/utils/token-storage.js +0 -57
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
|
-
import { promisify } from "node:util";
|
|
3
|
-
import { formatRequirement, getRequirementTree, loadAllRequirements, } from "../mcp/requirements.js";
|
|
4
|
-
import { getProjectInfo, readProjectSettings, } from "../utils/project-settings.js";
|
|
5
|
-
const execFileAsync = promisify(execFile);
|
|
6
|
-
function extractResults(parsed) {
|
|
7
|
-
if (Array.isArray(parsed))
|
|
8
|
-
return parsed;
|
|
9
|
-
if (parsed && typeof parsed === "object") {
|
|
10
|
-
const obj = parsed;
|
|
11
|
-
// { results: [...] } format
|
|
12
|
-
if (Array.isArray(obj.results))
|
|
13
|
-
return obj.results;
|
|
14
|
-
// { structured_output: { results: [...] } } format
|
|
15
|
-
if (obj.structured_output && typeof obj.structured_output === "object") {
|
|
16
|
-
const so = obj.structured_output;
|
|
17
|
-
if (Array.isArray(so.results))
|
|
18
|
-
return so.results;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
throw new Error("Unexpected browser-automation output format");
|
|
22
|
-
}
|
|
23
|
-
export async function browserTestCommand(requirementKey, url, options) {
|
|
24
|
-
// 1. Find project and load settings
|
|
25
|
-
const projectInfo = getProjectInfo();
|
|
26
|
-
if (!projectInfo) {
|
|
27
|
-
console.error("Error: No dotrequirements project found.");
|
|
28
|
-
console.log('Run "dotrequirements init" to create one.');
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
let settings;
|
|
32
|
-
try {
|
|
33
|
-
settings = readProjectSettings(projectInfo.rootPath);
|
|
34
|
-
}
|
|
35
|
-
catch (err) {
|
|
36
|
-
// Settings file exists but is invalid
|
|
37
|
-
console.error(`Error: ${err.message}`);
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
// 2. Determine URL
|
|
41
|
-
const targetURL = url || settings?.defaultURL;
|
|
42
|
-
if (!targetURL) {
|
|
43
|
-
console.error("Error: No URL provided and no defaultURL in project-settings.json.");
|
|
44
|
-
console.log('Either provide a URL argument or add "defaultURL" to .requirements/project-settings.json');
|
|
45
|
-
process.exit(1);
|
|
46
|
-
}
|
|
47
|
-
// 3. Resolve model config
|
|
48
|
-
const modelName = settings?.browserTest?.modelName;
|
|
49
|
-
const modelApiKey = settings?.browserTest?.modelApiKey;
|
|
50
|
-
const geminiApiKey = settings?.browserTest?.geminiApiKey;
|
|
51
|
-
if (!modelName && !modelApiKey && !geminiApiKey) {
|
|
52
|
-
console.error("Error: no browser-test model configured in project-settings.json.");
|
|
53
|
-
console.log("Add a block like:\n" +
|
|
54
|
-
' "browserTest": {\n' +
|
|
55
|
-
' "modelName": "gateway/anthropic/claude-haiku-4-5",\n' +
|
|
56
|
-
' "modelApiKey": "..."\n' +
|
|
57
|
-
" }\n" +
|
|
58
|
-
"to .requirements/project-settings.json. See the docs for supported models.");
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
if ((modelName && !modelApiKey) || (modelApiKey && !modelName)) {
|
|
62
|
-
console.error("Error: browserTest.modelName and browserTest.modelApiKey must be set together.");
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
// 4. Load requirements
|
|
66
|
-
const { flattened } = await loadAllRequirements(projectInfo.rootPath);
|
|
67
|
-
if (flattened.length === 0) {
|
|
68
|
-
console.error("Error: No requirements found in .requirements/");
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
71
|
-
// 5. Find the requirement tree
|
|
72
|
-
const requirementTree = getRequirementTree(flattened, requirementKey);
|
|
73
|
-
if (requirementTree.length === 0) {
|
|
74
|
-
console.error(`Error: Requirement "${requirementKey}" not found.`);
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
// 6. Format each requirement as an assertion
|
|
78
|
-
const assertions = requirementTree.map((req) => formatRequirement(req));
|
|
79
|
-
// 7. Build environment with injected secrets
|
|
80
|
-
const env = { ...process.env };
|
|
81
|
-
// env var keeps the key out of process listings (not a CLI flag)
|
|
82
|
-
if (modelApiKey) {
|
|
83
|
-
env.MODEL_API_KEY = modelApiKey;
|
|
84
|
-
}
|
|
85
|
-
else if (geminiApiKey) {
|
|
86
|
-
env.GEMINI_API_KEY = geminiApiKey;
|
|
87
|
-
}
|
|
88
|
-
if (settings?.browserTest?.vercelBypassSecret) {
|
|
89
|
-
env.VERCEL_AUTOMATION_BYPASS_SECRET =
|
|
90
|
-
settings.browserTest.vercelBypassSecret;
|
|
91
|
-
}
|
|
92
|
-
if (settings?.browserTest?.browserbaseApiKey) {
|
|
93
|
-
env.BROWSERBASE_API_KEY = settings.browserTest.browserbaseApiKey;
|
|
94
|
-
}
|
|
95
|
-
if (settings?.browserTest?.browserbaseProjectId) {
|
|
96
|
-
env.BROWSERBASE_PROJECT_ID = settings.browserTest.browserbaseProjectId;
|
|
97
|
-
}
|
|
98
|
-
// 8. Run browser-automation
|
|
99
|
-
if (!options.json) {
|
|
100
|
-
console.log(`Testing ${requirementKey} against ${targetURL}...\n`);
|
|
101
|
-
}
|
|
102
|
-
try {
|
|
103
|
-
const modelFlags = modelName ? ["--modelName", modelName] : [];
|
|
104
|
-
const { stdout } = await execFileAsync("npx", [
|
|
105
|
-
"@popoverai/browser-automation",
|
|
106
|
-
"test",
|
|
107
|
-
...modelFlags,
|
|
108
|
-
targetURL,
|
|
109
|
-
...assertions,
|
|
110
|
-
], { env, maxBuffer: 10 * 1024 * 1024 });
|
|
111
|
-
// 9. Parse results
|
|
112
|
-
let results;
|
|
113
|
-
try {
|
|
114
|
-
const parsed = JSON.parse(stdout.trim());
|
|
115
|
-
results = extractResults(parsed);
|
|
116
|
-
}
|
|
117
|
-
catch (parseErr) {
|
|
118
|
-
console.error("Error: Could not parse browser-automation output");
|
|
119
|
-
console.error(parseErr.message);
|
|
120
|
-
console.error(stdout);
|
|
121
|
-
process.exit(1);
|
|
122
|
-
}
|
|
123
|
-
// 10. Display results
|
|
124
|
-
if (options.json) {
|
|
125
|
-
outputJson(requirementTree, results);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
displayResults(requirementTree, results);
|
|
129
|
-
}
|
|
130
|
-
// 11. Exit with appropriate code
|
|
131
|
-
const failedCount = results.filter((r) => r.status !== "passed").length;
|
|
132
|
-
if (failedCount > 0) {
|
|
133
|
-
process.exit(1);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
catch (err) {
|
|
137
|
-
const error = err;
|
|
138
|
-
// browser-automation returns exit code 1 on failure, but still outputs JSON
|
|
139
|
-
if (error.stdout) {
|
|
140
|
-
try {
|
|
141
|
-
const parsed = JSON.parse(error.stdout.trim());
|
|
142
|
-
const results = extractResults(parsed);
|
|
143
|
-
if (options.json) {
|
|
144
|
-
outputJson(requirementTree, results);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
displayResults(requirementTree, results);
|
|
148
|
-
}
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
// Not JSON, show raw output
|
|
153
|
-
console.error("browser-automation error:");
|
|
154
|
-
if (error.stdout)
|
|
155
|
-
console.error(error.stdout);
|
|
156
|
-
if (error.stderr)
|
|
157
|
-
console.error(error.stderr);
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
console.error(`Error running browser-automation: ${error.message}`);
|
|
163
|
-
if (error.stderr)
|
|
164
|
-
console.error(error.stderr);
|
|
165
|
-
process.exit(1);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
function displayResults(requirements, results) {
|
|
170
|
-
let passedCount = 0;
|
|
171
|
-
let failedCount = 0;
|
|
172
|
-
for (let i = 0; i < requirements.length; i++) {
|
|
173
|
-
const req = requirements[i];
|
|
174
|
-
const result = results[i];
|
|
175
|
-
if (!result) {
|
|
176
|
-
console.log(` ? ${req.id}: No result`);
|
|
177
|
-
failedCount++;
|
|
178
|
-
continue;
|
|
179
|
-
}
|
|
180
|
-
const indent = " ".repeat(req.path.length);
|
|
181
|
-
const label = req.label ? ` (${req.label})` : "";
|
|
182
|
-
const icon = result.status === "passed" ? "\u2713" : "\u2717";
|
|
183
|
-
console.log(`${indent}${icon} ${req.id}${label}: ${req.content}`);
|
|
184
|
-
if (result.status !== "passed" && result.notes) {
|
|
185
|
-
console.log(`${indent} \u2192 ${result.notes}`);
|
|
186
|
-
}
|
|
187
|
-
if (result.status === "passed") {
|
|
188
|
-
passedCount++;
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
failedCount++;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
console.log();
|
|
195
|
-
if (failedCount === 0) {
|
|
196
|
-
console.log(`${passedCount}/${requirements.length} passed`);
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
console.log(`${passedCount}/${requirements.length} passed, ${failedCount} failed`);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function outputJson(requirements, results) {
|
|
203
|
-
const combined = requirements.map((req, i) => ({
|
|
204
|
-
id: req.id,
|
|
205
|
-
label: req.label || null,
|
|
206
|
-
content: req.content,
|
|
207
|
-
status: results[i]?.status || "blocked",
|
|
208
|
-
notes: results[i]?.notes || null,
|
|
209
|
-
}));
|
|
210
|
-
console.log(JSON.stringify(combined, null, 2));
|
|
211
|
-
}
|
|
212
|
-
//# sourceMappingURL=browsertest.js.map
|
package/dist/commands/login.d.ts
DELETED
|
@@ -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
|
package/dist/commands/login.js
DELETED
|
@@ -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
|
package/dist/commands/logout.js
DELETED
|
@@ -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
|