@nemus-cli/nemus 0.8.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +29 -5
  3. package/bin/workspace.js +12 -0
  4. package/dist/commands/analyze-deps.js +5 -12
  5. package/dist/commands/archive.js +13 -18
  6. package/dist/commands/branch/create.js +5 -12
  7. package/dist/commands/branch/switch.js +14 -25
  8. package/dist/commands/cache/manager.js +13 -24
  9. package/dist/commands/cleanup.js +14 -26
  10. package/dist/commands/config.js +82 -0
  11. package/dist/commands/configure-claude.js +4 -8
  12. package/dist/commands/configure.js +38 -32
  13. package/dist/commands/dashboard/session-picker.js +19 -26
  14. package/dist/commands/dashboard/workspace-picker.js +19 -26
  15. package/dist/commands/delete.js +15 -30
  16. package/dist/commands/ghq-status.js +7 -12
  17. package/dist/commands/go.js +18 -27
  18. package/dist/commands/history.js +6 -13
  19. package/dist/commands/list.js +20 -29
  20. package/dist/commands/remove-repo.js +21 -29
  21. package/dist/commands/save-context.js +5 -10
  22. package/dist/commands/sessions.js +19 -25
  23. package/dist/commands/suite/create.js +27 -53
  24. package/dist/commands/suite/delete.js +13 -25
  25. package/dist/commands/suite/export.js +20 -36
  26. package/dist/commands/suite/import.js +9 -20
  27. package/dist/commands/suite/use.js +9 -17
  28. package/dist/utils/config-schema.js +57 -0
  29. package/dist/utils/editor.js +35 -0
  30. package/dist/utils/prompt.js +26 -0
  31. package/dist/utils/prompts.js +86 -118
  32. package/package.json +3 -6
  33. package/src/commands/analyze-deps.ts +5 -9
  34. package/src/commands/archive.ts +5 -7
  35. package/src/commands/branch/create.ts +5 -9
  36. package/src/commands/branch/switch.ts +14 -22
  37. package/src/commands/cache/manager.ts +13 -21
  38. package/src/commands/cleanup.ts +14 -23
  39. package/src/commands/config.ts +52 -1
  40. package/src/commands/configure-claude.ts +4 -5
  41. package/src/commands/configure.ts +35 -29
  42. package/src/commands/dashboard/session-picker.ts +6 -11
  43. package/src/commands/dashboard/workspace-picker.ts +6 -11
  44. package/src/commands/delete.test.ts +36 -42
  45. package/src/commands/delete.ts +15 -27
  46. package/src/commands/ghq-status.ts +5 -7
  47. package/src/commands/go.ts +18 -25
  48. package/src/commands/history.ts +6 -10
  49. package/src/commands/list.test.ts +19 -26
  50. package/src/commands/list.ts +24 -31
  51. package/src/commands/remove-repo.ts +11 -17
  52. package/src/commands/save-context.ts +3 -5
  53. package/src/commands/sessions.ts +6 -10
  54. package/src/commands/suite/create.ts +28 -50
  55. package/src/commands/suite/delete.ts +14 -23
  56. package/src/commands/suite/export.ts +20 -33
  57. package/src/commands/suite/import.ts +9 -17
  58. package/src/commands/suite/use.ts +9 -14
  59. package/src/utils/config-schema.test.ts +49 -0
  60. package/src/utils/config-schema.ts +65 -0
  61. package/src/utils/editor.test.ts +37 -0
  62. package/src/utils/editor.ts +48 -0
  63. package/src/utils/prompt.ts +16 -0
  64. package/src/utils/prompts.test.ts +70 -41
  65. package/src/utils/prompts.ts +98 -128
@@ -32,15 +32,12 @@ 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.registerConfigureCommand = registerConfigureCommand;
40
37
  const child_process_1 = require("child_process");
41
38
  const fs = __importStar(require("fs"));
42
39
  const path = __importStar(require("path"));
43
- const inquirer_1 = __importDefault(require("inquirer"));
40
+ const prompt_1 = require("../utils/prompt");
44
41
  const config_1 = require("../utils/config");
45
42
  const cache_1 = require("../utils/cache");
46
43
  const logger_1 = require("../utils/logger");
