workon 1.3.0 → 2.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/lib/validation.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const File = require('phylo');
2
2
  const { spawn } = require('child_process');
3
3
  const path = require('path');
4
+ const registry = require('../commands/registry');
4
5
 
5
6
  class ProjectValidator {
6
7
  constructor(config) {
@@ -74,57 +75,35 @@ class ProjectValidator {
74
75
  });
75
76
  }
76
77
 
77
- validateEvents(events) {
78
+ async validateEvents(events) {
78
79
  if (!events || typeof events !== 'object') {
79
80
  return 'Events must be an object';
80
81
  }
81
82
 
82
- const validEvents = ['cwd', 'ide', 'web', 'claude'];
83
+ // Initialize registry if not already done
84
+ await registry.initialize();
85
+
86
+ const validEvents = registry.getValidEventNames();
83
87
  const invalidEvents = Object.keys(events).filter(event => !validEvents.includes(event));
84
88
 
85
89
  if (invalidEvents.length > 0) {
86
90
  return `Invalid events: ${invalidEvents.join(', ')}. Valid events: ${validEvents.join(', ')}`;
87
91
  }
88
92
 
89
- // Validate claude event configuration if present
90
- if (events.claude && typeof events.claude === 'object') {
91
- const claudeValidation = this.validateClaudeConfig(events.claude);
92
- if (claudeValidation !== true) {
93
- return claudeValidation;
93
+ // Delegate to command-specific validation
94
+ for (const [eventName, config] of Object.entries(events)) {
95
+ const command = registry.getCommandByName(eventName);
96
+ if (command && command.validation) {
97
+ const result = command.validation.validateConfig(config);
98
+ if (result !== true) {
99
+ return `${eventName}: ${result}`;
100
+ }
94
101
  }
95
102
  }
96
103
 
97
104
  return true;
98
105
  }
99
106
 
100
- validateClaudeConfig(config) {
101
- if (typeof config !== 'object') {
102
- return 'Claude configuration must be an object';
103
- }
104
-
105
- // Validate flags if present
106
- if (config.flags) {
107
- if (!Array.isArray(config.flags)) {
108
- return 'Claude flags must be an array';
109
- }
110
-
111
- // Basic flag validation - ensure they start with - or --
112
- const invalidFlags = config.flags.filter(flag =>
113
- typeof flag !== 'string' || (!flag.startsWith('-') && !flag.startsWith('--'))
114
- );
115
-
116
- if (invalidFlags.length > 0) {
117
- return `Invalid Claude flags: ${invalidFlags.join(', ')}. Flags must start with - or --`;
118
- }
119
- }
120
-
121
- // Validate split_terminal if present
122
- if (config.split_terminal !== undefined && typeof config.split_terminal !== 'boolean') {
123
- return 'Claude split_terminal must be a boolean';
124
- }
125
-
126
- return true;
127
- }
128
107
 
129
108
  validateUrl(url) {
130
109
  if (!url) return true; // Optional field
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workon",
3
- "version": "1.3.0",
3
+ "version": "2.0.0",
4
4
  "description": "Work on something great!",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -17,7 +17,7 @@
17
17
  "license": "MIT",
18
18
  "devDependencies": {
19
19
  "cz-conventional-changelog": "^2.0.0",
20
- "standard-version": "^4.2.0"
20
+ "standard-version": "^9.5.0"
21
21
  },
22
22
  "config": {
23
23
  "commitizen": {
@@ -0,0 +1,145 @@
1
+ const registry = require('./commands/registry');
2
+ const ProjectValidator = require('./lib/validation');
3
+
4
+ async function comprehensiveTest() {
5
+ console.log('🧪 Testing Command-Centric Architecture\n');
6
+
7
+ try {
8
+ // Test 1: Registry initialization
9
+ console.log('1. Testing registry initialization...');
10
+ await registry.initialize();
11
+ console.log(' ✅ Registry initialized successfully');
12
+
13
+ // Test 2: Command discovery
14
+ console.log('\n2. Testing command discovery...');
15
+ const commands = registry.getValidEventNames();
16
+ const expectedCommands = ['cwd', 'ide', 'web', 'claude', 'npm'];
17
+ const hasAllCommands = expectedCommands.every(cmd => commands.includes(cmd));
18
+ console.log(` 📋 Discovered commands: ${commands.join(', ')}`);
19
+ console.log(` ${hasAllCommands ? '✅' : '❌'} All expected commands found`);
20
+
21
+ // Test 3: Command metadata
22
+ console.log('\n3. Testing command metadata...');
23
+ for (const cmdName of expectedCommands) {
24
+ const command = registry.getCommandByName(cmdName);
25
+ if (command && command.metadata) {
26
+ console.log(` ✅ ${cmdName}: ${command.metadata.displayName}`);
27
+ } else {
28
+ console.log(` ❌ ${cmdName}: Missing metadata`);
29
+ }
30
+ }
31
+
32
+ // Test 4: Validation system
33
+ console.log('\n4. Testing validation system...');
34
+ const validator = new ProjectValidator({});
35
+
36
+ // Test valid configurations
37
+ const validConfigs = [
38
+ { cwd: true, ide: true },
39
+ { claude: { flags: ['--debug'] } },
40
+ { npm: 'dev' },
41
+ { npm: { command: 'test', watch: true } }
42
+ ];
43
+
44
+ for (const config of validConfigs) {
45
+ const result = await validator.validateEvents(config);
46
+ console.log(` ${result === true ? '✅' : '❌'} Valid config: ${JSON.stringify(config)}`);
47
+ if (result !== true) console.log(` Error: ${result}`);
48
+ }
49
+
50
+ // Test invalid configurations
51
+ const invalidConfigs = [
52
+ { invalid: true },
53
+ { claude: { flags: 'invalid' } },
54
+ { npm: { command: 123 } }
55
+ ];
56
+
57
+ for (const config of invalidConfigs) {
58
+ const result = await validator.validateEvents(config);
59
+ console.log(` ${result !== true ? '✅' : '❌'} Invalid config rejected: ${JSON.stringify(config)}`);
60
+ if (result !== true) console.log(` Error: ${result}`);
61
+ }
62
+
63
+ // Test 5: Command configuration
64
+ console.log('\n5. Testing command configuration...');
65
+ const claudeCommand = registry.getCommandByName('claude');
66
+ if (claudeCommand) {
67
+ const defaultConfig = claudeCommand.configuration.getDefaultConfig();
68
+ console.log(` ✅ Claude default config: ${defaultConfig}`);
69
+ }
70
+
71
+ const npmCommand = registry.getCommandByName('npm');
72
+ if (npmCommand) {
73
+ const defaultConfig = npmCommand.configuration.getDefaultConfig();
74
+ console.log(` ✅ NPM default config: ${defaultConfig}`);
75
+ }
76
+
77
+ // Test 6: Tmux integration
78
+ console.log('\n6. Testing tmux integration...');
79
+ const tmuxCommands = registry.getTmuxEnabledCommands();
80
+ console.log(` 📋 Tmux-enabled commands: ${tmuxCommands.map(c => `${c.name}(${c.priority})`).join(', ')}`);
81
+ console.log(` ${tmuxCommands.length > 0 ? '✅' : '❌'} Tmux commands found`);
82
+
83
+ // Test 7: Management UI data
84
+ console.log('\n7. Testing management UI data...');
85
+ const manageCommands = registry.getCommandsForManageUI();
86
+ console.log(` 📋 Management UI commands: ${manageCommands.length}`);
87
+ for (const cmd of manageCommands) {
88
+ console.log(` - ${cmd.name} (${cmd.value})`);
89
+ }
90
+ console.log(` ${manageCommands.length === expectedCommands.length ? '✅' : '❌'} All commands available for management`);
91
+
92
+ // Test 8: Command processing simulation
93
+ console.log('\n8. Testing command processing...');
94
+ const mockProject = {
95
+ name: 'test-project',
96
+ path: { path: '/test/path' },
97
+ ide: 'code',
98
+ homepage: 'https://example.com',
99
+ events: {
100
+ cwd: true,
101
+ ide: true,
102
+ claude: { flags: ['--debug'] },
103
+ npm: 'dev'
104
+ }
105
+ };
106
+
107
+ const shellCommands = [];
108
+ const context = {
109
+ project: mockProject,
110
+ isShellMode: true,
111
+ shellCommands
112
+ };
113
+
114
+ for (const eventName of ['cwd', 'ide', 'claude', 'npm']) {
115
+ const command = registry.getCommandByName(eventName);
116
+ if (command && command.processing) {
117
+ try {
118
+ await command.processing.processEvent(context);
119
+ console.log(` ✅ ${eventName} command processed`);
120
+ } catch (error) {
121
+ console.log(` ❌ ${eventName} command failed: ${error.message}`);
122
+ }
123
+ }
124
+ }
125
+
126
+ console.log(` 📋 Generated shell commands: ${shellCommands.length}`);
127
+ shellCommands.forEach((cmd, i) => console.log(` ${i + 1}. ${cmd}`));
128
+
129
+ console.log('\n🎉 All tests completed successfully!');
130
+ console.log('\n📊 Architecture Benefits Achieved:');
131
+ console.log(' ✅ Commands are self-contained');
132
+ console.log(' ✅ Validation is delegated to commands');
133
+ console.log(' ✅ Configuration is handled by commands');
134
+ console.log(' ✅ No hardcoded command lists');
135
+ console.log(' ✅ Auto-discovery works');
136
+ console.log(' ✅ Adding new commands requires touching only command directory');
137
+
138
+ } catch (error) {
139
+ console.error('❌ Test failed:', error.message);
140
+ console.error(error.stack);
141
+ process.exit(1);
142
+ }
143
+ }
144
+
145
+ comprehensiveTest();
@@ -0,0 +1,57 @@
1
+ const registry = require('./commands/registry');
2
+
3
+ async function testRegistry() {
4
+ console.log('Testing Command Registry...\n');
5
+
6
+ try {
7
+ await registry.initialize();
8
+ console.log('✅ Registry initialized successfully\n');
9
+
10
+ // Test getting valid event names
11
+ const eventNames = registry.getValidEventNames();
12
+ console.log('Valid event names:', eventNames);
13
+
14
+ // Test getting commands for manage UI
15
+ const manageCommands = registry.getCommandsForManageUI();
16
+ console.log('\nCommands for manage UI:');
17
+ manageCommands.forEach(cmd => {
18
+ console.log(` - ${cmd.name} (${cmd.value}): ${cmd.description}`);
19
+ });
20
+
21
+ // Test getting specific commands
22
+ console.log('\nTesting specific commands:');
23
+ const cwdCommand = registry.getCommandByName('cwd');
24
+ if (cwdCommand) {
25
+ console.log('✅ CWD command found');
26
+ console.log(' Metadata:', cwdCommand.metadata);
27
+ }
28
+
29
+ const claudeCommand = registry.getCommandByName('claude');
30
+ if (claudeCommand) {
31
+ console.log('✅ Claude command found');
32
+ console.log(' Metadata:', claudeCommand.metadata);
33
+ }
34
+
35
+ // Test tmux commands
36
+ const tmuxCommands = registry.getTmuxEnabledCommands();
37
+ console.log('\nTmux-enabled commands:');
38
+ tmuxCommands.forEach(cmd => {
39
+ console.log(` - ${cmd.name} (priority: ${cmd.priority})`);
40
+ });
41
+
42
+ // Test validation
43
+ console.log('\nTesting validation:');
44
+ if (cwdCommand) {
45
+ console.log('CWD validation (true):', cwdCommand.validation.validateConfig(true));
46
+ console.log('CWD validation (invalid):', cwdCommand.validation.validateConfig(123));
47
+ }
48
+
49
+ console.log('\n✅ All tests passed!');
50
+
51
+ } catch (error) {
52
+ console.error('❌ Error testing registry:', error.message);
53
+ console.error(error.stack);
54
+ }
55
+ }
56
+
57
+ testRegistry();