vibecodingmachine-cli 2026.2.26-1752 → 2026.3.9-1621

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 (74) hide show
  1. package/bin/auth/auth-compliance.js +7 -1
  2. package/bin/commands/agent-commands.js +150 -228
  3. package/bin/commands/command-aliases.js +68 -0
  4. package/bin/vibecodingmachine.js +1 -2
  5. package/package.json +2 -2
  6. package/src/commands/agents/list.js +71 -115
  7. package/src/commands/agents-check.js +16 -4
  8. package/src/commands/analyze-file-sizes.js +1 -1
  9. package/src/commands/auto-direct/auto-provider-manager.js +290 -0
  10. package/src/commands/auto-direct/auto-status-display.js +331 -0
  11. package/src/commands/auto-direct/auto-utils.js +439 -0
  12. package/src/commands/auto-direct/file-operations.js +110 -0
  13. package/src/commands/auto-direct/provider-config.js +1 -1
  14. package/src/commands/auto-direct/provider-manager.js +1 -1
  15. package/src/commands/auto-direct/status-display.js +1 -1
  16. package/src/commands/auto-direct/utils.js +24 -18
  17. package/src/commands/auto-direct-refactored.js +413 -0
  18. package/src/commands/auto-direct.js +594 -188
  19. package/src/commands/requirements/commands.js +353 -0
  20. package/src/commands/requirements/default-handlers.js +272 -0
  21. package/src/commands/requirements/disable.js +97 -0
  22. package/src/commands/requirements/enable.js +97 -0
  23. package/src/commands/requirements/utils.js +194 -0
  24. package/src/commands/requirements-refactored.js +60 -0
  25. package/src/commands/requirements.js +38 -771
  26. package/src/commands/specs/disable.js +96 -0
  27. package/src/commands/specs/enable.js +96 -0
  28. package/src/trui/TruiInterface.js +5 -11
  29. package/src/trui/agents/AgentInterface.js +24 -396
  30. package/src/trui/agents/handlers/CommandHandler.js +93 -0
  31. package/src/trui/agents/handlers/ContextManager.js +117 -0
  32. package/src/trui/agents/handlers/DisplayHandler.js +243 -0
  33. package/src/trui/agents/handlers/HelpHandler.js +51 -0
  34. package/src/utils/auth.js +13 -111
  35. package/src/utils/config.js +4 -0
  36. package/src/utils/interactive/requirements-navigation.js +17 -15
  37. package/src/utils/interactive-broken.js +2 -2
  38. package/src/utils/provider-checker/agent-runner.js +15 -1
  39. package/src/utils/provider-checker/cli-installer.js +149 -7
  40. package/src/utils/provider-checker/opencode-checker.js +588 -0
  41. package/src/utils/provider-checker/provider-validator.js +88 -3
  42. package/src/utils/provider-checker/time-formatter.js +3 -2
  43. package/src/utils/provider-manager.js +28 -20
  44. package/src/utils/provider-registry.js +35 -3
  45. package/src/utils/requirements-navigator/index.js +94 -0
  46. package/src/utils/requirements-navigator/input-handler.js +217 -0
  47. package/src/utils/requirements-navigator/section-loader.js +188 -0
  48. package/src/utils/requirements-navigator/tree-builder.js +105 -0
  49. package/src/utils/requirements-navigator/tree-renderer.js +50 -0
  50. package/src/utils/requirements-navigator.js +2 -583
  51. package/src/utils/trui-clarifications.js +188 -0
  52. package/src/utils/trui-feedback.js +54 -1
  53. package/src/utils/trui-kiro-integration.js +398 -0
  54. package/src/utils/trui-main-handlers.js +194 -0
  55. package/src/utils/trui-main-menu.js +235 -0
  56. package/src/utils/trui-nav-agents.js +178 -25
  57. package/src/utils/trui-nav-requirements.js +203 -27
  58. package/src/utils/trui-nav-settings.js +114 -1
  59. package/src/utils/trui-nav-specifications.js +44 -3
  60. package/src/utils/trui-navigation-backup.js +603 -0
  61. package/src/utils/trui-navigation.js +70 -228
  62. package/src/utils/trui-provider-health.js +274 -0
  63. package/src/utils/trui-provider-manager.js +376 -0
  64. package/src/utils/trui-quick-menu.js +25 -1
  65. package/src/utils/trui-req-actions-backup.js +507 -0
  66. package/src/utils/trui-req-actions.js +148 -216
  67. package/src/utils/trui-req-editor.js +170 -0
  68. package/src/utils/trui-req-file-ops.js +278 -0
  69. package/src/utils/trui-req-tree-old.js +719 -0
  70. package/src/utils/trui-req-tree.js +348 -627
  71. package/src/utils/trui-specifications.js +25 -7
  72. package/src/utils/trui-windsurf.js +231 -10
  73. package/src/utils/welcome-screen-extracted.js +2 -2
  74. package/src/utils/welcome-screen.js +2 -2