@@ -72,40 +69,49 @@ async function handleConfigure() {
72
69
  console.log(` Claude workspace table: ${current.claudeWorkspaceStatusLine !== false ? (0, colors_1.colorize)('Enabled', 'green') : (0, colors_1.colorize)('Disabled', 'red')}`);
73
70
  console.log('');
74
71
  try {
75
- const answers = await inquirer_1.default.prompt([
76
- { type: 'input', name: 'workspacesDir', message: 'Workspaces directory:', default: current.workspacesDir, validate: (val) => val.trim().length > 0 || 'Directory path is required' },
77
- { type: 'input', name: 'githubOrg', message: 'GitHub organization:', default: current.githubOrg, validate: (val) => /^[a-zA-Z0-9_-]+$/.test(val.trim()) || 'Must be a valid GitHub org name' },
78
- { type: 'list', name: 'cloneProtocol', message: 'Clone protocol:', choices: [{ name: 'SSH (git@github.com:...)', value: 'ssh' }, { name: 'HTTPS (https://github.com/...)', value: 'https' }], default: current.cloneProtocol },
79
- { type: 'confirm', name: 'autoLaunchClaude', message: 'Auto-launch AI agent after workspace creation?', default: current.autoLaunchClaude },
80
- { type: 'confirm', name: 'generateClaudeContext', message: 'Generate context file in workspaces?', default: current.generateClaudeContext },
81
- { type: 'confirm', name: 'installMcp', message: 'Install MCP server (Claude Code only)?', default: current.installMcp },
82
- { type: 'list', name: 'aiAgent', message: 'AI Agent(s) to integrate with:', choices: [
83
- { name: 'Auto-detect (recommended)', value: 'auto' },
84
- { name: 'Claude Code only', value: 'claude' },
85
- { name: 'Pi only', value: 'pi' },
86
- { name: 'OpenCode only', value: 'opencode' },
87
- { name: 'All available', value: 'both' },
88
- ], default: current.aiAgent },
89
- // Only ask about primary agent when aiAgent is 'both' or 'auto'
90
- // (when specific agent chosen, primary is implicitly that agent)
91
- { type: 'list', name: 'primaryAgent', message: 'Primary agent (used for launching):', choices: [
72
+ // Sequential modular prompts. The classic `when:` conditions become `if`
73
+ // guards; a skipped question leaves its answer key undefined, exactly as the
74
+ // classic API did (downstream code already tolerates that via `??`).
75
+ const answers = {};
76
+ answers.workspacesDir = await (0, prompt_1.input)({ message: 'Workspaces directory:', default: current.workspacesDir, validate: (val) => val.trim().length > 0 || 'Directory path is required' });
77
+ answers.githubOrg = await (0, prompt_1.input)({ message: 'GitHub organization:', default: current.githubOrg, validate: (val) => /^[a-zA-Z0-9_-]+$/.test(val.trim()) || 'Must be a valid GitHub org name' });
78
+ answers.cloneProtocol = await (0, prompt_1.select)({ message: 'Clone protocol:', choices: [{ name: 'SSH (git@github.com:...)', value: 'ssh' }, { name: 'HTTPS (https://github.com/...)', value: 'https' }], default: current.cloneProtocol });
79
+ answers.autoLaunchClaude = await (0, prompt_1.confirm)({ message: 'Auto-launch AI agent after workspace creation?', default: current.autoLaunchClaude });
80
+ answers.generateClaudeContext = await (0, prompt_1.confirm)({ message: 'Generate context file in workspaces?', default: current.generateClaudeContext });
81
+ answers.installMcp = await (0, prompt_1.confirm)({ message: 'Install MCP server (Claude Code only)?', default: current.installMcp });
82
+ answers.aiAgent = await (0, prompt_1.select)({ message: 'AI Agent(s) to integrate with:', choices: [
83
+ { name: 'Auto-detect (recommended)', value: 'auto' },
84
+ { name: 'Claude Code only', value: 'claude' },
85
+ { name: 'Pi only', value: 'pi' },
86
+ { name: 'OpenCode only', value: 'opencode' },
87
+ { name: 'All available', value: 'both' },
88
+ ], default: current.aiAgent });
89
+ // Only ask about primary agent when aiAgent is 'both' or 'auto'
90
+ // (when specific agent chosen, primary is implicitly that agent)
91
+ if (answers.aiAgent === 'both' || answers.aiAgent === 'auto') {
92
+ answers.primaryAgent = await (0, prompt_1.select)({ message: 'Primary agent (used for launching):', choices: [
92
93
  { name: 'Auto-detect (first available)', value: 'auto' },
93
94
  { name: 'Claude Code', value: 'claude' },
94
95
  { name: 'Pi', value: 'pi' },
95
96
  { name: 'OpenCode', value: 'opencode' },
96
- ], default: current.primaryAgent, when: (ans) => ans.aiAgent === 'both' || ans.aiAgent === 'auto' },
97
- { type: 'confirm', name: 'piWorkspaceInputStatus',
97
+ ], default: current.primaryAgent });
98
+ }
99
+ if (answers.aiAgent === 'pi' || answers.aiAgent === 'both' || answers.aiAgent === 'auto') {
100
+ answers.piWorkspaceInputStatus = await (0, prompt_1.confirm)({
98
101
  message: 'Show workspace status widget in Pi input area (branch, PRs, CI)?',
99
- default: current.piWorkspaceInputStatus !== false,
100
- when: (ans) => ans.aiAgent === 'pi' || ans.aiAgent === 'both' || ans.aiAgent === 'auto' },
101
- { type: 'confirm', name: 'claudeWorkspaceStatusLine',
102
+ default: current.piWorkspaceInputStatus !== false
103
+ });
104
+ }
105
+ if (answers.aiAgent === 'claude' || answers.aiAgent === 'both' || answers.aiAgent === 'auto') {
106
+ answers.claudeWorkspaceStatusLine = await (0, prompt_1.confirm)({
102
107
  message: 'Add workspace repo table to Claude Code status line?',
103
- default: current.claudeWorkspaceStatusLine !== false,
104
- when: (ans) => ans.aiAgent === 'claude' || ans.aiAgent === 'both' || ans.aiAgent === 'auto' },
105
- { type: 'confirm', name: 'autoReportBugs',
106
- message: 'Auto-file a GitHub issue when a command crashes? (deduped, sanitized)',
107
- default: current.autoReportBugs === true },
108
- ]);
108
+ default: current.claudeWorkspaceStatusLine !== false
109
+ });
110
+ }
111
+ answers.autoReportBugs = await (0, prompt_1.confirm)({
112
+ message: 'Auto-file a GitHub issue when a command crashes? (deduped, sanitized)',
113
+ default: current.autoReportBugs === true
114
+ });
109
115
  // Validate and normalize config
110
116
  let primaryAgent = answers.primaryAgent || 'auto';
111
117
  // If aiAgent is specific, primaryAgent must match
@@ -38,18 +38,13 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  return result;
39
39
  };
40
40
  })();
