workon 2.1.2 → 3.0.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/README.md +19 -4
- package/bin/workon +1 -11
- package/dist/cli.js +2227 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.cjs +1216 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +280 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +1173 -0
- package/dist/index.js.map +1 -0
- package/package.json +68 -21
- package/.claude/settings.local.json +0 -11
- package/.cursorindexingignore +0 -3
- package/.history/.gitignore_20250806202718 +0 -30
- package/.history/.gitignore_20250806231444 +0 -32
- package/.history/.gitignore_20250806231450 +0 -32
- package/.history/lib/tmux_20250806233103.js +0 -109
- package/.history/lib/tmux_20250806233219.js +0 -109
- package/.history/lib/tmux_20250806233223.js +0 -109
- package/.history/lib/tmux_20250806233230.js +0 -109
- package/.history/lib/tmux_20250806233231.js +0 -109
- package/.history/lib/tmux_20250807120751.js +0 -190
- package/.history/lib/tmux_20250807120757.js +0 -190
- package/.history/lib/tmux_20250807120802.js +0 -190
- package/.history/lib/tmux_20250807120808.js +0 -190
- package/.history/package_20250807114243.json +0 -43
- package/.history/package_20250807114257.json +0 -43
- package/.history/package_20250807114404.json +0 -43
- package/.history/package_20250807114409.json +0 -43
- package/.history/package_20250807114510.json +0 -43
- package/.history/package_20250807114637.json +0 -43
- package/.vscode/launch.json +0 -20
- package/.vscode/terminals.json +0 -11
- package/CHANGELOG.md +0 -103
- package/CLAUDE.md +0 -100
- package/cli/base.js +0 -16
- package/cli/config/index.js +0 -19
- package/cli/config/list.js +0 -26
- package/cli/config/set.js +0 -19
- package/cli/config/unset.js +0 -26
- package/cli/index.js +0 -184
- package/cli/interactive.js +0 -290
- package/cli/manage.js +0 -413
- package/cli/open.js +0 -414
- package/commands/base.js +0 -105
- package/commands/core/cwd/index.js +0 -86
- package/commands/core/ide/index.js +0 -84
- package/commands/core/web/index.js +0 -109
- package/commands/extensions/claude/index.js +0 -211
- package/commands/extensions/docker/index.js +0 -167
- package/commands/extensions/npm/index.js +0 -208
- package/commands/registry.js +0 -196
- package/demo-colon-syntax.js +0 -57
- package/docs/adr/001-command-centric-architecture.md +0 -304
- package/docs/adr/002-positional-command-arguments.md +0 -402
- package/docs/ideas.md +0 -93
- package/lib/config.js +0 -51
- package/lib/environment/base.js +0 -12
- package/lib/environment/index.js +0 -108
- package/lib/environment/project.js +0 -26
- package/lib/project.js +0 -68
- package/lib/tmux.js +0 -221
- package/lib/validation.js +0 -120
- package/test-architecture.js +0 -145
- package/test-colon-syntax.js +0 -85
- package/test-registry.js +0 -57
package/cli/manage.js
DELETED
|
@@ -1,413 +0,0 @@
|
|
|
1
|
-
const { command } = require('./base');
|
|
2
|
-
const inquirer = require('inquirer');
|
|
3
|
-
const File = require('phylo');
|
|
4
|
-
const ProjectValidator = require('../lib/validation');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const registry = require('../commands/registry');
|
|
7
|
-
|
|
8
|
-
class manage extends command {
|
|
9
|
-
async execute(params) {
|
|
10
|
-
let me = this;
|
|
11
|
-
me.validator = new ProjectValidator(me.config);
|
|
12
|
-
|
|
13
|
-
// Initialize command registry
|
|
14
|
-
await registry.initialize();
|
|
15
|
-
|
|
16
|
-
me.showLogo();
|
|
17
|
-
return me.startManagement();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
showLogo() {
|
|
21
|
-
let me = this;
|
|
22
|
-
let version = me.config.get('pkg').version;
|
|
23
|
-
|
|
24
|
-
if (!this._hasShownLogo) {
|
|
25
|
-
this.log.log(` 8\u001b[2m${' '.repeat(Math.max(15-version.length-1, 1))+'v'+version}\u001b[22m\nYb db dP .d8b. 8d8b 8.dP \u001b[92m.d8b. 8d8b.\u001b[0m\n YbdPYbdP 8' .8 8P 88b \u001b[92m8' .8 8P Y8\u001b[0m\n YP YP \`Y8P' 8 8 Yb \u001b[92m\`Y8P' 8 8\u001b[0m`);
|
|
26
|
-
this._hasShownLogo = true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async startManagement() {
|
|
31
|
-
let me = this;
|
|
32
|
-
const projects = me.config.get('projects') || {};
|
|
33
|
-
const projectNames = Object.keys(projects);
|
|
34
|
-
|
|
35
|
-
const mainMenu = {
|
|
36
|
-
type: 'list',
|
|
37
|
-
name: 'action',
|
|
38
|
-
message: 'Project Management',
|
|
39
|
-
choices: [
|
|
40
|
-
{
|
|
41
|
-
name: 'Create new project',
|
|
42
|
-
value: 'create'
|
|
43
|
-
},
|
|
44
|
-
...(projectNames.length > 0 ? [
|
|
45
|
-
{
|
|
46
|
-
name: 'Edit existing project',
|
|
47
|
-
value: 'edit'
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
name: 'Delete project',
|
|
51
|
-
value: 'delete'
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
name: 'List all projects',
|
|
55
|
-
value: 'list'
|
|
56
|
-
}
|
|
57
|
-
] : []),
|
|
58
|
-
new inquirer.Separator(),
|
|
59
|
-
{
|
|
60
|
-
name: 'Exit',
|
|
61
|
-
value: 'exit'
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const answer = await inquirer.prompt([mainMenu]);
|
|
67
|
-
|
|
68
|
-
switch (answer.action) {
|
|
69
|
-
case 'create':
|
|
70
|
-
return me.createProject();
|
|
71
|
-
case 'edit':
|
|
72
|
-
return me.editProject();
|
|
73
|
-
case 'delete':
|
|
74
|
-
return me.deleteProject();
|
|
75
|
-
case 'list':
|
|
76
|
-
return me.listProjects();
|
|
77
|
-
case 'exit':
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async createProject() {
|
|
83
|
-
let me = this;
|
|
84
|
-
const defaults = me.config.get('project_defaults') || {};
|
|
85
|
-
const projects = me.config.get('projects') || {};
|
|
86
|
-
|
|
87
|
-
me.log.log('\n🚀 Create New Project\n');
|
|
88
|
-
|
|
89
|
-
const questions = [
|
|
90
|
-
{
|
|
91
|
-
type: 'input',
|
|
92
|
-
name: 'name',
|
|
93
|
-
message: 'Project name:',
|
|
94
|
-
default: File.cwd().name,
|
|
95
|
-
validate: (value) => me.validator.validateProjectName(value, projects)
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
type: 'input',
|
|
99
|
-
name: 'path',
|
|
100
|
-
message: 'Project path (relative to base directory):',
|
|
101
|
-
default: (answers) => answers.name,
|
|
102
|
-
validate: (value) => {
|
|
103
|
-
const basePath = defaults.base || process.cwd();
|
|
104
|
-
return me.validator.validateProjectPath(value, basePath);
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
type: 'list',
|
|
109
|
-
name: 'ide',
|
|
110
|
-
message: 'IDE/Editor:',
|
|
111
|
-
choices: [
|
|
112
|
-
{ name: 'Visual Studio Code', value: 'code' },
|
|
113
|
-
{ name: 'IntelliJ IDEA', value: 'idea' },
|
|
114
|
-
{ name: 'Atom', value: 'atom' },
|
|
115
|
-
{ name: 'Sublime Text', value: 'subl' },
|
|
116
|
-
{ name: 'Vim', value: 'vim' },
|
|
117
|
-
{ name: 'Emacs', value: 'emacs' }
|
|
118
|
-
],
|
|
119
|
-
default: defaults.ide || 'code'
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
type: 'input',
|
|
123
|
-
name: 'homepage',
|
|
124
|
-
message: 'Project homepage (optional):',
|
|
125
|
-
validate: (value) => me.validator.validateUrl(value)
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
type: 'checkbox',
|
|
129
|
-
name: 'events',
|
|
130
|
-
message: 'Select events to enable:',
|
|
131
|
-
choices: registry.getCommandsForManageUI().map(cmd => ({
|
|
132
|
-
name: cmd.name,
|
|
133
|
-
value: cmd.value,
|
|
134
|
-
checked: ['cwd', 'ide'].includes(cmd.value) // Default enable cwd and ide
|
|
135
|
-
}))
|
|
136
|
-
}
|
|
137
|
-
];
|
|
138
|
-
|
|
139
|
-
const answers = await inquirer.prompt(questions);
|
|
140
|
-
|
|
141
|
-
// Convert events array to object and configure advanced options
|
|
142
|
-
const events = {};
|
|
143
|
-
for (const event of answers.events) {
|
|
144
|
-
const command = registry.getCommandByName(event);
|
|
145
|
-
if (command && command.configuration) {
|
|
146
|
-
const config = await command.configuration.configureInteractive();
|
|
147
|
-
events[event] = config;
|
|
148
|
-
} else {
|
|
149
|
-
events[event] = 'true';
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const projectConfig = {
|
|
154
|
-
path: answers.path,
|
|
155
|
-
ide: answers.ide,
|
|
156
|
-
events: events
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
if (answers.homepage) {
|
|
160
|
-
projectConfig.homepage = answers.homepage;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const confirm = await inquirer.prompt([{
|
|
164
|
-
type: 'confirm',
|
|
165
|
-
name: 'confirmed',
|
|
166
|
-
message: 'Create this project?',
|
|
167
|
-
default: true
|
|
168
|
-
}]);
|
|
169
|
-
|
|
170
|
-
if (confirm.confirmed) {
|
|
171
|
-
projects[answers.name] = projectConfig;
|
|
172
|
-
me.config.set('projects', projects);
|
|
173
|
-
me.log.log(`\n✅ Project '${answers.name}' created successfully!`);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const continuePrompt = await inquirer.prompt([{
|
|
177
|
-
type: 'confirm',
|
|
178
|
-
name: 'continue',
|
|
179
|
-
message: 'Return to main menu?',
|
|
180
|
-
default: true
|
|
181
|
-
}]);
|
|
182
|
-
|
|
183
|
-
if (continuePrompt.continue) {
|
|
184
|
-
return me.startManagement();
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
async editProject() {
|
|
189
|
-
let me = this;
|
|
190
|
-
const projects = me.config.get('projects') || {};
|
|
191
|
-
const projectNames = Object.keys(projects);
|
|
192
|
-
|
|
193
|
-
if (projectNames.length === 0) {
|
|
194
|
-
me.log.log('No projects found.');
|
|
195
|
-
return me.startManagement();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const projectChoice = await inquirer.prompt([{
|
|
199
|
-
type: 'list',
|
|
200
|
-
name: 'projectName',
|
|
201
|
-
message: 'Select project to edit:',
|
|
202
|
-
choices: projectNames.map(name => ({
|
|
203
|
-
name: `${name} (${projects[name].path})`,
|
|
204
|
-
value: name
|
|
205
|
-
}))
|
|
206
|
-
}]);
|
|
207
|
-
|
|
208
|
-
const project = projects[projectChoice.projectName];
|
|
209
|
-
const currentEvents = Object.keys(project.events || {}).filter(key => project.events[key] === 'true');
|
|
210
|
-
|
|
211
|
-
me.log.log(`\n✏️ Edit Project: ${projectChoice.projectName}\n`);
|
|
212
|
-
|
|
213
|
-
const questions = [
|
|
214
|
-
{
|
|
215
|
-
type: 'input',
|
|
216
|
-
name: 'path',
|
|
217
|
-
message: 'Project path:',
|
|
218
|
-
default: project.path,
|
|
219
|
-
validate: (value) => {
|
|
220
|
-
const defaults = me.config.get('project_defaults') || {};
|
|
221
|
-
const basePath = defaults.base || process.cwd();
|
|
222
|
-
return me.validator.validateProjectPath(value, basePath);
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
type: 'list',
|
|
227
|
-
name: 'ide',
|
|
228
|
-
message: 'IDE/Editor:',
|
|
229
|
-
choices: [
|
|
230
|
-
{ name: 'Visual Studio Code', value: 'code' },
|
|
231
|
-
{ name: 'IntelliJ IDEA', value: 'idea' },
|
|
232
|
-
{ name: 'Atom', value: 'atom' },
|
|
233
|
-
{ name: 'Sublime Text', value: 'subl' },
|
|
234
|
-
{ name: 'Vim', value: 'vim' },
|
|
235
|
-
{ name: 'Emacs', value: 'emacs' }
|
|
236
|
-
],
|
|
237
|
-
default: project.ide || 'code'
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
type: 'input',
|
|
241
|
-
name: 'homepage',
|
|
242
|
-
message: 'Project homepage:',
|
|
243
|
-
default: project.homepage || '',
|
|
244
|
-
validate: (value) => me.validator.validateUrl(value)
|
|
245
|
-
},
|
|
246
|
-
{
|
|
247
|
-
type: 'checkbox',
|
|
248
|
-
name: 'events',
|
|
249
|
-
message: 'Select events to enable:',
|
|
250
|
-
choices: registry.getCommandsForManageUI().map(cmd => ({
|
|
251
|
-
name: cmd.name,
|
|
252
|
-
value: cmd.value,
|
|
253
|
-
checked: currentEvents.includes(cmd.value)
|
|
254
|
-
}))
|
|
255
|
-
}
|
|
256
|
-
];
|
|
257
|
-
|
|
258
|
-
const answers = await inquirer.prompt(questions);
|
|
259
|
-
|
|
260
|
-
// Convert events array to object and configure advanced options
|
|
261
|
-
const events = {};
|
|
262
|
-
for (const event of answers.events) {
|
|
263
|
-
const command = registry.getCommandByName(event);
|
|
264
|
-
if (command && command.configuration) {
|
|
265
|
-
// Check if there's existing configuration to preserve
|
|
266
|
-
const existingConfig = project.events && project.events[event];
|
|
267
|
-
if (existingConfig && typeof existingConfig === 'object') {
|
|
268
|
-
const keepConfig = await inquirer.prompt([{
|
|
269
|
-
type: 'confirm',
|
|
270
|
-
name: 'keep',
|
|
271
|
-
message: `Keep existing ${command.metadata.displayName} configuration?`,
|
|
272
|
-
default: true
|
|
273
|
-
}]);
|
|
274
|
-
|
|
275
|
-
if (keepConfig.keep) {
|
|
276
|
-
events[event] = existingConfig;
|
|
277
|
-
} else {
|
|
278
|
-
events[event] = await command.configuration.configureInteractive();
|
|
279
|
-
}
|
|
280
|
-
} else {
|
|
281
|
-
events[event] = await command.configuration.configureInteractive();
|
|
282
|
-
}
|
|
283
|
-
} else {
|
|
284
|
-
events[event] = 'true';
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
const updatedProject = {
|
|
289
|
-
path: answers.path,
|
|
290
|
-
ide: answers.ide,
|
|
291
|
-
events: events
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
if (answers.homepage) {
|
|
295
|
-
updatedProject.homepage = answers.homepage;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
const confirm = await inquirer.prompt([{
|
|
299
|
-
type: 'confirm',
|
|
300
|
-
name: 'confirmed',
|
|
301
|
-
message: 'Save changes?',
|
|
302
|
-
default: true
|
|
303
|
-
}]);
|
|
304
|
-
|
|
305
|
-
if (confirm.confirmed) {
|
|
306
|
-
projects[projectChoice.projectName] = updatedProject;
|
|
307
|
-
me.config.set('projects', projects);
|
|
308
|
-
me.log.log(`\n✅ Project '${projectChoice.projectName}' updated successfully!`);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
const continuePrompt = await inquirer.prompt([{
|
|
312
|
-
type: 'confirm',
|
|
313
|
-
name: 'continue',
|
|
314
|
-
message: 'Return to main menu?',
|
|
315
|
-
default: true
|
|
316
|
-
}]);
|
|
317
|
-
|
|
318
|
-
if (continuePrompt.continue) {
|
|
319
|
-
return me.startManagement();
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
async deleteProject() {
|
|
324
|
-
let me = this;
|
|
325
|
-
const projects = me.config.get('projects') || {};
|
|
326
|
-
const projectNames = Object.keys(projects);
|
|
327
|
-
|
|
328
|
-
if (projectNames.length === 0) {
|
|
329
|
-
me.log.log('No projects found.');
|
|
330
|
-
return me.startManagement();
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
const projectChoice = await inquirer.prompt([{
|
|
334
|
-
type: 'list',
|
|
335
|
-
name: 'projectName',
|
|
336
|
-
message: 'Select project to delete:',
|
|
337
|
-
choices: projectNames.map(name => ({
|
|
338
|
-
name: `${name} (${projects[name].path})`,
|
|
339
|
-
value: name
|
|
340
|
-
}))
|
|
341
|
-
}]);
|
|
342
|
-
|
|
343
|
-
const confirm = await inquirer.prompt([{
|
|
344
|
-
type: 'confirm',
|
|
345
|
-
name: 'confirmed',
|
|
346
|
-
message: `Are you sure you want to delete '${projectChoice.projectName}'?`,
|
|
347
|
-
default: false
|
|
348
|
-
}]);
|
|
349
|
-
|
|
350
|
-
if (confirm.confirmed) {
|
|
351
|
-
delete projects[projectChoice.projectName];
|
|
352
|
-
me.config.set('projects', projects);
|
|
353
|
-
me.log.log(`\n✅ Project '${projectChoice.projectName}' deleted successfully!`);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
const continuePrompt = await inquirer.prompt([{
|
|
357
|
-
type: 'confirm',
|
|
358
|
-
name: 'continue',
|
|
359
|
-
message: 'Return to main menu?',
|
|
360
|
-
default: true
|
|
361
|
-
}]);
|
|
362
|
-
|
|
363
|
-
if (continuePrompt.continue) {
|
|
364
|
-
return me.startManagement();
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
async listProjects() {
|
|
369
|
-
let me = this;
|
|
370
|
-
const projects = me.config.get('projects') || {};
|
|
371
|
-
const projectNames = Object.keys(projects);
|
|
372
|
-
|
|
373
|
-
if (projectNames.length === 0) {
|
|
374
|
-
me.log.log('No projects found.');
|
|
375
|
-
return me.startManagement();
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
me.log.log('\n📋 All Projects:\n');
|
|
379
|
-
|
|
380
|
-
projectNames.forEach(name => {
|
|
381
|
-
const project = projects[name];
|
|
382
|
-
const events = Object.keys(project.events || {}).filter(key => project.events[key] === 'true');
|
|
383
|
-
|
|
384
|
-
me.log.log(`${name}:`);
|
|
385
|
-
me.log.log(` Path: ${project.path}`);
|
|
386
|
-
me.log.log(` IDE: ${project.ide}`);
|
|
387
|
-
if (project.homepage) {
|
|
388
|
-
me.log.log(` Homepage: ${project.homepage}`);
|
|
389
|
-
}
|
|
390
|
-
me.log.log(` Events: ${events.join(', ') || 'none'}`);
|
|
391
|
-
me.log.log('');
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
const continuePrompt = await inquirer.prompt([{
|
|
395
|
-
type: 'confirm',
|
|
396
|
-
name: 'continue',
|
|
397
|
-
message: 'Return to main menu?',
|
|
398
|
-
default: true
|
|
399
|
-
}]);
|
|
400
|
-
|
|
401
|
-
if (continuePrompt.continue) {
|
|
402
|
-
return me.startManagement();
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
manage.define({
|
|
409
|
-
help: 'Interactive project management',
|
|
410
|
-
switches: '[d#debug:boolean=false] [h#help:boolean=false]'
|
|
411
|
-
});
|
|
412
|
-
|
|
413
|
-
module.exports = manage;
|