vibecodingmachine-cli 1.0.5 → 1.0.7

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/.allnightai/temp/auto-status.json +6 -0
  3. package/.env +7 -0
  4. package/.eslintrc.js +16 -16
  5. package/README.md +85 -85
  6. package/bin/vibecodingmachine.js +274 -274
  7. package/jest.config.js +8 -8
  8. package/logs/audit/2025-11-07.jsonl +2 -2
  9. package/package.json +62 -62
  10. package/scripts/README.md +128 -128
  11. package/scripts/auto-start-wrapper.sh +92 -92
  12. package/scripts/postinstall.js +81 -81
  13. package/src/commands/auth.js +96 -96
  14. package/src/commands/auto-direct.js +1748 -1748
  15. package/src/commands/auto.js +4692 -4692
  16. package/src/commands/auto.js.bak +710 -710
  17. package/src/commands/ide.js +70 -70
  18. package/src/commands/repo.js +159 -159
  19. package/src/commands/requirements.js +161 -161
  20. package/src/commands/setup.js +91 -91
  21. package/src/commands/status.js +88 -88
  22. package/src/index.js +5 -5
  23. package/src/utils/auth.js +572 -577
  24. package/src/utils/auto-mode-ansi-ui.js +238 -238
  25. package/src/utils/auto-mode-simple-ui.js +161 -161
  26. package/src/utils/auto-mode-ui.js.bak.blessed +207 -207
  27. package/src/utils/auto-mode.js +65 -65
  28. package/src/utils/config.js +64 -64
  29. package/src/utils/interactive.js +3616 -3616
  30. package/src/utils/keyboard-handler.js +153 -152
  31. package/src/utils/logger.js +4 -4
  32. package/src/utils/persistent-header.js +116 -116
  33. package/src/utils/provider-registry.js +128 -128
  34. package/src/utils/status-card.js +120 -120
  35. package/src/utils/stdout-interceptor.js +127 -127
  36. package/tests/auto-mode.test.js +37 -37
  37. package/tests/config.test.js +34 -34
@@ -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
+