41
- var __importDefault = (this && this.__importDefault) || function (mod) {
42
- return (mod && mod.__esModule) ? mod : { "default": mod };
43
- };
44
41
  Object.defineProperty(exports, "__esModule", { value: true });
45
42
  const claude_sessions_1 = require("../../utils/claude-sessions");
46
43
  const launcher_1 = require("./launcher");
47
44
  const agent_config_1 = require("../../utils/agent-config");
48
45
  const colors_1 = require("../../utils/colors");
49
- const inquirer_1 = __importDefault(require("inquirer"));
50
- const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
46
+ const prompt_1 = require("../../utils/prompt");
51
47
  const fuzzy = __importStar(require("fuzzy"));
52
- inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
53
48
  async function main() {
54
49
  try {
55
50
  const sessions = await (0, claude_sessions_1.getWorkspaceSessions)();
@@ -62,26 +57,24 @@ async function main() {
62
57
  displayName: session.workspaceName,
63
58
  timeLabel: session.lastActiveLabel,
64
59
  }));
65
- const { selected } = await inquirer_1.default.prompt([{
66
- type: 'autocomplete',
67
- name: 'selected',
68
- message: 'Select session to resume:',
69
- source: async (_answersSoFar, input) => {
70
- const searchInput = input || '';
71
- const source = items.map(item => ({
72
- name: `${item.displayName} ${(0, colors_1.colorize)(item.timeLabel, 'dim')}`,
73
- value: item,
74
- }));
75
- if (!searchInput)
76
- return source;
77
- const results = fuzzy.filter(searchInput, items, { extract: (item) => item.displayName });
78
- return results.map(result => ({
79
- name: `${result.original.displayName} ${(0, colors_1.colorize)(result.original.timeLabel, 'dim')}`,
80
- value: result.original,
81
- }));
82
- },
83
- pageSize: 15,
84
- }]);
60
+ const selected = await (0, prompt_1.search)({
61
+ message: 'Select session to resume:',
62
+ pageSize: 15,
63
+ source: async (term) => {
64
+ const searchInput = term || '';
65
+ const source = items.map(item => ({
66
+ name: `${item.displayName} ${(0, colors_1.colorize)(item.timeLabel, 'dim')}`,
67
+ value: item,
68
+ }));
69
+ if (!searchInput)
70
+ return source;
71
+ const results = fuzzy.filter(searchInput, items, { extract: (item) => item.displayName });
72
+ return results.map(result => ({
73
+ name: `${result.original.displayName} ${(0, colors_1.colorize)(result.original.timeLabel, 'dim')}`,
74
+ value: result.original,
75
+ }));
76
+ },
77
+ });
85
78
  const item = selected;