@@ -0,0 +1,353 @@
1
+ /**
2
+ * Requirements Commands
3
+ *
4
+ * Core requirements management commands
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const chalk = require('chalk');
9
+ const chokidar = require('chokidar');
10
+ const {
11
+ getReqPathOrExit,
12
+ ensureRequirementsFile,
13
+ loadRequirements,
14
+ saveRequirements,
15
+ findRequirementByTitle,
16
+ findRequirementById,
17
+ generateRequirementId,
18
+ validateRequirement,
19
+ formatRequirement,
20
+ openInEditor
21
+ } = require('./utils');
22
+
23
+ /**
24
+ * List all requirements
25
+ */
26
+ async function list(options) {
27
+ try {
28
+ const { repoPath, reqPath } = await getReqPathOrExit();
29
+
30
+ if (!await fs.pathExists(reqPath)) {
31
+ console.log(chalk.yellow('No requirements file found. Use "app req add" to create one.'));
32
+ return;
33
+ }
34
+
35
+ const data = await loadRequirements(reqPath);
36
+ const { requirements, current } = data;
37
+
38
+ if (requirements.length === 0) {
39
+ console.log(chalk.yellow('No requirements found.'));
40
+ return;
41
+ }
42
+
43
+ console.log(chalk.blue('\nRequirements:'));
44
+
45
+ if (options.verbose) {
46
+ requirements.forEach((req, index) => {
47
+ const isCurrent = current && current.id === req.id;
48
+ console.log(`${index + 1}. ${formatRequirement(req, isCurrent)}`);
49
+ if (req.description) {
50
+ console.log(` ${chalk.gray(req.description)}`);
51
+ }
52
+ if (req.package) {
53
+ console.log(` ${chalk.cyan('Package:')} ${req.package}`);
54
+ }
55
+ if (req.created) {
56
+ console.log(` ${chalk.gray('Created:')} ${new Date(req.created).toLocaleDateString()}`);
57
+ }
58
+ console.log();
59
+ });
60
+ } else {
61
+ requirements.forEach((req, index) => {
62
+ const isCurrent = current && current.id === req.id;
63
+ console.log(`${index + 1}. ${formatRequirement(req, isCurrent)}`);
64
+ });
65
+ }
66
+
67
+ if (current) {
68
+ console.log(chalk.green(`\nCurrent: ${current.title}`));
69
+ }
70
+ } catch (error) {
71
+ console.error(chalk.red('Error listing requirements:'), error.message);
72
+ }
73
+ }
74
+
75
+ /**
76
+ * Add a new requirement
77
+ */
78
+ async function add(name, pkg, description) {
79
+ try {
80
+ const { reqPath, repoPath } = await getReqPathOrExit();
81
+ await ensureRequirementsFile(reqPath);
82
+
83
+ const data = await loadRequirements(reqPath);
84
+ const { requirements } = data;
85
+
86
+ // Check for duplicate
87
+ if (findRequirementByTitle(requirements, name)) {
88
+ console.error(chalk.red('Requirement with this title already exists.'));
89
+ return;
90
+ }
91
+
92
+ // Create new requirement
93
+ const requirement = {
94
+ id: generateRequirementId(requirements),
95
+ title: name,
96
+ description: description || '',
97
+ package: pkg || '',
98
+ status: 'pending',
99
+ created: new Date().toISOString(),
100
+ updated: new Date().toISOString()
101
+ };
102
+
103
+ if (!validateRequirement(requirement)) {
104
+ console.error(chalk.red('Invalid requirement data.'));
105
+ return;
106
+ }
107
+
108
+ requirements.push(requirement);
109
+ await saveRequirements(reqPath, data);
110
+
111
+ console.log(chalk.green('Requirement added successfully:'));
112
+ console.log(` ${formatRequirement(requirement)}`);
113
+ } catch (error) {
114
+ console.error(chalk.red('Error adding requirement:'), error.message);
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Show current requirement
120
+ */
121
+ async function current() {
122
+ try {
123
+ const { reqPath } = await getReqPathOrExit();
124
+
125
+ if (!await fs.pathExists(reqPath)) {
126
+ console.log(chalk.yellow('No requirements file found.'));
127
+ return;
128
+ }
129
+
130
+ const data = await loadRequirements(reqPath);
131
+ const { current } = data;
132
+
133
+ if (!current) {
134
+ console.log(chalk.yellow('No current requirement set.'));
135
+ return;
136
+ }
137
+
138
+ console.log(chalk.blue('\nCurrent Requirement:'));
139
+ console.log(` ${formatRequirement(current, true)}`);
140
+
141
+ if (current.description) {
142
+ console.log(chalk.gray(`\nDescription: ${current.description}`));
143
+ }
144
+
145
+ if (current.package) {
146
+ console.log(chalk.cyan(`Package: ${current.package}`));
147
+ }
148
+ } catch (error) {
149
+ console.error(chalk.red('Error getting current requirement:'), error.message);
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Set next requirement as current
155
+ */
156
+ async function next() {
157
+ try {
158
+ const { reqPath } = await getReqPathOrExit();
159
+
160
+ if (!await fs.pathExists(reqPath)) {
161
+ console.log(chalk.yellow('No requirements file found.'));
162
+ return;
163
+ }
164
+
165
+ const data = await loadRequirements(reqPath);
166
+ const { requirements, current } = data;
167
+
168
+ if (requirements.length === 0) {
169
+ console.log(chalk.yellow('No requirements found.'));
170
+ return;
171
+ }
172
+
173
+ // Find next requirement
174
+ let nextReq;
175
+ if (!current) {
176
+ nextReq = requirements[0];
177
+ } else {
178
+ const currentIndex = requirements.findIndex(req => req.id === current.id);
179
+ if (currentIndex >= 0 && currentIndex < requirements.length - 1) {
180
+ nextReq = requirements[currentIndex + 1];
181
+ } else {
182
+ console.log(chalk.yellow('Already at the last requirement.'));
183
+ return;
184
+ }
185
+ }
186
+
187
+ // Update current
188
+ data.current = nextReq;
189
+ await saveRequirements(reqPath, data);
190
+
191
+ console.log(chalk.green('Current requirement updated:'));
192
+ console.log(` ${formatRequirement(nextReq, true)}`);
193
+ } catch (error) {
194
+ console.error(chalk.red('Error setting next requirement:'), error.message);
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Edit requirements file
200
+ */
201
+ async function edit() {
202
+ try {
203
+ const { reqPath } = await getReqPathOrExit();
204
+
205
+ if (!await fs.pathExists(reqPath)) {
206
+ console.log(chalk.yellow('No requirements file found. Creating new one...'));
207
+ await ensureRequirementsFile(reqPath);
208
+ }
209
+
210
+ console.log(chalk.gray('Opening requirements file in default editor...'));
211
+ await openInEditor(reqPath);
212
+ } catch (error) {
213
+ console.error(chalk.red('Error editing requirements:'), error.message);
214
+ }
215
+ }
216
+
217
+ /**
218
+ * Watch requirements file for changes
219
+ */
220
+ async function watch() {
221
+ try {
222
+ const { reqPath } = await getReqPathOrExit();
223
+
224
+ if (!await fs.pathExists(reqPath)) {
225
+ console.log(chalk.yellow('No requirements file found.'));
226
+ return;
227
+ }
228
+
229
+ console.log(chalk.gray('Watching:'), chalk.cyan(reqPath));
230
+
231
+ const watcher = chokidar.watch(reqPath);
232
+
233
+ watcher.on('change', async () => {
234
+ console.log(chalk.blue('\nRequirements file changed. Reloading...'));
235
+ const data = await loadRequirements(reqPath);
236
+ const { requirements, current } = data;
237
+
238
+ console.log(chalk.green(`Found ${requirements.length} requirements`));
239
+ if (current) {
240
+ console.log(chalk.cyan(`Current: ${current.title}`));
241
+ }
242
+ });
243
+
244
+ console.log(chalk.green('Watching for changes. Press Ctrl+C to stop.'));
245
+
246
+ } catch (error) {
247
+ console.error(chalk.red('Error watching requirements:'), error.message);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Rename a requirement
253
+ */
254
+ async function rename(oldTitle, newTitle, description) {
255
+ try {
256
+ const { reqPath } = await getReqPathOrExit();
257
+
258
+ if (!await fs.pathExists(reqPath)) {
259
+ console.log(chalk.yellow('No requirements file found.'));
260
+ return;
261
+ }
262
+
263
+ const data = await loadRequirements(reqPath);
264
+ const { requirements, current } = data;
265
+
266
+ const requirement = findRequirementByTitle(requirements, oldTitle);
267
+ if (!requirement) {
268
+ console.error(chalk.red('Requirement not found.'));
269
+ return;
270
+ }
271
+
272
+ // Check for duplicate new title
273
+ if (findRequirementByTitle(requirements, newTitle)) {
274
+ console.error(chalk.red('A requirement with the new title already exists.'));
275
+ return;
276
+ }
277
+
278
+ // Update requirement
279
+ requirement.title = newTitle;
280
+ requirement.updated = new Date().toISOString();
281
+
282
+ if (description) {
283
+ requirement.description = description;
284
+ }
285
+
286
+ // Update current if needed
287
+ if (current && current.id === requirement.id) {
288
+ data.current = requirement;
289
+ }
290
+
291
+ await saveRequirements(reqPath, data);
292
+
293
+ console.log(chalk.green('Requirement renamed successfully:'));
294
+ console.log(` ${formatRequirement(requirement)}`);
295
+ } catch (error) {
296
+ console.error(chalk.red('Error renaming requirement:'), error.message);
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Show working requirement (alias for current)
302
+ */
303
+ async function working() {
304
+ return await current();
305
+ }
306
+
307
+ /**
308
+ * Number all requirements
309
+ */
310
+ async function numberAll() {
311
+ try {
312
+ const { reqPath, repoPath } = await getReqPathOrExit();
313
+
314
+ if (!await fs.pathExists(reqPath)) {
315
+ console.log(chalk.yellow('No requirements file found.'));
316
+ return;
317
+ }
318
+
319
+ const data = await loadRequirements(reqPath);
320
+ const { requirements } = data;
321
+
322
+ let changed = false;
323
+ requirements.forEach((req, index) => {
324
+ const newId = `R${index + 1}`;
325
+ if (req.id !== newId) {
326
+ req.id = newId;
327
+ req.updated = new Date().toISOString();
328
+ changed = true;
329
+ }
330
+ });
331
+
332
+ if (changed) {
333
+ await saveRequirements(reqPath, data);
334
+ console.log(chalk.green('Requirements renumbered successfully.'));
335
+ } else {
336
+ console.log(chalk.gray('Requirements already numbered correctly.'));
337
+ }
338
+ } catch (error) {
339
+ console.error(chalk.red('Error numbering requirements:'), error.message);
340
+ }
341
+ }
342
+
343
+ module.exports = {
344
+ list,
345
+ add,
346
+ current,
347
+ next,
348
+ edit,
349
+ watch,
350
+ rename,
351
+ working,
352
+ numberAll
353
+ };
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Default Requirement Handlers
3
+ *
4
+ * Commands for managing default requirements
5
+ */
6
+
7
+ const fs = require('fs-extra');
8
+ const chalk = require('chalk');
9
+ const path = require('path');
10
+ const { getRepoPath } = require('../../utils/config');
11
+ const { DefaultRequirementManager, JSONStorage } = require('vibecodingmachine-core');
12
+
13
+ /**
14
+ * Create a new default requirement
15
+ */
16
+ async function createDefault(title, options = {}) {
17
+ const { description, maxIterations } = options;
18
+ const repoPath = await getRepoPath();
19
+
20
+ if (!repoPath) {
21
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
22
+ return;
23
+ }
24
+
25
+ try {
26
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
27
+ const manager = new DefaultRequirementManager(storage);
28
+
29
+ await manager.create({
30
+ title,
31
+ description: description || '',
32
+ maxIterations: maxIterations || 5
33
+ });
34
+
35
+ console.log(chalk.green('Default requirement created successfully:'));
36
+ console.log(` ${chalk.cyan('Title:')} ${title}`);
37
+ if (description) {
38
+ console.log(` ${chalk.gray('Description:')} ${description}`);
39
+ }
40
+ console.log(` ${chalk.yellow('Max Iterations:')} ${maxIterations || 5}`);
41
+
42
+ } catch (error) {
43
+ console.error(chalk.red('Error creating default requirement:'), error.message);
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Edit existing default requirement
49
+ */
50
+ async function editDefault(options = {}) {
51
+ const { title, description, maxIterations } = options;
52
+ const repoPath = await getRepoPath();
53
+
54
+ if (!repoPath) {
55
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
56
+ return;
57
+ }
58
+
59
+ try {
60
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
61
+ const manager = new DefaultRequirementManager(storage);
62
+
63
+ const current = await manager.getCurrent();
64
+ if (!current) {
65
+ console.error(chalk.red('No default requirement found. Create one first.'));
66
+ return;
67
+ }
68
+
69
+ const updates = {};
70
+ if (title !== undefined) updates.title = title;
71
+ if (description !== undefined) updates.description = description;
72
+ if (maxIterations !== undefined) updates.maxIterations = maxIterations;
73
+
74
+ await manager.update(current.id, updates);
75
+
76
+ console.log(chalk.green('Default requirement updated successfully:'));
77
+
78
+ const updated = await manager.getCurrent();
79
+ console.log(` ${chalk.cyan('Title:')} ${updated.title}`);
80
+ if (updated.description) {
81
+ console.log(` ${chalk.gray('Description:')} ${updated.description}`);
82
+ }
83
+ console.log(` ${chalk.yellow('Max Iterations:')} ${updated.maxIterations}`);
84
+
85
+ } catch (error) {
86
+ console.error(chalk.red('Error editing default requirement:'), error.message);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Delete default requirement
92
+ */
93
+ async function deleteDefault() {
94
+ const repoPath = await getRepoPath();
95
+
96
+ if (!repoPath) {
97
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
98
+ return;
99
+ }
100
+
101
+ try {
102
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
103
+ const manager = new DefaultRequirementManager(storage);
104
+
105
+ const current = await manager.getCurrent();
106
+ if (!current) {
107
+ console.error(chalk.red('No default requirement found.'));
108
+ return;
109
+ }
110
+
111
+ await manager.delete(current.id);
112
+ console.log(chalk.green('Default requirement deleted successfully.'));
113
+
114
+ } catch (error) {
115
+ console.error(chalk.red('Error deleting default requirement:'), error.message);
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Show current default requirement status
121
+ */
122
+ async function showDefault() {
123
+ const repoPath = await getRepoPath();
124
+
125
+ if (!repoPath) {
126
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
127
+ return;
128
+ }
129
+
130
+ try {
131
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
132
+ const manager = new DefaultRequirementManager(storage);
133
+
134
+ const current = await manager.getCurrent();
135
+ if (!current) {
136
+ console.log(chalk.yellow('No default requirement found.'));
137
+ return;
138
+ }
139
+
140
+ console.log(chalk.blue('\nDefault Requirement:'));
141
+ console.log(` ${chalk.cyan('ID:')} ${current.id}`);
142
+ console.log(` ${chalk.cyan('Title:')} ${current.title}`);
143
+
144
+ if (current.description) {
145
+ console.log(` ${chalk.gray('Description:')} ${current.description}`);
146
+ }
147
+
148
+ console.log(` ${chalk.yellow('Max Iterations:')} ${current.maxIterations}`);
149
+ console.log(` ${chalk.gray('Status:')} ${current.status}`);
150
+
151
+ if (current.createdAt) {
152
+ console.log(` ${chalk.gray('Created:')} ${new Date(current.createdAt).toLocaleString()}`);
153
+ }
154
+
155
+ if (current.updatedAt) {
156
+ console.log(` ${chalk.gray('Updated:')} ${new Date(current.updatedAt).toLocaleString()}`);
157
+ }
158
+
159
+ if (current.iterations && current.iterations.length > 0) {
160
+ console.log(` ${chalk.blue('Iterations:')} ${current.iterations.length}`);
161
+ current.iterations.forEach((iteration, index) => {
162
+ const status = iteration.completed ? '✓' : '○';
163
+ console.log(` ${index + 1}. ${status} ${iteration.summary || 'No summary'}`);
164
+ });
165
+ }
166
+
167
+ } catch (error) {
168
+ console.error(chalk.red('Error showing default requirement:'), error.message);
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Pause default requirement
174
+ */
175
+ async function pauseDefault() {
176
+ const repoPath = await getRepoPath();
177
+
178
+ if (!repoPath) {
179
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
180
+ return;
181
+ }
182
+
183
+ try {
184
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
185
+ const manager = new DefaultRequirementManager(storage);
186
+
187
+ const current = await manager.getCurrent();
188
+ if (!current) {
189
+ console.error(chalk.red('No default requirement found.'));
190
+ return;
191
+ }
192
+
193
+ await manager.pause(current.id);
194
+ console.log(chalk.green('Default requirement paused successfully.'));
195
+
196
+ } catch (error) {
197
+ console.error(chalk.red('Error pausing default requirement:'), error.message);
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Resume default requirement
203
+ */
204
+ async function resumeDefault() {
205
+ const repoPath = await getRepoPath();
206
+
207
+ if (!repoPath) {
208
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
209
+ return;
210
+ }
211
+
212
+ try {
213
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
214
+ const manager = new DefaultRequirementManager(storage);
215
+
216
+ const current = await manager.getCurrent();
217
+ if (!current) {
218
+ console.error(chalk.red('No default requirement found.'));
219
+ return;
220
+ }
221
+
222
+ await manager.resume(current.id);
223
+ console.log(chalk.green('Default requirement resumed successfully.'));
224
+
225
+ } catch (error) {
226
+ console.error(chalk.red('Error resuming default requirement:'), error.message);
227
+ }
228
+ }
229
+
230
+ /**
231
+ * Set max iterations for default requirement
232
+ */
233
+ async function setMaxIterations(maxIterations) {
234
+ const repoPath = await getRepoPath();
235
+
236
+ if (!repoPath) {
237
+ console.error(chalk.red('No repository configured. Run "app init" first.'));
238
+ return;
239
+ }
240
+
241
+ if (!maxIterations || maxIterations < 1) {
242
+ console.error(chalk.red('Max iterations must be a positive number.'));
243
+ return;
244
+ }
245
+
246
+ try {
247
+ const storage = new JSONStorage(path.join(repoPath, '.vibecodingmachine'));
248
+ const manager = new DefaultRequirementManager(storage);
249
+
250
+ const current = await manager.getCurrent();
251
+ if (!current) {
252
+ console.error(chalk.red('No default requirement found.'));
253
+ return;
254
+ }
255
+
256
+ await manager.update(current.id, { maxIterations: parseInt(maxIterations) });
257
+ console.log(chalk.green(`Max iterations set to ${maxIterations}`));
258
+
259
+ } catch (error) {
260
+ console.error(chalk.red('Error setting max iterations:'), error.message);
261
+ }
262
+ }
263
+
264
+ module.exports = {
265
+ createDefault,
266
+ editDefault,
267
+ deleteDefault,
268
+ showDefault,
269
+ pauseDefault,
270
+ resumeDefault,
271
+ setMaxIterations
272
+ };
@@ -0,0 +1,97 @@
1
+ /**
2
+ * CLI Command: Disable Requirement
3
+ *
4
+ * Implements "app disable requirement" command for CLI interface.
5
+ * Follows constitutional requirements: <800 lines, test-first approach.
6
+ */
7
+
8
+ const { disableRequirement } = require('@vibecodingmachine/core/src/utils/requirement-enable-disable');
9
+
10
+ /**
11
+ * CLI disable requirement command implementation
12
+ */
13
+ class DisableRequirementCommand {
14
+ /**
15
+ * Create command instance
16
+ * @param {Object} options - Command options
17
+ */
18
+ constructor(options = {}) {
19
+ this.options = options;
20
+ }
21
+
22
+ /**
23
+ * Execute disable requirement command
24
+ * @param {Array} args - Command arguments [requirementText]
25
+ * @param {Object} options - Command options
26
+ * @returns {Promise<Object>} - Command result
27
+ */
28
+ async execute(args = [], options = {}) {
29
+ try {
30
+ // Parse arguments - requirement text can contain spaces
31
+ const requirementText = args.join(' ');
32
+ if (!requirementText) {
33
+ return {
34
+ success: false,
35
+ error: 'Missing required argument: requirementText',
36
+ usage: 'app disable requirement <requirementText>',
37
+ examples: [
38
+ 'app disable requirement "Add user authentication"',
39
+ 'app disable requirement "Implement OAuth2 login"'
40
+ ]
41
+ };
42
+ }
43
+
44
+ // Call core disable function
45
+ const result = await disableRequirement(requirementText);
46
+
47
+ if (!result.success) {
48
+ return {
49
+ success: false,
50
+ error: result.message
51
+ };
52
+ }
53
+
54
+ return {
55
+ success: true,
56
+ message: result.message,
57
+ data: {
58
+ requirementText,
59
+ status: 'disabled',
60
+ disabledAt: new Date().toISOString()
61
+ }
62
+ };
63
+ } catch (error) {
64
+ return {
65
+ success: false,
66
+ error: `Failed to disable requirement: ${error.message}`
67
+ };
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Get command help
73
+ * @returns {string} - Help text
74
+ */
75
+ getHelp() {
76
+ return `
77
+ Disable a requirement
78
+
79
+ Usage:
80
+ app disable requirement <requirementText>
81
+
82
+ Arguments:
83
+ requirementText Exact text of the requirement to disable
84
+
85
+ Examples:
86
+ app disable requirement "Add user authentication"
87
+ app disable requirement "Implement OAuth2 login"
88
+ app disable requirement "Create user registration page"
89
+
90
+ Description:
91
+ Disables a requirement by adding the DISABLED: prefix.
92
+ Disabled requirements will be skipped by auto-mode when running "start auto".
93
+ `.trim();
94
+ }
95
+ }
96
+
97
+ module.exports = DisableRequirementCommand;