@nemus-cli/nemus 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +10 -5
- package/bin/workspace.js +12 -0
- package/dist/commands/analyze-deps.js +5 -12
- package/dist/commands/archive.js +13 -18
- package/dist/commands/branch/create.js +5 -12
- package/dist/commands/branch/switch.js +14 -25
- package/dist/commands/cache/manager.js +13 -24
- package/dist/commands/cleanup.js +14 -26
- package/dist/commands/configure-claude.js +4 -8
- package/dist/commands/configure.js +38 -32
- package/dist/commands/dashboard/session-picker.js +19 -26
- package/dist/commands/dashboard/workspace-picker.js +19 -26
- package/dist/commands/delete.js +15 -30
- package/dist/commands/ghq-status.js +7 -12
- package/dist/commands/go.js +18 -27
- package/dist/commands/history.js +6 -13
- package/dist/commands/list.js +20 -29
- package/dist/commands/remove-repo.js +21 -29
- package/dist/commands/save-context.js +5 -10
- package/dist/commands/sessions.js +19 -25
- package/dist/commands/suite/create.js +27 -53
- package/dist/commands/suite/delete.js +13 -25
- package/dist/commands/suite/export.js +20 -36
- package/dist/commands/suite/import.js +9 -20
- package/dist/commands/suite/use.js +9 -17
- package/dist/utils/prompt.js +26 -0
- package/dist/utils/prompts.js +86 -118
- package/package.json +3 -6
- package/src/commands/analyze-deps.ts +5 -9
- package/src/commands/archive.ts +5 -7
- package/src/commands/branch/create.ts +5 -9
- package/src/commands/branch/switch.ts +14 -22
- package/src/commands/cache/manager.ts +13 -21
- package/src/commands/cleanup.ts +14 -23
- package/src/commands/configure-claude.ts +4 -5
- package/src/commands/configure.ts +35 -29
- package/src/commands/dashboard/session-picker.ts +6 -11
- package/src/commands/dashboard/workspace-picker.ts +6 -11
- package/src/commands/delete.test.ts +36 -42
- package/src/commands/delete.ts +15 -27
- package/src/commands/ghq-status.ts +5 -7
- package/src/commands/go.ts +18 -25
- package/src/commands/history.ts +6 -10
- package/src/commands/list.test.ts +19 -26
- package/src/commands/list.ts +24 -31
- package/src/commands/remove-repo.ts +11 -17
- package/src/commands/save-context.ts +3 -5
- package/src/commands/sessions.ts +6 -10
- package/src/commands/suite/create.ts +28 -50
- package/src/commands/suite/delete.ts +14 -23
- package/src/commands/suite/export.ts +20 -33
- package/src/commands/suite/import.ts +9 -17
- package/src/commands/suite/use.ts +9 -14
- package/src/utils/prompt.ts +16 -0
- package/src/utils/prompts.test.ts +70 -41
- package/src/utils/prompts.ts +98 -128
package/dist/utils/prompts.js
CHANGED
|
@@ -32,41 +32,31 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.promptMultiWorkspaceSelection = exports.promptWorkspaceSelection = exports.confirmWorkspaceCreation = exports.promptWorkspaceName = exports.promptRepositorySelection = exports.promptInstanceSuffix = void 0;
|
|
40
|
-
const
|
|
41
|
-
const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
|
|
37
|
+
const prompt_1 = require("./prompt");
|
|
42
38
|
const fuzzy = __importStar(require("fuzzy"));
|
|
43
39
|
const validation_1 = require("./validation");
|
|
44
40
|
const colors_1 = require("./colors");
|
|
45
|
-
// Register autocomplete prompt type
|
|
46
|
-
inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
|
|
47
41
|
const promptInstanceSuffix = async (repoName, existingDirectoryNames) => {
|
|
48
|
-
const
|
|
49
|
-
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return `"${candidateName}" already exists. Choose a different suffix`;
|
|
65
|
-
}
|
|
66
|
-
return true;
|
|
67
|
-
},
|
|
42
|
+
const suffix = await (0, prompt_1.input)({
|
|
43
|
+
message: `"${repoName}" already exists. Enter a suffix for this instance:`,
|
|
44
|
+
validate: (input) => {
|
|
45
|
+
if (!input || input.trim().length === 0) {
|
|
46
|
+
return 'Suffix cannot be empty';
|
|
47
|
+
}
|
|
48
|
+
const trimmed = input.trim();
|
|
49
|
+
// Validate characters (alphanumeric, hyphens, underscores)
|
|
50
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(trimmed)) {
|
|
51
|
+
return 'Suffix can only contain letters, numbers, hyphens, and underscores';
|
|
52
|
+
}
|
|
53
|
+
const candidateName = `${repoName}-${trimmed}`;
|
|
54
|
+
if (existingDirectoryNames.includes(candidateName)) {
|
|
55
|
+
return `"${candidateName}" already exists. Choose a different suffix`;
|
|
56
|
+
}
|
|
57
|
+
return true;
|
|
68
58
|
},
|
|
69
|
-
|
|
59
|
+
});
|
|
70
60
|
return suffix.trim();
|
|
71
61
|
};
|
|
72
62
|
exports.promptInstanceSuffix = promptInstanceSuffix;
|
|
@@ -80,38 +70,34 @@ const promptRepositorySelection = async (repos, existingDirectoryNames = []) =>
|
|
|
80
70
|
console.log('Type "done" when finished selecting repositories.\n');
|
|
81
71
|
while (true) {
|
|
82
72
|
try {
|
|
83
|
-
const
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}));
|
|
110
|
-
return [doneOption, ...suggestions];
|
|
111
|
-
},
|
|
112
|
-
pageSize: 16,
|
|
73
|
+
const repoName = await (0, prompt_1.search)({
|
|
74
|
+
message: `Search and select repository (${(0, colors_1.colorize)(String(selectedEntries.length), 'cyan')} selected):`,
|
|
75
|
+
pageSize: 16,
|
|
76
|
+
source: async (term) => {
|
|
77
|
+
const searchInput = term || '';
|
|
78
|
+
// Always include done option
|
|
79
|
+
const doneOption = { name: (0, colors_1.colorize)('done - Finish selection', 'green'), value: 'done' };
|
|
80
|
+
// If no input or "done" typed, show done + top repos
|
|
81
|
+
if (!searchInput || searchInput.toLowerCase().startsWith('done')) {
|
|
82
|
+
return [
|
|
83
|
+
doneOption,
|
|
84
|
+
...repos.slice(0, 15).map(repo => ({
|
|
85
|
+
name: `${repo.name}${repo.description ? ` - ${(0, colors_1.colorize)(repo.description, 'gray')}` : ''}`,
|
|
86
|
+
value: repo.name,
|
|
87
|
+
}))
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
// Perform fuzzy search
|
|
91
|
+
const results = fuzzy.filter(searchInput, repos, {
|
|
92
|
+
extract: (repo) => `${repo.name} ${repo.description || ''}`,
|
|
93
|
+
});
|
|
94
|
+
const suggestions = results.slice(0, 15).map(result => ({
|
|
95
|
+
name: `${result.original.name}${result.original.description ? ` - ${(0, colors_1.colorize)(result.original.description, 'gray')}` : ''}`,
|
|
96
|
+
value: result.original.name,
|
|
97
|
+
}));
|
|
98
|
+
return [doneOption, ...suggestions];
|
|
113
99
|
},
|
|
114
|
-
|
|
100
|
+
});
|
|
115
101
|
if (repoName === 'done') {
|
|
116
102
|
if (selectedEntries.length === 0) {
|
|
117
103
|
console.log((0, colors_1.colorize)('\nYou must select at least one repository\n', 'yellow'));
|
|
@@ -153,22 +139,17 @@ const promptRepositorySelection = async (repos, existingDirectoryNames = []) =>
|
|
|
153
139
|
};
|
|
154
140
|
exports.promptRepositorySelection = promptRepositorySelection;
|
|
155
141
|
const promptWorkspaceName = async () => {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
return validationResult;
|
|
165
|
-
}
|
|
166
|
-
return true;
|
|
167
|
-
},
|
|
168
|
-
filter: (input) => (0, validation_1.sanitizeWorkspaceName)(input),
|
|
142
|
+
const raw = await (0, prompt_1.input)({
|
|
143
|
+
message: 'Enter workspace name:',
|
|
144
|
+
validate: (value) => {
|
|
145
|
+
const validationResult = (0, validation_1.validateWorkspaceName)((0, validation_1.sanitizeWorkspaceName)(value));
|
|
146
|
+
if (validationResult !== true) {
|
|
147
|
+
return validationResult;
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
169
150
|
},
|
|
170
|
-
|
|
171
|
-
return
|
|
151
|
+
});
|
|
152
|
+
return (0, validation_1.sanitizeWorkspaceName)(raw);
|
|
172
153
|
};
|
|
173
154
|
exports.promptWorkspaceName = promptWorkspaceName;
|
|
174
155
|
const confirmWorkspaceCreation = async (workspaceName, repoCount, workspacePath) => {
|
|
@@ -179,14 +160,10 @@ const confirmWorkspaceCreation = async (workspaceName, repoCount, workspacePath)
|
|
|
179
160
|
console.log(`Location: ${(0, colors_1.colorize)(workspacePath, 'gray')}`);
|
|
180
161
|
console.log(`Repositories: ${(0, colors_1.colorize)(String(repoCount), 'yellow')}`);
|
|
181
162
|
console.log('='.repeat(60) + '\n');
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
message: 'Create workspace with these settings?',
|
|
187
|
-
default: true,
|
|
188
|
-
},
|
|
189
|
-
]);
|
|
163
|
+
const confirmed = await (0, prompt_1.confirm)({
|
|
164
|
+
message: 'Create workspace with these settings?',
|
|
165
|
+
default: true,
|
|
166
|
+
});
|
|
190
167
|
return confirmed;
|
|
191
168
|
};
|
|
192
169
|
exports.confirmWorkspaceCreation = confirmWorkspaceCreation;
|
|
@@ -199,17 +176,12 @@ const promptWorkspaceSelection = async (workspaces) => {
|
|
|
199
176
|
? `${ws.name} (${ws.metadata.repositories.length} repos)`
|
|
200
177
|
: ws.name,
|
|
201
178
|
value: ws.name,
|
|
202
|
-
short: ws.name,
|
|
203
179
|
}));
|
|
204
|
-
const
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
choices,
|
|
210
|
-
pageSize: 15,
|
|
211
|
-
},
|
|
212
|
-
]);
|
|
180
|
+
const workspaceName = await (0, prompt_1.select)({
|
|
181
|
+
message: 'Select workspace to update:',
|
|
182
|
+
choices,
|
|
183
|
+
pageSize: 15,
|
|
184
|
+
});
|
|
213
185
|
return workspaceName;
|
|
214
186
|
};
|
|
215
187
|
exports.promptWorkspaceSelection = promptWorkspaceSelection;
|
|
@@ -226,33 +198,29 @@ const promptMultiWorkspaceSelection = async (workspaces) => {
|
|
|
226
198
|
console.log((0, colors_1.colorize)('All workspaces selected.', 'yellow'));
|
|
227
199
|
break;
|
|
228
200
|
}
|
|
229
|
-
const
|
|
230
|
-
{
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}));
|
|
251
|
-
return [doneOption, ...suggestions];
|
|
252
|
-
},
|
|
253
|
-
pageSize: 16,
|
|
201
|
+
const workspaceName = await (0, prompt_1.search)({
|
|
202
|
+
message: `Search and select workspace (${(0, colors_1.colorize)(String(selectedNames.length), 'cyan')} selected):`,
|
|
203
|
+
pageSize: 16,
|
|
204
|
+
source: async (term) => {
|
|
205
|
+
const searchInput = term || '';
|
|
206
|
+
const doneOption = { name: (0, colors_1.colorize)('done - Finish selection', 'green'), value: 'done' };
|
|
207
|
+
if (!searchInput || searchInput.toLowerCase().startsWith('done')) {
|
|
208
|
+
return [
|
|
209
|
+
doneOption,
|
|
210
|
+
...availableNames.slice(0, 15).map(name => ({
|
|
211
|
+
name,
|
|
212
|
+
value: name,
|
|
213
|
+
}))
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
const results = fuzzy.filter(searchInput, availableNames);
|
|
217
|
+
const suggestions = results.slice(0, 15).map(result => ({
|
|
218
|
+
name: result.original,
|
|
219
|
+
value: result.original,
|
|
220
|
+
}));
|
|
221
|
+
return [doneOption, ...suggestions];
|
|
254
222
|
},
|
|
255
|
-
|
|
223
|
+
});
|
|
256
224
|
if (workspaceName === 'done') {
|
|
257
225
|
if (selectedNames.length === 0) {
|
|
258
226
|
console.log((0, colors_1.colorize)('\nYou must select at least one workspace\n', 'yellow'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nemus-cli/nemus",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"workspaces": [
|
|
5
5
|
"packages/*"
|
|
6
6
|
],
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/me-public/nemus#readme",
|
|
31
31
|
"engines": {
|
|
32
|
-
"node": ">=22.
|
|
32
|
+
"node": ">=22.13.0",
|
|
33
33
|
"npm": ">=9.0.0"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
@@ -67,21 +67,18 @@
|
|
|
67
67
|
"postinstall": "node scripts/postinstall.js"
|
|
68
68
|
},
|
|
69
69
|
"dependencies": {
|
|
70
|
+
"@inquirer/prompts": "^8.7.0",
|
|
70
71
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
71
72
|
"cli-progress": "^3.12.0",
|
|
72
73
|
"commander": "^15.0.0",
|
|
73
74
|
"fuzzy": "^0.1.3",
|
|
74
75
|
"ink": "^7.1.1",
|
|
75
|
-
"inquirer": "^8.0.0",
|
|
76
|
-
"inquirer-autocomplete-prompt": "^2.0.0",
|
|
77
76
|
"markdown-table": "^3.0.3",
|
|
78
77
|
"react": "^19.2.8",
|
|
79
78
|
"zod": "^4.3.6"
|
|
80
79
|
},
|
|
81
80
|
"devDependencies": {
|
|
82
81
|
"@types/cli-progress": "^3.11.0",
|
|
83
|
-
"@types/inquirer": "^9.0.3",
|
|
84
|
-
"@types/inquirer-autocomplete-prompt": "^2.0.0",
|
|
85
82
|
"@types/node": "^26.3.0",
|
|
86
83
|
"@types/react": "^19.2.2",
|
|
87
84
|
"ts-node": "^10.9.1",
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { logError, logInfo, logStep, logSuccess } from '../utils/logger';
|
|
12
12
|
import { outputJson, outputJsonError } from '../utils/output';
|
|
13
13
|
import { colorize } from '../utils/colors';
|
|
14
|
-
import
|
|
14
|
+
import { confirm } from '../utils/prompt';
|
|
15
15
|
import { resolveWorkspace } from '../utils/command-helpers';
|
|
16
16
|
|
|
17
17
|
const displayDependencyAnalysis = (analyses: Map<string, any>) => {
|
|
@@ -122,14 +122,10 @@ async function handleAnalyzeDeps(workspaceArg?: string, opts: { json?: boolean }
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
if (process.stdout.isTTY) {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
message: 'Save dependency analysis to workspace metadata?',
|
|
130
|
-
default: true,
|
|
131
|
-
},
|
|
132
|
-
]);
|
|
125
|
+
const saveToMetadata = await confirm({
|
|
126
|
+
message: 'Save dependency analysis to workspace metadata?',
|
|
127
|
+
default: true,
|
|
128
|
+
});
|
|
133
129
|
|
|
134
130
|
if (saveToMetadata) {
|
|
135
131
|
const updatedMetadata = updateWorkspaceMetadata(metadata, analyses);
|
package/src/commands/archive.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { listWorkspaces, archiveWorkspace, unarchiveWorkspace } from '../utils/w
|
|
|
3
3
|
import { promptMultiWorkspaceSelection } from '../utils/prompts';
|
|
4
4
|
import { logInfo, logSuccess, logError } from '../utils/logger';
|
|
5
5
|
import { colorize } from '../utils/colors';
|
|
6
|
-
import
|
|
6
|
+
import { confirm } from '../utils/prompt';
|
|
7
7
|
import { getGlobalOpts, parseList } from '../utils/command-helpers';
|
|
8
8
|
|
|
9
9
|
export function registerArchiveCommand(parent: Command) {
|
|
@@ -50,13 +50,12 @@ async function handleArchive(opts: {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
if (!opts.yes) {
|
|
53
|
-
const
|
|
54
|
-
type: 'confirm', name: 'confirmed',
|
|
53
|
+
const confirmed = await confirm({
|
|
55
54
|
message: selectedNames.length === 1
|
|
56
55
|
? `Unarchive workspace ${selectedNames[0]}?`
|
|
57
56
|
: `Unarchive these ${selectedNames.length} workspaces?`,
|
|
58
57
|
default: true,
|
|
59
|
-
}
|
|
58
|
+
});
|
|
60
59
|
if (!confirmed) return;
|
|
61
60
|
}
|
|
62
61
|
|
|
@@ -86,13 +85,12 @@ async function handleArchive(opts: {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
if (!opts.yes) {
|
|
89
|
-
const
|
|
90
|
-
type: 'confirm', name: 'confirmed',
|
|
88
|
+
const confirmed = await confirm({
|
|
91
89
|
message: selectedNames.length === 1
|
|
92
90
|
? `Archive workspace ${selectedNames[0]}? It will be auto-deleted in 30 days.`
|
|
93
91
|
: `Archive these ${selectedNames.length} workspaces? They will be auto-deleted in 30 days.`,
|
|
94
92
|
default: true,
|
|
95
|
-
}
|
|
93
|
+
});
|
|
96
94
|
if (!confirmed) return;
|
|
97
95
|
}
|
|
98
96
|
|
|
@@ -6,7 +6,7 @@ import { createBranch } from '../../utils/branch-operations';
|
|
|
6
6
|
import { logError, logInfo, logStep, logSuccess, logWarning } from '../../utils/logger';
|
|
7
7
|
import { colorize } from '../../utils/colors';
|
|
8
8
|
import { WORKSPACES_DIR } from '../../utils/config';
|
|
9
|
-
import
|
|
9
|
+
import { input } from '../../utils/prompt';
|
|
10
10
|
|
|
11
11
|
export interface BranchCreateOpts {
|
|
12
12
|
workspace?: string;
|
|
@@ -40,14 +40,10 @@ export const main = async (opts?: BranchCreateOpts) => {
|
|
|
40
40
|
logError('Usage: w branch create --workspace <name> --branch <branch>');
|
|
41
41
|
process.exit(1);
|
|
42
42
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
message: 'New branch name:',
|
|
48
|
-
validate: (input: string) => input.trim() ? true : 'Branch name cannot be empty',
|
|
49
|
-
},
|
|
50
|
-
]);
|
|
43
|
+
const branch = await input({
|
|
44
|
+
message: 'New branch name:',
|
|
45
|
+
validate: (input: string) => input.trim() ? true : 'Branch name cannot be empty',
|
|
46
|
+
});
|
|
51
47
|
branchName = branch;
|
|
52
48
|
}
|
|
53
49
|
|
|
@@ -7,7 +7,7 @@ import { promptWorkspaceSelection } from '../../utils/prompts';
|
|
|
7
7
|
import { logInfo, logSuccess, logError, logWarning } from '../../utils/logger';
|
|
8
8
|
import { colorize } from '../../utils/colors';
|
|
9
9
|
import { switchBranch, BranchSwitchResult } from '../../utils/branch-operations';
|
|
10
|
-
import
|
|
10
|
+
import { confirm, input } from '../../utils/prompt';
|
|
11
11
|
|
|
12
12
|
export interface BranchSwitchOpts {
|
|
13
13
|
workspace?: string;
|
|
@@ -61,20 +61,16 @@ export async function main(opts?: BranchSwitchOpts) {
|
|
|
61
61
|
logError('Usage: w branch switch --workspace <name> --branch <branch>');
|
|
62
62
|
process.exit(1);
|
|
63
63
|
}
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return 'Branch name cannot be empty';
|
|
73
|
-
}
|
|
74
|
-
return true;
|
|
75
|
-
},
|
|
64
|
+
const branch = await input({
|
|
65
|
+
message: 'Target branch name:',
|
|
66
|
+
default: 'main',
|
|
67
|
+
validate: (input: string) => {
|
|
68
|
+
if (!input || input.trim().length === 0) {
|
|
69
|
+
return 'Branch name cannot be empty';
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
76
72
|
},
|
|
77
|
-
|
|
73
|
+
});
|
|
78
74
|
targetBranch = branch;
|
|
79
75
|
}
|
|
80
76
|
|
|
@@ -82,14 +78,10 @@ export async function main(opts?: BranchSwitchOpts) {
|
|
|
82
78
|
|
|
83
79
|
// Skip confirmation when --yes flag is provided
|
|
84
80
|
if (!yes && process.stdout.isTTY) {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
message: 'Proceed with bulk branch switch?',
|
|
90
|
-
default: true,
|
|
91
|
-
},
|
|
92
|
-
]);
|
|
81
|
+
const confirmed = await confirm({
|
|
82
|
+
message: 'Proceed with bulk branch switch?',
|
|
83
|
+
default: true,
|
|
84
|
+
});
|
|
93
85
|
|
|
94
86
|
if (!confirmed) {
|
|
95
87
|
logInfo('Branch switch cancelled');
|
|
@@ -4,7 +4,7 @@ import { clearCache, getCacheStats } from '../../utils/cache';
|
|
|
4
4
|
import { fetchOrgRepos, verifyGhAuth, displayAuthInstructions } from '../../utils/github';
|
|
5
5
|
import { logInfo, logSuccess, logError } from '../../utils/logger';
|
|
6
6
|
import { colorize } from '../../utils/colors';
|
|
7
|
-
import
|
|
7
|
+
import { confirm, select } from '../../utils/prompt';
|
|
8
8
|
import * as fuzzy from 'fuzzy';
|
|
9
9
|
|
|
10
10
|
export async function cacheInfo() {
|
|
@@ -123,32 +123,24 @@ export async function main() {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// Interactive mode (original behavior)
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
name: '
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
{ name: 'Clear cache', value: 'clear' },
|
|
135
|
-
],
|
|
136
|
-
},
|
|
137
|
-
]);
|
|
126
|
+
const selectedAction = await select({
|
|
127
|
+
message: 'Select action:',
|
|
128
|
+
choices: [
|
|
129
|
+
{ name: 'View cache info', value: 'info' },
|
|
130
|
+
{ name: 'Refresh cache (force fetch from GitHub)', value: 'refresh' },
|
|
131
|
+
{ name: 'Clear cache', value: 'clear' },
|
|
132
|
+
],
|
|
133
|
+
});
|
|
138
134
|
|
|
139
135
|
if (selectedAction === 'info') {
|
|
140
136
|
await cacheInfo();
|
|
141
137
|
} else if (selectedAction === 'refresh') {
|
|
142
138
|
await cacheRefresh();
|
|
143
139
|
} else if (selectedAction === 'clear') {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
message: 'Are you sure you want to clear the cache?',
|
|
149
|
-
default: false,
|
|
150
|
-
},
|
|
151
|
-
]);
|
|
140
|
+
const confirmed = await confirm({
|
|
141
|
+
message: 'Are you sure you want to clear the cache?',
|
|
142
|
+
default: false,
|
|
143
|
+
});
|
|
152
144
|
|
|
153
145
|
if (confirmed) {
|
|
154
146
|
await cacheClear();
|
package/src/commands/cleanup.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { loadMetadata } from '../utils/workspace-meta';
|
|
|
5
5
|
import { removeNodeModules, removeBuildArtifacts, gitClean } from '../utils/cleanup-operations';
|
|
6
6
|
import { logError, logInfo, logStep, logSuccess } from '../utils/logger';
|
|
7
7
|
import { colorize } from '../utils/colors';
|
|
8
|
-
import
|
|
8
|
+
import { checkbox, confirm } from '../utils/prompt';
|
|
9
9
|
import { getGlobalOpts, resolveWorkspace } from '../utils/command-helpers';
|
|
10
10
|
|
|
11
11
|
export function registerCleanupCommand(parent: Command) {
|
|
@@ -54,19 +54,14 @@ async function handleCleanup(workspaceArg: string | undefined, opts: {
|
|
|
54
54
|
if (build) operations.push('build');
|
|
55
55
|
if (gitCleanFlag) operations.push('git_clean');
|
|
56
56
|
} else {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
name: '
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{ name: 'Git clean (remove untracked files)', value: 'git_clean' },
|
|
66
|
-
],
|
|
67
|
-
},
|
|
68
|
-
]);
|
|
69
|
-
operations = result.operations;
|
|
57
|
+
operations = await checkbox({
|
|
58
|
+
message: 'Select cleanup operations:',
|
|
59
|
+
choices: [
|
|
60
|
+
{ name: 'Remove node_modules (all repos)', value: 'node_modules' },
|
|
61
|
+
{ name: 'Remove build artifacts (dist, build, .next, coverage)', value: 'build' },
|
|
62
|
+
{ name: 'Git clean (remove untracked files)', value: 'git_clean' },
|
|
63
|
+
],
|
|
64
|
+
});
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
if (operations.length === 0) {
|
|
@@ -75,16 +70,12 @@ async function handleCleanup(workspaceArg: string | undefined, opts: {
|
|
|
75
70
|
}
|
|
76
71
|
|
|
77
72
|
if (!opts.yes) {
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
message: `Proceed with cleanup? This cannot be undone.`,
|
|
83
|
-
default: false,
|
|
84
|
-
},
|
|
85
|
-
]);
|
|
73
|
+
const confirmed = await confirm({
|
|
74
|
+
message: `Proceed with cleanup? This cannot be undone.`,
|
|
75
|
+
default: false,
|
|
76
|
+
});
|
|
86
77
|
|
|
87
|
-
if (!
|
|
78
|
+
if (!confirmed) {
|
|
88
79
|
logInfo('Cleanup cancelled');
|
|
89
80
|
return;
|
|
90
81
|
}
|
|
@@ -2,7 +2,7 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { loadClaudeConfig, saveClaudeConfig } from '../utils/claude-integration';
|
|
3
3
|
import { logSuccess, logError } from '../utils/logger';
|
|
4
4
|
import { colorize } from '../utils/colors';
|
|
5
|
-
import
|
|
5
|
+
import { confirm } from '../utils/prompt';
|
|
6
6
|
|
|
7
7
|
export function registerConfigureClaudeCommand(parent: Command) {
|
|
8
8
|
parent
|
|
@@ -27,10 +27,9 @@ async function handleConfigureClaude() {
|
|
|
27
27
|
console.log(` Generate context: ${currentConfig.generateContext ? colorize('Enabled', 'green') : colorize('Disabled', 'red')}`);
|
|
28
28
|
console.log('');
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
]);
|
|
30
|
+
const autoLaunch = await confirm({ message: 'Auto-launch Claude Code after workspace creation?', default: currentConfig.autoLaunch });
|
|
31
|
+
const generateContext = await confirm({ message: 'Generate CLAUDE.md context file in workspaces?', default: currentConfig.generateContext });
|
|
32
|
+
const answers = { autoLaunch, generateContext };
|
|
34
33
|
|
|
35
34
|
await saveClaudeConfig(answers);
|
|
36
35
|
|