86
79
  const session = item.session;
87
80
  const rawSessionId = session.sessionId;
@@ -38,17 +38,12 @@ var __importStar = (this && this.__importStar) || (function () {
38
38
  return result;
39
39
  };
40
40
  })();
41
- var __importDefault = (this && this.__importDefault) || function (mod) {
42
- return (mod && mod.__esModule) ? mod : { "default": mod };
43
- };
44
41
  Object.defineProperty(exports, "__esModule", { value: true });
45
42
  const workspace_meta_1 = require("../../utils/workspace-meta");
46
43
  const launcher_1 = require("./launcher");
47
44
  const agent_config_1 = require("../../utils/agent-config");
48
- const inquirer_1 = __importDefault(require("inquirer"));
49
- const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
45
+ const prompt_1 = require("../../utils/prompt");
50
46
  const fuzzy = __importStar(require("fuzzy"));
51
- inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
52
47
  async function main() {
53
48
  try {
54
49
  const workspaces = await (0, workspace_meta_1.listWorkspaces)();
@@ -61,26 +56,24 @@ async function main() {
61
56
  path: ws.path,
62
57
  repoCount: ws.metadata?.repositories?.length ?? 0,
63
58
  }));
64
- const { selected } = await inquirer_1.default.prompt([{
65
- type: 'autocomplete',
66
- name: 'selected',
67
- message: 'Select workspace to launch agent in:',
68
- source: async (_answersSoFar, input) => {
69
- const searchInput = input || '';
70
- const source = items.map(item => ({
71
- name: `${item.name} (${item.repoCount} repos)`,
72
- value: item,
73
- }));
74
- if (!searchInput)
75
- return source;
76
- const results = fuzzy.filter(searchInput, items, { extract: (item) => item.name });
77
- return results.map(result => ({
78
- name: `${result.original.name} (${result.original.repoCount} repos)`,
79
- value: result.original,
80
- }));
81
- },
82
- pageSize: 15,
83
- }]);
59
+ const selected = await (0, prompt_1.search)({
60
+ message: 'Select workspace to launch agent in:',
61
+ pageSize: 15,
62
+ source: async (term) => {
63
+ const searchInput = term || '';
64
+ const source = items.map(item => ({
65
+ name: `${item.name} (${item.repoCount} repos)`,
66
+ value: item,
67
+ }));
68
+ if (!searchInput)
69
+ return source;
70
+ const results = fuzzy.filter(searchInput, items, { extract: (item) => item.name });
71
+ return results.map(result => ({
72
+ name: `${result.original.name} (${result.original.repoCount} repos)`,
73
+ value: result.original,
74
+ }));
75
+ },
76
+ });
84
77
  const workspace = selected;
85
78
  const agent = (0, agent_config_1.getPrimaryAgent)();
86
79
  (0, launcher_1.launchAgentPane)(workspace.path, agent.launchCommand);
@@ -32,9 +32,6 @@ 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.registerDeleteCommand = registerDeleteCommand;
40
37
  exports.main = main;
@@ -44,7 +41,7 @@ const workspace_meta_1 = require("../utils/workspace-meta");
44
41
  const prompts_1 = require("../utils/prompts");
45
42
  const logger_1 = require("../utils/logger");
46
43
  const colors_1 = require("../utils/colors");
