vibecodingmachine-cli 1.0.3 → 1.0.5

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 (37) hide show
  1. package/.allnightai/REQUIREMENTS.md +11 -11
  2. package/.eslintrc.js +16 -16
  3. package/README.md +85 -85
  4. package/bin/vibecodingmachine.js +274 -274
  5. package/jest.config.js +8 -8
  6. package/logs/audit/2025-11-07.jsonl +2 -2
  7. package/package.json +62 -66
  8. package/scripts/README.md +128 -128
  9. package/scripts/auto-start-wrapper.sh +92 -92
  10. package/scripts/postinstall.js +81 -81
  11. package/src/commands/auth.js +96 -96
  12. package/src/commands/auto-direct.js +1748 -1748
  13. package/src/commands/auto.js +4692 -4692
  14. package/src/commands/auto.js.bak +710 -710
  15. package/src/commands/ide.js +70 -70
  16. package/src/commands/repo.js +159 -159
  17. package/src/commands/requirements.js +161 -161
  18. package/src/commands/setup.js +91 -91
  19. package/src/commands/status.js +88 -88
  20. package/src/index.js +5 -5
  21. package/src/utils/auth.js +577 -577
  22. package/src/utils/auto-mode-ansi-ui.js +238 -238
  23. package/src/utils/auto-mode-simple-ui.js +161 -161
  24. package/src/utils/auto-mode-ui.js.bak.blessed +207 -207
  25. package/src/utils/auto-mode.js +65 -65
  26. package/src/utils/config.js +64 -64
  27. package/src/utils/interactive.js +3616 -3616
  28. package/src/utils/keyboard-handler.js +152 -152
  29. package/src/utils/logger.js +4 -4
  30. package/src/utils/persistent-header.js +116 -116
  31. package/src/utils/provider-registry.js +128 -128
  32. package/src/utils/status-card.js +120 -120
  33. package/src/utils/stdout-interceptor.js +127 -127
  34. package/tests/auto-mode.test.js +37 -37
  35. package/tests/config.test.js +34 -34
  36. package/.allnightai/temp/auto-status.json +0 -6
  37. package/.env +0 -7
