@@ -110,7 +110,7 @@ async function main() {
110110 "version" , "help" , "init" , "setup" , "config" , "chat" , "telegram" , "slack" ,
111111 "whatsapp" , "messenger" , "discord" , "runs" , "tui" , "dashboard" , "self-improve" ,
112112 "providers" , "skills" , "memory" , "maintenance" , "voice" , "swarm" , "antigravity" ,
113- "run" , "doctor"
113+ "run" , "doctor" , "browser"
114114 ] ;
115115
116116 if ( ! KNOWN_COMMANDS . includes ( cmd ) ) {
@@ -179,6 +179,9 @@ async function main() {
179179 case "skills" :
180180 await runSkills ( args . slice ( 1 ) ) ;
181181 return ;
182+ case "browser" :
183+ await runBrowser ( args . slice ( 1 ) ) ;
184+ return ;
182185 case "memory" :
183186 await runMemory ( args . slice ( 1 ) ) ;
184187 return ;
@@ -1165,23 +1168,89 @@ async function runSkills(args: string[]): Promise<void> {
11651168 const sub = args [ 0 ] || "list" ;
11661169
11671170 if ( sub === "list" ) {
1168- const alpclaw = await buildAgent ( ) ;
1169- const skills = alpclaw . skills . list ( ) ;
1170- console . log ( pc . bold ( `\n Registered Skills (${ skills . length } )\n` ) ) ;
1171- for ( const skill of skills ) {
1172- const tags = skill . tags ?. join ( ", " ) || "" ;
1173- console . log (
1174- ` ${ pc . cyan ( skill . name . padEnd ( 20 ) ) } ${ pc . dim ( tags ) } ` ,
1175- ) ;
1171+ // Read skills without building the agent (no API keys needed)
1172+ let count = 0 ;
1173+ console . log ( pc . bold ( `\n Registered Skills\n` ) ) ;
1174+
1175+ try {
1176+ const skillsPkg = await import ( "@alpclaw/skills" ) ;
1177+ for ( const [ name , ExportedClass ] of Object . entries ( skillsPkg ) ) {
1178+ if ( typeof ExportedClass === "function" && name . endsWith ( "Skill" ) ) {
1179+ try {
1180+ const instance = new ( ExportedClass as any ) ( ) ;
1181+ if ( instance . manifest ) {
1182+ const tags = instance . manifest . tags ?. join ( ", " ) || "" ;
1183+ console . log ( ` ${ pc . cyan ( instance . manifest . name . padEnd ( 20 ) ) } ${ pc . dim ( tags ) } ` ) ;
1184+ count ++ ;
1185+ }
1186+ } catch { }
1187+ }
1188+ }
1189+
1190+ const toolsPkg = await import ( "@alpclaw/tools" ) ;
1191+ for ( const [ name , ExportedClass ] of Object . entries ( toolsPkg ) ) {
1192+ if ( typeof ExportedClass === "function" && name . endsWith ( "Tool" ) ) {
1193+ try {
1194+ const instance = new ( ExportedClass as any ) ( ) ;
1195+ if ( instance . manifest ) {
1196+ const tags = instance . manifest . tags ?. join ( ", " ) || "" ;
1197+ console . log ( ` ${ pc . cyan ( instance . manifest . name . padEnd ( 20 ) ) } ${ pc . dim ( tags ) } ` ) ;
1198+ count ++ ;
1199+ }
1200+ } catch { }
1201+ }
1202+ }
1203+ } catch ( e ) {
1204+ console . error ( pc . red ( " Failed to load skills list" ) ) ;
11761205 }
1177- console . log ( ) ;
1206+ console . log ( pc . dim ( `\n Total: ${ count } \n` ) ) ;
11781207 return ;
11791208 }
11801209
11811210 console . error ( pc . red ( `Unknown subcommand: skills ${ sub } ` ) ) ;
11821211 console . log ( pc . dim ( " Available: list" ) ) ;
11831212}
11841213
1214+ async function runBrowser ( args : string [ ] ) : Promise < void > {
1215+ const sub = args [ 0 ] ;
1216+ const url = args [ 1 ] ;
1217+ const pathArg = args [ 2 ] ;
1218+
1219+ if ( ! sub || ! url ) {
1220+ console . error ( pc . red ( "Usage: splash browser <open|screenshot> <url> [path]" ) ) ;
1221+ return ;
1222+ }
1223+
1224+ let playwright ;
1225+ try {
1226+ playwright = await import ( "playwright" ) ;
1227+ } catch {
1228+ console . error ( pc . red ( "[ERR] Install playwright or puppeteer to use browser tools." ) ) ;
1229+ return ;
1230+ }
1231+
1232+ try {
1233+ const browser = await playwright . chromium . launch ( { headless : true } ) ;
1234+ const page = await browser . newPage ( ) ;
1235+ await page . goto ( url , { waitUntil : "networkidle" } ) ;
1236+
1237+ if ( sub === "open" ) {
1238+ const content = await page . content ( ) ;
1239+ console . log ( `[OK] Snapshot size: ${ content . length } bytes` ) ;
1240+ } else if ( sub === "screenshot" ) {
1241+ const sp = pathArg || "screenshot.png" ;
1242+ await page . screenshot ( { path : sp , fullPage : true } ) ;
1243+ console . log ( `[OK] Screenshot saved to ${ sp } ` ) ;
1244+ } else {
1245+ console . error ( pc . red ( `[ERR] Unknown browser command: ${ sub } ` ) ) ;
1246+ }
1247+
1248+ await browser . close ( ) ;
1249+ } catch ( e : any ) {
1250+ console . error ( pc . red ( `[ERR] Browser failed: ${ e . message } ` ) ) ;
1251+ }
1252+ }
1253+
11851254// ──────────────────────────────────────────────────────────────────────────
11861255// Memory
11871256// ──────────────────────────────────────────────────────────────────────────
0 commit comments