vibecodingmachine-cli 2026.2.20-438 ā 2026.2.26-1739
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/bin/auth/auth-compliance.js +126 -0
- package/bin/cli-program.js +104 -0
- package/bin/cli-setup.js +52 -0
- package/bin/commands/agent-commands.js +310 -0
- package/bin/commands/auto-commands.js +70 -0
- package/bin/commands/command-aliases.js +118 -0
- package/bin/commands/repo-commands.js +39 -0
- package/bin/commands/rui-commands.js +152 -0
- package/bin/config/cli-config.js +394 -0
- package/bin/init/environment-setup.js +84 -0
- package/bin/update/update-checker.js +126 -0
- package/bin/vibecodingmachine-new.js +50 -0
- package/bin/vibecodingmachine.js +29 -663
- package/package.json +8 -2
- package/src/commands/agents/add.js +277 -0
- package/src/commands/agents/check.js +380 -0
- package/src/commands/agents/list.js +471 -0
- package/src/commands/agents/remove.js +351 -0
- package/src/commands/analyze-file-sizes.js +428 -0
- package/src/commands/auto-direct/code-processor.js +282 -0
- package/src/commands/auto-direct/file-scanner.js +266 -0
- package/src/commands/auto-direct/provider-config.js +178 -0
- package/src/commands/auto-direct/provider-manager.js +219 -0
- package/src/commands/auto-direct/requirement-manager.js +172 -0
- package/src/commands/auto-direct/status-display.js +91 -0
- package/src/commands/auto-direct/utils.js +106 -0
- package/src/commands/auto-direct.js +875 -488
- package/src/commands/auto-execution.js +342 -0
- package/src/commands/auto-provider-management.js +102 -0
- package/src/commands/auto-requirement-management.js +161 -0
- package/src/commands/auto-status-helpers.js +141 -0
- package/src/commands/auto.js +105 -5155
- package/src/commands/check-compliance.js +536 -0
- package/src/commands/continuous-scan.js +119 -0
- package/src/commands/ide.js +16 -4
- package/src/commands/refactor-file.js +486 -0
- package/src/commands/requirements.js +301 -2
- package/src/commands/timeout.js +290 -0
- package/src/trui/TruiInterface.js +108 -0
- package/src/trui/agents/AgentInterface.js +580 -0
- package/src/utils/antigravity-installer.js +60 -6
- package/src/utils/clarification-actions.js +290 -0
- package/src/utils/config.js +123 -2
- package/src/utils/first-run.js +5 -5
- package/src/utils/ide-handlers.js +212 -0
- package/src/utils/interactive/clarification-actions.js +348 -0
- package/src/utils/interactive/core-ui.js +265 -0
- package/src/utils/interactive/file-backup.js +237 -0
- package/src/utils/interactive/file-import-export.js +305 -0
- package/src/utils/interactive/file-operations.js +49 -0
- package/src/utils/interactive/file-validation.js +276 -0
- package/src/utils/interactive/interactive-prompts.js +480 -0
- package/src/utils/interactive/requirement-actions.js +127 -0
- package/src/utils/interactive/requirement-crud.js +356 -0
- package/src/utils/interactive/requirements-navigation.js +286 -0
- package/src/utils/interactive.js +390 -3459
- package/src/utils/provider-checker/agent-checker.js +250 -0
- package/src/utils/provider-checker/agent-runner.js +450 -0
- package/src/utils/provider-checker/cli-installer.js +123 -0
- package/src/utils/provider-checker/cli-utils.js +15 -0
- package/src/utils/provider-checker/format-utils.js +32 -0
- package/src/utils/provider-checker/ide-manager.js +72 -0
- package/src/utils/provider-checker/ide-utils.js +71 -0
- package/src/utils/provider-checker/node-detector.js +56 -0
- package/src/utils/provider-checker/node-utils.js +61 -0
- package/src/utils/provider-checker/process-spawn.js +22 -0
- package/src/utils/provider-checker/process-utils.js +37 -0
- package/src/utils/provider-checker/provider-validator.js +160 -0
- package/src/utils/provider-checker/quota-checker.js +54 -0
- package/src/utils/provider-checker/quota-detector.js +44 -0
- package/src/utils/provider-checker/requirements-manager.js +94 -0
- package/src/utils/provider-checker/test-requirements.js +95 -0
- package/src/utils/provider-checker/time-formatter.js +18 -0
- package/src/utils/provider-checker-new.js +14 -0
- package/src/utils/provider-checker.js +12 -407
- package/src/utils/provider-checkers/ide-manager.js +128 -0
- package/src/utils/provider-checkers/node-executable-finder.js +51 -0
- package/src/utils/provider-checkers/provider-checker-core.js +172 -0
- package/src/utils/provider-checkers/provider-checker-main.js +107 -0
- package/src/utils/provider-manager.js +60 -4
- package/src/utils/provider-registry.js +26 -3
- package/src/utils/provider-utils.js +173 -0
- package/src/utils/quota-detectors.js +212 -0
- package/src/utils/requirement-action-handlers.js +288 -0
- package/src/utils/requirement-actions/clarification-actions.js +229 -0
- package/src/utils/requirement-actions/confirmation-prompts.js +93 -0
- package/src/utils/requirement-actions/file-operations.js +92 -0
- package/src/utils/requirement-actions/helpers.js +40 -0
- package/src/utils/requirement-actions/requirement-operations.js +335 -0
- package/src/utils/requirement-actions.js +46 -856
- package/src/utils/requirement-file-operations.js +259 -0
- package/src/utils/requirement-helpers.js +128 -0
- package/src/utils/requirement-management.js +279 -0
- package/src/utils/requirement-navigation.js +146 -0
- package/src/utils/requirement-organization.js +271 -0
- package/src/utils/simple-trui.js +75 -1
- package/src/utils/trui-navigation.js +28 -2
- package/src/utils/trui-req-tree.js +196 -11
- package/src/utils/trui-specifications.js +31 -1
- package/src/utils/interactive-backup.js +0 -5664
- package/src/utils/trui-provider-manager.js +0 -182
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requirement Navigation Module
|
|
3
|
+
*
|
|
4
|
+
* Contains movement and ordering functions for requirements.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
9
|
+
const { getRequirementList, getSectionTitle } = require('./requirement-helpers');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Helper to move requirement down with 'j' key
|
|
13
|
+
*/
|
|
14
|
+
async function moveRequirementDown(req, sectionKey, tree) {
|
|
15
|
+
const reqList = getRequirementList(tree, sectionKey);
|
|
16
|
+
const sectionTitle = getSectionTitle(sectionKey);
|
|
17
|
+
const reqIndex = reqList.findIndex(r => r.title === req.title);
|
|
18
|
+
|
|
19
|
+
if (reqIndex === -1 || reqIndex === reqList.length - 1) return;
|
|
20
|
+
|
|
21
|
+
// Swap with next requirement
|
|
22
|
+
const nextReq = reqList[reqIndex + 1];
|
|
23
|
+
reqList[reqIndex + 1] = req;
|
|
24
|
+
reqList[reqIndex] = nextReq;
|
|
25
|
+
|
|
26
|
+
const reqPath = await getRequirementsPath();
|
|
27
|
+
const { saveRequirementsOrder } = require('./requirement-file-operations');
|
|
28
|
+
await saveRequirementsOrder(reqPath, sectionTitle, reqList);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Helper to move requirement up with 'k' key
|
|
33
|
+
*/
|
|
34
|
+
async function moveRequirementUp(req, sectionKey, tree) {
|
|
35
|
+
const reqList = getRequirementList(tree, sectionKey);
|
|
36
|
+
const sectionTitle = getSectionTitle(sectionKey);
|
|
37
|
+
const reqIndex = reqList.findIndex(r => r.title === req.title);
|
|
38
|
+
|
|
39
|
+
if (reqIndex <= 0) return;
|
|
40
|
+
|
|
41
|
+
// Swap with previous requirement
|
|
42
|
+
const prevReq = reqList[reqIndex - 1];
|
|
43
|
+
reqList[reqIndex - 1] = req;
|
|
44
|
+
reqList[reqIndex] = prevReq;
|
|
45
|
+
|
|
46
|
+
const reqPath = await getRequirementsPath();
|
|
47
|
+
const { saveRequirementsOrder } = require('./requirement-file-operations');
|
|
48
|
+
await saveRequirementsOrder(reqPath, sectionTitle, reqList);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Helper to promote requirement to next list (TODO -> TO VERIFY -> VERIFIED)
|
|
53
|
+
*/
|
|
54
|
+
async function promoteRequirement(req, sectionKey, tree, loadSection, loadVerified) {
|
|
55
|
+
const { promoteTodoToVerify, promoteToVerified } = require('vibecodingmachine-core');
|
|
56
|
+
const reqPath = await getRequirementsPath();
|
|
57
|
+
|
|
58
|
+
if (sectionKey === 'todo') {
|
|
59
|
+
await promoteTodoToVerify(req.title);
|
|
60
|
+
if (loadSection) await loadSection();
|
|
61
|
+
} else if (sectionKey === 'verify') {
|
|
62
|
+
await promoteToVerified(req.title);
|
|
63
|
+
if (loadVerified) await loadVerified();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Helper to demote requirement to previous list (VERIFIED -> TODO, TO VERIFY -> TODO)
|
|
69
|
+
*/
|
|
70
|
+
async function demoteRequirement(reqTitle, sectionKey, tree, loadSection, loadVerified) {
|
|
71
|
+
const { demoteVerifyToTodo, demoteFromVerifiedToTodo } = require('vibecodingmachine-core');
|
|
72
|
+
const reqPath = await getRequirementsPath();
|
|
73
|
+
|
|
74
|
+
if (sectionKey === 'verify') {
|
|
75
|
+
await demoteVerifyToTodo(reqTitle);
|
|
76
|
+
if (loadSection) await loadSection();
|
|
77
|
+
} else if (sectionKey === 'verified') {
|
|
78
|
+
await demoteFromVerifiedToTodo(reqTitle);
|
|
79
|
+
if (loadSection) await loadSection();
|
|
80
|
+
if (loadVerified) await loadVerified();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Helper to move requirement to recycled section
|
|
86
|
+
*/
|
|
87
|
+
async function moveRequirementToRecycled(reqPath, requirementTitle, fromSection) {
|
|
88
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
89
|
+
const lines = content.split('\n');
|
|
90
|
+
|
|
91
|
+
// Find and remove the requirement
|
|
92
|
+
let startIdx = -1;
|
|
93
|
+
let endIdx = -1;
|
|
94
|
+
|
|
95
|
+
for (let i = 0; i < lines.length; i++) {
|
|
96
|
+
if (lines[i].includes(`### ${requirementTitle}`)) {
|
|
97
|
+
startIdx = i;
|
|
98
|
+
// Find the end of this requirement
|
|
99
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
100
|
+
if (lines[j].startsWith('###') || lines[j].startsWith('##')) {
|
|
101
|
+
endIdx = j;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (endIdx === -1) endIdx = lines.length;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (startIdx === -1) return;
|
|
111
|
+
|
|
112
|
+
// Extract the requirement content
|
|
113
|
+
const reqContent = lines.slice(startIdx, endIdx);
|
|
114
|
+
|
|
115
|
+
// Remove from current section
|
|
116
|
+
lines.splice(startIdx, endIdx - startIdx);
|
|
117
|
+
|
|
118
|
+
// Find recycled section and add there
|
|
119
|
+
let recycledIdx = -1;
|
|
120
|
+
for (let i = 0; i < lines.length; i++) {
|
|
121
|
+
if (lines[i].includes('ā»ļø Recycled')) {
|
|
122
|
+
recycledIdx = i;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (recycledIdx !== -1) {
|
|
128
|
+
// Insert after the recycled header
|
|
129
|
+
let insertIdx = recycledIdx + 1;
|
|
130
|
+
while (insertIdx < lines.length && lines[insertIdx].trim() === '') {
|
|
131
|
+
insertIdx++;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
lines.splice(insertIdx, 0, ...reqContent);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
module.exports = {
|
|
141
|
+
moveRequirementDown,
|
|
142
|
+
moveRequirementUp,
|
|
143
|
+
promoteRequirement,
|
|
144
|
+
demoteRequirement,
|
|
145
|
+
moveRequirementToRecycled
|
|
146
|
+
};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requirement Organization Module
|
|
3
|
+
*
|
|
4
|
+
* Handles requirement reordering, promotion, demotion, and organizational actions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const chalk = require('chalk');
|
|
8
|
+
const inquirer = require('inquirer');
|
|
9
|
+
const fs = require('fs-extra');
|
|
10
|
+
const { getRequirementsPath } = require('vibecodingmachine-core');
|
|
11
|
+
const { getSectionTitle, getRequirementList } = require('./requirement-helpers');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Move requirement down in list
|
|
15
|
+
*/
|
|
16
|
+
async function moveRequirementDown(req, sectionKey, tree) {
|
|
17
|
+
const reqList = getRequirementList(tree, sectionKey);
|
|
18
|
+
const sectionTitle = getSectionTitle(sectionKey);
|
|
19
|
+
const reqIndex = reqList.findIndex(r => r.title === req.title);
|
|
20
|
+
|
|
21
|
+
if (reqIndex === -1 || reqIndex === reqList.length - 1) return;
|
|
22
|
+
|
|
23
|
+
const reqPath = await getRequirementsPath();
|
|
24
|
+
|
|
25
|
+
// Swap in the array
|
|
26
|
+
[reqList[reqIndex], reqList[reqIndex + 1]] = [reqList[reqIndex + 1], reqList[reqIndex]];
|
|
27
|
+
await saveRequirementsOrder(reqPath, sectionTitle, reqList);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Move requirement up in list
|
|
32
|
+
*/
|
|
33
|
+
async function moveRequirementUp(req, sectionKey, tree) {
|
|
34
|
+
const reqList = getRequirementList(tree, sectionKey);
|
|
35
|
+
const sectionTitle = getSectionTitle(sectionKey);
|
|
36
|
+
const reqIndex = reqList.findIndex(r => r.title === req.title);
|
|
37
|
+
|
|
38
|
+
if (reqIndex === -1 || reqIndex === 0) return;
|
|
39
|
+
|
|
40
|
+
const reqPath = await getRequirementsPath();
|
|
41
|
+
|
|
42
|
+
// Swap in the array
|
|
43
|
+
[reqList[reqIndex], reqList[reqIndex - 1]] = [reqList[reqIndex - 1], reqList[reqIndex]];
|
|
44
|
+
await saveRequirementsOrder(reqPath, sectionTitle, reqList);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Promote requirement to next list (TODO -> TO VERIFY -> VERIFIED)
|
|
49
|
+
*/
|
|
50
|
+
async function promoteRequirement(req, sectionKey, tree, loadSection, loadVerified) {
|
|
51
|
+
const { promoteTodoToVerify, promoteToVerified } = require('vibecodingmachine-core');
|
|
52
|
+
const reqPath = await getRequirementsPath();
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
if (sectionKey === 'todo') {
|
|
56
|
+
await promoteTodoToVerify(req.title);
|
|
57
|
+
// Reload sections
|
|
58
|
+
tree.todoReqs = await loadSection('todo', 'ā³ Requirements not yet completed');
|
|
59
|
+
tree.verifyReqs = await loadSection('verify', 'ā
Verified by AI screenshot');
|
|
60
|
+
} else if (sectionKey === 'verify') {
|
|
61
|
+
await promoteToVerified(req.title);
|
|
62
|
+
// Reload sections
|
|
63
|
+
tree.verifyReqs = await loadSection('verify', 'ā
Verified by AI screenshot');
|
|
64
|
+
tree.verifiedReqs = await loadVerified();
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {
|
|
67
|
+
console.log(chalk.red('Error promoting requirement:'), error.message);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Demote requirement to previous list (VERIFIED -> TODO, TO VERIFY -> TODO)
|
|
73
|
+
*/
|
|
74
|
+
async function demoteRequirement(reqTitle, sectionKey, tree, loadSection, loadVerified) {
|
|
75
|
+
const { demoteVerifyToTodo, demoteFromVerifiedToTodo } = require('vibecodingmachine-core');
|
|
76
|
+
const reqPath = await getRequirementsPath();
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
if (sectionKey === 'verify') {
|
|
80
|
+
await demoteVerifyToTodo(reqTitle);
|
|
81
|
+
// Reload sections
|
|
82
|
+
tree.todoReqs = await loadSection('todo', 'ā³ Requirements not yet completed');
|
|
83
|
+
tree.verifyReqs = await loadSection('verify', 'ā
Verified by AI screenshot');
|
|
84
|
+
} else if (sectionKey === 'verified') {
|
|
85
|
+
await demoteFromVerifiedToTodo(reqTitle);
|
|
86
|
+
// Reload sections
|
|
87
|
+
tree.verifyReqs = await loadSection('verify', 'ā
Verified by AI screenshot');
|
|
88
|
+
tree.verifiedReqs = await loadVerified();
|
|
89
|
+
tree.todoReqs = await loadSection('todo', 'ā³ Requirements not yet completed');
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.log(chalk.red('Error demoting requirement:'), error.message);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Handle adding requirements
|
|
98
|
+
*/
|
|
99
|
+
async function handleAddRequirement(type) {
|
|
100
|
+
const reqCommands = require('../commands/requirements');
|
|
101
|
+
const packages = ['all', 'cli', 'core', 'electron-app', 'web', 'mobile'];
|
|
102
|
+
|
|
103
|
+
if (type === 'add-one') {
|
|
104
|
+
const { pkg } = await inquirer.prompt([{
|
|
105
|
+
type: 'list',
|
|
106
|
+
name: 'pkg',
|
|
107
|
+
message: 'Which package?',
|
|
108
|
+
choices: packages
|
|
109
|
+
}]);
|
|
110
|
+
|
|
111
|
+
await reqCommands.add({ package: pkg, interactive: true });
|
|
112
|
+
} else if (type === 'add-many') {
|
|
113
|
+
const { selectedPackages } = await inquirer.prompt([{
|
|
114
|
+
type: 'checkbox',
|
|
115
|
+
name: 'selectedPackages',
|
|
116
|
+
message: 'Which packages?',
|
|
117
|
+
choices: packages
|
|
118
|
+
}]);
|
|
119
|
+
|
|
120
|
+
for (const pkg of selectedPackages) {
|
|
121
|
+
await reqCommands.add({ package: pkg, interactive: true });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Save requirements order to file
|
|
128
|
+
*/
|
|
129
|
+
async function saveRequirementsOrder(reqPath, sectionTitle, reqList) {
|
|
130
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
131
|
+
const lines = content.split('\n');
|
|
132
|
+
|
|
133
|
+
// Find the section
|
|
134
|
+
let sectionStart = -1;
|
|
135
|
+
let sectionEnd = -1;
|
|
136
|
+
|
|
137
|
+
for (let i = 0; i < lines.length; i++) {
|
|
138
|
+
if (lines[i].startsWith(`## ${sectionTitle}`)) {
|
|
139
|
+
sectionStart = i;
|
|
140
|
+
// Find the end of this section
|
|
141
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
142
|
+
if (lines[j].startsWith('##')) {
|
|
143
|
+
sectionEnd = j;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (sectionEnd === -1) sectionEnd = lines.length;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (sectionStart !== -1) {
|
|
153
|
+
// Build new section content
|
|
154
|
+
const newSection = [lines[sectionStart], ''];
|
|
155
|
+
|
|
156
|
+
reqList.forEach(req => {
|
|
157
|
+
newSection.push(`### ${req.title}`);
|
|
158
|
+
if (req.details && req.details.length > 0) {
|
|
159
|
+
req.details.forEach(detail => newSection.push(detail));
|
|
160
|
+
}
|
|
161
|
+
newSection.push(''); // Empty line after requirement
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// Replace the section
|
|
165
|
+
lines.splice(sectionStart, sectionEnd - sectionStart, ...newSection);
|
|
166
|
+
|
|
167
|
+
// Save
|
|
168
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Move requirement to recycled section
|
|
174
|
+
*/
|
|
175
|
+
async function moveRequirementToRecycled(reqPath, requirementTitle, fromSection) {
|
|
176
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
177
|
+
const lines = content.split('\n');
|
|
178
|
+
|
|
179
|
+
// Find the requirement to move
|
|
180
|
+
let startIdx = -1;
|
|
181
|
+
let endIdx = -1;
|
|
182
|
+
|
|
183
|
+
for (let i = 0; i < lines.length; i++) {
|
|
184
|
+
if (lines[i].includes(`### ${requirementTitle}`)) {
|
|
185
|
+
startIdx = i;
|
|
186
|
+
// Find the end of this requirement
|
|
187
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
188
|
+
if (lines[j].startsWith('###') || lines[j].startsWith('##')) {
|
|
189
|
+
endIdx = j;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (endIdx === -1) endIdx = lines.length;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (startIdx !== -1) {
|
|
199
|
+
// Extract the requirement content
|
|
200
|
+
const reqContent = lines.slice(startIdx, endIdx);
|
|
201
|
+
|
|
202
|
+
// Remove from original section
|
|
203
|
+
lines.splice(startIdx, endIdx - startIdx);
|
|
204
|
+
|
|
205
|
+
// Find recycled section and insert there
|
|
206
|
+
let insertIdx = -1;
|
|
207
|
+
for (let i = 0; i < lines.length; i++) {
|
|
208
|
+
if (lines[i].startsWith('## ā»ļø Recycled')) {
|
|
209
|
+
insertIdx = i + 2; // After the section header and empty line
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (insertIdx === -1) {
|
|
215
|
+
// Create recycled section if it doesn't exist
|
|
216
|
+
lines.push('## ā»ļø Recycled', '');
|
|
217
|
+
insertIdx = lines.length;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
lines.splice(insertIdx, 0, ...reqContent);
|
|
221
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Permanently delete requirement
|
|
227
|
+
*/
|
|
228
|
+
async function permanentlyDeleteRequirement(req, tree) {
|
|
229
|
+
const reqList = getRequirementList(tree, 'recycled');
|
|
230
|
+
const reqIndex = reqList.findIndex(r => r.title === req.title);
|
|
231
|
+
|
|
232
|
+
if (reqIndex === -1) return;
|
|
233
|
+
|
|
234
|
+
const confirmed = await confirmAction(`Permanently delete "${req.title}"? This cannot be undone. (r/y/N)`);
|
|
235
|
+
if (!confirmed) {
|
|
236
|
+
console.log(chalk.gray('Cancelled.'));
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const reqPath = await getRequirementsPath();
|
|
241
|
+
const content = await fs.readFile(reqPath, 'utf8');
|
|
242
|
+
const lines = content.split('\n');
|
|
243
|
+
|
|
244
|
+
// Find and remove the requirement
|
|
245
|
+
for (let i = 0; i < lines.length; i++) {
|
|
246
|
+
if (lines[i].includes(`### ${req.title}`)) {
|
|
247
|
+
// Find the end of this requirement
|
|
248
|
+
let endIdx = i + 1;
|
|
249
|
+
while (endIdx < lines.length && !lines[endIdx].startsWith('###') && !lines[endIdx].startsWith('##')) {
|
|
250
|
+
endIdx++;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
lines.splice(i, endIdx - i);
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
await fs.writeFile(reqPath, lines.join('\n'));
|
|
259
|
+
reqList.splice(reqIndex, 1);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
module.exports = {
|
|
263
|
+
moveRequirementDown,
|
|
264
|
+
moveRequirementUp,
|
|
265
|
+
promoteRequirement,
|
|
266
|
+
demoteRequirement,
|
|
267
|
+
handleAddRequirement,
|
|
268
|
+
saveRequirementsOrder,
|
|
269
|
+
moveRequirementToRecycled,
|
|
270
|
+
permanentlyDeleteRequirement
|
|
271
|
+
};
|
package/src/utils/simple-trui.js
CHANGED
|
@@ -79,7 +79,7 @@ class SimpleTRUI {
|
|
|
79
79
|
|
|
80
80
|
async showAgentsMenu() {
|
|
81
81
|
console.log(chalk.blue('\nš¤ Agents Management\n'));
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
const { action } = await inquirer.prompt([
|
|
84
84
|
{
|
|
85
85
|
type: 'list',
|
|
@@ -87,6 +87,7 @@ class SimpleTRUI {
|
|
|
87
87
|
message: 'Choose action:',
|
|
88
88
|
choices: [
|
|
89
89
|
{ name: 'š List Agents', value: 'list' },
|
|
90
|
+
{ name: 'š Check Agents', value: 'check' },
|
|
90
91
|
{ name: 'ā¬
ļø Back', value: 'back' }
|
|
91
92
|
]
|
|
92
93
|
}
|
|
@@ -94,6 +95,79 @@ class SimpleTRUI {
|
|
|
94
95
|
|
|
95
96
|
if (action === 'list') {
|
|
96
97
|
this.showAgentsList();
|
|
98
|
+
} else if (action === 'check') {
|
|
99
|
+
await this.checkAgents();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async checkAgents() {
|
|
104
|
+
console.log(chalk.blue('\nš Checking Agents...\n'));
|
|
105
|
+
|
|
106
|
+
const { checkAllProviders } = require('./provider-checker');
|
|
107
|
+
const { getProviderDefinitions, getProviderPreferences } = require('./provider-registry');
|
|
108
|
+
const { getAutoConfig } = require('../../../electron-app/src/main/config');
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
const autoConfig = getAutoConfig();
|
|
112
|
+
const definitions = getProviderDefinitions();
|
|
113
|
+
const prefs = getProviderPreferences();
|
|
114
|
+
const enabledMap = (prefs && prefs.enabled) ? prefs.enabled : {};
|
|
115
|
+
|
|
116
|
+
// Only check enabled providers
|
|
117
|
+
const providerIds = definitions.filter(d => enabledMap[d.id] !== false).map(d => d.id);
|
|
118
|
+
const repoPath = process.cwd();
|
|
119
|
+
|
|
120
|
+
console.log(chalk.gray(`Checking ${providerIds.length} enabled agents...\n`));
|
|
121
|
+
|
|
122
|
+
const onProgress = (id, phase) => {
|
|
123
|
+
const def = definitions.find(d => d.id === id);
|
|
124
|
+
const name = def ? def.name : id;
|
|
125
|
+
if (phase === 'installing') {
|
|
126
|
+
console.log(chalk.yellow(`ā³ Installing ${name}...`));
|
|
127
|
+
} else if (phase === 'checking') {
|
|
128
|
+
console.log(chalk.gray(`š Checking ${name}...`));
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const results = await checkAllProviders(providerIds, autoConfig, repoPath, onProgress, null);
|
|
133
|
+
|
|
134
|
+
// Display results
|
|
135
|
+
console.log(chalk.blue('\nš Results:\n'));
|
|
136
|
+
|
|
137
|
+
let successful = 0;
|
|
138
|
+
let failed = 0;
|
|
139
|
+
|
|
140
|
+
for (const [id, result] of Object.entries(results)) {
|
|
141
|
+
const def = definitions.find(d => d.id === id);
|
|
142
|
+
const name = def ? def.name : id;
|
|
143
|
+
|
|
144
|
+
if (result.status === 'success') {
|
|
145
|
+
console.log(chalk.green(`ā ${name} - Reachable`));
|
|
146
|
+
successful++;
|
|
147
|
+
} else {
|
|
148
|
+
console.log(chalk.red(`ā ${name} - ${result.message || 'Failed'}`));
|
|
149
|
+
failed++;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(chalk.blue(`\n${successful}/${providerIds.length} agents reachable\n`));
|
|
154
|
+
|
|
155
|
+
await inquirer.prompt([
|
|
156
|
+
{
|
|
157
|
+
type: 'input',
|
|
158
|
+
name: 'continue',
|
|
159
|
+
message: 'Press Enter to continue...'
|
|
160
|
+
}
|
|
161
|
+
]);
|
|
162
|
+
} catch (error) {
|
|
163
|
+
console.log(chalk.red(`\nā Error checking agents: ${error.message}\n`));
|
|
164
|
+
await inquirer.prompt([
|
|
165
|
+
{
|
|
166
|
+
type: 'input',
|
|
167
|
+
name: 'continue',
|
|
168
|
+
message: 'Press Enter to continue...'
|
|
169
|
+
}
|
|
170
|
+
]);
|
|
97
171
|
}
|
|
98
172
|
}
|
|
99
173
|
|
|
@@ -91,7 +91,7 @@ class TRUINavigation {
|
|
|
91
91
|
const {
|
|
92
92
|
showRequirementsTree,
|
|
93
93
|
} = require('./trui-req-tree');
|
|
94
|
-
const { showProviderManagerMenu } = require('./
|
|
94
|
+
const { showProviderManagerMenu } = require('./provider-manager');
|
|
95
95
|
const { showSettings } = require('./trui-nav-settings');
|
|
96
96
|
const { addRequirementFlow } = require('./trui-req-actions');
|
|
97
97
|
const { addSpecificationFlow } = require('./trui-nav-specifications');
|
|
@@ -102,7 +102,18 @@ class TRUINavigation {
|
|
|
102
102
|
while (true) {
|
|
103
103
|
try {
|
|
104
104
|
const items = await buildMainMenuItems();
|
|
105
|
-
|
|
105
|
+
|
|
106
|
+
// Extra keys handler for ! and 1 commands
|
|
107
|
+
const extraKeys = (str, key, selectedIndex, context) => {
|
|
108
|
+
if (str === '!' || str === '1') {
|
|
109
|
+
// Run agents check command
|
|
110
|
+
context.resolveWith('agents-check');
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const result = await showQuickMenu(items, this._lastIndex, extraKeys);
|
|
106
117
|
this._lastIndex = result.selectedIndex;
|
|
107
118
|
const action = result.value;
|
|
108
119
|
|
|
@@ -177,6 +188,21 @@ class TRUINavigation {
|
|
|
177
188
|
continue;
|
|
178
189
|
}
|
|
179
190
|
|
|
191
|
+
if (action === 'agents-check') {
|
|
192
|
+
try {
|
|
193
|
+
const agentsCheckModule = require('../commands/agents-check');
|
|
194
|
+
console.clear();
|
|
195
|
+
console.log(chalk.bold.cyan('š Checking agents...\n'));
|
|
196
|
+
await agentsCheckModule();
|
|
197
|
+
await this._pause();
|
|
198
|
+
} catch (err) {
|
|
199
|
+
console.log(chalk.red('Agents check error: ' + err.message));
|
|
200
|
+
await this._pause();
|
|
201
|
+
}
|
|
202
|
+
console.clear();
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
|
|
180
206
|
if (action === 'settings') {
|
|
181
207
|
try { await showSettings(); } catch (err) { console.log(chalk.red('Settings error: ' + err.message)); await this._pause(); }
|
|
182
208
|
console.clear();
|