@@ -1,207 +1,207 @@
1
- const blessed = require('blessed');
2
- const chalk = require('chalk');
3
-
4
- /**
5
- * Create and display a blessed-based UI for Auto Mode
6
- * Shows: persistent menu header, status card, and scrolling output
7
- * @param {object} options - UI configuration
8
- * @param {string} options.menuContent - Menu content to display in header
9
- * @param {function} options.onExit - Callback when user presses Ctrl+C or q
10
- * @returns {object} UI interface with methods to update status and append output
11
- */
12
- function createAutoModeUI(options = {}) {
13
- const { menuContent = '', onExit } = options;
14
-
15
- // Create screen
16
- const screen = blessed.screen({
17
- smartCSR: true,
18
- title: 'AllNightAI Auto Mode',
19
- fullUnicode: true,
20
- forceUnicode: true
21
- });
22
-
23
- // Clear screen and render immediately
24
- screen.clearRegion(0, screen.width, 0, screen.height);
25
-
26
- // Header box (menu) - use fixed height instead of shrink
27
- const headerHeight = 11; // Fixed height for header
28
- const header = blessed.box({
29
- top: 0,
30
- left: 0,
31
- width: '100%',
32
- height: headerHeight,
33
- content: menuContent,
34
- tags: true,
35
- border: {
36
- type: 'line'
37
- },
38
- style: {
39
- border: {
40
- fg: 'cyan'
41
- }
42
- }
43
- });
44
-
45
- // Status card (purple/magenta border like GUI)
46
- const statusCardHeight = 12;
47
- const statusCard = blessed.box({
48
- top: headerHeight,
49
- left: 0,
50
- width: '100%',
51
- height: statusCardHeight,
52
- tags: true,
53
- border: {
54
- type: 'round'
55
- },
56
- style: {
57
- border: {
58
- fg: 'magenta'
59
- }
60
- },
61
- label: ' Auto Mode Status '
62
- });
63
-
64
- // Output log (scrollable)
65
- const totalHeaderHeight = headerHeight + statusCardHeight;
66
- const outputLog = blessed.log({
67
- top: totalHeaderHeight,
68
- left: 0,
69
- width: '100%',
70
- height: `100%-${totalHeaderHeight}`,
71
- tags: true,
72
- border: {
73
- type: 'line'
74
- },
75
- style: {
76
- border: {
77
- fg: 'green'
78
- }
79
- },
80
- label: ' Aider Output ',
81
- scrollable: true,
82
- alwaysScroll: true,
83
- mouse: true,
84
- keys: true,
85
- vi: true,
86
- scrollbar: {
87
- ch: ' ',
88
- track: {
89
- bg: 'cyan'
90
- },
91
- style: {
92
- inverse: true
93
- }
94
- }
95
- });
96
-
97
- // Append all elements to screen
98
- screen.append(header);
99
- screen.append(statusCard);
100
- screen.append(outputLog);
101
-
102
- // Focus the output log for scrolling
103
- outputLog.focus();
104
-
105
- // Key bindings
106
- screen.key(['escape', 'q', 'C-c'], () => {
107
- if (onExit) {
108
- onExit();
109
- }
110
- screen.destroy();
111
- process.exit(0);
112
- });
113
-
114
- // Initial render
115
- screen.render();
116
-
117
- /**
118
- * Update the status card with new status information
119
- * @param {object} status - Status object
120
- * @param {string} status.requirement - Current requirement
121
- * @param {string} status.step - Current step (PREPARE, ACT, CLEAN UP, VERIFY, DONE)
122
- * @param {number} status.chatCount - Current chat count
123
- * @param {number|null} status.maxChats - Max chats or null for unlimited
124
- * @param {number} status.progress - Progress percentage (0-100)
125
- */
126
- function updateStatus(status) {
127
- const {
128
- requirement = 'No requirement loaded',
129
- step = 'UNKNOWN',
130
- chatCount = 0,
131
- maxChats = null,
132
- progress = 0
133
- } = status;
134
-
135
- // Step color mapping
136
- const stepColors = {
137
- 'PREPARE': '{cyan-fg}',
138
- 'ACT': '{yellow-fg}',
139
- 'CLEAN UP': '{magenta-fg}',
140
- 'VERIFY': '{blue-fg}',
141
- 'DONE': '{green-fg}',
142
- 'UNKNOWN': '{gray-fg}'
143
- };
144
-
145
- const stepColor = stepColors[step] || '{gray-fg}';
146
-
147
- // Progress bar
148
- const barWidth = 40;
149
- const filledWidth = Math.round((progress / 100) * barWidth);
150
- const emptyWidth = barWidth - filledWidth;
151
- const progressBar = '{green-fg}' + '█'.repeat(filledWidth) + '{/green-fg}' +
152
- '{gray-fg}' + '░'.repeat(emptyWidth) + '{/gray-fg}';
153
-
154
- // Chat counter
155
- const chatDisplay = maxChats
156
- ? `Chat ${chatCount}/${maxChats}`
157
- : `Chat ${chatCount} (unlimited)`;
158
-
159
- // Build card content
160
- const content = `
161
- {bold}📋 Current Requirement{/bold}
162
-
163
- ${requirement.length > 70 ? requirement.substring(0, 67) + '...' : requirement}
164
-
165
- {bold}🚦 Status:{/bold} ${stepColor}{bold}${step}{/bold}{/}
166
-
167
- ${progressBar} ${progress}%
168
-
169
- {gray-fg}${chatDisplay}{/gray-fg}
170
- `;
171
-
172
- statusCard.setContent(content);
173
- screen.render();
174
- }
175
-
176
- /**
177
- * Append a line to the output log
178
- * @param {string} line - Line to append
179
- */
180
- function appendOutput(line) {
181
- outputLog.log(line);
182
- screen.render();
183
- }
184
-
185
- /**
186
- * Clear the output log
187
- */
188
- function clearOutput() {
189
- outputLog.setContent('');
190
- screen.render();
191
- }
192
-
193
- return {
194
- screen,
195
- header,
196
- statusCard,
197
- outputLog,
198
- updateStatus,
199
- appendOutput,
200
- clearOutput,
201
- destroy: () => screen.destroy()
202
- };
203
- }
204
-
205
- module.exports = {
206
- createAutoModeUI
207
- };
1
+ const blessed = require('blessed');
2
+ const chalk = require('chalk');
3
+
4
+ /**
5
+ * Create and display a blessed-based UI for Auto Mode
6
+ * Shows: persistent menu header, status card, and scrolling output
7
+ * @param {object} options - UI configuration
8
+ * @param {string} options.menuContent - Menu content to display in header
9
+ * @param {function} options.onExit - Callback when user presses Ctrl+C or q
10
+ * @returns {object} UI interface with methods to update status and append output
11
+ */
12
+ function createAutoModeUI(options = {}) {
13
+ const { menuContent = '', onExit } = options;
14
+
15
+ // Create screen
16
+ const screen = blessed.screen({
17
+ smartCSR: true,
18
+ title: 'AllNightAI Auto Mode',
19
+ fullUnicode: true,
20
+ forceUnicode: true
21
+ });
22
+
23
+ // Clear screen and render immediately
24
+ screen.clearRegion(0, screen.width, 0, screen.height);
25
+
26
+ // Header box (menu) - use fixed height instead of shrink
27
+ const headerHeight = 11; // Fixed height for header
28
+ const header = blessed.box({
29
+ top: 0,
30
+ left: 0,
31
+ width: '100%',
32
+ height: headerHeight,
33
+ content: menuContent,
34
+ tags: true,
35
+ border: {
36
+ type: 'line'
37
+ },
38
+ style: {
39
+ border: {
40
+ fg: 'cyan'
41
+ }
42
+ }
43
+ });
44
+
45
+ // Status card (purple/magenta border like GUI)
46
+ const statusCardHeight = 12;
47
+ const statusCard = blessed.box({
48
+ top: headerHeight,
49
+ left: 0,
50
+ width: '100%',
51
+ height: statusCardHeight,
52
+ tags: true,
53
+ border: {
54
+ type: 'round'
55
+ },
56
+ style: {
57
+ border: {
58
+ fg: 'magenta'
59
+ }
60
+ },
61
+ label: ' Auto Mode Status '
62
+ });
63
+
64
+ // Output log (scrollable)
65
+ const totalHeaderHeight = headerHeight + statusCardHeight;
66
+ const outputLog = blessed.log({
67
+ top: totalHeaderHeight,
68
+ left: 0,
69
+ width: '100%',
70
+ height: `100%-${totalHeaderHeight}`,
71
+ tags: true,
72
+ border: {
73
+ type: 'line'
74
+ },
75
+ style: {
76
+ border: {
77
+ fg: 'green'
78
+ }
79
+ },
80
+ label: ' Aider Output ',
81
+ scrollable: true,
82
+ alwaysScroll: true,
83
+ mouse: true,
84
+ keys: true,
85
+ vi: true,
86
+ scrollbar: {
87
+ ch: ' ',
88
+ track: {
89
+ bg: 'cyan'
90
+ },
91
+ style: {
92
+ inverse: true
93
+ }
94
+ }
95
+ });
96
+
97
+ // Append all elements to screen
98
+ screen.append(header);
99
+ screen.append(statusCard);
100
+ screen.append(outputLog);
101
+
102
+ // Focus the output log for scrolling
103
+ outputLog.focus();
104
+
105
+ // Key bindings
106
+ screen.key(['escape', 'q', 'C-c'], () => {
107
+ if (onExit) {
108
+ onExit();
109
+ }
110
+ screen.destroy();
111
+ process.exit(0);
112
+ });
113
+
114
+ // Initial render
115
+ screen.render();
116
+
117
+ /**
118
+ * Update the status card with new status information
119
+ * @param {object} status - Status object
120
+ * @param {string} status.requirement - Current requirement
121
+ * @param {string} status.step - Current step (PREPARE, ACT, CLEAN UP, VERIFY, DONE)
122
+ * @param {number} status.chatCount - Current chat count
123
+ * @param {number|null} status.maxChats - Max chats or null for unlimited
124
+ * @param {number} status.progress - Progress percentage (0-100)
125
+ */
126
+ function updateStatus(status) {
127
+ const {
128
+ requirement = 'No requirement loaded',
129
+ step = 'UNKNOWN',
130
+ chatCount = 0,
131
+ maxChats = null,
132
+ progress = 0
133
+ } = status;
134
+
135
+ // Step color mapping
136
+ const stepColors = {
137
+ 'PREPARE': '{cyan-fg}',
138
+ 'ACT': '{yellow-fg}',
139
+ 'CLEAN UP': '{magenta-fg}',
140
+ 'VERIFY': '{blue-fg}',
141
+ 'DONE': '{green-fg}',
142
+ 'UNKNOWN': '{gray-fg}'
143
+ };
144
+
145
+ const stepColor = stepColors[step] || '{gray-fg}';
146
+
147
+ // Progress bar
148
+ const barWidth = 40;
149
+ const filledWidth = Math.round((progress / 100) * barWidth);
150
+ const emptyWidth = barWidth - filledWidth;
151
+ const progressBar = '{green-fg}' + '█'.repeat(filledWidth) + '{/green-fg}' +
152
+ '{gray-fg}' + '░'.repeat(emptyWidth) + '{/gray-fg}';
153
+
154
+ // Chat counter
155
+ const chatDisplay = maxChats
156
+ ? `Chat ${chatCount}/${maxChats}`
157
+ : `Chat ${chatCount} (unlimited)`;
158
+
159
+ // Build card content
160
+ const content = `
161
+ {bold}📋 Current Requirement{/bold}
162
+
163
+ ${requirement.length > 70 ? requirement.substring(0, 67) + '...' : requirement}
164
+
165
+ {bold}🚦 Status:{/bold} ${stepColor}{bold}${step}{/bold}{/}
166
+
167
+ ${progressBar} ${progress}%
168
+
169
+ {gray-fg}${chatDisplay}{/gray-fg}
170
+ `;
171
+
172
+ statusCard.setContent(content);
173
+ screen.render();
174
+ }
175
+
176
+ /**
177
+ * Append a line to the output log
178
+ * @param {string} line - Line to append
179
+ */
180
+ function appendOutput(line) {
181
+ outputLog.log(line);
182
+ screen.render();
183
+ }
184
+
185
+ /**
186
+ * Clear the output log
187
+ */
188
+ function clearOutput() {
189
+ outputLog.setContent('');
190
+ screen.render();
191
+ }
192
+
193
+ return {
194
+ screen,
195
+ header,
196
+ statusCard,
197
+ outputLog,
198
+ updateStatus,
199
+ appendOutput,
200
+ clearOutput,
201
+ destroy: () => screen.destroy()
202
+ };
203
+ }
204
+
205
+ module.exports = {
206
+ createAutoModeUI
207
+ };
@@ -1,65 +1,65 @@
1
- const path = require('path');
2
- const fs = require('fs-extra');
3
- const { getRepoPath } = require('./config');
4
- const { logAutoModeStart, logAutoModeStop } = require('vibecodingmachine-core');
5
-
6
- function getStatusPath(repoPath) {
7
- return path.join(repoPath, '.vibecodingmachine', 'temp', 'auto-status.json');
8
- }
9
-
10
- async function checkAutoModeStatus() {
11
- const repoPath = await getRepoPath();
12
- if (!repoPath) return { running: false };
13
- const statusPath = getStatusPath(repoPath);
14
- if (!await fs.pathExists(statusPath)) return { running: false };
15
- try {
16
- const status = await fs.readJson(statusPath);
17
- return status;
18
- } catch {
19
- return { running: false };
20
- }
21
- }
22
-
23
- async function startAutoMode(repoPath, config) {
24
- const statusPath = getStatusPath(repoPath);
25
- await fs.ensureDir(path.dirname(statusPath));
26
- const status = {
27
- running: true,
28
- startedAt: new Date().toISOString(),
29
- chatCount: 0,
30
- ide: config.ide || 'cline'
31
- };
32
- await fs.writeJson(statusPath, status, { spaces: 2 });
33
-
34
- // Log to audit log
35
- logAutoModeStart(config.ide || 'cline', config.maxChats || 0);
36
- }
37
-
38
- async function stopAutoMode(reason = 'manual') {
39
- const repoPath = await getRepoPath();
40
- if (!repoPath) return;
41
- const statusPath = getStatusPath(repoPath);
42
- if (!await fs.pathExists(statusPath)) return;
43
- const current = await fs.readJson(statusPath).catch(() => ({}));
44
- await fs.writeJson(statusPath, { ...current, running: false }, { spaces: 2 });
45
-
46
- // Log to audit log
47
- logAutoModeStop(reason);
48
- }
49
-
50
- async function updateAutoModeStatus(repoPath, updates) {
51
- const statusPath = getStatusPath(repoPath);
52
- if (!await fs.pathExists(statusPath)) return;
53
- const current = await fs.readJson(statusPath).catch(() => ({ running: true }));
54
- await fs.writeJson(statusPath, { ...current, ...updates }, { spaces: 2 });
55
- }
56
-
57
- module.exports = {
58
- checkAutoModeStatus,
59
- startAutoMode,
60
- stopAutoMode,
61
- updateAutoModeStatus
62
- };
63
-
64
-
65
-
1
+ const path = require('path');
2
+ const fs = require('fs-extra');
3
+ const { getRepoPath } = require('./config');
4
+ const { logAutoModeStart, logAutoModeStop } = require('vibecodingmachine-core');
5
+
6
+ function getStatusPath(repoPath) {
7
+ return path.join(repoPath, '.vibecodingmachine', 'temp', 'auto-status.json');
8
+ }
9
+
10
+ async function checkAutoModeStatus() {
11
+ const repoPath = await getRepoPath();
12
+ if (!repoPath) return { running: false };
13
+ const statusPath = getStatusPath(repoPath);
14
+ if (!await fs.pathExists(statusPath)) return { running: false };
15
+ try {
16
+ const status = await fs.readJson(statusPath);
17
+ return status;
18
+ } catch {
19
+ return { running: false };
20
+ }
21
+ }
22
+
23
+ async function startAutoMode(repoPath, config) {
24
+ const statusPath = getStatusPath(repoPath);
25
+ await fs.ensureDir(path.dirname(statusPath));
26
+ const status = {
27
+ running: true,
28
+ startedAt: new Date().toISOString(),
29
+ chatCount: 0,
30
+ ide: config.ide || 'cline'
31
+ };
32
+ await fs.writeJson(statusPath, status, { spaces: 2 });
33
+
34
+ // Log to audit log
35
+ logAutoModeStart(config.ide || 'cline', config.maxChats || 0);
36
+ }
37
+
38
+ async function stopAutoMode(reason = 'manual') {
39
+ const repoPath = await getRepoPath();
40
+ if (!repoPath) return;
41
+ const statusPath = getStatusPath(repoPath);
42
+ if (!await fs.pathExists(statusPath)) return;
43
+ const current = await fs.readJson(statusPath).catch(() => ({}));
44
+ await fs.writeJson(statusPath, { ...current, running: false }, { spaces: 2 });
45
+
46
+ // Log to audit log
47
+ logAutoModeStop(reason);
48
+ }
49
+
50
+ async function updateAutoModeStatus(repoPath, updates) {
51
+ const statusPath = getStatusPath(repoPath);
52
+ if (!await fs.pathExists(statusPath)) return;
53
+ const current = await fs.readJson(statusPath).catch(() => ({ running: true }));
54
+ await fs.writeJson(statusPath, { ...current, ...updates }, { spaces: 2 });
55
+ }
56
+
57
+ module.exports = {
58
+ checkAutoModeStatus,
59
+ startAutoMode,
60
+ stopAutoMode,
61
+ updateAutoModeStatus
62
+ };
63
+
64
+
65
+
@@ -1,64 +1,64 @@
1
- const path = require('path');
2
- const os = require('os');
3
- const fs = require('fs-extra');
4
-
5
- const DEFAULT_CONFIG_DIR = path.join(os.homedir(), '.config', 'vibecodingmachine');
6
- const DEFAULT_CONFIG_PATH = path.join(DEFAULT_CONFIG_DIR, 'config.json');
7
-
8
- function getConfigPath() {
9
- const override = process.env.ALLNIGHTAI_CONFIG_PATH;
10
- if (override) return override;
11
- return DEFAULT_CONFIG_PATH;
12
- }
13
-
14
- async function ensureConfigFile() {
15
- const cfgPath = getConfigPath();
16
- await fs.ensureDir(path.dirname(cfgPath));
17
- if (!await fs.pathExists(cfgPath)) {
18
- const defaultConfig = { repoPath: null, auto: {} };
19
- await fs.writeJson(cfgPath, defaultConfig, { spaces: 2 });
20
- }
21
- }
22
-
23
- async function readConfig() {
24
- await ensureConfigFile();
25
- return fs.readJson(getConfigPath());
26
- }
27
-
28
- async function writeConfig(config) {
29
- await fs.writeJson(getConfigPath(), config, { spaces: 2 });
30
- }
31
-
32
- async function getRepoPath() {
33
- const cfg = await readConfig();
34
- return cfg.repoPath || null;
35
- }
36
-
37
- async function setRepoPath(repoPath) {
38
- const cfg = await readConfig();
39
- cfg.repoPath = repoPath;
40
- await writeConfig(cfg);
41
- }
42
-
43
- async function getAutoConfig() {
44
- const cfg = await readConfig();
45
- return cfg.auto || {};
46
- }
47
-
48
- async function setAutoConfig(autoConfig) {
49
- const cfg = await readConfig();
50
- // Merge with existing auto config to preserve fields like aiderModel
51
- cfg.auto = { ...(cfg.auto || {}), ...(autoConfig || {}) };
52
- await writeConfig(cfg);
53
- }
54
-
55
- module.exports = {
56
- getRepoPath,
57
- setRepoPath,
58
- getAutoConfig,
59
- setAutoConfig,
60
- readConfig,
61
- writeConfig
62
- };
63
-
64
-
1
+ const path = require('path');
2
+ const os = require('os');
3
+ const fs = require('fs-extra');
4
+
5
+ const DEFAULT_CONFIG_DIR = path.join(os.homedir(), '.config', 'vibecodingmachine');
6
+ const DEFAULT_CONFIG_PATH = path.join(DEFAULT_CONFIG_DIR, 'config.json');
7
+
8
+ function getConfigPath() {
9
+ const override = process.env.ALLNIGHTAI_CONFIG_PATH;
10
+ if (override) return override;
11
+ return DEFAULT_CONFIG_PATH;
12
+ }
13
+
14
+ async function ensureConfigFile() {
15
+ const cfgPath = getConfigPath();
16
+ await fs.ensureDir(path.dirname(cfgPath));
17
+ if (!await fs.pathExists(cfgPath)) {
18
+ const defaultConfig = { repoPath: null, auto: {} };
19
+ await fs.writeJson(cfgPath, defaultConfig, { spaces: 2 });
20
+ }
21
+ }
22
+
23
+ async function readConfig() {
24
+ await ensureConfigFile();
25
+ return fs.readJson(getConfigPath());
26
+ }
27
+
28
+ async function writeConfig(config) {
29
+ await fs.writeJson(getConfigPath(), config, { spaces: 2 });
30
+ }
31
+
32
+ async function getRepoPath() {
33
+ const cfg = await readConfig();
34
+ return cfg.repoPath || null;
35
+ }
36
+
37
+ async function setRepoPath(repoPath) {
38
+ const cfg = await readConfig();
39
+ cfg.repoPath = repoPath;
40
+ await writeConfig(cfg);
41
+ }
42
+
43
+ async function getAutoConfig() {
44
+ const cfg = await readConfig();
45
+ return cfg.auto || {};
46
+ }
47
+
48
+ async function setAutoConfig(autoConfig) {
49
+ const cfg = await readConfig();
50
+ // Merge with existing auto config to preserve fields like aiderModel
51
+ cfg.auto = { ...(cfg.auto || {}), ...(autoConfig || {}) };
52
+ await writeConfig(cfg);
53
+ }
54
+
55
+ module.exports = {
56
+ getRepoPath,
57
+ setRepoPath,
58
+ getAutoConfig,
59
+ setAutoConfig,
60
+ readConfig,
61
+ writeConfig
62
+ };
63
+
64
+