47
- const inquirer_1 = __importDefault(require("inquirer"));
44
+ const prompt_1 = require("../utils/prompt");
48
45
  const command_helpers_1 = require("../utils/command-helpers");
49
46
  function registerDeleteCommand(parent) {
50
47
  parent
@@ -105,16 +102,12 @@ async function handleDelete(opts) {
105
102
  console.log('');
106
103
  (0, logger_1.logWarning)('This will permanently delete all cloned repositories in the selected workspaces!');
107
104
  if (!opts.yes) {
108
- const { confirmed } = await inquirer_1.default.prompt([
109
- {
110
- type: 'confirm',
111
- name: 'confirmed',
112
- message: targets.length === 1
113
- ? `Delete workspace ${targets[0].name}?`
114
- : `Delete these ${targets.length} workspaces?`,
115
- default: true,
116
- },
117
- ]);
105
+ const confirmed = await (0, prompt_1.confirm)({
106
+ message: targets.length === 1
107
+ ? `Delete workspace ${targets[0].name}?`
108
+ : `Delete these ${targets.length} workspaces?`,
109
+ default: true,
110
+ });
118
111
  if (!confirmed) {
119
112
  (0, logger_1.logInfo)('Deletion cancelled');
120
113
  process.exit(0);
@@ -171,14 +164,10 @@ async function handleDelete(opts) {
171
164
  const confirmMessage = resolved.length === 1
172
165
  ? `Delete workspace ${resolved[0].name}?`
173
166
  : `Delete these ${resolved.length} workspaces?`;
174
- const { confirmed } = await inquirer_1.default.prompt([
175
- {
176
- type: 'confirm',
177
- name: 'confirmed',
178
- message: confirmMessage,
179
- default: true,
180
- },
181
- ]);
167
+ const confirmed = await (0, prompt_1.confirm)({
168
+ message: confirmMessage,
169
+ default: true,
170
+ });
182
171
  if (confirmed) {
183
172
  for (const { name, path: workspacePath } of resolved) {
184
173
  try {
@@ -198,14 +187,10 @@ async function handleDelete(opts) {
198
187
  (0, logger_1.logInfo)('No more workspaces remaining');
199
188
  break;
200
189
  }
201
- const { deleteMore } = await inquirer_1.default.prompt([
202
- {
203
- type: 'confirm',
204
- name: 'deleteMore',
205
- message: 'Delete more workspaces?',
206
- default: false,
207
- },
208
- ]);
190
+ const deleteMore = await (0, prompt_1.confirm)({
191
+ message: 'Delete more workspaces?',
192
+ default: false,
193
+ });
209
194
  if (!deleteMore) {
210
195
  break;
211
196
  }
@@ -1,13 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.registerGhqStatusCommand = registerGhqStatusCommand;
7
4
  const ghq_integration_1 = require("../utils/ghq-integration");
8
5
  const logger_1 = require("../utils/logger");
9
6
  const colors_1 = require("../utils/colors");
10
- const inquirer_1 = __importDefault(require("inquirer"));
7
+ const prompt_1 = require("../utils/prompt");
11
8
  function registerGhqStatusCommand(parent) {
12
9
  parent
13
10
  .command('ghq-status')
@@ -30,10 +27,9 @@ async function handleGhqStatus() {
30
27
  console.log(` Managed repositories: ${(0, colors_1.colorize)(String(status.repoCount || 0), 'yellow')}`);
31
28
  console.log('');
32
29
  if (status.repoCount && status.repoCount > 0) {
33
- const { showRepos } = await inquirer_1.default.prompt([{
34
- type: 'confirm', name: 'showRepos',
35
- message: `View all ${status.repoCount} managed repositories?`, default: false,
36
- }]);
30
+ const showRepos = await (0, prompt_1.confirm)({
31
+ message: `View all ${status.repoCount} managed repositories?`, default: false,
32
+ });
37
33
  if (showRepos) {
38
34
  const repos = await (0, ghq_integration_1.ghqList)();
39
35
  console.log('');
@@ -47,10 +43,9 @@ async function handleGhqStatus() {
47
43
  (0, logger_1.logWarning)('ghq is not installed');
48
44
  console.log('');
49
45
  console.log('The workspace manager will use direct git clones.');
50
- const { showInfo } = await inquirer_1.default.prompt([{
51
- type: 'confirm', name: 'showInfo',
52
- message: 'Show ghq installation information?', default: true,
53
- }]);
46
+ const showInfo = await (0, prompt_1.confirm)({
47
+ message: 'Show ghq installation information?', default: true,
48
+ });
54
49
  if (showInfo) {
55
50
  (0, ghq_integration_1.displayGhqInfo)();
56
51
  }
@@ -32,9 +32,6 @@ 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.registerGoCommand = registerGoCommand;
40
37
  const path = __importStar(require("path"));
@@ -45,10 +42,8 @@ const workspace_meta_1 = require("../utils/workspace-meta");
45
42
  const claude_sessions_1 = require("../utils/claude-sessions");
46
43
  const logger_1 = require("../utils/logger");
47
44
  const colors_1 = require("../utils/colors");
48
- const inquirer_1 = __importDefault(require("inquirer"));
49
- const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
45
+ const prompt_1 = require("../utils/prompt");
50
46
  const fuzzy = __importStar(require("fuzzy"));
51
- inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
52
47
  const TEMP_FILE = path.join(os.homedir(), '.workspace-last-go');
53
48
  const RESUME_FLAG_FILE = path.join(os.homedir(), '.workspace-resume-session');
54
49
  function registerGoCommand(parent) {
@@ -100,28 +95,24 @@ async function handleGo(workspaceArg) {
100
95
  return 1;
101
96
  return 0;
102
97
  });
103
- const { workspaceName } = await inquirer_1.default.prompt([
104
- {
105
- type: 'autocomplete',
106
- name: 'workspaceName',
107
- message: 'Select workspace to navigate to:',
108
- source: async (_answersSoFar, input) => {
109
- const searchInput = input || '';
110
- const source = items.map(item => ({
111
- name: `${item.name} ${item.lastActiveLabel ? (0, colors_1.colorize)(item.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${item.repoCount} repos`, 'dim')}`,
112
- value: item.name,
113
- }));
114
- if (!searchInput)
115
- return source;
116
- const results = fuzzy.filter(searchInput, items, { extract: (item) => item.name });
117
- return results.map(result => ({
118
- name: `${result.original.name} ${result.original.lastActiveLabel ? (0, colors_1.colorize)(result.original.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${result.original.repoCount} repos`, 'dim')}`,
119
- value: result.original.name,
120
- }));
121
- },
122
- pageSize: 15,
98
+ const workspaceName = await (0, prompt_1.search)({
99
+ message: 'Select workspace to navigate to:',
100
+ pageSize: 15,
101
+ source: async (term) => {
102
+ const searchInput = term || '';
103
+ const source = items.map(item => ({
104
+ name: `${item.name} ${item.lastActiveLabel ? (0, colors_1.colorize)(item.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${item.repoCount} repos`, 'dim')}`,
105
+ value: item.name,
106
+ }));
107
+ if (!searchInput)
108
+ return source;
109
+ const results = fuzzy.filter(searchInput, items, { extract: (item) => item.name });
110
+ return results.map(result => ({
111
+ name: `${result.original.name} ${result.original.lastActiveLabel ? (0, colors_1.colorize)(result.original.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${result.original.repoCount} repos`, 'dim')}`,
112
+ value: result.original.name,
113
+ }));
123
114
  },
124
- ]);
115
+ });
125
116
  selectedWorkspace = workspaceName;
126
117
  }
127
118
  const workspacePath = path.join(config_1.WORKSPACES_DIR, selectedWorkspace);
@@ -1,13 +1,10 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.registerHistoryCommand = registerHistoryCommand;
7
4
  const history_1 = require("../utils/history");
8
5
  const logger_1 = require("../utils/logger");
9
6
  const colors_1 = require("../utils/colors");
10
- const inquirer_1 = __importDefault(require("inquirer"));
7
+ const prompt_1 = require("../utils/prompt");
11
8
  const command_helpers_1 = require("../utils/command-helpers");
12
9
  const displayHistoryTable = (records) => {
13
10
  if (records.length === 0) {
@@ -78,15 +75,11 @@ function registerHistoryCommand(parent) {
78
75
  (0, logger_1.logSuccess)('Operation history cleared');
79
76
  return;
80
77
  }
81
- const { confirm } = await inquirer_1.default.prompt([
82
- {
83
- type: 'confirm',
84
- name: 'confirm',
85
- message: 'Are you sure you want to clear operation history?',
86
- default: false,
87
- },
88
- ]);
89
- if (confirm) {
78
+ const confirmed = await (0, prompt_1.confirm)({
79
+ message: 'Are you sure you want to clear operation history?',
80
+ default: false,
81
+ });
82
+ if (confirmed) {
90
83
  await (0, history_1.clearHistory)();
91
84
  (0, logger_1.logSuccess)('Operation history cleared');
92
85
  }
@@ -32,9 +32,6 @@ 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.registerListCommand = registerListCommand;
40
37
  exports.main = main;
@@ -46,10 +43,8 @@ const claude_sessions_1 = require("../utils/claude-sessions");
46
43
  const logger_1 = require("../utils/logger");
47
44
  const output_1 = require("../utils/output");
48
45
  const colors_1 = require("../utils/colors");
49
- const inquirer_1 = __importDefault(require("inquirer"));
50
- const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
46
+ const prompt_1 = require("../utils/prompt");
51
47
  const fuzzy = __importStar(require("fuzzy"));
52
- inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
53
48
  const TEMP_FILE = path.join(os.homedir(), '.workspace-last-go');
54
49
  const RESUME_FLAG_FILE = path.join(os.homedir(), '.workspace-resume-session');
55
50
  function registerListCommand(parent) {
@@ -155,30 +150,26 @@ async function handleList(opts) {
155
150
  }
156
151
  console.log('');
157
152
  if (items.length > 0 && (process.stdout.isTTY || process.env.VITEST === 'true')) {
158
- const { selected } = await inquirer_1.default.prompt([
159
- {
160
- type: 'autocomplete',
161
- name: 'selected',
162
- message: 'Select workspace to open:',
163
- source: async (_answersSoFar, input) => {
164
- const searchInput = input || '';
165
- const source = items.map(item => ({
166
- name: `${item.name} ${item.lastActiveLabel ? (0, colors_1.colorize)(item.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${item.repoCount} repos`, 'dim')}`,
167
- value: item.name,
168
- }));
169
- if (!searchInput)
170
- return source;
171
- const results = fuzzy.filter(searchInput, items, {
172
- extract: (item) => item.name,
173
- });
174
- return results.map(result => ({
175
- name: `${result.original.name} ${result.original.lastActiveLabel ? (0, colors_1.colorize)(result.original.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${result.original.repoCount} repos`, 'dim')}`,
176
- value: result.original.name,
177
- }));
178
- },
179
- pageSize: 15,
153
+ const selected = await (0, prompt_1.search)({
154
+ message: 'Select workspace to open:',
155
+ pageSize: 15,
156
+ source: async (term) => {
157
+ const searchInput = term || '';
158
+ const source = items.map(item => ({
159
+ name: `${item.name} ${item.lastActiveLabel ? (0, colors_1.colorize)(item.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${item.repoCount} repos`, 'dim')}`,
160
+ value: item.name,
161
+ }));
162
+ if (!searchInput)
163
+ return source;
164
+ const results = fuzzy.filter(searchInput, items, {
165
+ extract: (item) => item.name,
166
+ });
167
+ return results.map(result => ({
168
+ name: `${result.original.name} ${result.original.lastActiveLabel ? (0, colors_1.colorize)(result.original.lastActiveLabel, 'dim') : (0, colors_1.colorize)('no session', 'dim')} ${(0, colors_1.colorize)(`${result.original.repoCount} repos`, 'dim')}`,
169
+ value: result.original.name,
170
+ }));
180
171
  },
181
- ]);
172
+ });
182
173
  const selectedItem = items.find(i => i.name === selected);
183
174
  if (selectedItem) {
184
175
  await fsPromises.writeFile(TEMP_FILE, selectedItem.wsPath, 'utf-8');
@@ -32,9 +32,6 @@ 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.registerRemoveRepoCommand = registerRemoveRepoCommand;
40
37
  const fs = __importStar(require("fs/promises"));
@@ -44,11 +41,9 @@ const workspace_meta_1 = require("../utils/workspace-meta");
44
41
  const claude_integration_1 = require("../utils/claude-integration");
45
42
  const logger_1 = require("../utils/logger");
46
43
  const colors_1 = require("../utils/colors");
47
- const inquirer_1 = __importDefault(require("inquirer"));
48
- const inquirer_autocomplete_prompt_1 = __importDefault(require("inquirer-autocomplete-prompt"));
44
+ const prompt_1 = require("../utils/prompt");
49
45
  const fuzzy = __importStar(require("fuzzy"));
50
46
  const command_helpers_1 = require("../utils/command-helpers");
51
- inquirer_1.default.registerPrompt('autocomplete', inquirer_autocomplete_prompt_1.default);
52
47
  function registerRemoveRepoCommand(parent) {
53
48
  parent
54
49
  .command('remove-repo')
@@ -99,10 +94,9 @@ async function handleRemoveRepo(opts) {
99
94
  (0, logger_1.logSuccess)(`Workspace "${workspaceName}" deleted.`);
100
95
  }
101
96
  else {
102
- const { deleteWorkspace } = await inquirer_1.default.prompt([{
103
- type: 'confirm', name: 'deleteWorkspace',
104
- message: `Delete the entire workspace folder "${workspaceName}"?`, default: false,
105
- }]);
97
+ const deleteWorkspace = await (0, prompt_1.confirm)({
98
+ message: `Delete the entire workspace folder "${workspaceName}"?`, default: false,
99
+ });
106
100
  if (deleteWorkspace) {
107
101
  await fs.rm(workspacePath, { recursive: true, force: true });
108
102
  (0, logger_1.logSuccess)(`Workspace "${workspaceName}" deleted.`);
@@ -135,20 +129,19 @@ async function handleRemoveRepo(opts) {
135
129
  break;
136
130
  }
137
131
  try {
138
- const { repoDir } = await inquirer_1.default.prompt([{
139
- type: 'autocomplete', name: 'repoDir',
140
- message: `Search and select repository (${(0, colors_1.colorize)(String(selectedDirs.length), 'cyan')} selected):`,
141
- source: async (_answersSoFar, input) => {
142
- const searchInput = input || '';
143
- const doneOption = { name: (0, colors_1.colorize)('done - Finish selection', 'green'), value: 'done' };
144
- if (!searchInput || searchInput.toLowerCase().startsWith('done')) {
145
- return [doneOption, ...available.map(e => ({ name: e.displayName, value: e.dirName }))];
146
- }
147
- const results = fuzzy.filter(searchInput, available, { extract: (e) => e.displayName });
148
- return [doneOption, ...results.map(result => ({ name: result.original.displayName, value: result.original.dirName }))];
149
- },
150
- pageSize: 16,
151
- }]);
132
+ const repoDir = await (0, prompt_1.search)({
133
+ message: `Search and select repository (${(0, colors_1.colorize)(String(selectedDirs.length), 'cyan')} selected):`,
134
+ pageSize: 16,
135
+ source: async (term) => {
136
+ const searchInput = term || '';
137
+ const doneOption = { name: (0, colors_1.colorize)('done - Finish selection', 'green'), value: 'done' };
138
+ if (!searchInput || searchInput.toLowerCase().startsWith('done')) {
139
+ return [doneOption, ...available.map(e => ({ name: e.displayName, value: e.dirName }))];
140
+ }
141
+ const results = fuzzy.filter(searchInput, available, { extract: (e) => e.displayName });
142
+ return [doneOption, ...results.map(result => ({ name: result.original.displayName, value: result.original.dirName }))];
143
+ },
144
+ });
152
145
  if (repoDir === 'done') {
153
146
  if (selectedDirs.length === 0) {
154
147
  console.log((0, colors_1.colorize)('\nYou must select at least one repository\n', 'yellow'));
@@ -170,11 +163,10 @@ async function handleRemoveRepo(opts) {
170
163
  selectedDirs.forEach(dir => console.log(` - ${dir}`));
171
164
  console.log('');
172
165
  if (!opts.yes) {
173
- const { confirm } = await inquirer_1.default.prompt([{
174
- type: 'confirm', name: 'confirm',
175
- message: `Remove ${selectedDirs.length} instance(s)? This will delete the directories.`, default: false,
176
- }]);
177
- if (!confirm) {
166
+ const confirmed = await (0, prompt_1.confirm)({
167
+ message: `Remove ${selectedDirs.length} instance(s)? This will delete the directories.`, default: false,
168
+ });
169
+ if (!confirmed) {
178
170
  (0, logger_1.logInfo)('Removal cancelled');
179
171
  process.exit(0);
180
172
  }