vibecodingmachine-core 1.0.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/.babelrc +13 -0
- package/README.md +28 -0
- package/__tests__/applescript-manager-claude-fix.test.js +286 -0
- package/__tests__/requirement-2-auto-start-looping.test.js +69 -0
- package/__tests__/requirement-3-auto-start-looping.test.js +69 -0
- package/__tests__/requirement-4-auto-start-looping.test.js +69 -0
- package/__tests__/requirement-6-auto-start-looping.test.js +73 -0
- package/__tests__/requirement-7-status-tracking.test.js +332 -0
- package/jest.config.js +18 -0
- package/jest.setup.js +12 -0
- package/package.json +46 -0
- package/src/auth/access-denied.html +119 -0
- package/src/auth/shared-auth-storage.js +230 -0
- package/src/autonomous-mode/feature-implementer.cjs +70 -0
- package/src/autonomous-mode/feature-implementer.js +425 -0
- package/src/chat-management/chat-manager.cjs +71 -0
- package/src/chat-management/chat-manager.js +342 -0
- package/src/ide-integration/__tests__/applescript-manager-thread-closure.test.js +227 -0
- package/src/ide-integration/aider-cli-manager.cjs +850 -0
- package/src/ide-integration/applescript-diagnostics.js +0 -0
- package/src/ide-integration/applescript-manager.cjs +1088 -0
- package/src/ide-integration/applescript-manager.js +2803 -0
- package/src/ide-integration/applescript-open-apps.js +0 -0
- package/src/ide-integration/applescript-read-response.js +0 -0
- package/src/ide-integration/applescript-send-text.js +0 -0
- package/src/ide-integration/applescript-thread-closure.js +0 -0
- package/src/ide-integration/applescript-utils.js +306 -0
- package/src/ide-integration/cdp-manager.cjs +221 -0
- package/src/ide-integration/cdp-manager.js +321 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +301 -0
- package/src/ide-integration/cline-cli-manager.cjs +2252 -0
- package/src/ide-integration/continue-cli-manager.js +431 -0
- package/src/ide-integration/provider-manager.cjs +354 -0
- package/src/ide-integration/quota-detector.cjs +34 -0
- package/src/ide-integration/quota-detector.js +349 -0
- package/src/ide-integration/windows-automation-manager.js +262 -0
- package/src/index.cjs +43 -0
- package/src/index.js +17 -0
- package/src/llm/direct-llm-manager.cjs +609 -0
- package/src/ui/ButtonComponents.js +247 -0
- package/src/ui/ChatInterface.js +499 -0
- package/src/ui/StateManager.js +259 -0
- package/src/ui/StateManager.test.js +0 -0
- package/src/utils/audit-logger.cjs +116 -0
- package/src/utils/config-helpers.cjs +94 -0
- package/src/utils/config-helpers.js +94 -0
- package/src/utils/electron-update-checker.js +78 -0
- package/src/utils/gcloud-auth.cjs +394 -0
- package/src/utils/logger.cjs +193 -0
- package/src/utils/logger.js +191 -0
- package/src/utils/repo-helpers.cjs +120 -0
- package/src/utils/repo-helpers.js +120 -0
- package/src/utils/requirement-helpers.js +432 -0
- package/src/utils/update-checker.js +167 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// @vibecodingmachine/core - Logger Utility
|
|
2
|
+
// Provides consistent logging functionality across the core package
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Logger utility for consistent logging
|
|
6
|
+
* Provides structured logging with different levels and formatting
|
|
7
|
+
*/
|
|
8
|
+
export class Logger {
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.level = options.level || 'info';
|
|
11
|
+
this.prefix = options.prefix || 'VibeCodingMachine';
|
|
12
|
+
this.enableTimestamp = options.enableTimestamp !== false;
|
|
13
|
+
this.enableColors = options.enableColors !== false;
|
|
14
|
+
|
|
15
|
+
// Log levels in order of priority
|
|
16
|
+
this.levels = {
|
|
17
|
+
error: 0,
|
|
18
|
+
warn: 1,
|
|
19
|
+
info: 2,
|
|
20
|
+
debug: 3,
|
|
21
|
+
trace: 4
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get current timestamp
|
|
27
|
+
* @returns {string} Formatted timestamp
|
|
28
|
+
*/
|
|
29
|
+
getTimestamp() {
|
|
30
|
+
if (!this.enableTimestamp) return '';
|
|
31
|
+
return new Date().toISOString();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Format log message
|
|
36
|
+
* @param {string} level - Log level
|
|
37
|
+
* @param {string} message - Log message
|
|
38
|
+
* @param {Array} args - Additional arguments
|
|
39
|
+
* @returns {string} Formatted log message
|
|
40
|
+
*/
|
|
41
|
+
formatMessage(level, message, args = []) {
|
|
42
|
+
const timestamp = this.getTimestamp();
|
|
43
|
+
const timestampStr = timestamp ? `[${timestamp}] ` : '';
|
|
44
|
+
const prefixStr = this.prefix ? `[${this.prefix}] ` : '';
|
|
45
|
+
const levelStr = `[${level.toUpperCase()}] `;
|
|
46
|
+
|
|
47
|
+
let formattedMessage = `${timestampStr}${prefixStr}${levelStr}${message}`;
|
|
48
|
+
|
|
49
|
+
if (args.length > 0) {
|
|
50
|
+
formattedMessage += ' ' + args.map(arg =>
|
|
51
|
+
typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
|
|
52
|
+
).join(' ');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return formattedMessage;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Check if level should be logged
|
|
60
|
+
* @param {string} level - Log level to check
|
|
61
|
+
* @returns {boolean} Whether to log this level
|
|
62
|
+
*/
|
|
63
|
+
shouldLog(level) {
|
|
64
|
+
return this.levels[level] <= this.levels[this.level];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Log error message
|
|
69
|
+
* @param {string} message - Error message
|
|
70
|
+
* @param {...any} args - Additional arguments
|
|
71
|
+
*/
|
|
72
|
+
error(message, ...args) {
|
|
73
|
+
if (!this.shouldLog('error')) return;
|
|
74
|
+
|
|
75
|
+
const formattedMessage = this.formatMessage('error', message, args);
|
|
76
|
+
console.error(formattedMessage);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Log warning message
|
|
81
|
+
* @param {string} message - Warning message
|
|
82
|
+
* @param {...any} args - Additional arguments
|
|
83
|
+
*/
|
|
84
|
+
warn(message, ...args) {
|
|
85
|
+
if (!this.shouldLog('warn')) return;
|
|
86
|
+
|
|
87
|
+
const formattedMessage = this.formatMessage('warn', message, args);
|
|
88
|
+
console.warn(formattedMessage);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Log info message
|
|
93
|
+
* @param {string} message - Info message
|
|
94
|
+
* @param {...any} args - Additional arguments
|
|
95
|
+
*/
|
|
96
|
+
info(message, ...args) {
|
|
97
|
+
if (!this.shouldLog('info')) return;
|
|
98
|
+
|
|
99
|
+
const formattedMessage = this.formatMessage('info', message, args);
|
|
100
|
+
console.info(formattedMessage);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Log debug message
|
|
105
|
+
* @param {string} message - Debug message
|
|
106
|
+
* @param {...any} args - Additional arguments
|
|
107
|
+
*/
|
|
108
|
+
debug(message, ...args) {
|
|
109
|
+
if (!this.shouldLog('debug')) return;
|
|
110
|
+
|
|
111
|
+
const formattedMessage = this.formatMessage('debug', message, args);
|
|
112
|
+
console.debug(formattedMessage);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Log trace message
|
|
117
|
+
* @param {string} message - Trace message
|
|
118
|
+
* @param {...any} args - Additional arguments
|
|
119
|
+
*/
|
|
120
|
+
trace(message, ...args) {
|
|
121
|
+
if (!this.shouldLog('trace')) return;
|
|
122
|
+
|
|
123
|
+
const formattedMessage = this.formatMessage('trace', message, args);
|
|
124
|
+
console.trace(formattedMessage);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Log message (alias for info)
|
|
129
|
+
* @param {string} message - Log message
|
|
130
|
+
* @param {...any} args - Additional arguments
|
|
131
|
+
*/
|
|
132
|
+
log(message, ...args) {
|
|
133
|
+
this.info(message, ...args);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Set log level
|
|
138
|
+
* @param {string} level - New log level
|
|
139
|
+
*/
|
|
140
|
+
setLevel(level) {
|
|
141
|
+
if (this.levels.hasOwnProperty(level)) {
|
|
142
|
+
this.level = level;
|
|
143
|
+
} else {
|
|
144
|
+
this.warn(`Invalid log level: ${level}. Using 'info' instead.`);
|
|
145
|
+
this.level = 'info';
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Get current log level
|
|
151
|
+
* @returns {string} Current log level
|
|
152
|
+
*/
|
|
153
|
+
getLevel() {
|
|
154
|
+
return this.level;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Create a child logger with a specific prefix
|
|
159
|
+
* @param {string} childPrefix - Prefix for the child logger
|
|
160
|
+
* @param {Object} options - Additional options
|
|
161
|
+
* @returns {Logger} Child logger instance
|
|
162
|
+
*/
|
|
163
|
+
child(childPrefix, options = {}) {
|
|
164
|
+
const fullPrefix = this.prefix ? `${this.prefix}:${childPrefix}` : childPrefix;
|
|
165
|
+
return new Logger({
|
|
166
|
+
level: this.level,
|
|
167
|
+
prefix: fullPrefix,
|
|
168
|
+
enableTimestamp: this.enableTimestamp,
|
|
169
|
+
enableColors: this.enableColors,
|
|
170
|
+
...options
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Create default logger instance
|
|
176
|
+
export const logger = new Logger({
|
|
177
|
+
level: process.env.NODE_ENV === 'development' ? 'debug' : 'info',
|
|
178
|
+
prefix: 'VibeCodingMachine',
|
|
179
|
+
enableTimestamp: true,
|
|
180
|
+
enableColors: true
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Export console methods for backward compatibility
|
|
184
|
+
export const consoleLogger = {
|
|
185
|
+
log: (...args) => logger.log(...args),
|
|
186
|
+
info: (...args) => logger.info(...args),
|
|
187
|
+
warn: (...args) => logger.warn(...args),
|
|
188
|
+
error: (...args) => logger.error(...args),
|
|
189
|
+
debug: (...args) => logger.debug(...args),
|
|
190
|
+
trace: (...args) => logger.trace(...args)
|
|
191
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { getConfigValue } = require('./config-helpers.cjs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Get the hostname for the current machine
|
|
8
|
+
* @returns {string} The hostname (includes .local suffix if present)
|
|
9
|
+
*/
|
|
10
|
+
function getHostname() {
|
|
11
|
+
return os.hostname(); // Keep full hostname including .local
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if computer name setting is enabled
|
|
16
|
+
* Reads from shared config location (same as Electron app)
|
|
17
|
+
* @returns {Promise<boolean>} True if enabled
|
|
18
|
+
*/
|
|
19
|
+
async function isComputerNameEnabled() {
|
|
20
|
+
return await getConfigValue('computerNameEnabled', false);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get the requirements filename (always uses hostname-specific file)
|
|
25
|
+
* @param {string} hostname - Optional hostname (defaults to current hostname)
|
|
26
|
+
* @param {boolean} useHostname - Optional override (deprecated, always uses hostname)
|
|
27
|
+
* @returns {Promise<string>} The requirements filename
|
|
28
|
+
*/
|
|
29
|
+
async function getRequirementsFilename(hostname = null, useHostname = null) {
|
|
30
|
+
// Always use hostname-specific file to ensure consistency across CLI and Electron app
|
|
31
|
+
const host = hostname || getHostname();
|
|
32
|
+
return `REQUIREMENTS-${host}.md`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if .vibecodingmachine directories exist in either location
|
|
37
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
38
|
+
* @returns {Promise<Object>} Status object with exists, insideExists, siblingExists, insideDir, siblingDir
|
|
39
|
+
*/
|
|
40
|
+
async function checkVibeCodingMachineExists(repoPath = null) {
|
|
41
|
+
try {
|
|
42
|
+
const cwd = repoPath || process.cwd();
|
|
43
|
+
const repoName = path.basename(cwd);
|
|
44
|
+
const insideDir = path.join(cwd, '.vibecodingmachine');
|
|
45
|
+
const siblingDir = path.join(path.dirname(cwd), `.vibecodingmachine-${repoName}`);
|
|
46
|
+
|
|
47
|
+
const insideExists = await fs.pathExists(insideDir);
|
|
48
|
+
const siblingExists = await fs.pathExists(siblingDir);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
exists: insideExists || siblingExists,
|
|
52
|
+
insideExists,
|
|
53
|
+
siblingExists,
|
|
54
|
+
insideDir,
|
|
55
|
+
siblingDir
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return {
|
|
59
|
+
exists: false,
|
|
60
|
+
insideExists: false,
|
|
61
|
+
siblingExists: false,
|
|
62
|
+
insideDir: null,
|
|
63
|
+
siblingDir: null
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get the .vibecodingmachine directory path (checks both inside and sibling locations)
|
|
70
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
71
|
+
* @returns {Promise<string|null>} The path to the .vibecodingmachine directory or null if not found
|
|
72
|
+
*/
|
|
73
|
+
async function getVibeCodingMachineDir(repoPath = null) {
|
|
74
|
+
const status = await checkVibeCodingMachineExists(repoPath);
|
|
75
|
+
if (status.insideExists) {
|
|
76
|
+
return status.insideDir;
|
|
77
|
+
} else if (status.siblingExists) {
|
|
78
|
+
return status.siblingDir;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get the path to the REQUIREMENTS file (with hostname)
|
|
85
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
86
|
+
* @param {string} hostname - Optional hostname (defaults to current hostname)
|
|
87
|
+
* @returns {Promise<string|null>} The path to the REQUIREMENTS file or null if .vibecodingmachine dir not found
|
|
88
|
+
*/
|
|
89
|
+
async function getRequirementsPath(repoPath = null, hostname = null) {
|
|
90
|
+
const allnightDir = await getVibeCodingMachineDir(repoPath);
|
|
91
|
+
if (!allnightDir) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const filename = await getRequirementsFilename(hostname);
|
|
95
|
+
return path.join(allnightDir, filename);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Check if REQUIREMENTS file exists (with hostname)
|
|
100
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
101
|
+
* @param {string} hostname - Optional hostname (defaults to current hostname)
|
|
102
|
+
* @returns {Promise<boolean>} True if REQUIREMENTS file exists
|
|
103
|
+
*/
|
|
104
|
+
async function requirementsExists(repoPath = null, hostname = null) {
|
|
105
|
+
const reqPath = await getRequirementsPath(repoPath, hostname);
|
|
106
|
+
if (!reqPath) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return await fs.pathExists(reqPath);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = {
|
|
113
|
+
getHostname,
|
|
114
|
+
isComputerNameEnabled,
|
|
115
|
+
getRequirementsFilename,
|
|
116
|
+
checkVibeCodingMachineExists,
|
|
117
|
+
getVibeCodingMachineDir,
|
|
118
|
+
getRequirementsPath,
|
|
119
|
+
requirementsExists
|
|
120
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const { getConfigValue } = require('./config-helpers');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Get the hostname for the current machine
|
|
8
|
+
* @returns {string} The hostname (includes .local suffix if present)
|
|
9
|
+
*/
|
|
10
|
+
function getHostname() {
|
|
11
|
+
return os.hostname(); // Keep full hostname including .local
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if computer name setting is enabled
|
|
16
|
+
* Reads from shared config location (same as Electron app)
|
|
17
|
+
* @returns {Promise<boolean>} True if enabled
|
|
18
|
+
*/
|
|
19
|
+
async function isComputerNameEnabled() {
|
|
20
|
+
return await getConfigValue('computerNameEnabled', false);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Get the requirements filename (always uses hostname-specific file)
|
|
25
|
+
* @param {string} hostname - Optional hostname (defaults to current hostname)
|
|
26
|
+
* @param {boolean} useHostname - Optional override (deprecated, always uses hostname)
|
|
27
|
+
* @returns {Promise<string>} The requirements filename
|
|
28
|
+
*/
|
|
29
|
+
async function getRequirementsFilename(hostname = null, useHostname = null) {
|
|
30
|
+
// Always use hostname-specific file to ensure consistency across CLI and Electron app
|
|
31
|
+
const host = hostname || getHostname();
|
|
32
|
+
return `REQUIREMENTS-${host}.md`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if .vibecodingmachine directories exist in either location
|
|
37
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
38
|
+
* @returns {Promise<Object>} Status object with exists, insideExists, siblingExists, insideDir, siblingDir
|
|
39
|
+
*/
|
|
40
|
+
async function checkVibeCodingMachineExists(repoPath = null) {
|
|
41
|
+
try {
|
|
42
|
+
const cwd = repoPath || process.cwd();
|
|
43
|
+
const repoName = path.basename(cwd);
|
|
44
|
+
const insideDir = path.join(cwd, '.vibecodingmachine');
|
|
45
|
+
const siblingDir = path.join(path.dirname(cwd), `.vibecodingmachine-${repoName}`);
|
|
46
|
+
|
|
47
|
+
const insideExists = await fs.pathExists(insideDir);
|
|
48
|
+
const siblingExists = await fs.pathExists(siblingDir);
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
exists: insideExists || siblingExists,
|
|
52
|
+
insideExists,
|
|
53
|
+
siblingExists,
|
|
54
|
+
insideDir,
|
|
55
|
+
siblingDir
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return {
|
|
59
|
+
exists: false,
|
|
60
|
+
insideExists: false,
|
|
61
|
+
siblingExists: false,
|
|
62
|
+
insideDir: null,
|
|
63
|
+
siblingDir: null
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get the .vibecodingmachine directory path (checks both inside and sibling locations)
|
|
70
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
71
|
+
* @returns {Promise<string|null>} The path to the .vibecodingmachine directory or null if not found
|
|
72
|
+
*/
|
|
73
|
+
async function getVibeCodingMachineDir(repoPath = null) {
|
|
74
|
+
const status = await checkVibeCodingMachineExists(repoPath);
|
|
75
|
+
if (status.insideExists) {
|
|
76
|
+
return status.insideDir;
|
|
77
|
+
} else if (status.siblingExists) {
|
|
78
|
+
return status.siblingDir;
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get the path to the REQUIREMENTS file (with hostname)
|
|
85
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
86
|
+
* @param {string} hostname - Optional hostname (defaults to current hostname)
|
|
87
|
+
* @returns {Promise<string|null>} The path to the REQUIREMENTS file or null if .vibecodingmachine dir not found
|
|
88
|
+
*/
|
|
89
|
+
async function getRequirementsPath(repoPath = null, hostname = null) {
|
|
90
|
+
const allnightDir = await getVibeCodingMachineDir(repoPath);
|
|
91
|
+
if (!allnightDir) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const filename = await getRequirementsFilename(hostname);
|
|
95
|
+
return path.join(allnightDir, filename);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Check if REQUIREMENTS file exists (with hostname)
|
|
100
|
+
* @param {string} repoPath - The repository path (defaults to cwd)
|
|
101
|
+
* @param {string} hostname - Optional hostname (defaults to current hostname)
|
|
102
|
+
* @returns {Promise<boolean>} True if REQUIREMENTS file exists
|
|
103
|
+
*/
|
|
104
|
+
async function requirementsExists(repoPath = null, hostname = null) {
|
|
105
|
+
const reqPath = await getRequirementsPath(repoPath, hostname);
|
|
106
|
+
if (!reqPath) {
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return await fs.pathExists(reqPath);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = {
|
|
113
|
+
getHostname,
|
|
114
|
+
isComputerNameEnabled,
|
|
115
|
+
getRequirementsFilename,
|
|
116
|
+
checkVibeCodingMachineExists,
|
|
117
|
+
getVibeCodingMachineDir,
|
|
118
|
+
getRequirementsPath,
|
|
119
|
+
requirementsExists
|
|
120
|
+
};
|