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.
Files changed (54) hide show
  1. package/.babelrc +13 -0
  2. package/README.md +28 -0
  3. package/__tests__/applescript-manager-claude-fix.test.js +286 -0
  4. package/__tests__/requirement-2-auto-start-looping.test.js +69 -0
  5. package/__tests__/requirement-3-auto-start-looping.test.js +69 -0
  6. package/__tests__/requirement-4-auto-start-looping.test.js +69 -0
  7. package/__tests__/requirement-6-auto-start-looping.test.js +73 -0
  8. package/__tests__/requirement-7-status-tracking.test.js +332 -0
  9. package/jest.config.js +18 -0
  10. package/jest.setup.js +12 -0
  11. package/package.json +46 -0
  12. package/src/auth/access-denied.html +119 -0
  13. package/src/auth/shared-auth-storage.js +230 -0
  14. package/src/autonomous-mode/feature-implementer.cjs +70 -0
  15. package/src/autonomous-mode/feature-implementer.js +425 -0
  16. package/src/chat-management/chat-manager.cjs +71 -0
  17. package/src/chat-management/chat-manager.js +342 -0
  18. package/src/ide-integration/__tests__/applescript-manager-thread-closure.test.js +227 -0
  19. package/src/ide-integration/aider-cli-manager.cjs +850 -0
  20. package/src/ide-integration/applescript-diagnostics.js +0 -0
  21. package/src/ide-integration/applescript-manager.cjs +1088 -0
  22. package/src/ide-integration/applescript-manager.js +2803 -0
  23. package/src/ide-integration/applescript-open-apps.js +0 -0
  24. package/src/ide-integration/applescript-read-response.js +0 -0
  25. package/src/ide-integration/applescript-send-text.js +0 -0
  26. package/src/ide-integration/applescript-thread-closure.js +0 -0
  27. package/src/ide-integration/applescript-utils.js +306 -0
  28. package/src/ide-integration/cdp-manager.cjs +221 -0
  29. package/src/ide-integration/cdp-manager.js +321 -0
  30. package/src/ide-integration/claude-code-cli-manager.cjs +301 -0
  31. package/src/ide-integration/cline-cli-manager.cjs +2252 -0
  32. package/src/ide-integration/continue-cli-manager.js +431 -0
  33. package/src/ide-integration/provider-manager.cjs +354 -0
  34. package/src/ide-integration/quota-detector.cjs +34 -0
  35. package/src/ide-integration/quota-detector.js +349 -0
  36. package/src/ide-integration/windows-automation-manager.js +262 -0
  37. package/src/index.cjs +43 -0
  38. package/src/index.js +17 -0
  39. package/src/llm/direct-llm-manager.cjs +609 -0
  40. package/src/ui/ButtonComponents.js +247 -0
  41. package/src/ui/ChatInterface.js +499 -0
  42. package/src/ui/StateManager.js +259 -0
  43. package/src/ui/StateManager.test.js +0 -0
  44. package/src/utils/audit-logger.cjs +116 -0
  45. package/src/utils/config-helpers.cjs +94 -0
  46. package/src/utils/config-helpers.js +94 -0
  47. package/src/utils/electron-update-checker.js +78 -0
  48. package/src/utils/gcloud-auth.cjs +394 -0
  49. package/src/utils/logger.cjs +193 -0
  50. package/src/utils/logger.js +191 -0
  51. package/src/utils/repo-helpers.cjs +120 -0
  52. package/src/utils/repo-helpers.js +120 -0
  53. package/src/utils/requirement-helpers.js +432 -0
  54. package/src/utils/update-checker.js +167 -0
