@@ -143,42 +143,22 @@ async function main() {
143143// Help
144144// ──────────────────────────────────────────────────────────────────────────
145145
146- function printHelp ( ) {
147- console . log ( renderBanner ( { subtitle : "Autonomous Agent" } ) ) ;
146+ function printHelp ( ) : void {
147+ console . log ( renderBanner ( { compact : true } ) ) ;
148148 console . log (
149149 [
150- pc . bold ( "USAGE" ) ,
151- ` ${ pc . cyan ( "splash" ) } Open an interactive chat` ,
152- ` ${ pc . cyan ( "splash" ) } "build me a script" Run a one-shot task` ,
153- ` ${ pc . cyan ( "splash" ) } "..." --background Detach and return a run id` ,
154150 "" ,
155- pc . bold ( "CORE COMMANDS" ) ,
156- ` ${ pc . cyan ( "splash init" ) } 30-second setup wizard` ,
157- ` ${ pc . cyan ( "splash tui" ) } Open the live run dashboard` ,
158- ` ${ pc . cyan ( "splash help" ) } Show this help` ,
151+ ` ${ pc . cyan ( "Run " ) } ${ pc . dim ( "│" ) } run, exec, ask, "prompt"` ,
152+ ` ${ pc . cyan ( "Memory" ) } ${ pc . dim ( "│" ) } memory list/search/export, profile show/set` ,
153+ ` ${ pc . cyan ( "Config" ) } ${ pc . dim ( "│" ) } config list/get/set, providers list/test` ,
154+ ` ${ pc . cyan ( "Skills" ) } ${ pc . dim ( "│" ) } skills list, skills enable/disable, skills suggest` ,
155+ ` ${ pc . cyan ( "Runs " ) } ${ pc . dim ( "│" ) } runs list/logs/stop/retry` ,
156+ ` ${ pc . cyan ( "System" ) } ${ pc . dim ( "│" ) } doctor, update, auth, init` ,
159157 "" ,
160- pc . bold ( "RUNS" ) ,
161- ` ${ pc . cyan ( "splash runs list" ) } Show active/recent runs` ,
162- ` ${ pc . cyan ( "splash runs logs" ) } ID [--follow] Tail events for a run` ,
163- ` ${ pc . cyan ( "splash runs attach" ) } ID Open a run in the TUI` ,
164- ` ${ pc . cyan ( "splash runs stop" ) } ID Cancel a running run` ,
165- ` ${ pc . cyan ( "splash runs retry" ) } ID [-b] Re-run a task` ,
158+ pc . dim ( ` Config: ${ globalConfigPath ( ) } ` ) ,
159+ pc . dim ( ` Env: SPLASH_* vars work. .env in cwd is read.` ) ,
166160 "" ,
167- pc . bold ( "CONFIG" ) ,
168- ` ${ pc . cyan ( "splash config list" ) } Show effective config` ,
169- ` ${ pc . cyan ( "splash config doctor" ) } Verify keys / perms / reachability` ,
170- ` ${ pc . cyan ( "splash config preset" ) } fast|balanced|safe` ,
171- ` ${ pc . cyan ( "splash config set" ) } KEY VAL Set a field` ,
172- ` ${ pc . cyan ( "splash config set-key" ) } P VAL Save API key for provider` ,
173- "" ,
174- pc . bold ( "PLATFORMS" ) ,
175- ` ${ pc . cyan ( "splash telegram" ) } |${ pc . cyan ( "slack" ) } |${ pc . cyan ( "whatsapp" ) } |${ pc . cyan ( "messenger" ) } |${ pc . cyan ( "discord" ) } ` ,
176- "" ,
177- pc . dim ( `Config: ${ globalConfigPath ( ) } ` ) ,
178- pc . dim ( `Env: SPLASH_* and legacy ALPCLAW_* vars both work. .env in cwd is read.` ) ,
179- pc . dim ( `Alias: \`alpclaw\` still works — it delegates to \`splash\`.` ) ,
180- "" ,
181- ] . join ( "\n" ) ,
161+ ] . join ( "\n" )
182162 ) ;
183163}
184164
@@ -196,13 +176,19 @@ async function runInit() {
196176 next . apiKeys = { ...( existing . apiKeys || { } ) } ;
197177
198178 const provider = await p . select ( {
199- message : "Default provider:" ,
179+ message : "1. Default provider:" ,
200180 options : [
201- { value : "openrouter" , label : "OpenRouter — recommended, unlocks Kimi K2, DeepSeek, Qwen, Claude, GPT-4 " } ,
181+ { value : "openrouter" , label : "OpenRouter — recommended, unlocks massive model catalog " } ,
202182 { value : "claude" , label : "Anthropic Claude" } ,
203183 { value : "openai" , label : "OpenAI (GPT-4o)" } ,
204184 { value : "gemini" , label : "Google Gemini" } ,
205185 { value : "deepseek" , label : "DeepSeek" } ,
186+ { value : "nous" , label : "Nous Portal" } ,
187+ { value : "groq" , label : "Groq (ultra-fast)" } ,
188+ { value : "mistral" , label : "Mistral" } ,
189+ { value : "cerebras" , label : "Cerebras" } ,
190+ { value : "cohere" , label : "Cohere" } ,
191+ { value : "nvidia" , label : "NVIDIA NIM" } ,
206192 { value : "ollama" , label : "Ollama (local, no key needed)" } ,
207193 ] ,
208194 } ) ;
@@ -211,14 +197,14 @@ async function runInit() {
211197 next . defaultProvider = provider as string ;
212198
213199 if ( provider !== "ollama" ) {
214- const key = await p . password ( { message : `Paste your ${ provider } API key (input hidden):` } ) ;
200+ const key = await p . password ( { message : `2. Paste your ${ provider } API key (input hidden):` } ) ;
215201 if ( p . isCancel ( key ) ) return abort ( ) ;
216202 if ( key ) next . apiKeys [ provider as string ] = key as string ;
217203 }
218204
219205 if ( provider === "openrouter" ) {
220206 const model = await p . select ( {
221- message : "Default model:" ,
207+ message : "3. Default model:" ,
222208 options : [
223209 { value : "moonshotai/kimi-k2" , label : "Kimi K2 (Moonshot) — long context, strong coding" } ,
224210 { value : "moonshotai/kimi-k2-0905" , label : "Kimi K2 0905 (newer snapshot)" } ,
@@ -232,7 +218,7 @@ async function runInit() {
232218 }
233219
234220 const safety = await p . select ( {
235- message : "Safety level:" ,
221+ message : "4. Safety level:" ,
236222 options : [
237223 { value : "standard" , label : "Standard — confirms risky actions (recommended)" } ,
238224 { value : "strict" , label : "Strict — confirms every action" } ,
@@ -241,6 +227,20 @@ async function runInit() {
241227 } ) ;
242228 if ( ! p . isCancel ( safety ) ) next . safetyMode = safety as GlobalConfigShape [ "safetyMode" ] ;
243229
230+ const theme = await p . select ( {
231+ message : "5. CLI Theme:" ,
232+ options : [
233+ { value : "splash" , label : "Splash (Default) — Water animations & rich output" } ,
234+ { value : "hermes" , label : "Hermes — Clean bracket-based logs" } ,
235+ { value : "openclaw" , label : "OpenClaw — Compact status-light header" } ,
236+ { value : "minimal" , label : "Minimal — Pure prompt, silent execution" } ,
237+ ] ,
238+ } ) ;
239+ if ( ! p . isCancel ( theme ) ) {
240+ next . cli = next . cli || { } ;
241+ next . cli . style = theme as "splash" | "hermes" | "openclaw" | "minimal" ;
242+ }
243+
244244 writeGlobalConfig ( next ) ;
245245 p . outro ( pc . green ( `✓ Saved to ${ globalConfigPath ( ) } ` ) ) ;
246246 console . log ( pc . dim ( `\nTry it: ${ pc . cyan ( "splash \"summarize this folder\"" ) } ` ) ) ;
@@ -340,8 +340,9 @@ async function runConfig(args: string[]) {
340340
341341async function runDoctor ( args : string [ ] ) : Promise < void > {
342342 const json = args . includes ( "--json" ) ;
343+ const autofix = args . includes ( "--fix" ) || args . includes ( "--autofix" ) ;
343344 const cfg = readGlobalConfig ( ) ;
344- const checks : { name : string ; ok : boolean ; detail : string ; fix ?: string } [ ] = [ ] ;
345+ const checks : { name : string ; ok : boolean ; detail : string ; fix ?: string ; autoFixer ?: ( ) => Promise < void > | void } [ ] = [ ] ;
345346
346347 // 1. provider key present
347348 const hasAnyKey =
@@ -357,6 +358,10 @@ async function runDoctor(args: string[]): Promise<void> {
357358 ok : hasAnyKey ,
358359 detail : hasAnyKey ? "found" : "none" ,
359360 fix : "splash init — or splash config set-key openrouter sk-or-..." ,
361+ autoFixer : async ( ) => {
362+ console . log ( pc . yellow ( "\nMissing provider key. Launching setup wizard..." ) ) ;
363+ await runInit ( ) ;
364+ }
360365 } ) ;
361366
362367 // 2. write perms
@@ -374,6 +379,12 @@ async function runDoctor(args: string[]): Promise<void> {
374379 ok : writable ,
375380 detail : dir ,
376381 fix : `chmod u+w ${ dir } ` ,
382+ autoFixer : ( ) => {
383+ try {
384+ if ( ! fs . existsSync ( dir ) ) fs . mkdirSync ( dir , { recursive : true , mode : 0o700 } ) ;
385+ fs . chmodSync ( dir , 0o700 ) ;
386+ } catch ( e ) { }
387+ }
377388 } ) ;
378389
379390 // 3. runs dir
@@ -386,7 +397,18 @@ async function runDoctor(args: string[]): Promise<void> {
386397 } catch {
387398 runsOK = false ;
388399 }
389- checks . push ( { name : "runs dir writable" , ok : runsOK , detail : rdir } ) ;
400+ checks . push ( {
401+ name : "runs dir writable" ,
402+ ok : runsOK ,
403+ detail : rdir ,
404+ fix : `chmod u+w ${ rdir } ` ,
405+ autoFixer : ( ) => {
406+ try {
407+ if ( ! fs . existsSync ( rdir ) ) fs . mkdirSync ( rdir , { recursive : true , mode : 0o700 } ) ;
408+ fs . chmodSync ( rdir , 0o700 ) ;
409+ } catch ( e ) { }
410+ }
411+ } ) ;
390412
391413 // 4. provider reachability (best effort — skip if no fetch)
392414 const defaultProvider = cfg . defaultProvider || "openrouter" ;
@@ -433,6 +455,20 @@ async function runDoctor(args: string[]): Promise<void> {
433455 const bad = checks . filter ( ( c ) => ! c . ok ) . length ;
434456 console . log ( ) ;
435457 console . log ( bad === 0 ? pc . green ( "All checks passed." ) : pc . yellow ( `${ bad } check(s) failed.` ) ) ;
458+
459+ if ( bad !== 0 && autofix ) {
460+ console . log ( pc . cyan ( "\nRunning autofix for failed checks..." ) ) ;
461+ for ( const c of checks ) {
462+ if ( ! c . ok && c . autoFixer ) {
463+ await c . autoFixer ( ) ;
464+ }
465+ }
466+ console . log ( pc . green ( "\nAutofix complete. Run `splash doctor` again to verify." ) ) ;
467+ process . exit ( 0 ) ;
468+ } else if ( bad !== 0 && ! autofix ) {
469+ console . log ( pc . dim ( `\nRun \`${ pc . cyan ( "splash doctor --fix" ) } \` to automatically resolve issues.` ) ) ;
470+ }
471+
436472 if ( bad !== 0 ) process . exit ( 1 ) ;
437473}
438474
0 commit comments