Skip to content

Commit 2f7f895

Browse files
committed
chore: wip
1 parent 6069578 commit 2f7f895

File tree

6 files changed

+207
-71
lines changed

6 files changed

+207
-71
lines changed

.vscode/dictionary.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ precmd
2929
prefetch
3030
preinstall
3131
quickfix
32+
shellcode
3233
shikijs
3334
socio
3435
Solana

packages/launchpad/bin/cli.ts

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,10 @@
11
#!/usr/bin/env bun
2-
import fs from 'node:fs'
32
import path from 'node:path'
43
import process from 'node:process'
54
import { CAC } from 'cac'
65
import { resolveCommand } from '../src/commands'
76
import { config } from '../src/config'
8-
// Avoid importing the dev barrel here to prevent parsing heavy modules at startup
9-
// doctor helpers no longer needed here; delegated via modular command
10-
// import { formatDoctorReport, runDoctorChecks } from '../src/doctor'
11-
// info helpers no longer needed here; delegated via modular command
12-
// import { formatPackageInfo, formatPackageNotFound, getDetailedPackageInfo, packageExists } from '../src/info'
13-
// search helpers no longer needed here; delegated via modular command
14-
// import { formatSearchResults, getPopularPackages, searchPackages } from '../src/search'
15-
// shim helpers no longer needed here; delegated via modular command
16-
// import { create_shim, shim_dir } from '../src/shim'
17-
// tags helpers no longer needed here; delegated via modular command
18-
// import { formatCategoriesList, formatPackagesByCategory, formatTagSearchResults, getAvailableCategories, getPackagesByCategory, searchPackagesByTag } from '../src/tags'
7+
198
process.env.LAUNCHPAD_CLI_MODE = '1'
209
// Import package.json for version
2110
const packageJson = await import('../package.json')
@@ -345,7 +334,8 @@ cli
345334
const argv: string[] = []
346335
if (options?.verbose)
347336
argv.push('--verbose')
348-
if (options?.path) { argv.push('--path', options.path) }
337+
if (options?.path)
338+
argv.push('--path', options.path)
349339
if (options?.force)
350340
argv.push('--force')
351341
if (options?.autoPath === false)
@@ -385,8 +375,10 @@ cli
385375
argv.push('--force')
386376
if (options?.verbose)
387377
argv.push('--verbose')
388-
if (options?.release) { argv.push('--release', options.release) }
389-
if (options?.target) { argv.push('--target', options.target) }
378+
if (options?.release)
379+
argv.push('--release', options.release)
380+
if (options?.target)
381+
argv.push('--target', options.target)
390382
const cmd = await resolveCommand('setup')
391383
if (!cmd)
392384
return
@@ -449,8 +441,10 @@ cli
449441
argv.push('--force')
450442
if (options?.verbose)
451443
argv.push('--verbose')
452-
if (options?.target) { argv.push('--target', options.target) }
453-
if (options?.release) { argv.push('--release', options.release) }
444+
if (options?.target)
445+
argv.push('--target', options.target)
446+
if (options?.release)
447+
argv.push('--release', options.release)
454448
if (options?.dryRun)
455449
argv.push('--dry-run')
456450
const cmd = await resolveCommand('upgrade')
@@ -552,12 +546,15 @@ cli
552546
.option('--test-mode', 'Generate shellcode for testing (bypasses test environment checks)')
553547
.action(async ({ testMode }) => {
554548
try {
555-
// Use computed dynamic import to prevent Bun from pre-parsing this module at CLI startup
556-
const mod = await import('../src/dev/' + 'shellcode')
557-
const { shellcode } = mod as { shellcode: (testMode?: boolean) => string }
558-
console.log(shellcode(testMode))
559-
// Force immediate exit to prevent any hanging
560-
process.exit(0)
549+
const argv: string[] = []
550+
if (testMode)
551+
argv.push('--test-mode')
552+
const cmd = await resolveCommand('dev:shellcode')
553+
if (!cmd)
554+
return
555+
const code = await cmd.run({ argv, env: process.env })
556+
if (typeof code === 'number' && code !== 0)
557+
process.exit(code)
561558
}
562559
catch (error) {
563560
console.error('Failed to generate shellcode:', error instanceof Error ? error.message : String(error))
@@ -1380,20 +1377,21 @@ cli
13801377
json?: boolean
13811378
}) => {
13821379
try {
1383-
const { runFileDetectionBenchmark } = await import('../src/dev/benchmark')
1384-
1385-
const depths = options?.depths && typeof options.depths === 'string'
1386-
? options.depths.split(',').map(d => Number.parseInt(d.trim(), 10)).filter(d => !Number.isNaN(d))
1387-
: [3, 7, 15, 25]
1388-
1389-
const iterations = options?.iterations ? Number.parseInt(options.iterations, 10) : undefined
1390-
1391-
await runFileDetectionBenchmark({
1392-
depths,
1393-
iterations,
1394-
verbose: options?.verbose || false,
1395-
json: options?.json || false,
1396-
})
1380+
const argv: string[] = []
1381+
if (options?.iterations)
1382+
argv.push('--iterations', String(options.iterations))
1383+
if (options?.depths)
1384+
argv.push('--depths', options.depths)
1385+
if (options?.verbose)
1386+
argv.push('--verbose')
1387+
if (options?.json)
1388+
argv.push('--json')
1389+
const cmd = await resolveCommand('benchmark:file-detection')
1390+
if (!cmd)
1391+
return
1392+
const code = await cmd.run({ argv, env: process.env })
1393+
if (typeof code === 'number' && code !== 0)
1394+
process.exit(code)
13971395
}
13981396
catch (error) {
13991397
console.error('Benchmark failed:', error instanceof Error ? error.message : String(error))
@@ -1433,40 +1431,25 @@ cli
14331431
password?: string
14341432
}) => {
14351433
try {
1436-
const { createProjectDatabase, generateLaravelConfig } = await import('../src/services/database')
1437-
const dbName = options.name || path.basename(process.cwd()).replace(/\W/g, '_')
1438-
1439-
const dbOptions = {
1440-
host: options.host,
1441-
port: options.port ? Number.parseInt(options.port, 10) : undefined,
1442-
user: options.user,
1443-
password: options.password,
1444-
type: options.type === 'auto' ? undefined : options.type as any,
1445-
}
1446-
1447-
const connectionInfo = await createProjectDatabase(dbName, dbOptions)
1448-
1449-
console.warn('\n📋 Database Connection Details:')
1450-
console.warn(` Type: ${connectionInfo.type}`)
1451-
if (connectionInfo.host)
1452-
console.warn(` Host: ${connectionInfo.host}`)
1453-
if (connectionInfo.port)
1454-
console.warn(` Port: ${connectionInfo.port}`)
1455-
console.warn(` Database: ${connectionInfo.database}`)
1456-
if (connectionInfo.username)
1457-
console.warn(` Username: ${connectionInfo.username}`)
1458-
if (connectionInfo.path)
1459-
console.warn(` Path: ${connectionInfo.path}`)
1460-
1461-
// Generate Laravel .env configuration
1462-
const envConfig = generateLaravelConfig(connectionInfo)
1463-
console.warn('\n🔧 Laravel .env configuration:')
1464-
console.warn(envConfig)
1465-
1466-
// Check if this is a Laravel project and offer to update .env
1467-
if (fs.existsSync('artisan') && fs.existsSync('.env')) {
1468-
console.warn('\n💡 Laravel project detected! You can update your .env file with the configuration above.')
1469-
}
1434+
const argv: string[] = []
1435+
if (options?.name)
1436+
argv.push('--name', options.name)
1437+
if (options?.type)
1438+
argv.push('--type', options.type)
1439+
if (options?.host)
1440+
argv.push('--host', options.host)
1441+
if (options?.port)
1442+
argv.push('--port', String(options.port))
1443+
if (options?.user)
1444+
argv.push('--user', options.user)
1445+
if (options?.password)
1446+
argv.push('--password', options.password)
1447+
const cmd = await resolveCommand('db:create')
1448+
if (!cmd)
1449+
return
1450+
const code = await cmd.run({ argv, env: process.env })
1451+
if (typeof code === 'number' && code !== 0)
1452+
process.exit(code)
14701453
}
14711454
catch (error) {
14721455
console.error(`Failed to create database: ${error instanceof Error ? error.message : String(error)}`)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import type { Command } from '../../cli/types'
2+
3+
function parseArgs(argv: string[]): { depths?: number[], iterations?: number, verbose?: boolean, json?: boolean } {
4+
const result: { depths?: number[], iterations?: number, verbose?: boolean, json?: boolean } = {}
5+
for (let i = 0; i < argv.length; i++) {
6+
const a = argv[i]
7+
if (a === '--verbose') {
8+
result.verbose = true
9+
}
10+
else if (a === '--json') {
11+
result.json = true
12+
}
13+
else if (a === '--iterations' && i + 1 < argv.length) {
14+
const v = Number.parseInt(argv[++i], 10)
15+
if (!Number.isNaN(v))
16+
result.iterations = v
17+
}
18+
else if (a === '--depths' && i + 1 < argv.length) {
19+
const v = String(argv[++i])
20+
const depths = v.split(',').map(d => Number.parseInt(d.trim(), 10)).filter(d => !Number.isNaN(d))
21+
if (depths.length > 0)
22+
result.depths = depths
23+
}
24+
}
25+
return result
26+
}
27+
28+
const command: Command = {
29+
name: 'benchmark:file-detection',
30+
description: 'Benchmark file detection performance (shell vs Bun)',
31+
async run({ argv }) {
32+
const { runFileDetectionBenchmark } = await import('../../dev/benchmark')
33+
const opts = parseArgs(argv)
34+
await runFileDetectionBenchmark({
35+
depths: opts.depths,
36+
iterations: opts.iterations,
37+
verbose: opts.verbose,
38+
json: opts.json,
39+
})
40+
return 0
41+
},
42+
}
43+
44+
export default command
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import type { Command } from '../../cli/types'
2+
import fs from 'node:fs'
3+
import path from 'node:path'
4+
import process from 'node:process'
5+
6+
function parseArgs(argv: string[]): {
7+
name?: string
8+
type?: 'postgres' | 'mysql' | 'sqlite' | 'auto'
9+
host?: string
10+
port?: number
11+
user?: string
12+
password?: string
13+
} {
14+
const opts: any = {}
15+
for (let i = 0; i < argv.length; i++) {
16+
const a = argv[i]
17+
if (a === '--name' && i + 1 < argv.length) {
18+
opts.name = String(argv[++i])
19+
}
20+
else if (a === '--type' && i + 1 < argv.length) {
21+
const v = String(argv[++i]) as any
22+
if (['postgres', 'mysql', 'sqlite', 'auto'].includes(v))
23+
opts.type = v
24+
}
25+
else if (a === '--host' && i + 1 < argv.length) {
26+
opts.host = String(argv[++i])
27+
}
28+
else if (a === '--port' && i + 1 < argv.length) {
29+
const v = Number.parseInt(argv[++i], 10)
30+
if (!Number.isNaN(v))
31+
opts.port = v
32+
}
33+
else if (a === '--user' && i + 1 < argv.length) {
34+
opts.user = String(argv[++i])
35+
}
36+
else if (a === '--password' && i + 1 < argv.length) {
37+
opts.password = String(argv[++i])
38+
}
39+
}
40+
return opts
41+
}
42+
43+
const command: Command = {
44+
name: 'db:create',
45+
description: 'Create a database for the current project',
46+
async run({ argv }) {
47+
const { createProjectDatabase, generateLaravelConfig } = await import('../../services/database')
48+
const opts = parseArgs(argv)
49+
50+
const dbName = opts.name || path.basename(process.cwd()).replace(/\W/g, '_')
51+
52+
const dbOptions = {
53+
host: opts.host,
54+
port: opts.port,
55+
user: opts.user,
56+
password: opts.password,
57+
type: opts.type === 'auto' ? undefined : (opts.type as any),
58+
}
59+
60+
const connectionInfo = await createProjectDatabase(dbName, dbOptions)
61+
62+
console.warn('\n📋 Database Connection Details:')
63+
console.warn(` Type: ${connectionInfo.type}`)
64+
if (connectionInfo.host)
65+
console.warn(` Host: ${connectionInfo.host}`)
66+
if (connectionInfo.port)
67+
console.warn(` Port: ${connectionInfo.port}`)
68+
console.warn(` Database: ${connectionInfo.database}`)
69+
if (connectionInfo.username)
70+
console.warn(` Username: ${connectionInfo.username}`)
71+
if (connectionInfo.path)
72+
console.warn(` Path: ${connectionInfo.path}`)
73+
74+
// Generate Laravel .env configuration
75+
const envConfig = generateLaravelConfig(connectionInfo)
76+
console.warn('\n🔧 Laravel .env configuration:')
77+
console.warn(envConfig)
78+
79+
// Check if this is a Laravel project and offer to update .env
80+
if (fs.existsSync('artisan') && fs.existsSync('.env')) {
81+
console.warn('\n💡 Laravel project detected! You can update your .env file with the configuration above.')
82+
}
83+
84+
return 0
85+
},
86+
}
87+
88+
export default command
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* eslint-disable no-console */
2+
import type { Command } from '../../cli/types'
3+
4+
const command: Command = {
5+
name: 'dev:shellcode',
6+
description: 'Generate shell integration code',
7+
async run({ argv }) {
8+
const testMode = argv.includes('--test-mode')
9+
// Use computed dynamic import to prevent Bun from pre-parsing this module at CLI startup
10+
const mod = await import('../../dev/shellcode')
11+
const { shellcode } = mod as { shellcode: (testMode?: boolean) => string }
12+
console.log(shellcode(testMode))
13+
return 0
14+
},
15+
}
16+
17+
export default command

packages/launchpad/src/commands/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const registry: Record<string, () => Promise<Command>> = {
55
'bootstrap': async () => (await import('./bootstrap')).default,
66
'setup': async () => (await import('./setup')).default,
77
'upgrade': async () => (await import('./upgrade')).default,
8+
'dev:shellcode': async () => (await import('./dev/shellcode')).default,
89
'dev:check-updates': async () => (await import('./dev/check-updates')).default,
910
'dev:find-project-root': async () => (await import('./dev/find-project-root')).default,
1011
'dev:md5': async () => (await import('./dev/md5')).default,
@@ -32,6 +33,8 @@ const registry: Record<string, () => Promise<Command>> = {
3233
'outdated': async () => (await import('./outdated')).default,
3334
'update': async () => (await import('./update')).default,
3435
'debug:deps': async () => (await import('./debug/deps')).default,
36+
'benchmark:file-detection': async () => (await import('./benchmark/file-detection')).default,
37+
'db:create': async () => (await import('./db/create')).default,
3538
// services
3639
'start': async () => (await import('./start')).default,
3740
'stop': async () => (await import('./stop')).default,

0 commit comments

Comments
 (0)