11import { Command } from 'commander' ;
2- import chalk from 'chalk' ;
3- import { generateTypes } from './commands/generate' ;
4- import { startRepl } from './commands/repl' ;
5- import { serve } from './commands/serve' ;
6- import { dev } from './commands/dev' ;
7- import { start } from './commands/start' ;
8- import { build } from './commands/build' ;
9- import { test } from './commands/test' ;
10- import { lint } from './commands/lint' ;
11- import { format } from './commands/format' ;
12- import { initProject } from './commands/init' ;
13- import { newMetadata } from './commands/new' ;
14- import { i18nExtract , i18nInit , i18nValidate } from './commands/i18n' ;
15- import { migrate , migrateCreate , migrateStatus } from './commands/migrate' ;
16- import { aiGenerate , aiValidate , aiChat , aiConversational } from './commands/ai' ;
17- import { syncDatabase } from './commands/sync' ;
18- import { doctorCommand , validateCommand } from './commands/doctor' ;
19- import { dbPushCommand } from './commands/database-push' ;
2+ import { registerLifecycleCommands } from './register/lifecycle' ;
3+ import { registerScaffoldCommands } from './register/scaffold' ;
4+ import { registerDatabaseCommands } from './register/database' ;
5+ import { registerAiCommands } from './register/ai' ;
6+ import { registerToolsCommands } from './register/tools' ;
7+ import { registerI18nCommands } from './register/i18n' ;
208
219const program = new Command ( ) ;
2210
@@ -25,304 +13,12 @@ program
2513 . description ( 'ObjectQL CLI tool - The ObjectStack AI Protocol Interface' )
2614 . version ( '1.5.0' ) ;
2715
28- // ==========================================
29- // 1. Lifecycle Commands
30- // ==========================================
31-
32- program
33- . command ( 'init' )
34- . description ( 'Create a new ObjectQL project (Deprecated)' )
35- . action ( async ( ) => {
36- console . log ( chalk . red ( '\n⚠️ DEPRECATED: The "objectql init" command has been removed.' ) ) ;
37- console . log ( chalk . white ( 'Please use the standard initializer instead:\n' ) ) ;
38- console . log ( chalk . cyan ( ' npm create @objectql@latest <my-app>' ) ) ;
39- console . log ( '' ) ;
40- process . exit ( 1 ) ;
41- } ) ;
42-
43- program
44- . command ( 'dev' )
45- . description ( 'Start development server with hot reload and type generation' )
46- . option ( '-p, --port <number>' , 'Port to listen on' , '3000' )
47- . option ( '-d, --dir <path>' , 'Directory containing schema' , '.' )
48- . option ( '-c, --config <path>' , 'Path to objectql.config.ts/js' )
49- . option ( '--modules <items>' , 'Comma-separated list of modules to load' )
50- . option ( '--no-watch' , 'Disable file watching' )
51- . action ( async ( options ) => {
52- await dev ( {
53- port : parseInt ( options . port ) ,
54- dir : options . dir ,
55- config : options . config ,
56- modules : options . modules ,
57- watch : options . watch
58- } ) ;
59- } ) ;
60-
61- program
62- . command ( 'build' )
63- . description ( 'Build project for production' )
64- . option ( '-d, --dir <path>' , 'Source directory' , '.' )
65- . option ( '-o, --output <path>' , 'Output directory' , './dist' )
66- . option ( '--no-types' , 'Skip TypeScript type generation' )
67- . option ( '--no-validate' , 'Skip metadata validation' )
68- . action ( async ( options ) => {
69- await build ( {
70- dir : options . dir ,
71- output : options . output ,
72- types : options . types ,
73- validate : options . validate
74- } ) ;
75- } ) ;
76-
77- program
78- . command ( 'start' )
79- . description ( 'Start production server' )
80- . option ( '-p, --port <number>' , 'Port to listen on' , '3000' )
81- . option ( '-d, --dir <path>' , 'Directory containing schema' , '.' )
82- . option ( '-c, --config <path>' , 'Path to objectql.config.ts/js' )
83- . action ( async ( options ) => {
84- await start ( {
85- port : parseInt ( options . port ) ,
86- dir : options . dir ,
87- config : options . config
88- } ) ;
89- } ) ;
90-
91- // ==========================================
92- // 2. Scaffolding & Generators
93- // ==========================================
94-
95- program
96- . command ( 'generate <schematic> <name>' )
97- . alias ( 'g' )
98- . description ( 'Generate a new metadata element (object, action, etc.)' )
99- . option ( '-d, --dir <path>' , 'Output directory' , '.' )
100- . action ( async ( schematic , name , options ) => {
101- try {
102- // Maps to existing newMetadata which accepts (type, name, dir)
103- await newMetadata ( { type : schematic , name, dir : options . dir } ) ;
104- } catch ( error ) {
105- console . error ( error ) ;
106- process . exit ( 1 ) ;
107- }
108- } ) ;
109-
110- program
111- . command ( 'types' )
112- . description ( 'Force regenerate TypeScript definitions' )
113- . option ( '-s, --source <path>' , 'Source directory' , '.' )
114- . option ( '-o, --output <path>' , 'Output directory' , './src/generated' )
115- . action ( async ( options ) => {
116- try {
117- await generateTypes ( options . source , options . output ) ;
118- } catch ( error ) {
119- console . error ( error ) ;
120- process . exit ( 1 ) ;
121- }
122- } ) ;
123-
124- // ==========================================
125- // 3. Database Operations
126- // ==========================================
127-
128- const dbCmd = program . command ( 'db' ) . description ( 'Database operations' ) ;
129-
130- dbCmd
131- . command ( 'push' )
132- . description ( 'Push metadata schema changes to the database' )
133- . option ( '--force' , 'Bypass safety checks' )
134- . action ( async ( options ) => {
135- try {
136- await dbPushCommand ( options ) ;
137- } catch ( error ) {
138- console . error ( error ) ;
139- process . exit ( 1 ) ;
140- }
141- } ) ;
142-
143- dbCmd
144- . command ( 'pull' )
145- . description ( 'Introspect database and generate metadata (Reverse Engineering)' )
146- . option ( '-c, --config <path>' , 'Path to objectql.config.ts/js' )
147- . option ( '-o, --output <path>' , 'Output directory' , './src/objects' )
148- . option ( '-t, --tables <tables...>' , 'Specific tables to sync' )
149- . option ( '-f, --force' , 'Overwrite existing files' )
150- . action ( async ( options ) => {
151- try {
152- // Maps to existing syncDatabase
153- await syncDatabase ( options ) ;
154- } catch ( error ) {
155- console . error ( error ) ;
156- process . exit ( 1 ) ;
157- }
158- } ) ;
159-
160- // Migration commands - kept as top level or move to db:migrate?
161- // Staying top level or db:migrate is fine. Let's keep `migrate` top level for familiarity with typeorm/prisma users or move to db?
162- // User request: "Declarative > Imperative".
163- // Let's alias db:migrate to migrate for now, or just keep migrate.
164- // Standard in many tools is `migrate` or `db migrate`.
165- // Let's keep `migrate` as top level group for explicit control.
166-
167- const migrateCmd = program
168- . command ( 'migrate' )
169- . description ( 'Manage database migrations' ) ;
170-
171- migrateCmd
172- . command ( 'up' ) // Changed from default action to explicit 'up'
173- . description ( 'Run pending migrations' )
174- . option ( '-c, --config <path>' , 'Path to objectql.config.ts/js' )
175- . option ( '-d, --dir <path>' , 'Migrations directory' , './migrations' )
176- . action ( async ( options ) => {
177- await migrate ( options ) ;
178- } ) ;
179-
180- migrateCmd
181- . command ( 'create <name>' )
182- . description ( 'Create a new migration file' )
183- . option ( '-d, --dir <path>' , 'Migrations directory' , './migrations' )
184- . action ( async ( name , options ) => {
185- await migrateCreate ( { name, dir : options . dir } ) ;
186- } ) ;
187-
188- migrateCmd
189- . command ( 'status' )
190- . description ( 'Show migration status' )
191- . action ( async ( options ) => {
192- await migrateStatus ( options ) ;
193- } ) ;
194-
195-
196- // ==========================================
197- // 4. AI Architect
198- // ==========================================
199-
200- const aiCmd = program
201- . command ( 'ai' )
202- . description ( 'AI Architect capabilities' ) ;
203-
204- aiCmd
205- . command ( 'chat' )
206- . description ( 'Interactive architecture chat' )
207- . option ( '-p, --prompt <text>' , 'Initial prompt' )
208- . action ( async ( options ) => {
209- await aiChat ( { initialPrompt : options . prompt } ) ;
210- } ) ;
211-
212- aiCmd
213- . command ( 'run <prompt>' ) // Changed from generate to run/exec for simple "Do this"
214- . description ( 'Execute an AI modification on the project (e.g. "Add a blog module")' )
215- . option ( '-o, --output <path>' , 'Output directory' , './src' )
216- . action ( async ( prompt , options ) => {
217- // Maps to simple conversational or generate
218- // Let's map to aiGenerate but pass description
219- await aiGenerate ( { description : prompt , output : options . output , type : 'custom' } ) ;
220- } ) ;
221-
222- // ==========================================
223- // 5. Diagnostics & Tools
224- // ==========================================
225-
226- program
227- . command ( 'doctor' )
228- . description ( 'Check environment and configuration health' )
229- . action ( async ( ) => {
230- await doctorCommand ( ) ;
231- } ) ;
232-
233- program
234- . command ( 'validate' )
235- . description ( 'Validate all metadata files' )
236- . option ( '-d, --dir <path>' , 'Directory to validate' , '.' )
237- . action ( async ( options ) => {
238- await validateCommand ( options ) ;
239- } ) ;
240-
241- program
242- . command ( 'repl' )
243- . description ( 'Start interactive REPL' )
244- . option ( '-c, --config <path>' , 'Path to objectql.config.ts' )
245- . action ( async ( options ) => {
246- await startRepl ( options . config ) ;
247- } ) ;
248-
249- program
250- . command ( 'test' )
251- . description ( 'Run tests' )
252- . action ( async ( options ) => {
253- await test ( options ) ;
254- } ) ;
255-
256- program
257- . command ( 'lint' )
258- . description ( 'Lint metadata files' )
259- . action ( async ( options ) => {
260- await lint ( options ) ;
261- } ) ;
262-
263- program
264- . command ( 'format' )
265- . description ( 'Format metadata files' )
266- . action ( async ( options ) => {
267- await format ( options ) ;
268- } ) ;
269-
270- // ==========================================
271- // 6. I18n
272- // ==========================================
273-
274- const i18nCmd = program
275- . command ( 'i18n' )
276- . description ( 'Internationalization commands' ) ;
277-
278- i18nCmd
279- . command ( 'extract' )
280- . description ( 'Extract translatable strings from metadata files' )
281- . option ( '-s, --source <path>' , 'Source directory' , '.' )
282- . option ( '-o, --output <path>' , 'Output directory' , './src/i18n' )
283- . option ( '-l, --lang <lang>' , 'Language code' , 'en' )
284- . action ( async ( options ) => {
285- try {
286- await i18nExtract ( options ) ;
287- } catch ( error ) {
288- console . error ( error ) ;
289- process . exit ( 1 ) ;
290- }
291- } ) ;
292-
293- i18nCmd
294- . command ( 'init <lang>' )
295- . description ( 'Initialize i18n for a new language' )
296- . option ( '-b, --base-dir <path>' , 'Base i18n directory' , './src/i18n' )
297- . action ( async ( lang , options ) => {
298- try {
299- await i18nInit ( { lang, baseDir : options . baseDir } ) ;
300- } catch ( error ) {
301- console . error ( error ) ;
302- process . exit ( 1 ) ;
303- }
304- } ) ;
305-
306- i18nCmd
307- . command ( 'validate <lang>' )
308- . description ( 'Validate translation completeness' )
309- . option ( '-b, --base-dir <path>' , 'Base i18n directory' , './src/i18n' )
310- . option ( '--base-lang <lang>' , 'Base language to compare against' , 'en' )
311- . action ( async ( lang , options ) => {
312- try {
313- await i18nValidate ( { lang, baseDir : options . baseDir , baseLang : options . baseLang } ) ;
314- } catch ( error ) {
315- console . error ( error ) ;
316- process . exit ( 1 ) ;
317- }
318- } ) ;
319-
320- // Backward compatibility (Hidden or Deprecated)
321- program
322- . command ( 'new <type> <name>' , { hidden : true } )
323- . action ( async ( type , name , options ) => {
324- console . warn ( chalk . yellow ( 'Deprecated: Use "objectql generate" instead.' ) ) ;
325- await newMetadata ( { type, name, dir : options . dir } ) ;
326- } ) ;
16+ // Register all command groups
17+ registerLifecycleCommands ( program ) ;
18+ registerScaffoldCommands ( program ) ;
19+ registerDatabaseCommands ( program ) ;
20+ registerAiCommands ( program ) ;
21+ registerToolsCommands ( program ) ;
22+ registerI18nCommands ( program ) ;
32723
32824program . parse ( process . argv ) ;
0 commit comments