@@ -0,0 +1,230 @@
1
+ const os = require('os');
2
+ const path = require('path');
3
+ const fs = require('fs-extra');
4
+
5
+ const CONFIG_DIR = path.join(os.homedir(), '.config', 'allnightai');
6
+ const TOKEN_FILE = path.join(CONFIG_DIR, 'token.json');
7
+ const PROFILE_FILE = path.join(CONFIG_DIR, 'profile.json');
8
+ const USAGE_FILE = path.join(CONFIG_DIR, 'usage.json');
9
+
10
+ /**
11
+ * Shared authentication storage for both CLI and Electron
12
+ * Stores tokens and profiles in ~/.config/allnightai/
13
+ */
14
+ class SharedAuthStorage {
15
+ /**
16
+ * Decode JWT token (simple base64 decode, no verification)
17
+ */
18
+ decodeJWT(token) {
19
+ const parts = token.split('.');
20
+ if (parts.length !== 3) throw new Error('Invalid JWT');
21
+
22
+ const payload = Buffer.from(parts[1], 'base64').toString('utf8');
23
+ return JSON.parse(payload);
24
+ }
25
+
26
+ /**
27
+ * Check if authenticated
28
+ */
29
+ async isAuthenticated() {
30
+ const token = await this.getToken();
31
+ if (!token) return false;
32
+
33
+ try {
34
+ // Decode JWT to check expiration
35
+ const payload = this.decodeJWT(token);
36
+ const now = Math.floor(Date.now() / 1000);
37
+
38
+ if (payload.exp && payload.exp > now) {
39
+ return true;
40
+ }
41
+ } catch (error) {
42
+ return false;
43
+ }
44
+
45
+ return false;
46
+ }
47
+
48
+ /**
49
+ * Get stored token
50
+ */
51
+ async getToken() {
52
+ try {
53
+ if (await fs.pathExists(TOKEN_FILE)) {
54
+ const data = await fs.readJson(TOKEN_FILE);
55
+ return data.token;
56
+ }
57
+ } catch (error) {
58
+ console.error('Failed to read token:', error);
59
+ }
60
+ return null;
61
+ }
62
+
63
+ /**
64
+ * Save token
65
+ */
66
+ async saveToken(token) {
67
+ await fs.ensureDir(CONFIG_DIR);
68
+ await fs.writeJson(TOKEN_FILE, { token }, { spaces: 2 });
69
+
70
+ // Also save user profile from token
71
+ try {
72
+ const payload = this.decodeJWT(token);
73
+ const email = payload.email;
74
+
75
+ // Note: Beta access control is handled server-side by Cognito Pre-Auth Lambda
76
+ // If we reached here, the user has already passed beta allowlist check
77
+
78
+ const profile = {
79
+ userId: payload.sub,
80
+ email: email,
81
+ name: payload.name || email,
82
+ picture: payload.picture,
83
+ tier: 'free', // Default, will be updated later
84
+ maxIterations: 10
85
+ };
86
+ await this.saveUserProfile(profile);
87
+ } catch (error) {
88
+ console.error('Failed to save user profile:', error);
89
+ throw error;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Delete token
95
+ */
96
+ async deleteToken() {
97
+ if (await fs.pathExists(TOKEN_FILE)) {
98
+ await fs.remove(TOKEN_FILE);
99
+ }
100
+ if (await fs.pathExists(PROFILE_FILE)) {
101
+ await fs.remove(PROFILE_FILE);
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Get user profile
107
+ */
108
+ async getUserProfile() {
109
+ try {
110
+ if (await fs.pathExists(PROFILE_FILE)) {
111
+ return await fs.readJson(PROFILE_FILE);
112
+ }
113
+ } catch (error) {
114
+ console.error('Failed to read profile:', error);
115
+ }
116
+ return null;
117
+ }
118
+
119
+ /**
120
+ * Save user profile
121
+ */
122
+ async saveUserProfile(profile) {
123
+ await fs.ensureDir(CONFIG_DIR);
124
+ await fs.writeJson(PROFILE_FILE, profile, { spaces: 2 });
125
+ }
126
+
127
+ /**
128
+ * Check if user can run auto mode (quota check)
129
+ */
130
+ async canRunAutoMode() {
131
+ const token = await this.getToken();
132
+ if (!token) {
133
+ return { canRun: false, reason: 'Not authenticated' };
134
+ }
135
+
136
+ const profile = await this.getUserProfile();
137
+ if (!profile) {
138
+ return { canRun: false, reason: 'No user profile found' };
139
+ }
140
+
141
+ // Get today's usage from local tracking
142
+ const today = new Date().toISOString().split('T')[0];
143
+ let usage = 0;
144
+ try {
145
+ if (await fs.pathExists(USAGE_FILE)) {
146
+ const usageData = await fs.readJson(USAGE_FILE);
147
+ usage = usageData[today] || 0;
148
+ }
149
+ } catch (error) {
150
+ console.error('Error reading usage:', error);
151
+ }
152
+
153
+ // Check if user can run based on tier
154
+ const isPremium = profile.tier === 'premium';
155
+ const maxIterations = isPremium ? 999999 : (profile.maxIterations || 10);
156
+
157
+ if (!isPremium && usage >= maxIterations) {
158
+ return {
159
+ canRun: false,
160
+ reason: `Daily limit reached (${usage}/${maxIterations})`,
161
+ tier: profile.tier,
162
+ todayUsage: usage,
163
+ maxIterations: maxIterations
164
+ };
165
+ }
166
+
167
+ return {
168
+ canRun: true,
169
+ tier: profile.tier,
170
+ features: {
171
+ unlimitedIterations: isPremium,
172
+ cloudSync: isPremium,
173
+ mobileApp: isPremium
174
+ },
175
+ todayUsage: usage,
176
+ maxIterations: maxIterations
177
+ };
178
+ }
179
+
180
+ /**
181
+ * Log iteration (for quota tracking)
182
+ */
183
+ async logIteration() {
184
+ const today = new Date().toISOString().split('T')[0];
185
+
186
+ try {
187
+ await fs.ensureDir(CONFIG_DIR);
188
+
189
+ let usageData = {};
190
+ if (await fs.pathExists(USAGE_FILE)) {
191
+ usageData = await fs.readJson(USAGE_FILE);
192
+ }
193
+
194
+ usageData[today] = (usageData[today] || 0) + 1;
195
+
196
+ await fs.writeJson(USAGE_FILE, usageData, { spaces: 2 });
197
+ return true;
198
+ } catch (error) {
199
+ console.error('Error logging iteration:', error);
200
+ return false;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * Activate license key
206
+ */
207
+ async activateLicense(licenseKey) {
208
+ // TODO: Call backend API to validate and activate license
209
+ // For now, just upgrade to premium locally
210
+ const profile = await this.getUserProfile();
211
+ if (profile) {
212
+ profile.tier = 'premium';
213
+ profile.maxIterations = 999999;
214
+ profile.licenseKey = licenseKey;
215
+ await this.saveUserProfile(profile);
216
+ return { success: true, tier: 'premium' };
217
+ }
218
+ return { success: false, error: 'Not authenticated' };
219
+ }
220
+
221
+ /**
222
+ * Logout
223
+ */
224
+ async logout() {
225
+ await this.deleteToken();
226
+ return true;
227
+ }
228
+ }
229
+
230
+ module.exports = new SharedAuthStorage();
@@ -0,0 +1,70 @@
1
+ // @vibecodingmachine/core - Feature Implementer (CommonJS) - Stub
2
+ // Handles autonomous mode feature implementation and development workflow
3
+
4
+ class FeatureImplementer {
5
+ constructor(options = {}) {
6
+ this.logger = options.logger || console;
7
+ this.electronAPI = options.electronAPI || null;
8
+ this.onStatusUpdate = options.onStatusUpdate || (() => {});
9
+ this.onProgressUpdate = options.onProgressUpdate || (() => {});
10
+ this.onMessageUpdate = options.onMessageUpdate || (() => {});
11
+ this.onErrorUpdate = options.onErrorUpdate || (() => {});
12
+ this.onCompleteUpdate = options.onCompleteUpdate || (() => {});
13
+ }
14
+
15
+ async startAutonomousMode(ide, tabId) {
16
+ this.logger.log('startAutonomousMode stub called for:', ide, tabId);
17
+ return {
18
+ success: true,
19
+ progress: 0,
20
+ completed: false,
21
+ taskCount: 0
22
+ };
23
+ }
24
+
25
+ stopAutonomousMode() {
26
+ this.logger.log('stopAutonomousMode stub');
27
+ }
28
+
29
+ pauseAutonomousMode() {
30
+ this.logger.log('pauseAutonomousMode stub');
31
+ }
32
+
33
+ resumeAutonomousMode() {
34
+ this.logger.log('resumeAutonomousMode stub');
35
+ }
36
+
37
+ getState() {
38
+ return {
39
+ isAutonomousMode: false,
40
+ isPaused: false,
41
+ isStopped: false,
42
+ currentProgress: 0,
43
+ taskCount: 0
44
+ };
45
+ }
46
+
47
+ setElectronAPI(electronAPI) {
48
+ this.electronAPI = electronAPI;
49
+ }
50
+
51
+ setCallbacks(callbacks) {
52
+ if (callbacks.onStatusUpdate) {
53
+ this.onStatusUpdate = callbacks.onStatusUpdate;
54
+ }
55
+ if (callbacks.onProgressUpdate) {
56
+ this.onProgressUpdate = callbacks.onProgressUpdate;
57
+ }
58
+ if (callbacks.onMessageUpdate) {
59
+ this.onMessageUpdate = callbacks.onMessageUpdate;
60
+ }
61
+ if (callbacks.onErrorUpdate) {
62
+ this.onErrorUpdate = callbacks.onErrorUpdate;
63
+ }
64
+ if (callbacks.onCompleteUpdate) {
65
+ this.onCompleteUpdate = callbacks.onCompleteUpdate;
66
+ }
67
+ }
68
+ }
69
+
70
+ module.exports = { FeatureImplementer };