@vobs/cli 1.7.8 → 1.8.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.
Files changed (80) hide show
  1. package/dist/banner.cjs +22 -3
  2. package/dist/banner.cjs.map +1 -1
  3. package/dist/banner.d.cts +6 -2
  4. package/dist/banner.d.ts +6 -2
  5. package/dist/banner.js +20 -3
  6. package/dist/banner.js.map +1 -1
  7. package/dist/cli.cjs +361 -21
  8. package/dist/cli.cjs.map +1 -1
  9. package/dist/cli.d.cts +10 -1
  10. package/dist/cli.d.ts +10 -1
  11. package/dist/cli.js +351 -12
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/add.cjs +2 -2
  14. package/dist/commands/add.cjs.map +1 -1
  15. package/dist/commands/add.js +2 -2
  16. package/dist/commands/add.js.map +1 -1
  17. package/dist/commands/build.cjs +2 -2
  18. package/dist/commands/build.cjs.map +1 -1
  19. package/dist/commands/build.js +2 -2
  20. package/dist/commands/build.js.map +1 -1
  21. package/dist/commands/check.cjs +382 -0
  22. package/dist/commands/check.cjs.map +1 -0
  23. package/dist/commands/check.d.cts +34 -0
  24. package/dist/commands/check.d.ts +34 -0
  25. package/dist/commands/check.js +343 -0
  26. package/dist/commands/check.js.map +1 -0
  27. package/dist/commands/dev.cjs +2 -2
  28. package/dist/commands/dev.cjs.map +1 -1
  29. package/dist/commands/dev.js +2 -2
  30. package/dist/commands/dev.js.map +1 -1
  31. package/dist/commands/dsh.cjs +2 -2
  32. package/dist/commands/dsh.cjs.map +1 -1
  33. package/dist/commands/dsh.js +2 -2
  34. package/dist/commands/dsh.js.map +1 -1
  35. package/dist/commands/generate.cjs +2 -2
  36. package/dist/commands/generate.cjs.map +1 -1
  37. package/dist/commands/generate.js +2 -2
  38. package/dist/commands/generate.js.map +1 -1
  39. package/dist/commands/index.cjs +34 -17
  40. package/dist/commands/index.cjs.map +1 -1
  41. package/dist/commands/index.js +25 -8
  42. package/dist/commands/index.js.map +1 -1
  43. package/dist/commands/init.cjs +20 -3
  44. package/dist/commands/init.cjs.map +1 -1
  45. package/dist/commands/init.js +20 -3
  46. package/dist/commands/init.js.map +1 -1
  47. package/dist/index.cjs +399 -25
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.js +388 -14
  50. package/dist/index.js.map +1 -1
  51. package/dist/repl.cjs +34 -17
  52. package/dist/repl.cjs.map +1 -1
  53. package/dist/repl.js +25 -8
  54. package/dist/repl.js.map +1 -1
  55. package/dist/start.cjs +399 -25
  56. package/dist/start.cjs.map +1 -1
  57. package/dist/start.d.cts +8 -1
  58. package/dist/start.d.ts +8 -1
  59. package/dist/start.js +388 -14
  60. package/dist/start.js.map +1 -1
  61. package/dist/utils/logger.cjs +2 -2
  62. package/dist/utils/logger.cjs.map +1 -1
  63. package/dist/utils/logger.js +2 -2
  64. package/dist/utils/logger.js.map +1 -1
  65. package/dist/version.cjs +47 -0
  66. package/dist/version.cjs.map +1 -0
  67. package/dist/version.d.cts +3 -0
  68. package/dist/version.d.ts +3 -0
  69. package/dist/version.js +23 -0
  70. package/dist/version.js.map +1 -0
  71. package/package.json +3 -2
  72. package/src/banner.ts +11 -5
  73. package/src/cli-process.test.ts +139 -0
  74. package/src/cli.ts +30 -2
  75. package/src/commands/check.test.ts +238 -0
  76. package/src/commands/check.ts +461 -0
  77. package/src/commands/init.ts +2 -1
  78. package/src/start.ts +66 -5
  79. package/src/utils/logger.ts +14 -2
  80. package/src/version.ts +27 -0
package/dist/start.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/utils/logger.ts","../src/utils/file.ts","../src/utils/pm.ts","../src/commands/dev.ts","../src/commands/build.ts","../src/commands/generate.ts","../src/commands/add.ts","../src/commands/dsh.ts","../src/banner.ts","../src/repl.ts","../src/start.ts"],"sourcesContent":["import { cac } from 'cac'\nimport { initCommand } from './commands/init.js'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { generateCommand } from './commands/generate.js'\nimport { addCommand } from './commands/add.js'\nimport { dshCommand } from './commands/dsh.js'\nimport { showBanner, showLogo, showDevBanner } from './banner.js'\n\nexport function createCLI(): ReturnType<typeof cac> {\n const cli = cac('vobs')\n\n cli\n .command('init [name]', 'Create a new vobs project')\n .option('--dir <dir>', 'Target directory')\n .option('--pm <pm>', 'Package manager (pnpm/npm/yarn)')\n .option('--no-typescript', 'Do not use TypeScript')\n .option('--no-git', 'Do not initialize git')\n .action(async (name: string, options: Record<string, unknown>) => {\n await initCommand({\n name,\n targetDir: options.dir as string | undefined,\n packageManager: options.pm as 'pnpm' | 'npm' | 'yarn' | undefined,\n typescript: options.typescript !== false,\n git: options.git !== false\n })\n })\n\n cli\n .command('create [name]', 'Alias for init')\n .option('--dir <dir>', 'Target directory')\n .option('--pm <pm>', 'Package manager (pnpm/npm/yarn)')\n .option('--no-typescript', 'Do not use TypeScript')\n .option('--no-git', 'Do not initialize git')\n .action(async (name: string, options: Record<string, unknown>) => {\n await initCommand({\n name,\n targetDir: options.dir as string | undefined,\n packageManager: options.pm as 'pnpm' | 'npm' | 'yarn' | undefined,\n typescript: options.typescript !== false,\n git: options.git !== false\n })\n })\n\n cli\n .command('dev', 'Start the dev server')\n .option('--config <path>', 'Vite config file')\n .option('--port <port>', 'Port to listen on')\n .option('--open', 'Open browser on start')\n .action(async (options: Record<string, unknown>) => {\n showDevBanner()\n await devCommand({\n config: options.config as string | undefined,\n port: options.port as number | undefined,\n open: options.open as boolean | undefined\n })\n })\n\n cli\n .command('build', 'Build for production')\n .option('--config <path>', 'Vite config file')\n .option('--outDir <dir>', 'Output directory')\n .option('--mode <mode>', 'Build mode')\n .action(async (options: Record<string, unknown>) => {\n await buildCommand({\n config: options.config as string | undefined,\n outDir: options.outDir as string | undefined,\n mode: options.mode as string | undefined\n })\n })\n\n cli\n .command('generate [name]', 'Generate code (component/page)')\n .alias('g')\n .option('--type <type>', 'Type: component or page')\n .option('--dir <dir>', 'Target directory')\n .action(async (name: string, options: Record<string, unknown>) => {\n await generateCommand({\n name,\n type: (options.type as 'component' | 'page') || undefined,\n targetDir: options.dir as string | undefined\n })\n })\n\n cli\n .command('add [package]', 'Add a package')\n .option('-D, --dev', 'Save as dev dependency')\n .action(async (pkg: string, options: Record<string, unknown>) => {\n await addCommand({\n package: pkg,\n dev: options.dev as boolean | undefined\n })\n })\n\n cli\n .command('dsh [action] [target]', 'DSH 插件工具链(init / dev / build / check / install)')\n .option('--dir <dir>', 'init:目标目录')\n .option('--pm <pm>', 'init:包管理器(pnpm/npm)')\n .option('--port <port>', 'dev:预览端口', { default: 5199 })\n .option('--profile <name>', 'install:DSH profile 名', { default: 'desktop' })\n .option('--spec <spec>', 'install:完整安装 spec')\n .option('--repo <owner/name>', 'install:GitHub owner/name')\n .option('--tag <ref>', 'install:Git tag / 分支 / commit')\n .option('--subpath <path>', 'install:仓库内子目录')\n .option('--from <path>', 'install:从本地目录安装')\n .option('--dry', 'install:只打印命令,不执行')\n .action(async (action: string, target: string | undefined, options: Record<string, unknown>) => {\n await dshCommand(action, target, {\n dir: options.dir as string | undefined,\n pm: options.pm as 'pnpm' | 'npm' | undefined,\n profile: options.profile as string | undefined,\n spec: options.spec as string | undefined,\n repo: options.repo as string | undefined,\n tag: options.tag as string | undefined,\n subpath: options.subpath as string | undefined,\n from: options.from as string | undefined,\n dry: options.dry === true,\n port: options.port === undefined ? undefined : Number(options.port)\n })\n })\n\n cli\n .command('logo', 'Show the vobs CLI logo and version info')\n .action(() => {\n showLogo()\n })\n\n cli.on('--help', () => {\n showBanner()\n })\n\n cli.help()\n cli.version('1.0.0')\n\n return cli\n}","import { resolve } from 'node:path'\nimport { execSync } from 'node:child_process'\nimport * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { scaffoldProject } from '../utils/file.js'\nimport { installDependencies } from '../utils/pm.js'\nimport type { InitOptions } from '../types.js'\n\nexport async function initCommand(options: Partial<InitOptions>): Promise<void> {\n const projectName = options.name || (await p.text({\n message: 'Project name:',\n placeholder: 'my-vobs-app',\n validate: (v) => !v ? 'Project name is required' : undefined\n })) as string\n\n if (p.isCancel(projectName)) {\n p.cancel('Cancelled')\n return\n }\n\n const targetDir = options.targetDir || resolve(process.cwd(), projectName)\n\n const packageManager = options.packageManager || (await p.select({\n message: 'Package manager:',\n options: [\n { value: 'pnpm', label: 'pnpm' },\n { value: 'npm', label: 'npm' },\n { value: 'yarn', label: 'yarn' }\n ]\n })) as 'pnpm' | 'npm' | 'yarn'\n\n if (p.isCancel(packageManager)) {\n p.cancel('Cancelled')\n return\n }\n\n const useTypescript = options.typescript ?? (await p.confirm({\n message: 'Use TypeScript?',\n initialValue: true\n })) as boolean\n\n if (p.isCancel(useTypescript)) {\n p.cancel('Cancelled')\n return\n }\n\n const initGit = options.git ?? (await p.confirm({\n message: 'Initialize a git repository?',\n initialValue: true\n })) as boolean\n\n if (p.isCancel(initGit)) {\n p.cancel('Cancelled')\n return\n }\n\n logger.step(`Creating project ${projectName}...`)\n\n await scaffoldProject(targetDir, {\n name: projectName,\n packageName: projectName.toLowerCase().replace(/\\s+/g, '-'),\n typescript: useTypescript,\n vobsVersion: '1.0.0'\n })\n\n logger.success('Project scaffolded')\n\n logger.step('Installing dependencies...')\n installDependencies(targetDir, packageManager)\n logger.success('Dependencies installed')\n\n if (initGit) {\n logger.step('Initializing git repository...')\n try {\n execSync('git init', { cwd: targetDir, stdio: 'ignore' })\n logger.success('Git repository initialized')\n } catch {\n logger.warn('Git not found, skipping git init')\n }\n }\n\n logger.step('Done!')\n console.log(`\\n ${packageManager === 'pnpm' ? 'pnpm' : packageManager === 'yarn' ? 'yarn' : 'npm run'} dev\\n`)\n}","import pc from 'picocolors'\n\nfunction timestamp(): string {\n return pc.dim(`[${new Date().toLocaleTimeString()}]`)\n}\n\nexport function info(msg: string): void {\n console.log(`${timestamp()} ${pc.cyan('ℹ')} ${msg}`)\n}\n\nexport function success(msg: string): void {\n console.log(`${timestamp()} ${pc.green('✔')} ${msg}`)\n}\n\nexport function warn(msg: string): void {\n console.log(`${timestamp()} ${pc.yellow('⚠')} ${msg}`)\n}\n\nexport function error(msg: string): void {\n console.error(`${timestamp()} ${pc.red('✖')} ${msg}`)\n}\n\nexport function step(msg: string): void {\n console.log(`\\n ${pc.bold(pc.cyan(msg))}`)\n}\n\nexport const logger = { info, success, warn, error, step }","import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport Handlebars from 'handlebars'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst TEMPLATES_ROOT = resolve(__dirname, '..', 'templates')\n\n/** Get the absolute path to the templates directory */\nexport function getTemplatesDir(): string {\n return TEMPLATES_ROOT\n}\n\n/** Read a template file and compile it with Handlebars */\nexport function renderTemplate(\n templatePath: string,\n context: Record<string, unknown>\n): string {\n const source = readFileSync(templatePath, 'utf-8')\n const template = Handlebars.compile(source)\n return template(context)\n}\n\n/** Write a file, creating parent directories if needed */\nexport function writeFile(dir: string, filename: string, content: string): void {\n const filePath = resolve(dir, filename)\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, content, 'utf-8')\n}\n\n/** Ensure a directory exists */\nexport function ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/** Check if a path exists */\nexport function pathExists(path: string): boolean {\n return existsSync(path)\n}\n\n/** Copy a template directory recursively, rendering each .hbs file */\nasync function copyDirRecursive(srcDir: string, destDir: string, context: Record<string, unknown>): Promise<void> {\n const { readdirSync } = await import('node:fs')\n const { join } = await import('node:path')\n\n const entries = readdirSync(srcDir, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name)\n const isHbs = entry.name.endsWith('.hbs')\n const destName = isHbs ? entry.name.slice(0, -4) : entry.name\n const destPath = join(destDir, destName)\n\n if (entry.isDirectory()) {\n ensureDir(destPath)\n await copyDirRecursive(srcPath, destPath, context)\n } else if (isHbs) {\n const content = renderTemplate(srcPath, context)\n writeFile(destDir, destName, content)\n } else {\n const content = readFileSync(srcPath, 'utf-8')\n writeFile(destDir, destName, content)\n }\n }\n}\n\n/** Scaffold a project from a named template under `src/templates`. */\nexport async function scaffoldProject(\n targetDir: string,\n context: Record<string, unknown>,\n template = 'basic'\n): Promise<void> {\n const templateDir = resolve(TEMPLATES_ROOT, template)\n if (!existsSync(templateDir)) {\n throw new Error(`模板不存在: ${template}(可用模板见 ${TEMPLATES_ROOT})`)\n }\n ensureDir(targetDir)\n await copyDirRecursive(templateDir, targetDir, context)\n}","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { execSync } from 'node:child_process'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn'\n\n/** Detect the package manager to use */\nexport function detectPackageManager(targetDir?: string): PackageManager {\n // Check if a specific package manager is locked\n if (targetDir) {\n if (existsSync(resolve(targetDir, 'pnpm-lock.yaml'))) return 'pnpm'\n if (existsSync(resolve(targetDir, 'yarn.lock'))) return 'yarn'\n if (existsSync(resolve(targetDir, 'package-lock.json'))) return 'npm'\n }\n\n // Check for global preference\n const userAgent = process.env.npm_config_user_agent || ''\n if (userAgent.startsWith('pnpm')) return 'pnpm'\n if (userAgent.startsWith('yarn')) return 'yarn'\n if (userAgent.startsWith('npm')) return 'npm'\n\n // Default to pnpm\n return 'pnpm'\n}\n\n/** Install dependencies in a directory */\nexport function installDependencies(targetDir: string, pm: PackageManager): void {\n const cmd = pm === 'yarn' ? 'yarn' : `${pm} install`\n execSync(cmd, { cwd: targetDir, stdio: 'inherit' })\n}\n\n/** Add a package as a dependency */\nexport function addPackage(targetDir: string, pm: PackageManager, pkg: string, dev: boolean): void {\n const installFlag = dev ? '-D' : ''\n const cmd = pm === 'npm'\n ? `npm install ${installFlag} ${pkg}`\n : pm === 'yarn'\n ? `yarn add ${installFlag} ${pkg}`\n : `pnpm add ${installFlag} ${pkg}`\n\n execSync(cmd, { cwd: targetDir, stdio: 'inherit' })\n}","import { createServer } from 'vite'\nimport { logger } from '../utils/logger.js'\nimport type { DevOptions } from '../types.js'\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n logger.info('Starting dev server...')\n\n const server = await createServer({\n configFile: options.config,\n server: {\n port: options.port,\n open: options.open\n }\n })\n\n await server.listen()\n server.printUrls()\n logger.success('Dev server is running')\n}","import { build } from 'vite'\nimport { logger } from '../utils/logger.js'\nimport type { BuildOptions } from '../types.js'\n\nexport async function buildCommand(options: BuildOptions): Promise<void> {\n logger.info('Building for production...')\n\n await build({\n configFile: options.config,\n build: {\n outDir: options.outDir\n },\n mode: options.mode || 'production'\n })\n\n logger.success('Build complete')\n}","import { resolve } from 'node:path'\nimport * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { renderTemplate, writeFile, getTemplatesDir, ensureDir } from '../utils/file.js'\nimport type { GenerateOptions, ComponentTemplateContext, PageTemplateContext } from '../types.js'\n\nexport async function generateCommand(options: Partial<GenerateOptions>): Promise<void> {\n const type = options.type || (await p.select({\n message: 'What to generate?',\n options: [\n { value: 'component', label: 'Component' },\n { value: 'page', label: 'Page' }\n ]\n })) as 'component' | 'page'\n\n if (p.isCancel(type)) {\n p.cancel('Cancelled')\n return\n }\n\n const name = options.name || (await p.text({\n message: 'Name:',\n placeholder: type === 'component' ? 'Button' : 'AboutPage',\n validate: (v) => !v ? 'Name is required' : undefined\n })) as string\n\n if (p.isCancel(name)) {\n p.cancel('Cancelled')\n return\n }\n\n const templatesDir = getTemplatesDir()\n\n if (type === 'component') {\n const targetDir = options.targetDir || resolve(process.cwd(), 'src/components')\n ensureDir(targetDir)\n\n const context: ComponentTemplateContext = {\n name: toPascalCase(name),\n kebabName: toKebabCase(name)\n }\n\n const content = renderTemplate(\n resolve(templatesDir, 'component.hbs'),\n context as unknown as Record<string, unknown>\n )\n\n const filename = `${context.name}.tsx`\n writeFile(targetDir, filename, content)\n logger.success(`Created ${type} at ${resolve(targetDir, filename)}`)\n } else {\n const targetDir = options.targetDir || resolve(process.cwd(), 'src/pages')\n ensureDir(targetDir)\n\n const context: PageTemplateContext = {\n name: toPascalCase(name),\n path: `/${toKebabCase(name)}`\n }\n\n const content = renderTemplate(\n resolve(templatesDir, 'page.hbs'),\n context as unknown as Record<string, unknown>\n )\n\n const filename = `${context.name}.tsx`\n writeFile(targetDir, filename, content)\n logger.success(`Created ${type} at ${resolve(targetDir, filename)}`)\n }\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(/\\s+/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('')\n}\n\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([A-Z])/g, '-$1')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/--+/g, '-')\n .replace(/^-|-$/g, '')\n}","import * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { detectPackageManager, addPackage } from '../utils/pm.js'\nimport type { AddOptions } from '../types.js'\n\nexport async function addCommand(options: Partial<AddOptions>): Promise<void> {\n const pkg = options.package || (await p.text({\n message: 'Package to add:',\n placeholder: '@vobs/ui',\n validate: (v) => !v ? 'Package name is required' : undefined\n })) as string\n\n if (p.isCancel(pkg)) {\n p.cancel('Cancelled')\n return\n }\n\n const isDev = options.dev ?? (await p.confirm({\n message: 'Save as dev dependency?',\n initialValue: false\n })) as boolean\n\n if (p.isCancel(isDev)) {\n p.cancel('Cancelled')\n return\n }\n\n const pm = detectPackageManager(process.cwd())\n\n logger.step(`Installing ${pkg}...`)\n addPackage(process.cwd(), pm, pkg, isDev)\n\n logger.success(`Installed ${pkg}`)\n console.log(`\\n Import it in your code:\\n`)\n console.log(` import { ... } from '${pkg}'`)\n console.log()\n}","import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { execSync, spawnSync } from 'node:child_process'\nimport { createServer, type ServerResponse } from 'node:http'\nimport { createRequire } from 'node:module'\nimport { isAbsolute, basename, dirname, join, relative, resolve } from 'node:path'\nimport * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { ensureDir, scaffoldProject } from '../utils/file.js'\nimport { installDependencies, type PackageManager } from '../utils/pm.js'\n\nexport interface DshOptions {\n dir?: string\n pm?: PackageManager\n profile?: string\n spec?: string\n repo?: string\n tag?: string\n subpath?: string\n from?: string\n dry?: boolean\n port?: number\n}\n\n/** 平台内置模块:这些 `require` 出现在产物里是正常的。 */\nconst PLATFORM_MODULES = ['react', 'react-dom']\n\nconst vobsVersion = (): string => {\n try {\n const manifest = JSON.parse(\n readFileSync(new URL('../../package.json', import.meta.url), 'utf8')\n ) as { version?: string }\n return manifest.version ?? '1.7.5'\n } catch {\n return '1.7.5'\n }\n}\n\n/** 去掉 scope,得到 cordis 行 id 与目录名都可用的标识。 */\nfunction toRowId(packageName: string): string {\n return packageName.replace(/^@[^/]+\\//u, '')\n}\n\n/* ------------------------------------------------------------------ init */\n\nasync function dshInitCommand(target: string | undefined, options: DshOptions): Promise<void> {\n const name = target ?? ((await p.text({\n message: '插件包名(npm 包名,小写):',\n placeholder: 'dsh-plugin-my-panel',\n validate: value => (/^[a-z0-9][a-z0-9._~-]*$/u.test(value) ? undefined : '必须是合法的 npm 包名')\n })) as string)\n\n if (p.isCancel(name)) {\n p.cancel('已取消')\n return\n }\n\n const packageManager =\n options.pm ??\n ((await p.select({\n message: '包管理器:',\n options: [\n { value: 'pnpm', label: 'pnpm' },\n { value: 'npm', label: 'npm' }\n ]\n })) as PackageManager)\n\n if (p.isCancel(packageManager)) {\n p.cancel('已取消')\n return\n }\n\n const targetDir = options.dir !== undefined ? resolve(options.dir) : resolve(process.cwd(), name)\n const rowId = toRowId(name)\n const displayName = rowId\n .replace(/^dsh-plugin-/u, '')\n .split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n\n logger.step(`创建 DSH 插件项目 ${name} …`)\n await scaffoldProject(\n targetDir,\n { packageName: name, rowId, displayName, vobsVersion: vobsVersion() },\n 'dsh-plugin'\n )\n\n // 单独写 .gitignore:模板里的点文件在打包时容易丢,而且这里的规则有一条很关键 ——\n // lib/ 是产物,**必须提交**(DSH 安装时不构建)。\n ensureDir(targetDir)\n writeFileSync(\n resolve(targetDir, '.gitignore'),\n ['node_modules/', '*.log', '*.tsbuildinfo', '', '# lib/ 是构建产物,必须提交:DSH 安装时不会构建你的包。', ''].join('\\n'),\n 'utf8'\n )\n logger.success('项目已生成')\n\n logger.step('安装依赖 …')\n try {\n installDependencies(targetDir, packageManager)\n logger.success('依赖已安装')\n } catch {\n logger.warn(`依赖安装失败,请手动执行 ${packageManager} install`)\n }\n\n logger.step('下一步')\n console.log(`\n cd ${name}\n ${packageManager} run dev # 本地预览,不用装进 DSH\n ${packageManager} run build # 产出 lib/{index,client}.js\n\n # 提交产物并打 tag 之后,在 DSH 插件页填:\n github:<owner>/<repo>#v0.1.0&path:/<本包在仓库中的路径>\n`)\n}\n\n/* ----------------------------------------------------------------- build */\n\n/**\n * 构建 DSH 插件产物。\n *\n * 一个可安装的插件包有**两半**:Host 侧(cordis 插件,ESM)与 Client 侧\n * (浏览器 bundle)。项目的 vite.config 只负责 Client(`dshBundle()` 会把产物\n * 落到 package.json 声明的位置),Host 这一半由本命令补上 ——\n * 否则 `exports[\".\"]` 指向的文件根本不存在,装进 DSH 必然失败。\n */\nasync function dshBuildCommand(): Promise<void> {\n const projectDir = process.cwd()\n const configFile = resolve(projectDir, 'vite.config.ts')\n if (!existsSync(configFile)) {\n logger.error('当前目录没有 vite.config.ts,请在插件项目根目录运行。')\n process.exitCode = 1\n return\n }\n\n const manifest = readManifest(projectDir)\n if (manifest === undefined) {\n logger.error('读不到 package.json。')\n process.exitCode = 1\n return\n }\n\n const hostEntry = resolveExport(manifest, '.')\n if (hostEntry === undefined) {\n logger.error('package.json 的 exports 里没有 \".\",DSH 加载不到 Host 侧插件。')\n process.exitCode = 1\n return\n }\n\n const { build } = await import('vite')\n\n logger.info('构建客户端产物 …')\n await build({ configFile, mode: 'production' })\n\n logger.info('构建 Host 产物 …')\n const hostTarget = resolve(projectDir, hostEntry.replace(/^\\.\\//u, ''))\n const hostEntrySource = resolve(projectDir, 'src', 'host', 'index.ts')\n if (!existsSync(hostEntrySource)) {\n logger.warn(`没有找到 ${hostEntrySource},跳过 Host 构建。`)\n return\n }\n await build({\n configFile: false,\n root: projectDir,\n logLevel: 'warn',\n build: {\n outDir: relative(projectDir, dirname(hostTarget)) || '.',\n emptyOutDir: false,\n target: 'es2022',\n minify: false,\n sourcemap: false,\n lib: {\n entry: hostEntrySource,\n formats: ['es'],\n fileName: () => basename(hostTarget)\n }\n }\n })\n\n logger.success('构建完成 → 客户端与 Host 产物都已就位')\n}\n\n/* ------------------------------------------------------------------ dev */\n\n/** 从 exports 字段里取出一个子路径,兼容字符串与一层条件对象两种写法。 */\nexport function resolveExport(manifest: Record<string, unknown>, key: string): string | undefined {\n const exportsField = (manifest.exports ?? {}) as Record<string, unknown>\n const entry = exportsField[key]\n if (typeof entry === 'string') return entry\n if (typeof entry === 'object' && entry !== null) {\n const record = entry as Record<string, unknown>\n for (const condition of ['default', 'import', 'require']) {\n const value = record[condition]\n if (typeof value === 'string') return value\n }\n }\n return undefined\n}\n\n/** 生成预览页。纯函数,便于单测。 */\nexport function buildPreviewHtml(options: { packageName: string; title?: string }): string {\n // 包名会被嵌进 <script> 里:JSON 序列化不会转义 `/`,所以必须自己把 `<` 干掉,\n // 否则一个含 </script> 的包名就能突破标签。\n const name = JSON.stringify(options.packageName).replace(/</gu, '\\\\u003c')\n const title = (options.title ?? options.packageName).replace(/[<>&]/gu, '')\n return `<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>vobs preview · ${title}</title>\n</head>\n<body>\n<div id=\"root\"></div>\n\n<!-- 1. 先装垫片:必须在插件 bundle 之前,捕获它的 factory 注册 -->\n<script>\n window.__VOBS_DSH_PREVIEW__ = { factories: new Map() };\n window.__ModuleLoader__ = {\n load: function (entry) { window.__VOBS_DSH_PREVIEW__.factories.set(entry.id, entry.factory); }\n };\n</script>\n\n<!-- 2. 插件产物:它只注册 factory,不产生副作用 -->\n<script src=\"/client.js\"></script>\n\n<!-- 3. 启动预览外壳 -->\n<script type=\"module\">\n import { startPreview } from '/preview.js';\n window.__VOBS_PREVIEW__ = startPreview({\n container: document.getElementById('root'),\n packageName: ${name}\n });\n</script>\n\n<!-- 4. 重建后自动刷新;?static=1 关掉长连接,便于无头截图与 CI 断言 -->\n<script>\n if (!location.search.includes('static')) {\n new EventSource('/events').addEventListener('reload', function () { location.reload(); });\n }\n</script>\n</body>\n</html>\n`\n}\n\n/**\n * vite 的构建监听器。只声明本命令用到的两个成员 ——\n * `vite` 没有把 rollup 的 `RollupWatcher` 再导出,为一个 dev 命令引入 rollup 类型不划算。\n */\ninterface BuildWatcher {\n on(event: 'event', handler: (event: { code?: string; error?: { message?: string } }) => void): void\n close(): Promise<void>\n}\n\nasync function dshDevCommand(options: DshOptions): Promise<void> {\n const projectDir = process.cwd()\n const manifest = readManifest(projectDir)\n if (manifest === undefined) {\n logger.error('当前目录没有可读的 package.json。')\n process.exitCode = 1\n return\n }\n if (readManifest(projectDir)?.dsh === undefined) {\n logger.error('这不是一个 DSH 插件项目(package.json 里没有 dsh 字段)。')\n process.exitCode = 1\n return\n }\n\n const packageName = typeof manifest.name === 'string' ? manifest.name : 'dsh-plugin'\n const clientEntry = resolveExport(manifest, './client')\n if (clientEntry === undefined) {\n logger.error('package.json 的 exports 里没有 \"./client\",页面拿不到客户端 bundle。')\n process.exitCode = 1\n return\n }\n const clientFile = resolve(projectDir, clientEntry.replace(/^\\.\\//u, ''))\n\n // 预览运行时从**项目自己**的 node_modules 解析:项目才是声明 @vobs/dsh 的那一方。\n let previewFile: string | undefined\n try {\n const projectRequire = createRequire(join(projectDir, 'package.json'))\n let packageRoot: string | undefined\n try {\n // 首选:包导出了 ./package.json(@vobs/dsh 有)。\n packageRoot = dirname(projectRequire.resolve('@vobs/dsh/package.json'))\n } catch {\n // 回退:解析主入口(dist/index.js 或 dist/index.cjs),再回到包根。\n packageRoot = dirname(dirname(projectRequire.resolve('@vobs/dsh')))\n }\n const candidate = join(packageRoot, 'dist', 'preview.js')\n previewFile = existsSync(candidate) ? candidate : undefined\n } catch {\n previewFile = undefined\n }\n if (previewFile === undefined) {\n logger.error('项目里找不到 @vobs/dsh 的预览运行时。先安装依赖:pnpm add -D @vobs/dsh')\n process.exitCode = 1\n return\n }\n\n const port = options.port ?? 5199\n const clients = new Set<ServerResponse>()\n const broadcast = (event: string): void => {\n for (const client of clients) client.write(`event: ${event}\\ndata: 1\\n\\n`)\n }\n\n /* 先构建一次,再进监听模式 */\n logger.info('构建产物 …')\n const { build } = await import('vite')\n const configFile = resolve(projectDir, 'vite.config.ts')\n let buildError: string | undefined\n\n try {\n const watcher = (await build({\n configFile,\n mode: 'development',\n logLevel: 'warn',\n build: { watch: {} }\n })) as unknown as BuildWatcher\n\n watcher.on('event', event => {\n if (event.code === 'END') {\n buildError = undefined\n logger.success('重新构建完成')\n broadcast('reload')\n } else if (event.code === 'ERROR') {\n buildError = event.error?.message ?? '构建失败'\n logger.error(buildError)\n }\n })\n process.on('SIGINT', () => {\n void watcher.close().then(() => process.exit(0))\n })\n } catch (error) {\n logger.error(`构建失败:${error instanceof Error ? error.message : String(error)}`)\n process.exitCode = 1\n return\n }\n\n const server = createServer((request, response) => {\n const url = (request.url ?? '/').split('?')[0]\n\n if (url === '/events') {\n response.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-store',\n connection: 'keep-alive'\n })\n response.write(': connected\\n\\n')\n clients.add(response)\n request.on('close', () => clients.delete(response))\n return\n }\n\n const send = (body: string | Buffer, type: string): void => {\n response.writeHead(200, { 'content-type': type, 'cache-control': 'no-store' })\n response.end(body)\n }\n\n if (url === '/') {\n send(buildPreviewHtml({ packageName }), 'text/html; charset=utf-8')\n return\n }\n if (url === '/preview.js') {\n void readFile(previewFile as string).then(body => send(body, 'text/javascript; charset=utf-8'))\n return\n }\n if (url === '/client.js') {\n if (!existsSync(clientFile)) {\n response.writeHead(503, { 'content-type': 'text/plain; charset=utf-8' })\n response.end(`还没有产物:${clientEntry}\\n${buildError ?? ''}`)\n return\n }\n void readFile(clientFile).then(body => send(body, 'text/javascript; charset=utf-8'))\n return\n }\n\n response.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' })\n response.end('not found')\n })\n\n await new Promise<void>(resolveListen => {\n server.listen(port, '127.0.0.1', resolveListen)\n })\n\n logger.success(`预览已就绪:http://127.0.0.1:${port}/`)\n console.log('\\n 改代码会自动重建并刷新页面;Ctrl+C 退出。\\n')\n}\n\n/* ----------------------------------------------------------------- check */\n\ninterface CheckResult {\n errors: string[]\n warnings: string[]\n passed: string[]\n}\n\n/** 读取并解析 package.json。 */\nfunction readManifest(dir: string): Record<string, unknown> | undefined {\n try {\n return JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf8')) as Record<string, unknown>\n } catch {\n return undefined\n }\n}\n\n/**\n * 装前一致性校验:把「装进 DSH 之后才发现坏」的问题提前到本地。\n *\n * 检查项全部来自 DSH 的客户端插件契约与 pnpm 的 Git 子目录安装约束。\n */\nexport function collectIssues(dir: string): CheckResult {\n const result: CheckResult = { errors: [], warnings: [], passed: [] }\n const manifest = readManifest(dir)\n\n if (manifest === undefined) {\n result.errors.push('读不到 package.json(JSON 语法错误或文件缺失)')\n return result\n }\n\n const name = typeof manifest.name === 'string' ? manifest.name : ''\n if (name === '') result.errors.push('package.json 缺少 name')\n else result.passed.push(`包名 ${name}`)\n\n const dsh = (manifest.dsh ?? {}) as Record<string, unknown>\n const bundle = (dsh.bundle ?? {}) as Record<string, unknown>\n const client = (dsh.client ?? {}) as Record<string, unknown>\n\n if (typeof bundle.patch !== 'string') {\n result.errors.push('缺少 dsh.bundle.patch —— DSH 不会把这个包当作组合包(bundle)')\n } else {\n const patchPath = resolve(dir, bundle.patch.replace(/^\\.\\//u, ''))\n if (!existsSync(patchPath)) {\n result.errors.push(`dsh.bundle.patch 指向的 ${bundle.patch} 不存在`)\n } else {\n const text = readFileSync(patchPath, 'utf8')\n if (!text.includes('insert:')) result.errors.push('cordis.patch.yml 里没有 insert: 段落,插件行不会进组合树')\n else if (name !== '' && !text.includes(name)) {\n result.warnings.push(`cordis.patch.yml 里没有出现包名 ${name},确认 insert 的 name 写对了`)\n } else result.passed.push('cordis.patch.yml 会插入本包的行')\n }\n }\n\n if (client.platform !== 'web') {\n result.errors.push(\"dsh.client.platform 必须是 'web' —— 否则 DSH 不会给页面提供客户端 bundle\")\n } else result.passed.push('dsh.client.platform = web')\n\n const exportsField = (manifest.exports ?? {}) as Record<string, string>\n const hostEntry = exportsField['.']\n const clientEntry = exportsField['./client']\n if (typeof hostEntry !== 'string') result.errors.push('exports[\".\"] 未声明 —— DSH 加载不到 Host 侧插件')\n else if (!existsSync(resolve(dir, hostEntry.replace(/^\\.\\//u, '')))) {\n result.errors.push(`exports[\".\"] 指向的 ${hostEntry} 不存在,先构建`)\n } else result.passed.push('Host 入口存在')\n\n if (typeof clientEntry !== 'string') result.errors.push('exports[\"./client\"] 未声明 —— 页面拿不到客户端 bundle')\n\n const scripts = (manifest.scripts ?? {}) as Record<string, string>\n if (scripts.prepare !== undefined || scripts.postinstall !== undefined) {\n result.errors.push('声明了 prepare / postinstall —— DSH 安装时不构建,产物必须预先提交')\n } else result.passed.push('没有安装期生命周期钩子')\n\n const dependencyText = JSON.stringify({\n dependencies: manifest.dependencies,\n peerDependencies: manifest.peerDependencies,\n devDependencies: manifest.devDependencies\n })\n if (dependencyText.includes('workspace:')) {\n result.errors.push('依赖里出现了 workspace: 协议 —— GitHub 子目录直装时解析不了')\n } else result.passed.push('没有 workspace: 协议依赖')\n\n if (typeof clientEntry === 'string') {\n const clientPath = resolve(dir, clientEntry.replace(/^\\.\\//u, ''))\n if (!existsSync(clientPath)) {\n result.errors.push(`客户端产物 ${clientEntry} 不存在,先运行构建`)\n } else {\n const code = readFileSync(clientPath, 'utf8')\n const loads = (code.match(/__ModuleLoader__\\.load\\(/gu) ?? []).length\n if (loads !== 1) result.errors.push(`客户端产物里 __ModuleLoader__.load 出现 ${loads} 次,应为 1 次(先构建)`)\n else result.passed.push('产物形态是 DSH 客户端模块协议')\n\n if (code.includes('import(')) result.errors.push('客户端产物里有动态 import(),DSH 只支持自包含 chunk')\n\n const requires = [...code.matchAll(/require\\((['\"])([^'\"]+)\\1\\)/gu)].map(match => match[2] ?? '')\n const foreign = requires.filter(id => !PLATFORM_MODULES.includes(id) && !id.startsWith('@deepseek-ai/'))\n if (foreign.length > 0) {\n result.errors.push(`产物 require 了非平台模块:${[...new Set(foreign)].join(', ')} —— 依赖没有被打进产物`)\n } else if (requires.length > 0) {\n result.passed.push(`产物只 require 平台模块(${[...new Set(requires)].join(', ')})`)\n }\n\n if (name !== '' && !code.includes(`\"${name}\"`) && !code.includes(`'${name}'`)) {\n result.warnings.push(`产物里的模块 id 与包名 ${name} 不一致,检查 dshBundle({ id })`)\n }\n }\n }\n\n return result\n}\n\nfunction dshCheckCommand(): void {\n const dir = process.cwd()\n const result = collectIssues(dir)\n\n logger.step('DSH 插件装前校验')\n for (const item of result.passed) console.log(` ✔ ${item}`)\n for (const item of result.warnings) console.log(` ⚠ ${item}`)\n for (const item of result.errors) console.log(` ✖ ${item}`)\n\n if (result.errors.length > 0) {\n logger.error(`${result.errors.length} 项不通过,装进 DSH 后不会正常工作。`)\n process.exitCode = 1\n return\n }\n logger.success(`全部通过(${result.passed.length} 项${result.warnings.length > 0 ? `,${result.warnings.length} 条警告` : ''})`)\n}\n\n/* --------------------------------------------------------------- install */\n\n/** 读取 pnpm 版本;拿不到就返回 undefined。 */\nfunction readPnpmVersion(): string | undefined {\n try {\n return execSync('pnpm --version', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()\n } catch {\n return undefined\n }\n}\n\nconst majorOf = (version: string | undefined): number => {\n const major = Number.parseInt((version ?? '').split('.')[0] ?? '', 10)\n return Number.isFinite(major) ? major : 0\n}\n\n/** 组装安装 spec。 */\nexport function buildInstallSpec(options: DshOptions): { spec?: string; error?: string } {\n if (options.spec !== undefined) return { spec: options.spec }\n\n if (options.from !== undefined) {\n const target = resolve(options.from)\n if (!existsSync(target)) return { error: `--from 指向的路径不存在:${target}` }\n return { spec: target }\n }\n\n if (options.repo !== undefined) {\n const ref = options.tag !== undefined && options.tag !== '' ? `#${options.tag}` : ''\n const sub = options.subpath !== undefined && options.subpath !== '' ? `${ref === '' ? '#' : '&'}path:${options.subpath}` : ''\n return { spec: `github:${options.repo}${ref}${sub}` }\n }\n\n return { error: '需要 --spec、--from 或 --repo 之一来指定安装来源。' }\n}\n\n/**\n * 在 Windows 上调用 dsh 的引号策略。\n *\n * `.cmd` 无法被 CreateProcess 直接执行(EINVAL),必须走 shell;而 shell 会把\n * 裸传参数原样拼接,`github:owner/repo#tag&path:/sub` 里的 `&` 就变成命令分隔符 ——\n * 实测会**静默地把 spec 截断成 `#tag`**,然后装上 monorepo 根而不是目标子包。\n * 所以含特殊字符的参数必须自己加引号。\n */\nconst CMD_NEEDS_QUOTE = /[\\s&|<>^()\"']/u\n\nfunction quoteForCmd(part: string): string {\n return CMD_NEEDS_QUOTE.test(part) ? `\"${part.replace(/\"/gu, '\"\"')}\"` : part\n}\n\n/** 组装一条给 shell 执行的命令行(仅供 Windows 使用)。 */\nexport function buildShellCommand(exe: string, args: readonly string[]): string {\n return [exe, ...args].map(quoteForCmd).join(' ')\n}\n\nfunction spawnDsh(args: string[], dry: boolean): number {\n if (dry) {\n console.log(`\\n ${buildShellCommand('dsh', args)}\\n`)\n return 0\n }\n\n if (process.platform === 'win32') {\n const result = spawnSync(buildShellCommand('dsh', args), { stdio: 'inherit', shell: true })\n return result.status ?? 1\n }\n\n const result = spawnSync('dsh', args, { stdio: 'inherit' })\n return result.status ?? 1\n}\n\nfunction dshInstallCommand(options: DshOptions): void {\n const profile = options.profile ?? 'desktop'\n const { spec, error } = buildInstallSpec(options)\n\n if (spec === undefined) {\n logger.error(error ?? '未知错误')\n process.exitCode = 1\n return\n }\n\n const usesSubpath = spec.includes('path:')\n const pnpmVersion = readPnpmVersion()\n\n if (usesSubpath && pnpmVersion !== undefined && majorOf(pnpmVersion) < 11) {\n logger.warn(\n `检测到 pnpm ${pnpmVersion}:11 以下不支持 git 子目录语法(#…&path:),` +\n '会静默装成仓库根而不是你想要的子包。DSH 内置的 pnpm 11 不受影响 —— 建议改用 DSH 插件页安装。'\n )\n }\n\n if (usesSubpath && process.platform === 'win32') {\n logger.info('Windows:会通过 cmd /d /s /c 执行,避免 & 被当成命令分隔符。')\n }\n\n logger.step(`安装到 profile「${profile}」`)\n console.log(` spec: ${spec}`)\n\n if (!isAbsolute(spec) && !spec.startsWith('github:') && !spec.startsWith('git+') && !spec.startsWith('http')) {\n logger.warn('这个 spec 既不是绝对路径也不是 git/URL,确认没有写错。')\n }\n\n const status = spawnDsh(['plugin', '--profile', profile, 'add', spec], options.dry === true)\n if (options.dry === true) {\n logger.info('dry run:以上命令没有执行。')\n return\n }\n if (status !== 0) {\n logger.error(`安装失败(退出码 ${status})。诊断日志在 ~/.dsh/profiles/${profile}/.plugin-manager/logs/`)\n process.exitCode = status\n return\n }\n logger.success('安装完成 —— 完全退出 DSH 再打开即可生效')\n}\n\n/* ------------------------------------------------------------- dispatcher */\n\nconst ACTIONS: Record<string, string> = {\n init: '创建一个 DSH 插件项目',\n dev: '本地预览(浏览器里看面板,不用装进 DSH)',\n build: '构建 lib/{index,client}.js',\n check: '装前一致性校验',\n install: '把插件装进 DSH profile'\n}\n\n/** `vobs dsh <action> [target]` 的分发入口。 */\nexport async function dshCommand(\n action: string | undefined,\n target: string | undefined,\n options: DshOptions\n): Promise<void> {\n switch (action) {\n case 'init':\n case 'create':\n await dshInitCommand(target, options)\n return\n case 'dev':\n await dshDevCommand(options)\n return\n case 'build':\n await dshBuildCommand()\n return\n case 'check':\n dshCheckCommand()\n return\n case 'install':\n dshInstallCommand(options)\n return\n default:\n // 不带子命令时只列用法(这是最自然的「我该用什么」入口),\n // 真正写错子命令时才报错。\n if (action !== undefined && action !== '') logger.error(`未知子命令: ${action}`)\n console.log('\\n 可用子命令:')\n for (const [name, description] of Object.entries(ACTIONS)) {\n console.log(` vobs dsh ${name.padEnd(8)} ${description}`)\n }\n if (action !== undefined && action !== '') process.exitCode = 1\n }\n}\n","/**\n * VOBS CLI Banner — Mathematical Bold Sans-Serif\n * 𝗩𝗢𝗕𝗦 𝗖𝗟𝗜 𝘃𝟭.𝟬\n * Signals First · Zero Re-renders · Ultra Lightweight\n *\n * The banner is left-aligned with a fixed indent rather than horizontally\n * centered. Centering depends on the terminal column width and per-glyph\n * render width, neither of which is reliably knowable, so it drifts as the\n * window resizes. Fixed indent is stable across any terminal size.\n */\n\nconst BANNER_LINE1 = '𝗩𝗢𝗕𝗦 𝗖𝗟𝗜 𝘃𝟭.𝟬'\nconst BANNER_TAGLINE = 'Signals First · Zero Re-renders · Ultra Lightweight'\n\n/** Fixed left indent applied to every banner line (2 spaces). */\nconst INDENT = ' '\nconst DIM = '\\x1b[2m'\nconst RESET = '\\x1b[0m'\n\n/** Show full banner (used for logo command, --help) */\nexport function showLogo(): void {\n console.log()\n console.log()\n console.log(`${INDENT}${BANNER_LINE1}`)\n console.log()\n console.log(`${INDENT}${DIM}${BANNER_TAGLINE}${RESET}`)\n console.log()\n console.log()\n}\n\n/** Show single-line version banner (used for --version) */\nexport function showBanner(): void {\n console.log(`${INDENT}${BANNER_LINE1}`)\n}\n\n/** Show the dev server start banner */\nexport function showDevBanner(): void {\n console.log()\n console.log(`${INDENT}${BANNER_LINE1}`)\n console.log()\n}","import { createInterface } from 'node:readline/promises'\nimport { stdin, stdout } from 'node:process'\nimport pc from 'picocolors'\nimport { showLogo, showBanner } from './banner.js'\nimport { initCommand } from './commands/init.js'\nimport { generateCommand } from './commands/generate.js'\nimport { addCommand } from './commands/add.js'\n\n/**\n * Interactive REPL shell. Runs `vobs` with no arguments and stays in CLI\n * mode accepting repeated commands until the user types `exit` / `quit`\n * or presses Ctrl+C / Ctrl+D.\n */\nexport async function startRepl(): Promise<void> {\n showLogo()\n\n const rl = createInterface({\n input: stdin,\n output: stdout,\n prompt: ` ${pc.magenta('❯')} `,\n terminal: true\n })\n\n rl.prompt()\n\n for await (const rawLine of rl) {\n const line = rawLine.trim()\n\n if (!line) {\n rl.prompt()\n continue\n }\n\n // Split into args, honoring simple double quotes\n const args = splitArgs(line)\n\n try {\n await dispatch(args)\n } catch (err) {\n console.error(` ${pc.red('✖')} ${err instanceof Error ? err.message : String(err)}`)\n }\n\n rl.prompt()\n }\n}\n\ntype Command = (args: string[]) => Promise<void>\n\n/** Internal command table for the REPL */\nconst TABLE: Record<string, { cmd: Command; help: string }> = {\n help: {\n cmd: async () => {\n console.log(` ${pc.bold('Available commands:')}`)\n console.log(` ${pc.dim('exit|quit')} Leave the interactive CLI`)\n console.log(` ${pc.dim('clear')} Clear the screen`)\n console.log(` ${pc.dim('logo')} Re-print the banner`)\n console.log(` ${pc.dim('version')} Show version`)\n console.log(` ${pc.dim('init <name>')} Create a new vobs project`)\n console.log(` ${pc.dim('generate <name>')} Generate a component/page`)\n console.log(` ${pc.dim('add <package>')} Add a package`)\n console.log(` ${pc.dim('dev|build')} Use \\`vobs dev\\` / \\`vobs build\\` in a terminal`)\n },\n help: ''\n },\n logo: { cmd: async () => showLogo(), help: '' },\n version: { cmd: async () => showBanner(), help: '' },\n clear: {\n cmd: async () => {\n process.stdout.write('\\x1Bc')\n },\n help: ''\n },\n exit: { cmd: async () => process.exit(0), help: '' },\n quit: { cmd: async () => process.exit(0), help: '' },\n init: {\n cmd: async (args) => {\n await initCommand({\n name: args[0],\n targetDir: undefined,\n packageManager: undefined,\n typescript: true,\n git: true\n })\n },\n help: ''\n },\n generate: {\n cmd: async (args) => {\n await generateCommand({\n name: args[0],\n type: undefined,\n targetDir: undefined\n })\n },\n help: ''\n },\n g: {\n cmd: async (args) => {\n await generateCommand({\n name: args[0],\n type: undefined,\n targetDir: undefined\n })\n },\n help: ''\n },\n add: {\n cmd: async (args) => {\n await addCommand({ package: args[0], dev: args.includes('-D') || args.includes('--dev') })\n },\n help: ''\n }\n}\n\n/** Dispatch a parsed command line to the internal table */\nasync function dispatch(args: string[]): Promise<void> {\n const name = args[0]\n const rest = args.slice(1)\n\n if (!name) return\n\n const entry = TABLE[name]\n if (entry) {\n await entry.cmd(rest)\n return\n }\n\n console.log(` ${pc.yellow('⚠')} Unknown command: ${pc.bold(String(name))}. Type ${pc.cyan('help')} to see options.`)\n}\n\n/** Minimal tokenizer supporting double-quoted arguments */\nfunction splitArgs(line: string): string[] {\n const out: string[] = []\n const re = /[^\\s\"']+|\"([^\"]*)\"|'([^']*)'/g\n let m: RegExpExecArray | null\n while ((m = re.exec(line)) !== null) {\n out.push(m[1] ?? m[2] ?? m[0])\n }\n return out\n}","import { createCLI } from './cli.js'\nimport { showBanner } from './banner.js'\nimport { startRepl } from './repl.js'\n\n/** Entry point: decides between interactive REPL and single-shot commands */\nexport async function start(args: string[]): Promise<void> {\n // No args (or explicit `cli`) → launch the interactive REPL\n if (args.length === 0 || args[0] === 'cli') {\n await startRepl()\n return\n }\n\n if (args.includes('--version') || args.includes('-V')) {\n showBanner()\n return\n }\n\n // Let cac read the full process.argv so single-shot commands dispatch correctly\n createCLI().parse()\n}"],"mappings":"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","names":["resolve","execSync","join","existsSync","resolve","existsSync","resolve","resolve","execSync","resolve","p","resolve","p","existsSync","readFileSync","writeFileSync","execSync","createServer","dirname","resolve","p","readFileSync","resolve","writeFileSync","existsSync","build","dirname","error","createServer","text","execSync","result","pc","pc"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/init.ts","../src/utils/logger.ts","../src/utils/file.ts","../src/utils/pm.ts","../src/version.ts","../src/commands/dev.ts","../src/commands/build.ts","../src/commands/generate.ts","../src/commands/add.ts","../src/commands/dsh.ts","../src/commands/check.ts","../src/banner.ts","../src/repl.ts","../src/start.ts"],"sourcesContent":["import { cac } from 'cac'\nimport { initCommand } from './commands/init.js'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { generateCommand } from './commands/generate.js'\nimport { addCommand } from './commands/add.js'\nimport { dshCommand } from './commands/dsh.js'\nimport { checkCommand } from './commands/check.js'\nimport { showBanner, showLogo, showDevBanner } from './banner.js'\nimport { cliVersion } from './version.js'\n\nexport function createCLI(): ReturnType<typeof cac> {\n const cli = cac('vobs')\n\n cli\n .command('init [name]', 'Create a new vobs project')\n .option('--dir <dir>', 'Target directory')\n .option('--pm <pm>', 'Package manager (pnpm/npm/yarn)')\n .option('--no-typescript', 'Do not use TypeScript')\n .option('--no-git', 'Do not initialize git')\n .action(async (name: string, options: Record<string, unknown>) => {\n await initCommand({\n name,\n targetDir: options.dir as string | undefined,\n packageManager: options.pm as 'pnpm' | 'npm' | 'yarn' | undefined,\n typescript: options.typescript !== false,\n git: options.git !== false\n })\n })\n\n cli\n .command('create [name]', 'Alias for init')\n .option('--dir <dir>', 'Target directory')\n .option('--pm <pm>', 'Package manager (pnpm/npm/yarn)')\n .option('--no-typescript', 'Do not use TypeScript')\n .option('--no-git', 'Do not initialize git')\n .action(async (name: string, options: Record<string, unknown>) => {\n await initCommand({\n name,\n targetDir: options.dir as string | undefined,\n packageManager: options.pm as 'pnpm' | 'npm' | 'yarn' | undefined,\n typescript: options.typescript !== false,\n git: options.git !== false\n })\n })\n\n cli\n .command('dev', 'Start the dev server')\n .option('--config <path>', 'Vite config file')\n .option('--port <port>', 'Port to listen on')\n .option('--open', 'Open browser on start')\n .action(async (options: Record<string, unknown>) => {\n showDevBanner()\n await devCommand({\n config: options.config as string | undefined,\n port: options.port as number | undefined,\n open: options.open as boolean | undefined\n })\n })\n\n cli\n .command('build', 'Build for production')\n .option('--config <path>', 'Vite config file')\n .option('--outDir <dir>', 'Output directory')\n .option('--mode <mode>', 'Build mode')\n .action(async (options: Record<string, unknown>) => {\n await buildCommand({\n config: options.config as string | undefined,\n outDir: options.outDir as string | undefined,\n mode: options.mode as string | undefined\n })\n })\n\n cli\n .command('generate [name]', 'Generate code (component/page)')\n .alias('g')\n .option('--type <type>', 'Type: component or page')\n .option('--dir <dir>', 'Target directory')\n .action(async (name: string, options: Record<string, unknown>) => {\n await generateCommand({\n name,\n type: (options.type as 'component' | 'page') || undefined,\n targetDir: options.dir as string | undefined\n })\n })\n\n cli\n .command('add [package]', 'Add a package')\n .option('-D, --dev', 'Save as dev dependency')\n .action(async (pkg: string, options: Record<string, unknown>) => {\n await addCommand({\n package: pkg,\n dev: options.dev as boolean | undefined\n })\n })\n\n cli\n .command('check [dir]', '静态检查源码:effect 自订阅 / 列表写进分支 / 组件体里读信号(行内抑制:上一行写 // vobs-check-ignore-next-line)')\n .option('--json', '以 JSON 输出(给 AI 与工具消费)')\n .option('--write', `把结果写到 ${'.vobs/check.json'}(开发台面板读它)`)\n .option('--include-tests', '把测试文件也纳入检查(默认跳过)')\n .action(async (dir: string | undefined, options: Record<string, unknown>) => {\n await checkCommand({\n dir,\n json: options.json === true,\n write: options.write === true,\n includeTests: options.includeTests === true\n })\n })\n\n cli\n .command('dsh [action] [target]', 'DSH 插件工具链(init / dev / build / check / install)')\n .option('--dir <dir>', 'init:目标目录')\n .option('--pm <pm>', 'init:包管理器(pnpm/npm)')\n .option('--port <port>', 'dev:预览端口', { default: 5199 })\n .option('--profile <name>', 'install:DSH profile 名', { default: 'desktop' })\n .option('--spec <spec>', 'install:完整安装 spec')\n .option('--repo <owner/name>', 'install:GitHub owner/name')\n .option('--tag <ref>', 'install:Git tag / 分支 / commit')\n .option('--subpath <path>', 'install:仓库内子目录')\n .option('--from <path>', 'install:从本地目录安装')\n .option('--dry', 'install:只打印命令,不执行')\n .action(async (action: string, target: string | undefined, options: Record<string, unknown>) => {\n await dshCommand(action, target, {\n dir: options.dir as string | undefined,\n pm: options.pm as 'pnpm' | 'npm' | undefined,\n profile: options.profile as string | undefined,\n spec: options.spec as string | undefined,\n repo: options.repo as string | undefined,\n tag: options.tag as string | undefined,\n subpath: options.subpath as string | undefined,\n from: options.from as string | undefined,\n dry: options.dry === true,\n port: options.port === undefined ? undefined : Number(options.port)\n })\n })\n\n cli\n .command('logo', 'Show the vobs CLI logo and version info')\n .action(() => {\n showLogo()\n })\n\n cli.on('--help', () => {\n showBanner()\n })\n\n cli.help()\n cli.version(cliVersion())\n\n return cli\n}\n\n/**\n * 已注册的子命令名(含别名)。\n *\n * 存在的理由:cac 对\"没有命令匹配\"不做任何兜底(既不报错也不输出,直接返回),\n * 而 `start()` 的 `--version` 短路又用的是 `args.includes('--version')` ——\n * 于是 `vobs chekc`(拼错)静默成功,`vobs check --version` 则只打 banner、check 根本没跑。\n * 用这份清单把\"跑某个命令\"与\"顶层用法错误\"分开。\n */\nexport const KNOWN_SUBCOMMANDS: readonly string[] = [\n 'init', 'create', 'dev', 'build', 'generate', 'g', 'add', 'check', 'dsh', 'logo'\n]\n","import { resolve } from 'node:path'\nimport { execSync } from 'node:child_process'\nimport * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { scaffoldProject } from '../utils/file.js'\nimport { installDependencies } from '../utils/pm.js'\nimport type { InitOptions } from '../types.js'\nimport { cliVersion } from '../version.js'\n\nexport async function initCommand(options: Partial<InitOptions>): Promise<void> {\n const projectName = options.name || (await p.text({\n message: 'Project name:',\n placeholder: 'my-vobs-app',\n validate: (v) => !v ? 'Project name is required' : undefined\n })) as string\n\n if (p.isCancel(projectName)) {\n p.cancel('Cancelled')\n return\n }\n\n const targetDir = options.targetDir || resolve(process.cwd(), projectName)\n\n const packageManager = options.packageManager || (await p.select({\n message: 'Package manager:',\n options: [\n { value: 'pnpm', label: 'pnpm' },\n { value: 'npm', label: 'npm' },\n { value: 'yarn', label: 'yarn' }\n ]\n })) as 'pnpm' | 'npm' | 'yarn'\n\n if (p.isCancel(packageManager)) {\n p.cancel('Cancelled')\n return\n }\n\n const useTypescript = options.typescript ?? (await p.confirm({\n message: 'Use TypeScript?',\n initialValue: true\n })) as boolean\n\n if (p.isCancel(useTypescript)) {\n p.cancel('Cancelled')\n return\n }\n\n const initGit = options.git ?? (await p.confirm({\n message: 'Initialize a git repository?',\n initialValue: true\n })) as boolean\n\n if (p.isCancel(initGit)) {\n p.cancel('Cancelled')\n return\n }\n\n logger.step(`Creating project ${projectName}...`)\n\n await scaffoldProject(targetDir, {\n name: projectName,\n packageName: projectName.toLowerCase().replace(/\\s+/g, '-'),\n typescript: useTypescript,\n vobsVersion: cliVersion()\n })\n\n logger.success('Project scaffolded')\n\n logger.step('Installing dependencies...')\n installDependencies(targetDir, packageManager)\n logger.success('Dependencies installed')\n\n if (initGit) {\n logger.step('Initializing git repository...')\n try {\n execSync('git init', { cwd: targetDir, stdio: 'ignore' })\n logger.success('Git repository initialized')\n } catch {\n logger.warn('Git not found, skipping git init')\n }\n }\n\n logger.step('Done!')\n console.log(`\\n ${packageManager === 'pnpm' ? 'pnpm' : packageManager === 'yarn' ? 'yarn' : 'npm run'} dev\\n`)\n}","import pc from 'picocolors'\n\n/*\n * 诊断/日志一律走 **stderr**,stdout 只留给**数据**。\n *\n * 为什么这不是洁癖:`vobs check --json` 的输出是给 AI 与开发台面板消费的机器接口,\n * 而 `--json --write` 时 `logger.info('报告写入 …')` 会先往 stdout 打一行带时间戳的\n * `[14:24:23] ℹ …`,于是 `JSON.parse(stdout)` 直接失败(实测\n * `.artifacts/probe-audit-cli-check.mjs`:同一脚本里 `--json` 可 parse、`--json --write` 不可)。\n * `warn` 同理。\n *\n * 注意:`error` 本来就走 stderr;`success`/`step` 保持 stdout(它们是给人看的**主输出**,\n * 不是旁路日志),`check` 的成功行也仍是 stdout。\n */\nfunction timestamp(): string {\n return pc.dim(`[${new Date().toLocaleTimeString()}]`)\n}\n\nexport function info(msg: string): void {\n console.error(`${timestamp()} ${pc.cyan('ℹ')} ${msg}`)\n}\n\nexport function success(msg: string): void {\n console.log(`${timestamp()} ${pc.green('✔')} ${msg}`)\n}\n\nexport function warn(msg: string): void {\n console.error(`${timestamp()} ${pc.yellow('⚠')} ${msg}`)\n}\n\nexport function error(msg: string): void {\n console.error(`${timestamp()} ${pc.red('✖')} ${msg}`)\n}\n\nexport function step(msg: string): void {\n console.log(`\\n ${pc.bold(pc.cyan(msg))}`)\n}\n\nexport const logger = { info, success, warn, error, step }","import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs'\nimport { resolve, dirname } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport Handlebars from 'handlebars'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst TEMPLATES_ROOT = resolve(__dirname, '..', 'templates')\n\n/** Get the absolute path to the templates directory */\nexport function getTemplatesDir(): string {\n return TEMPLATES_ROOT\n}\n\n/** Read a template file and compile it with Handlebars */\nexport function renderTemplate(\n templatePath: string,\n context: Record<string, unknown>\n): string {\n const source = readFileSync(templatePath, 'utf-8')\n const template = Handlebars.compile(source)\n return template(context)\n}\n\n/** Write a file, creating parent directories if needed */\nexport function writeFile(dir: string, filename: string, content: string): void {\n const filePath = resolve(dir, filename)\n mkdirSync(dirname(filePath), { recursive: true })\n writeFileSync(filePath, content, 'utf-8')\n}\n\n/** Ensure a directory exists */\nexport function ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/** Check if a path exists */\nexport function pathExists(path: string): boolean {\n return existsSync(path)\n}\n\n/** Copy a template directory recursively, rendering each .hbs file */\nasync function copyDirRecursive(srcDir: string, destDir: string, context: Record<string, unknown>): Promise<void> {\n const { readdirSync } = await import('node:fs')\n const { join } = await import('node:path')\n\n const entries = readdirSync(srcDir, { withFileTypes: true })\n\n for (const entry of entries) {\n const srcPath = join(srcDir, entry.name)\n const isHbs = entry.name.endsWith('.hbs')\n const destName = isHbs ? entry.name.slice(0, -4) : entry.name\n const destPath = join(destDir, destName)\n\n if (entry.isDirectory()) {\n ensureDir(destPath)\n await copyDirRecursive(srcPath, destPath, context)\n } else if (isHbs) {\n const content = renderTemplate(srcPath, context)\n writeFile(destDir, destName, content)\n } else {\n const content = readFileSync(srcPath, 'utf-8')\n writeFile(destDir, destName, content)\n }\n }\n}\n\n/** Scaffold a project from a named template under `src/templates`. */\nexport async function scaffoldProject(\n targetDir: string,\n context: Record<string, unknown>,\n template = 'basic'\n): Promise<void> {\n const templateDir = resolve(TEMPLATES_ROOT, template)\n if (!existsSync(templateDir)) {\n throw new Error(`模板不存在: ${template}(可用模板见 ${TEMPLATES_ROOT})`)\n }\n ensureDir(targetDir)\n await copyDirRecursive(templateDir, targetDir, context)\n}","import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { execSync } from 'node:child_process'\n\nexport type PackageManager = 'pnpm' | 'npm' | 'yarn'\n\n/** Detect the package manager to use */\nexport function detectPackageManager(targetDir?: string): PackageManager {\n // Check if a specific package manager is locked\n if (targetDir) {\n if (existsSync(resolve(targetDir, 'pnpm-lock.yaml'))) return 'pnpm'\n if (existsSync(resolve(targetDir, 'yarn.lock'))) return 'yarn'\n if (existsSync(resolve(targetDir, 'package-lock.json'))) return 'npm'\n }\n\n // Check for global preference\n const userAgent = process.env.npm_config_user_agent || ''\n if (userAgent.startsWith('pnpm')) return 'pnpm'\n if (userAgent.startsWith('yarn')) return 'yarn'\n if (userAgent.startsWith('npm')) return 'npm'\n\n // Default to pnpm\n return 'pnpm'\n}\n\n/** Install dependencies in a directory */\nexport function installDependencies(targetDir: string, pm: PackageManager): void {\n const cmd = pm === 'yarn' ? 'yarn' : `${pm} install`\n execSync(cmd, { cwd: targetDir, stdio: 'inherit' })\n}\n\n/** Add a package as a dependency */\nexport function addPackage(targetDir: string, pm: PackageManager, pkg: string, dev: boolean): void {\n const installFlag = dev ? '-D' : ''\n const cmd = pm === 'npm'\n ? `npm install ${installFlag} ${pkg}`\n : pm === 'yarn'\n ? `yarn add ${installFlag} ${pkg}`\n : `pnpm add ${installFlag} ${pkg}`\n\n execSync(cmd, { cwd: targetDir, stdio: 'inherit' })\n}","import { readFileSync } from 'node:fs'\n\n/**\n * CLI 版本号的**单一来源**:直接读本包的 `package.json`。\n *\n * 此前版本号在三处各自硬编码,且都与 `package.json` 不符:\n * - `banner.ts` 的 `𝗩𝗢𝗕𝗦 𝗖𝗟𝗜 𝘃𝟭.𝟬` 常量 —— 这就是 `vobs --version` 的**全部**输出;\n * - `cli.ts` 的 `cli.version('1.0.0')` —— `--help` 头部显示 `vobs/1.0.0`;\n * - `init.ts` 的 `vobsVersion: '1.0.0'` —— 写进脚手架产物。\n * 同一个仓库的 `commands/dsh.ts` 早就有正确的\"读 package.json\"实现,所以这不是能力问题,\n * 而是没人从**外部**看过 CLI 的版本输出(三处不一致也正因如此从未被发现)。\n */\nlet cached: string | undefined\n\nexport function cliVersion(): string {\n if (cached !== undefined) return cached\n try {\n const manifest = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf8')\n ) as { version?: string }\n cached = manifest.version ?? '0.0.0'\n } catch {\n // 读不到 package.json(被打包成单文件等)时不要谎报一个像真版本号的常量\n cached = '0.0.0'\n }\n return cached\n}\n","import { createServer } from 'vite'\nimport { logger } from '../utils/logger.js'\nimport type { DevOptions } from '../types.js'\n\nexport async function devCommand(options: DevOptions): Promise<void> {\n logger.info('Starting dev server...')\n\n const server = await createServer({\n configFile: options.config,\n server: {\n port: options.port,\n open: options.open\n }\n })\n\n await server.listen()\n server.printUrls()\n logger.success('Dev server is running')\n}","import { build } from 'vite'\nimport { logger } from '../utils/logger.js'\nimport type { BuildOptions } from '../types.js'\n\nexport async function buildCommand(options: BuildOptions): Promise<void> {\n logger.info('Building for production...')\n\n await build({\n configFile: options.config,\n build: {\n outDir: options.outDir\n },\n mode: options.mode || 'production'\n })\n\n logger.success('Build complete')\n}","import { resolve } from 'node:path'\nimport * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { renderTemplate, writeFile, getTemplatesDir, ensureDir } from '../utils/file.js'\nimport type { GenerateOptions, ComponentTemplateContext, PageTemplateContext } from '../types.js'\n\nexport async function generateCommand(options: Partial<GenerateOptions>): Promise<void> {\n const type = options.type || (await p.select({\n message: 'What to generate?',\n options: [\n { value: 'component', label: 'Component' },\n { value: 'page', label: 'Page' }\n ]\n })) as 'component' | 'page'\n\n if (p.isCancel(type)) {\n p.cancel('Cancelled')\n return\n }\n\n const name = options.name || (await p.text({\n message: 'Name:',\n placeholder: type === 'component' ? 'Button' : 'AboutPage',\n validate: (v) => !v ? 'Name is required' : undefined\n })) as string\n\n if (p.isCancel(name)) {\n p.cancel('Cancelled')\n return\n }\n\n const templatesDir = getTemplatesDir()\n\n if (type === 'component') {\n const targetDir = options.targetDir || resolve(process.cwd(), 'src/components')\n ensureDir(targetDir)\n\n const context: ComponentTemplateContext = {\n name: toPascalCase(name),\n kebabName: toKebabCase(name)\n }\n\n const content = renderTemplate(\n resolve(templatesDir, 'component.hbs'),\n context as unknown as Record<string, unknown>\n )\n\n const filename = `${context.name}.tsx`\n writeFile(targetDir, filename, content)\n logger.success(`Created ${type} at ${resolve(targetDir, filename)}`)\n } else {\n const targetDir = options.targetDir || resolve(process.cwd(), 'src/pages')\n ensureDir(targetDir)\n\n const context: PageTemplateContext = {\n name: toPascalCase(name),\n path: `/${toKebabCase(name)}`\n }\n\n const content = renderTemplate(\n resolve(templatesDir, 'page.hbs'),\n context as unknown as Record<string, unknown>\n )\n\n const filename = `${context.name}.tsx`\n writeFile(targetDir, filename, content)\n logger.success(`Created ${type} at ${resolve(targetDir, filename)}`)\n }\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(/\\s+/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('')\n}\n\nfunction toKebabCase(str: string): string {\n return str\n .replace(/([A-Z])/g, '-$1')\n .toLowerCase()\n .replace(/^-/, '')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/--+/g, '-')\n .replace(/^-|-$/g, '')\n}","import * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { detectPackageManager, addPackage } from '../utils/pm.js'\nimport type { AddOptions } from '../types.js'\n\nexport async function addCommand(options: Partial<AddOptions>): Promise<void> {\n const pkg = options.package || (await p.text({\n message: 'Package to add:',\n placeholder: '@vobs/ui',\n validate: (v) => !v ? 'Package name is required' : undefined\n })) as string\n\n if (p.isCancel(pkg)) {\n p.cancel('Cancelled')\n return\n }\n\n const isDev = options.dev ?? (await p.confirm({\n message: 'Save as dev dependency?',\n initialValue: false\n })) as boolean\n\n if (p.isCancel(isDev)) {\n p.cancel('Cancelled')\n return\n }\n\n const pm = detectPackageManager(process.cwd())\n\n logger.step(`Installing ${pkg}...`)\n addPackage(process.cwd(), pm, pkg, isDev)\n\n logger.success(`Installed ${pkg}`)\n console.log(`\\n Import it in your code:\\n`)\n console.log(` import { ... } from '${pkg}'`)\n console.log()\n}","import { existsSync, readFileSync, writeFileSync } from 'node:fs'\nimport { readFile } from 'node:fs/promises'\nimport { execSync, spawnSync } from 'node:child_process'\nimport { createServer, type ServerResponse } from 'node:http'\nimport { createRequire } from 'node:module'\nimport { isAbsolute, basename, dirname, join, relative, resolve } from 'node:path'\nimport * as p from '@clack/prompts'\nimport { logger } from '../utils/logger.js'\nimport { ensureDir, scaffoldProject } from '../utils/file.js'\nimport { installDependencies, type PackageManager } from '../utils/pm.js'\n\nexport interface DshOptions {\n dir?: string\n pm?: PackageManager\n profile?: string\n spec?: string\n repo?: string\n tag?: string\n subpath?: string\n from?: string\n dry?: boolean\n port?: number\n}\n\n/** 平台内置模块:这些 `require` 出现在产物里是正常的。 */\nconst PLATFORM_MODULES = ['react', 'react-dom']\n\nconst vobsVersion = (): string => {\n try {\n const manifest = JSON.parse(\n readFileSync(new URL('../../package.json', import.meta.url), 'utf8')\n ) as { version?: string }\n return manifest.version ?? '1.7.5'\n } catch {\n return '1.7.5'\n }\n}\n\n/** 去掉 scope,得到 cordis 行 id 与目录名都可用的标识。 */\nfunction toRowId(packageName: string): string {\n return packageName.replace(/^@[^/]+\\//u, '')\n}\n\n/* ------------------------------------------------------------------ init */\n\nasync function dshInitCommand(target: string | undefined, options: DshOptions): Promise<void> {\n const name = target ?? ((await p.text({\n message: '插件包名(npm 包名,小写):',\n placeholder: 'dsh-plugin-my-panel',\n validate: value => (/^[a-z0-9][a-z0-9._~-]*$/u.test(value) ? undefined : '必须是合法的 npm 包名')\n })) as string)\n\n if (p.isCancel(name)) {\n p.cancel('已取消')\n return\n }\n\n const packageManager =\n options.pm ??\n ((await p.select({\n message: '包管理器:',\n options: [\n { value: 'pnpm', label: 'pnpm' },\n { value: 'npm', label: 'npm' }\n ]\n })) as PackageManager)\n\n if (p.isCancel(packageManager)) {\n p.cancel('已取消')\n return\n }\n\n const targetDir = options.dir !== undefined ? resolve(options.dir) : resolve(process.cwd(), name)\n const rowId = toRowId(name)\n const displayName = rowId\n .replace(/^dsh-plugin-/u, '')\n .split('-')\n .map(part => part.charAt(0).toUpperCase() + part.slice(1))\n .join(' ')\n\n logger.step(`创建 DSH 插件项目 ${name} …`)\n await scaffoldProject(\n targetDir,\n { packageName: name, rowId, displayName, vobsVersion: vobsVersion() },\n 'dsh-plugin'\n )\n\n // 单独写 .gitignore:模板里的点文件在打包时容易丢,而且这里的规则有一条很关键 ——\n // lib/ 是产物,**必须提交**(DSH 安装时不构建)。\n ensureDir(targetDir)\n writeFileSync(\n resolve(targetDir, '.gitignore'),\n ['node_modules/', '*.log', '*.tsbuildinfo', '', '# lib/ 是构建产物,必须提交:DSH 安装时不会构建你的包。', ''].join('\\n'),\n 'utf8'\n )\n logger.success('项目已生成')\n\n logger.step('安装依赖 …')\n try {\n installDependencies(targetDir, packageManager)\n logger.success('依赖已安装')\n } catch {\n logger.warn(`依赖安装失败,请手动执行 ${packageManager} install`)\n }\n\n logger.step('下一步')\n console.log(`\n cd ${name}\n ${packageManager} run dev # 本地预览,不用装进 DSH\n ${packageManager} run build # 产出 lib/{index,client}.js\n\n # 提交产物并打 tag 之后,在 DSH 插件页填:\n github:<owner>/<repo>#v0.1.0&path:/<本包在仓库中的路径>\n`)\n}\n\n/* ----------------------------------------------------------------- build */\n\n/**\n * 构建 DSH 插件产物。\n *\n * 一个可安装的插件包有**两半**:Host 侧(cordis 插件,ESM)与 Client 侧\n * (浏览器 bundle)。项目的 vite.config 只负责 Client(`dshBundle()` 会把产物\n * 落到 package.json 声明的位置),Host 这一半由本命令补上 ——\n * 否则 `exports[\".\"]` 指向的文件根本不存在,装进 DSH 必然失败。\n */\nasync function dshBuildCommand(): Promise<void> {\n const projectDir = process.cwd()\n const configFile = resolve(projectDir, 'vite.config.ts')\n if (!existsSync(configFile)) {\n logger.error('当前目录没有 vite.config.ts,请在插件项目根目录运行。')\n process.exitCode = 1\n return\n }\n\n const manifest = readManifest(projectDir)\n if (manifest === undefined) {\n logger.error('读不到 package.json。')\n process.exitCode = 1\n return\n }\n\n const hostEntry = resolveExport(manifest, '.')\n if (hostEntry === undefined) {\n logger.error('package.json 的 exports 里没有 \".\",DSH 加载不到 Host 侧插件。')\n process.exitCode = 1\n return\n }\n\n const { build } = await import('vite')\n\n logger.info('构建客户端产物 …')\n await build({ configFile, mode: 'production' })\n\n logger.info('构建 Host 产物 …')\n const hostTarget = resolve(projectDir, hostEntry.replace(/^\\.\\//u, ''))\n const hostEntrySource = resolve(projectDir, 'src', 'host', 'index.ts')\n if (!existsSync(hostEntrySource)) {\n logger.warn(`没有找到 ${hostEntrySource},跳过 Host 构建。`)\n return\n }\n await build({\n configFile: false,\n root: projectDir,\n logLevel: 'warn',\n build: {\n outDir: relative(projectDir, dirname(hostTarget)) || '.',\n emptyOutDir: false,\n target: 'es2022',\n minify: false,\n sourcemap: false,\n lib: {\n entry: hostEntrySource,\n formats: ['es'],\n fileName: () => basename(hostTarget)\n }\n }\n })\n\n logger.success('构建完成 → 客户端与 Host 产物都已就位')\n}\n\n/* ------------------------------------------------------------------ dev */\n\n/** 从 exports 字段里取出一个子路径,兼容字符串与一层条件对象两种写法。 */\nexport function resolveExport(manifest: Record<string, unknown>, key: string): string | undefined {\n const exportsField = (manifest.exports ?? {}) as Record<string, unknown>\n const entry = exportsField[key]\n if (typeof entry === 'string') return entry\n if (typeof entry === 'object' && entry !== null) {\n const record = entry as Record<string, unknown>\n for (const condition of ['default', 'import', 'require']) {\n const value = record[condition]\n if (typeof value === 'string') return value\n }\n }\n return undefined\n}\n\n/** 生成预览页。纯函数,便于单测。 */\nexport function buildPreviewHtml(options: { packageName: string; title?: string }): string {\n // 包名会被嵌进 <script> 里:JSON 序列化不会转义 `/`,所以必须自己把 `<` 干掉,\n // 否则一个含 </script> 的包名就能突破标签。\n const name = JSON.stringify(options.packageName).replace(/</gu, '\\\\u003c')\n const title = (options.title ?? options.packageName).replace(/[<>&]/gu, '')\n return `<!doctype html>\n<html lang=\"zh-CN\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>vobs preview · ${title}</title>\n</head>\n<body>\n<div id=\"root\"></div>\n\n<!-- 1. 先装垫片:必须在插件 bundle 之前,捕获它的 factory 注册 -->\n<script>\n window.__VOBS_DSH_PREVIEW__ = { factories: new Map() };\n window.__ModuleLoader__ = {\n load: function (entry) { window.__VOBS_DSH_PREVIEW__.factories.set(entry.id, entry.factory); }\n };\n</script>\n\n<!-- 2. 插件产物:它只注册 factory,不产生副作用 -->\n<script src=\"/client.js\"></script>\n\n<!-- 3. 启动预览外壳 -->\n<script type=\"module\">\n import { startPreview } from '/preview.js';\n window.__VOBS_PREVIEW__ = startPreview({\n container: document.getElementById('root'),\n packageName: ${name}\n });\n</script>\n\n<!-- 4. 重建后自动刷新;?static=1 关掉长连接,便于无头截图与 CI 断言 -->\n<script>\n if (!location.search.includes('static')) {\n new EventSource('/events').addEventListener('reload', function () { location.reload(); });\n }\n</script>\n</body>\n</html>\n`\n}\n\n/**\n * vite 的构建监听器。只声明本命令用到的两个成员 ——\n * `vite` 没有把 rollup 的 `RollupWatcher` 再导出,为一个 dev 命令引入 rollup 类型不划算。\n */\ninterface BuildWatcher {\n on(event: 'event', handler: (event: { code?: string; error?: { message?: string } }) => void): void\n close(): Promise<void>\n}\n\nasync function dshDevCommand(options: DshOptions): Promise<void> {\n const projectDir = process.cwd()\n const manifest = readManifest(projectDir)\n if (manifest === undefined) {\n logger.error('当前目录没有可读的 package.json。')\n process.exitCode = 1\n return\n }\n if (readManifest(projectDir)?.dsh === undefined) {\n logger.error('这不是一个 DSH 插件项目(package.json 里没有 dsh 字段)。')\n process.exitCode = 1\n return\n }\n\n const packageName = typeof manifest.name === 'string' ? manifest.name : 'dsh-plugin'\n const clientEntry = resolveExport(manifest, './client')\n if (clientEntry === undefined) {\n logger.error('package.json 的 exports 里没有 \"./client\",页面拿不到客户端 bundle。')\n process.exitCode = 1\n return\n }\n const clientFile = resolve(projectDir, clientEntry.replace(/^\\.\\//u, ''))\n\n // 预览运行时从**项目自己**的 node_modules 解析:项目才是声明 @vobs/dsh 的那一方。\n let previewFile: string | undefined\n try {\n const projectRequire = createRequire(join(projectDir, 'package.json'))\n let packageRoot: string | undefined\n try {\n // 首选:包导出了 ./package.json(@vobs/dsh 有)。\n packageRoot = dirname(projectRequire.resolve('@vobs/dsh/package.json'))\n } catch {\n // 回退:解析主入口(dist/index.js 或 dist/index.cjs),再回到包根。\n packageRoot = dirname(dirname(projectRequire.resolve('@vobs/dsh')))\n }\n const candidate = join(packageRoot, 'dist', 'preview.js')\n previewFile = existsSync(candidate) ? candidate : undefined\n } catch {\n previewFile = undefined\n }\n if (previewFile === undefined) {\n logger.error('项目里找不到 @vobs/dsh 的预览运行时。先安装依赖:pnpm add -D @vobs/dsh')\n process.exitCode = 1\n return\n }\n\n const port = options.port ?? 5199\n const clients = new Set<ServerResponse>()\n const broadcast = (event: string): void => {\n for (const client of clients) client.write(`event: ${event}\\ndata: 1\\n\\n`)\n }\n\n /* 先构建一次,再进监听模式 */\n logger.info('构建产物 …')\n const { build } = await import('vite')\n const configFile = resolve(projectDir, 'vite.config.ts')\n let buildError: string | undefined\n\n try {\n const watcher = (await build({\n configFile,\n mode: 'development',\n logLevel: 'warn',\n build: { watch: {} }\n })) as unknown as BuildWatcher\n\n watcher.on('event', event => {\n if (event.code === 'END') {\n buildError = undefined\n logger.success('重新构建完成')\n broadcast('reload')\n } else if (event.code === 'ERROR') {\n buildError = event.error?.message ?? '构建失败'\n logger.error(buildError)\n }\n })\n process.on('SIGINT', () => {\n void watcher.close().then(() => process.exit(0))\n })\n } catch (error) {\n logger.error(`构建失败:${error instanceof Error ? error.message : String(error)}`)\n process.exitCode = 1\n return\n }\n\n const server = createServer((request, response) => {\n const url = (request.url ?? '/').split('?')[0]\n\n if (url === '/events') {\n response.writeHead(200, {\n 'content-type': 'text/event-stream',\n 'cache-control': 'no-store',\n connection: 'keep-alive'\n })\n response.write(': connected\\n\\n')\n clients.add(response)\n request.on('close', () => clients.delete(response))\n return\n }\n\n const send = (body: string | Buffer, type: string): void => {\n response.writeHead(200, { 'content-type': type, 'cache-control': 'no-store' })\n response.end(body)\n }\n\n if (url === '/') {\n send(buildPreviewHtml({ packageName }), 'text/html; charset=utf-8')\n return\n }\n if (url === '/preview.js') {\n void readFile(previewFile as string).then(body => send(body, 'text/javascript; charset=utf-8'))\n return\n }\n if (url === '/client.js') {\n if (!existsSync(clientFile)) {\n response.writeHead(503, { 'content-type': 'text/plain; charset=utf-8' })\n response.end(`还没有产物:${clientEntry}\\n${buildError ?? ''}`)\n return\n }\n void readFile(clientFile).then(body => send(body, 'text/javascript; charset=utf-8'))\n return\n }\n\n response.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' })\n response.end('not found')\n })\n\n await new Promise<void>(resolveListen => {\n server.listen(port, '127.0.0.1', resolveListen)\n })\n\n logger.success(`预览已就绪:http://127.0.0.1:${port}/`)\n console.log('\\n 改代码会自动重建并刷新页面;Ctrl+C 退出。\\n')\n}\n\n/* ----------------------------------------------------------------- check */\n\ninterface CheckResult {\n errors: string[]\n warnings: string[]\n passed: string[]\n}\n\n/** 读取并解析 package.json。 */\nfunction readManifest(dir: string): Record<string, unknown> | undefined {\n try {\n return JSON.parse(readFileSync(resolve(dir, 'package.json'), 'utf8')) as Record<string, unknown>\n } catch {\n return undefined\n }\n}\n\n/**\n * 装前一致性校验:把「装进 DSH 之后才发现坏」的问题提前到本地。\n *\n * 检查项全部来自 DSH 的客户端插件契约与 pnpm 的 Git 子目录安装约束。\n */\nexport function collectIssues(dir: string): CheckResult {\n const result: CheckResult = { errors: [], warnings: [], passed: [] }\n const manifest = readManifest(dir)\n\n if (manifest === undefined) {\n result.errors.push('读不到 package.json(JSON 语法错误或文件缺失)')\n return result\n }\n\n const name = typeof manifest.name === 'string' ? manifest.name : ''\n if (name === '') result.errors.push('package.json 缺少 name')\n else result.passed.push(`包名 ${name}`)\n\n const dsh = (manifest.dsh ?? {}) as Record<string, unknown>\n const bundle = (dsh.bundle ?? {}) as Record<string, unknown>\n const client = (dsh.client ?? {}) as Record<string, unknown>\n\n if (typeof bundle.patch !== 'string') {\n result.errors.push('缺少 dsh.bundle.patch —— DSH 不会把这个包当作组合包(bundle)')\n } else {\n const patchPath = resolve(dir, bundle.patch.replace(/^\\.\\//u, ''))\n if (!existsSync(patchPath)) {\n result.errors.push(`dsh.bundle.patch 指向的 ${bundle.patch} 不存在`)\n } else {\n const text = readFileSync(patchPath, 'utf8')\n if (!text.includes('insert:')) result.errors.push('cordis.patch.yml 里没有 insert: 段落,插件行不会进组合树')\n else if (name !== '' && !text.includes(name)) {\n result.warnings.push(`cordis.patch.yml 里没有出现包名 ${name},确认 insert 的 name 写对了`)\n } else result.passed.push('cordis.patch.yml 会插入本包的行')\n }\n }\n\n if (client.platform !== 'web') {\n result.errors.push(\"dsh.client.platform 必须是 'web' —— 否则 DSH 不会给页面提供客户端 bundle\")\n } else result.passed.push('dsh.client.platform = web')\n\n const exportsField = (manifest.exports ?? {}) as Record<string, string>\n const hostEntry = exportsField['.']\n const clientEntry = exportsField['./client']\n if (typeof hostEntry !== 'string') result.errors.push('exports[\".\"] 未声明 —— DSH 加载不到 Host 侧插件')\n else if (!existsSync(resolve(dir, hostEntry.replace(/^\\.\\//u, '')))) {\n result.errors.push(`exports[\".\"] 指向的 ${hostEntry} 不存在,先构建`)\n } else result.passed.push('Host 入口存在')\n\n if (typeof clientEntry !== 'string') result.errors.push('exports[\"./client\"] 未声明 —— 页面拿不到客户端 bundle')\n\n const scripts = (manifest.scripts ?? {}) as Record<string, string>\n if (scripts.prepare !== undefined || scripts.postinstall !== undefined) {\n result.errors.push('声明了 prepare / postinstall —— DSH 安装时不构建,产物必须预先提交')\n } else result.passed.push('没有安装期生命周期钩子')\n\n const dependencyText = JSON.stringify({\n dependencies: manifest.dependencies,\n peerDependencies: manifest.peerDependencies,\n devDependencies: manifest.devDependencies\n })\n if (dependencyText.includes('workspace:')) {\n result.errors.push('依赖里出现了 workspace: 协议 —— GitHub 子目录直装时解析不了')\n } else result.passed.push('没有 workspace: 协议依赖')\n\n if (typeof clientEntry === 'string') {\n const clientPath = resolve(dir, clientEntry.replace(/^\\.\\//u, ''))\n if (!existsSync(clientPath)) {\n result.errors.push(`客户端产物 ${clientEntry} 不存在,先运行构建`)\n } else {\n const code = readFileSync(clientPath, 'utf8')\n const loads = (code.match(/__ModuleLoader__\\.load\\(/gu) ?? []).length\n if (loads !== 1) result.errors.push(`客户端产物里 __ModuleLoader__.load 出现 ${loads} 次,应为 1 次(先构建)`)\n else result.passed.push('产物形态是 DSH 客户端模块协议')\n\n if (code.includes('import(')) result.errors.push('客户端产物里有动态 import(),DSH 只支持自包含 chunk')\n\n const requires = [...code.matchAll(/require\\((['\"])([^'\"]+)\\1\\)/gu)].map(match => match[2] ?? '')\n const foreign = requires.filter(id => !PLATFORM_MODULES.includes(id) && !id.startsWith('@deepseek-ai/'))\n if (foreign.length > 0) {\n result.errors.push(`产物 require 了非平台模块:${[...new Set(foreign)].join(', ')} —— 依赖没有被打进产物`)\n } else if (requires.length > 0) {\n result.passed.push(`产物只 require 平台模块(${[...new Set(requires)].join(', ')})`)\n }\n\n if (name !== '' && !code.includes(`\"${name}\"`) && !code.includes(`'${name}'`)) {\n result.warnings.push(`产物里的模块 id 与包名 ${name} 不一致,检查 dshBundle({ id })`)\n }\n }\n }\n\n return result\n}\n\nfunction dshCheckCommand(): void {\n const dir = process.cwd()\n const result = collectIssues(dir)\n\n logger.step('DSH 插件装前校验')\n for (const item of result.passed) console.log(` ✔ ${item}`)\n for (const item of result.warnings) console.log(` ⚠ ${item}`)\n for (const item of result.errors) console.log(` ✖ ${item}`)\n\n if (result.errors.length > 0) {\n logger.error(`${result.errors.length} 项不通过,装进 DSH 后不会正常工作。`)\n process.exitCode = 1\n return\n }\n logger.success(`全部通过(${result.passed.length} 项${result.warnings.length > 0 ? `,${result.warnings.length} 条警告` : ''})`)\n}\n\n/* --------------------------------------------------------------- install */\n\n/** 读取 pnpm 版本;拿不到就返回 undefined。 */\nfunction readPnpmVersion(): string | undefined {\n try {\n return execSync('pnpm --version', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim()\n } catch {\n return undefined\n }\n}\n\nconst majorOf = (version: string | undefined): number => {\n const major = Number.parseInt((version ?? '').split('.')[0] ?? '', 10)\n return Number.isFinite(major) ? major : 0\n}\n\n/** 组装安装 spec。 */\nexport function buildInstallSpec(options: DshOptions): { spec?: string; error?: string } {\n if (options.spec !== undefined) return { spec: options.spec }\n\n if (options.from !== undefined) {\n const target = resolve(options.from)\n if (!existsSync(target)) return { error: `--from 指向的路径不存在:${target}` }\n return { spec: target }\n }\n\n if (options.repo !== undefined) {\n const ref = options.tag !== undefined && options.tag !== '' ? `#${options.tag}` : ''\n const sub = options.subpath !== undefined && options.subpath !== '' ? `${ref === '' ? '#' : '&'}path:${options.subpath}` : ''\n return { spec: `github:${options.repo}${ref}${sub}` }\n }\n\n return { error: '需要 --spec、--from 或 --repo 之一来指定安装来源。' }\n}\n\n/**\n * 在 Windows 上调用 dsh 的引号策略。\n *\n * `.cmd` 无法被 CreateProcess 直接执行(EINVAL),必须走 shell;而 shell 会把\n * 裸传参数原样拼接,`github:owner/repo#tag&path:/sub` 里的 `&` 就变成命令分隔符 ——\n * 实测会**静默地把 spec 截断成 `#tag`**,然后装上 monorepo 根而不是目标子包。\n * 所以含特殊字符的参数必须自己加引号。\n */\nconst CMD_NEEDS_QUOTE = /[\\s&|<>^()\"']/u\n\nfunction quoteForCmd(part: string): string {\n return CMD_NEEDS_QUOTE.test(part) ? `\"${part.replace(/\"/gu, '\"\"')}\"` : part\n}\n\n/** 组装一条给 shell 执行的命令行(仅供 Windows 使用)。 */\nexport function buildShellCommand(exe: string, args: readonly string[]): string {\n return [exe, ...args].map(quoteForCmd).join(' ')\n}\n\nfunction spawnDsh(args: string[], dry: boolean): number {\n if (dry) {\n console.log(`\\n ${buildShellCommand('dsh', args)}\\n`)\n return 0\n }\n\n if (process.platform === 'win32') {\n const result = spawnSync(buildShellCommand('dsh', args), { stdio: 'inherit', shell: true })\n return result.status ?? 1\n }\n\n const result = spawnSync('dsh', args, { stdio: 'inherit' })\n return result.status ?? 1\n}\n\nfunction dshInstallCommand(options: DshOptions): void {\n const profile = options.profile ?? 'desktop'\n const { spec, error } = buildInstallSpec(options)\n\n if (spec === undefined) {\n logger.error(error ?? '未知错误')\n process.exitCode = 1\n return\n }\n\n const usesSubpath = spec.includes('path:')\n const pnpmVersion = readPnpmVersion()\n\n if (usesSubpath && pnpmVersion !== undefined && majorOf(pnpmVersion) < 11) {\n logger.warn(\n `检测到 pnpm ${pnpmVersion}:11 以下不支持 git 子目录语法(#…&path:),` +\n '会静默装成仓库根而不是你想要的子包。DSH 内置的 pnpm 11 不受影响 —— 建议改用 DSH 插件页安装。'\n )\n }\n\n if (usesSubpath && process.platform === 'win32') {\n logger.info('Windows:会通过 cmd /d /s /c 执行,避免 & 被当成命令分隔符。')\n }\n\n logger.step(`安装到 profile「${profile}」`)\n console.log(` spec: ${spec}`)\n\n if (!isAbsolute(spec) && !spec.startsWith('github:') && !spec.startsWith('git+') && !spec.startsWith('http')) {\n logger.warn('这个 spec 既不是绝对路径也不是 git/URL,确认没有写错。')\n }\n\n const status = spawnDsh(['plugin', '--profile', profile, 'add', spec], options.dry === true)\n if (options.dry === true) {\n logger.info('dry run:以上命令没有执行。')\n return\n }\n if (status !== 0) {\n logger.error(`安装失败(退出码 ${status})。诊断日志在 ~/.dsh/profiles/${profile}/.plugin-manager/logs/`)\n process.exitCode = status\n return\n }\n logger.success('安装完成 —— 完全退出 DSH 再打开即可生效')\n}\n\n/* ------------------------------------------------------------- dispatcher */\n\nconst ACTIONS: Record<string, string> = {\n init: '创建一个 DSH 插件项目',\n dev: '本地预览(浏览器里看面板,不用装进 DSH)',\n build: '构建 lib/{index,client}.js',\n check: '装前一致性校验',\n install: '把插件装进 DSH profile'\n}\n\n/** `vobs dsh <action> [target]` 的分发入口。 */\nexport async function dshCommand(\n action: string | undefined,\n target: string | undefined,\n options: DshOptions\n): Promise<void> {\n switch (action) {\n case 'init':\n case 'create':\n await dshInitCommand(target, options)\n return\n case 'dev':\n await dshDevCommand(options)\n return\n case 'build':\n await dshBuildCommand()\n return\n case 'check':\n dshCheckCommand()\n return\n case 'install':\n dshInstallCommand(options)\n return\n default:\n // 不带子命令时只列用法(这是最自然的「我该用什么」入口),\n // 真正写错子命令时才报错。\n if (action !== undefined && action !== '') logger.error(`未知子命令: ${action}`)\n console.log('\\n 可用子命令:')\n for (const [name, description] of Object.entries(ACTIONS)) {\n console.log(` vobs dsh ${name.padEnd(8)} ${description}`)\n }\n if (action !== undefined && action !== '') process.exitCode = 1\n }\n}\n","/**\n * `vobs check` —— 不跑应用就能给出的源码问题清单。\n *\n * 为什么需要它:vobs 里最容易犯的错是**不发声**的错(effect 自订阅、列表写进三元分支\n * 后失去 keyed 复用)。运行时护栏(`@vobs/vobs/dev`)能抓到,但那要求先把应用跑起来;\n * 静态检查让你(和 AI)在**写完之后、运行之前**就知道哪里不对。\n *\n * 产出与框架其余部分同一套词汇(code / severity / fix),字段直接对应\n * `@vobs/runtime/error` 的 `VobsError`,因此能直接喂给开发台面板或 AI。\n *\n * 规则的高精度是刻意的:宁可少报,也不要误报 —— 误报会让 AI 去改本来正确的代码。\n *\n * ## 已知限制\n *\n * 三条规则都是**启发式**的(靠名字与形状判断),所以会撞到合法代码:\n *\n * - `VOBS_C210`:把「同一个 `X.value` 的读写」当作信号自订阅。**分不清信号与恰好叫 `value`\n * 的普通字段** —— `entry.value = x`(DTO / ref / 配置对象)会被误报。收窄成「只认裸标识符」\n * 会连 `props.name.value` 这种真信号一起放过,所以保持现状 + 提供行内抑制。\n * - `VOBS_C232` / `VOBS_C118`:前者看的是「列表表达式是否写在分支里」,后者看「组件体里\n * 是否把信号读取存进了局部变量」。都只看形状,不做类型推断。\n *\n * 撞上误报时的正规做法是**行内抑制**(`// vobs-check-ignore-next-line`),\n * 而不是关掉整条规则或改写本来正确的代码。\n */\nimport { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport ts from 'typescript'\nimport { logger } from '../utils/logger.js'\n\nexport interface CheckOptions {\n readonly dir?: string\n readonly json?: boolean\n /** 把结果写到 `<root>/.vobs/check.json`(开发台面板读这个文件显示「项目」页)。 */\n readonly write?: boolean\n /** 把测试文件也纳入检查(默认跳过:fixture 里常有意为之的写法会淹没真问题)。 */\n readonly includeTests?: boolean\n}\n\n/** 检查报告的固定落点,相对被检查的根目录。 */\nexport const REPORT_PATH = '.vobs/check.json'\n\n/** 测试文件默认跳过。 */\nconst TEST_FILE = /(?:^|\\/)(?:[^/]*\\.(?:test|spec)\\.tsx?|__tests__\\/)/u\n\nexport interface CheckDiagnostic {\n /** 稳定错误码,AI 与文档按它检索。 */\n readonly code: string\n readonly severity: 'error' | 'warning'\n readonly message: string\n /** 该怎么改。只报错对 AI 没有价值。 */\n readonly fix: string\n /** 相对目标目录的路径。 */\n readonly file: string\n readonly line: number\n readonly column: number\n /** 出错那一行的原文,方便直接定位。 */\n readonly snippet: string\n}\n\n/** effect 写入了自己依赖的信号。 */\nexport const VOBS_C210 = 'VOBS_C210'\n/** 列表写在分支位置 —— 失去 keyed 复用。 */\nexport const VOBS_C232 = 'VOBS_C232'\n/** 在组件体里读信号并存进局部变量 —— 组件体只执行一次,之后永不更新。 */\nexport const VOBS_C118 = 'VOBS_C118'\n\nconst SKIP_DIRS = new Set(['node_modules', 'dist', 'lib', 'build', '.git', '.vobs', 'coverage'])\n\n/**\n * 收集目标下的 .ts/.tsx。\n *\n * **根目录**读不到时**必须抛错**,不能返回空数组:此前那个 `catch { return }` 把\n * 不存在的目录、以及\"误传一个文件进来\"都变成 `0 个文件` + exit 0 ——\n * `vobs check <不存在的目录>` 会打印 `✔ 检查通过 —— 0 个文件,没有发现问题`。\n * CI 里把路径写错就是**永久绿灯**,比报错更危险(一个检查工具在最该失败的场景下静默通过)。\n *\n * 子目录读不到仍然跳过(权限不足/竞态删除不该让整次检查失败)——那是有意的容错,\n * 与\"根目录不存在\"不是一回事。\n */\nasync function collectSources(root: string): Promise<string[]> {\n let rootStat\n try {\n rootStat = await stat(root)\n } catch {\n throw new Error(`路径不存在:${root}`)\n }\n if (!rootStat.isDirectory()) {\n throw new Error(`不是目录:${root}(vobs check 接受一个目录)`)\n }\n\n const found: string[] = []\n const walk = async (dir: string): Promise<void> => {\n let entries\n try {\n entries = await readdir(dir, { withFileTypes: true })\n } catch (error) {\n // 根目录在第一次 stat 之后消失(竞态)也必须暴露,而不是混进\"0 个文件\"\n if (dir === root) {\n throw new Error(`无法读取目录:${root}(${error instanceof Error ? error.message : String(error)})`)\n }\n return\n }\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (SKIP_DIRS.has(entry.name) || entry.name.startsWith('.')) continue\n await walk(path.join(dir, entry.name))\n continue\n }\n if (!entry.isFile()) continue\n if (!/\\.tsx?$/u.test(entry.name) || entry.name.endsWith('.d.ts')) continue\n found.push(path.join(dir, entry.name))\n }\n }\n await walk(root)\n return found.sort()\n}\n\n/* ------------------------------------------------------------------ 工具 */\n\n/** 该节点是否返回 JSX(函数体里出现 JSX 元素/片段)。 */\nfunction returnsJsx(node: ts.Node): boolean {\n let seen = false\n const visit = (child: ts.Node): void => {\n if (seen) return\n if (ts.isJsxElement(child) || ts.isJsxSelfClosingElement(child) || ts.isJsxFragment(child)) {\n seen = true\n return\n }\n // 不进入嵌套函数:内层组件返回 JSX 不代表外层是组件\n if (child !== node && (ts.isFunctionLike(child))) return\n ts.forEachChild(child, visit)\n }\n ts.forEachChild(node, visit)\n return seen\n}\n\n/**\n * `X.value` 形式的内存读取,返回接收者的文本(`count`、`props.name` 都算)。\n *\n * 用文本而不是标识符:信号经常是别人传进来的(`props.name.value`),\n * 只认裸标识符会把这些全漏掉。\n */\nfunction signalNameOf(node: ts.Node): string | undefined {\n if (!ts.isPropertyAccessExpression(node)) return undefined\n if (node.name.text !== 'value') return undefined\n return node.expression.getText()\n}\n\nfunction lineSnippet(source: ts.SourceFile, node: ts.Node): string {\n const { line } = source.getLineAndCharacterOfPosition(node.getStart(source))\n return (source.text.split(/\\r?\\n/u)[line] ?? '').trim()\n}\n\nfunction diagnosticAt(\n source: ts.SourceFile,\n file: string,\n node: ts.Node,\n rest: Omit<CheckDiagnostic, 'file' | 'line' | 'column' | 'snippet'>\n): CheckDiagnostic {\n const { line, character } = source.getLineAndCharacterOfPosition(node.getStart(source))\n return {\n ...rest,\n file,\n line: line + 1,\n column: character + 1,\n snippet: lineSnippet(source, node)\n }\n}\n\nconst isWriteOperator = (kind: ts.SyntaxKind): boolean =>\n kind === ts.SyntaxKind.EqualsToken\n || kind === ts.SyntaxKind.PlusEqualsToken\n || kind === ts.SyntaxKind.MinusEqualsToken\n || kind === ts.SyntaxKind.AsteriskEqualsToken\n || kind === ts.SyntaxKind.SlashEqualsToken\n\n/* ------------------------------------------------- 规则 A:effect 自订阅 */\n\nfunction ruleEffectSelfSubscription(source: ts.SourceFile, file: string): CheckDiagnostic[] {\n const found: CheckDiagnostic[] = []\n\n const inspectEffectBody = (body: ts.Node): void => {\n const reads = new Map<string, ts.Node>()\n const writes = new Map<string, ts.Node>()\n\n const visit = (node: ts.Node, insideUntrack: boolean): void => {\n // 嵌套函数有自己的订阅语义,不算在本次 effect 的读写里\n if (node !== body && ts.isFunctionLike(node)) return\n\n // untrack(...) 里的写入不建立订阅 → 正是正确写法\n const nextUntracked = insideUntrack\n || (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'untrack')\n\n if (ts.isBinaryExpression(node) && isWriteOperator(node.operatorToken.kind)) {\n const name = signalNameOf(node.left)\n if (name !== undefined && !nextUntracked) writes.set(name, node)\n } else if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node))\n && (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken)) {\n // `count.value++` 同时是读和写 —— 这正是自订阅的经典形态\n const name = signalNameOf(node.operand)\n if (name !== undefined) {\n if (!nextUntracked) writes.set(name, node)\n reads.set(name, node)\n }\n } else if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)\n && node.expression.name.text === 'set') {\n if (!nextUntracked) writes.set(node.expression.expression.getText(), node)\n } else {\n const name = signalNameOf(node)\n if (name !== undefined) {\n const parent = node.parent\n // 只有赋值类运算符的左侧才不是「读」;`count.value < 1` 的左侧仍然是读\n const isAssignmentTarget = ts.isBinaryExpression(parent)\n && isWriteOperator(parent.operatorToken.kind)\n && parent.left === node\n if (!isAssignmentTarget) reads.set(name, node)\n }\n }\n\n ts.forEachChild(node, child => visit(child, nextUntracked))\n }\n\n visit(body, false)\n\n for (const [name, writeNode] of writes) {\n if (!reads.has(name)) continue\n found.push(diagnosticAt(source, file, writeNode, {\n code: VOBS_C210,\n severity: 'error',\n message: `effect 写入了它自己依赖的信号 \"${name}\" —— 这次写入会把它重新调度,形成自订阅循环`,\n fix: `把这次写入包进 untrack:untrack(() => { ${name}.value = next });`\n + '如果这个 effect 本来就只该做副作用,检查是不是误读了不该读的信号。'\n }))\n }\n }\n\n const visit = (node: ts.Node): void => {\n if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)\n && (node.expression.text === 'effect' || node.expression.text === 'renderEffect')) {\n const callback = node.arguments[0]\n if (callback !== undefined && (ts.isArrowFunction(callback) || ts.isFunctionExpression(callback))) {\n inspectEffectBody(callback.body)\n }\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n\n return found\n}\n\n/* -------------------------------------- 规则 B:列表写在分支位置(C232) */\n\nfunction isKeyedListCall(node: ts.Node): boolean {\n if (!ts.isCallExpression(node)) return false\n if (!ts.isPropertyAccessExpression(node.expression) || node.expression.name.text !== 'map') return false\n const callback = node.arguments[0]\n return callback !== undefined && ts.isFunctionLike(callback) && returnsJsx(callback)\n}\n\nfunction ruleListInBranch(source: ts.SourceFile, file: string): CheckDiagnostic[] {\n const found: CheckDiagnostic[] = []\n const message = 'list 写在三元/&& 的分支里 —— 会走多态插入,失去 keyed 复用'\n const fix = '把 list 提成**直接的**子表达式:先写条件分支,再单独写 {items.map(...)}。'\n + '三元里同时有节点与 list 时,list 那一支不会编译成 insertList。'\n\n const visit = (node: ts.Node): void => {\n if (ts.isConditionalExpression(node)) {\n for (const branch of [node.whenTrue, node.whenFalse]) {\n if (isKeyedListCall(branch)) {\n found.push(diagnosticAt(source, file, branch, { code: VOBS_C232, severity: 'warning', message, fix }))\n }\n }\n } else if (ts.isBinaryExpression(node)\n && node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken\n && isKeyedListCall(node.right)) {\n found.push(diagnosticAt(source, file, node.right, { code: VOBS_C232, severity: 'warning', message, fix }))\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n\n return found\n}\n\n/* --------------------------------- 规则 C:组件体里读信号存局部变量(C118) */\n\nfunction containsSignalRead(node: ts.Node): boolean {\n let seen = false\n const visit = (child: ts.Node): void => {\n if (seen) return\n // 函数体内的读取是**延迟**的(事件处理器、定时器、回调),不算「组件体里读信号」。\n // 这条必须放在最前面:`const handler = () => { signal.value }` 里的读取完全正常。\n if (ts.isFunctionLike(child)) return\n if (signalNameOf(child) !== undefined) {\n seen = true\n return\n }\n ts.forEachChild(child, visit)\n }\n visit(node)\n return seen\n}\n\nfunction ruleSignalCapturedInBody(source: ts.SourceFile, file: string): CheckDiagnostic[] {\n const found: CheckDiagnostic[] = []\n\n const inspectComponent = (fn: ts.FunctionLikeDeclaration): void => {\n const body = fn.body\n if (body === undefined || !ts.isBlock(body) || !returnsJsx(fn)) return\n\n // 组件体里「读信号 + 存进 const」\n const captured: { name: string; node: ts.VariableDeclaration }[] = []\n for (const statement of body.statements) {\n if (!ts.isVariableStatement(statement)) continue\n for (const declaration of statement.declarationList.declarations) {\n if (!ts.isIdentifier(declaration.name) || declaration.initializer === undefined) continue\n if (containsSignalRead(declaration.initializer)) {\n captured.push({ name: declaration.name.text, node: declaration })\n }\n }\n }\n if (captured.length === 0) return\n\n // 这些名字是否在 JSX 表达式里被用到\n const usedInJsx = new Set<string>()\n const visit = (node: ts.Node): void => {\n if (ts.isJsxExpression(node) && node.expression !== undefined) {\n const scan = (child: ts.Node): void => {\n if (ts.isIdentifier(child)) usedInJsx.add(child.text)\n ts.forEachChild(child, scan)\n }\n scan(node.expression)\n }\n ts.forEachChild(node, visit)\n }\n visit(body)\n\n for (const item of captured) {\n if (!usedInJsx.has(item.name)) continue\n found.push(diagnosticAt(source, file, item.node, {\n code: VOBS_C118,\n severity: 'warning',\n message: `组件体里读了信号并存进 \"${item.name}\" —— 组件体只执行一次,这个值之后永远不会更新`,\n fix: `把读取放进动态表达式(直接在 JSX 里用 .value),或改成 memo 派生值:`\n + `const ${item.name} = memo(() => ...)。`\n }))\n }\n }\n\n const visit = (node: ts.Node): void => {\n if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {\n inspectComponent(node)\n }\n ts.forEachChild(node, visit)\n }\n visit(source)\n\n return found\n}\n\n/* -------------------------------------------------------------- 入口 */\n\n/**\n * 行内抑制:`// vobs-check-ignore-next-line`。\n *\n * 这三条规则都是**启发式**的:它们靠名字与形状判断「这看起来像信号自订阅 / 像写在分支里的列表 /\n * 像在组件体里读信号」,而有些合法代码恰好长成那样。检查器没有逃生口的话,用户只能关掉整条\n * 规则(或者被 CI 挡住去做假的改写)—— 那比漏报更糟。\n *\n * 只支持「抑制下一行」:作用范围最小、读代码时一眼看得见,也没有整文件豁免那种一刀切。\n * 实测就撞到过一例:`ListEntry.value` 是普通字段,但写法与信号自订阅完全相同\n * (后来给它改了名,但用户代码里不会有这种运气)。\n */\nconst IGNORE_NEXT_LINE = /vobs-check-ignore-next-line/u\n\n/** 被行内注释抑制的行号集合(1-based,收集的是「注释的下一行」)。 */\nfunction suppressedLines(text: string): Set<number> {\n const suppressed = new Set<number>()\n const lines = text.split(/\\r?\\n/u)\n for (let index = 0; index < lines.length; index++) {\n if (IGNORE_NEXT_LINE.test(lines[index])) suppressed.add(index + 2)\n }\n return suppressed\n}\n\nexport function analyzeSource(text: string, file: string): CheckDiagnostic[] {\n const source = ts.createSourceFile(file, text, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX)\n const suppressed = suppressedLines(text)\n return [\n ...ruleEffectSelfSubscription(source, file),\n ...ruleListInBranch(source, file),\n ...ruleSignalCapturedInBody(source, file)\n ]\n .filter(item => !suppressed.has(item.line))\n .sort((a, b) => a.line - b.line || a.column - b.column)\n}\n\nexport async function checkCommand(options: CheckOptions = {}): Promise<void> {\n const root = path.resolve(options.dir ?? process.cwd())\n let all: string[]\n try {\n all = await collectSources(root)\n } catch (error) {\n // 路径无效必须是**失败**,不能是\"0 个文件,检查通过\"(见 collectSources 注释)\n logger.error(error instanceof Error ? error.message : String(error))\n process.exitCode = 1\n return\n }\n const files = options.includeTests === true\n ? all\n : all.filter(file => !TEST_FILE.test(path.relative(root, file).split(path.sep).join('/')))\n const skipped = all.length - files.length\n\n const diagnostics: CheckDiagnostic[] = []\n for (const absolute of files) {\n const text = await readFile(absolute, 'utf8')\n const relative = path.relative(root, absolute).split(path.sep).join('/')\n diagnostics.push(...analyzeSource(text, relative))\n }\n\n const errors = diagnostics.filter(item => item.severity === 'error')\n const report = { root, files: files.length, skippedTests: skipped, diagnostics }\n\n if (options.write === true) {\n const target = path.join(root, REPORT_PATH)\n await mkdir(path.dirname(target), { recursive: true })\n await writeFile(target, `${JSON.stringify(report, null, 2)}\\n`, 'utf8')\n // --json 时 stdout 必须只剩 JSON,所以这行提示走 logger(stderr)\n logger.info(`报告写入 ${REPORT_PATH}(开发台面板读它显示「项目」页)`)\n }\n\n if (options.json === true) {\n console.log(JSON.stringify(report, null, 2))\n if (errors.length > 0) process.exitCode = 1\n return\n }\n\n if (diagnostics.length === 0) {\n logger.success(`检查通过 —— ${files.length} 个文件${skipped > 0 ? `(跳过 ${skipped} 个测试文件)` : ''},没有发现问题`)\n return\n }\n\n console.log('')\n for (const item of diagnostics) {\n const mark = item.severity === 'error' ? '✖' : '!'\n console.log(` ${mark} ${item.file}:${item.line}:${item.column} ${item.code}`)\n console.log(` ${item.message}`)\n if (item.snippet !== '') console.log(` ${item.snippet}`)\n console.log(` → ${item.fix}`)\n console.log('')\n }\n const warnings = diagnostics.length - errors.length\n console.log(\n ` ${errors.length} 个错误 · ${warnings} 个警告 · 共检查 ${files.length} 个文件`\n + `${skipped > 0 ? `(跳过 ${skipped} 个测试文件,用 --include-tests 纳入)` : ''}\\n`\n )\n\n if (errors.length > 0) process.exitCode = 1\n}\n","/**\n * VOBS CLI Banner — Mathematical Bold Sans-Serif\n * 𝗩𝗢𝗕𝗦 𝗖𝗟𝗜\n * Signals First · Zero Re-renders · Ultra Lightweight\n *\n * The banner is left-aligned with a fixed indent rather than horizontally\n * centered. Centering depends on the terminal column width and per-glyph\n * render width, neither of which is reliably knowable, so it drifts as the\n * window resizes. Fixed indent is stable across any terminal size.\n *\n * ⚠️ 这里**只放品牌字形,不放版本号**。版本号曾以数学粗体常量 `𝘃𝟭.𝟬` 的形式写死在这里,\n * 而它就是 `--version` 的全部输出 —— 打印一个和 package.json 不符的版本比不打印更糟。\n * 真实版本统一由 `version.ts` 的 `cliVersion()` 提供。\n */\n\nimport { cliVersion } from './version.js'\n\nconst BANNER_LINE1 = '𝗩𝗢𝗕𝗦 𝗖𝗟𝗜'\nconst BANNER_TAGLINE = 'Signals First · Zero Re-renders · Ultra Lightweight'\n\n/** Fixed left indent applied to every banner line (2 spaces). */\nconst INDENT = ' '\nconst DIM = '\\x1b[2m'\nconst RESET = '\\x1b[0m'\n\n/** Show full banner (used for logo command, --help) */\nexport function showLogo(): void {\n console.log()\n console.log()\n console.log(`${INDENT}${BANNER_LINE1}`)\n console.log()\n console.log(`${INDENT}${DIM}${BANNER_TAGLINE}${RESET}`)\n console.log()\n console.log()\n}\n\n/** Show single-line version banner (used for --version):真实版本号,不是品牌字形。 */\nexport function showBanner(): void {\n console.log(`${INDENT}${BANNER_LINE1} v${cliVersion()}`)\n}\n\n/** Show the dev server start banner */\nexport function showDevBanner(): void {\n console.log()\n console.log(`${INDENT}${BANNER_LINE1} v${cliVersion()}`)\n console.log()\n}","import { createInterface } from 'node:readline/promises'\nimport { stdin, stdout } from 'node:process'\nimport pc from 'picocolors'\nimport { showLogo, showBanner } from './banner.js'\nimport { initCommand } from './commands/init.js'\nimport { generateCommand } from './commands/generate.js'\nimport { addCommand } from './commands/add.js'\n\n/**\n * Interactive REPL shell. Runs `vobs` with no arguments and stays in CLI\n * mode accepting repeated commands until the user types `exit` / `quit`\n * or presses Ctrl+C / Ctrl+D.\n */\nexport async function startRepl(): Promise<void> {\n showLogo()\n\n const rl = createInterface({\n input: stdin,\n output: stdout,\n prompt: ` ${pc.magenta('❯')} `,\n terminal: true\n })\n\n rl.prompt()\n\n for await (const rawLine of rl) {\n const line = rawLine.trim()\n\n if (!line) {\n rl.prompt()\n continue\n }\n\n // Split into args, honoring simple double quotes\n const args = splitArgs(line)\n\n try {\n await dispatch(args)\n } catch (err) {\n console.error(` ${pc.red('✖')} ${err instanceof Error ? err.message : String(err)}`)\n }\n\n rl.prompt()\n }\n}\n\ntype Command = (args: string[]) => Promise<void>\n\n/** Internal command table for the REPL */\nconst TABLE: Record<string, { cmd: Command; help: string }> = {\n help: {\n cmd: async () => {\n console.log(` ${pc.bold('Available commands:')}`)\n console.log(` ${pc.dim('exit|quit')} Leave the interactive CLI`)\n console.log(` ${pc.dim('clear')} Clear the screen`)\n console.log(` ${pc.dim('logo')} Re-print the banner`)\n console.log(` ${pc.dim('version')} Show version`)\n console.log(` ${pc.dim('init <name>')} Create a new vobs project`)\n console.log(` ${pc.dim('generate <name>')} Generate a component/page`)\n console.log(` ${pc.dim('add <package>')} Add a package`)\n console.log(` ${pc.dim('dev|build')} Use \\`vobs dev\\` / \\`vobs build\\` in a terminal`)\n },\n help: ''\n },\n logo: { cmd: async () => showLogo(), help: '' },\n version: { cmd: async () => showBanner(), help: '' },\n clear: {\n cmd: async () => {\n process.stdout.write('\\x1Bc')\n },\n help: ''\n },\n exit: { cmd: async () => process.exit(0), help: '' },\n quit: { cmd: async () => process.exit(0), help: '' },\n init: {\n cmd: async (args) => {\n await initCommand({\n name: args[0],\n targetDir: undefined,\n packageManager: undefined,\n typescript: true,\n git: true\n })\n },\n help: ''\n },\n generate: {\n cmd: async (args) => {\n await generateCommand({\n name: args[0],\n type: undefined,\n targetDir: undefined\n })\n },\n help: ''\n },\n g: {\n cmd: async (args) => {\n await generateCommand({\n name: args[0],\n type: undefined,\n targetDir: undefined\n })\n },\n help: ''\n },\n add: {\n cmd: async (args) => {\n await addCommand({ package: args[0], dev: args.includes('-D') || args.includes('--dev') })\n },\n help: ''\n }\n}\n\n/** Dispatch a parsed command line to the internal table */\nasync function dispatch(args: string[]): Promise<void> {\n const name = args[0]\n const rest = args.slice(1)\n\n if (!name) return\n\n const entry = TABLE[name]\n if (entry) {\n await entry.cmd(rest)\n return\n }\n\n console.log(` ${pc.yellow('⚠')} Unknown command: ${pc.bold(String(name))}. Type ${pc.cyan('help')} to see options.`)\n}\n\n/** Minimal tokenizer supporting double-quoted arguments */\nfunction splitArgs(line: string): string[] {\n const out: string[] = []\n const re = /[^\\s\"']+|\"([^\"]*)\"|'([^']*)'/g\n let m: RegExpExecArray | null\n while ((m = re.exec(line)) !== null) {\n out.push(m[1] ?? m[2] ?? m[0])\n }\n return out\n}","import { createCLI, KNOWN_SUBCOMMANDS } from './cli.js'\nimport { showBanner } from './banner.js'\nimport { startRepl } from './repl.js'\n\n/** 帮助/版本文本里出现的 flag —— 它们不是\"未知 flag\"。 */\nconst META_FLAGS = new Set(['--help', '-h', '--version', '-V'])\n\n/**\n * 该 flag 是否属于**顶层**用法(相对\"某个子命令的 flag\"而言)。\n *\n * `vobs --port 3000` 里的 `--port` 不是顶层 flag(它属于 `dev`),\n * 所以这里只认 `-`/`--` 开头的未知项,交由调用方按\"有没有子命令\"决定是不是错误。\n */\nfunction isFlag(token: string): boolean {\n return token.startsWith('-') && token !== '-'\n}\n\n/**\n * 单命令分发。\n *\n * 此前 `start()` 在 `--version` 之后直接 `createCLI().parse()` 就结束,而 cac 对\n * \"没有命令匹配\"**不做任何兜底**:既不报错、也不输出、退出码还是 0。\n * 于是 `vobs chekc`(拼错)在 CI 里静默成功;`vobs --totally-unknown` 同样 0 字节 + exit 0。\n * 这里补上兜底:未知子命令与未知顶层 flag 都进 stderr 且 **exit 1**。\n */\nexport async function start(args: string[]): Promise<void> {\n // No args (or explicit `cli`) → launch the interactive REPL\n if (args.length === 0 || args[0] === 'cli') {\n await startRepl()\n return\n }\n\n const first = args[0]\n const hasSubcommand = KNOWN_SUBCOMMANDS.includes(first)\n\n /*\n * `--version` / `-V` 只有在**没有子命令**时才表示\"打印版本\"。\n * 此前是 `args.includes('--version')` —— 任何位置出现都会短路,\n * 于是 `vobs check --version` 只打 banner、check 根本没跑(静默吞掉一个真命令)。\n */\n if (!hasSubcommand && (args.includes('--version') || args.includes('-V'))) {\n showBanner()\n return\n }\n\n if (!hasSubcommand && !isFlag(first)) {\n process.stderr.write(`✖ 未知命令:${first}\\n\\n`)\n try {\n createCLI().parse(['node', 'vobs', '--help'])\n } catch {\n // 帮助输出失败不应掩盖真正的错误:错误已写进 stderr、退出码才是判据\n }\n process.exitCode = 1\n return\n }\n\n if (!hasSubcommand && isFlag(first) && !META_FLAGS.has(first)) {\n process.stderr.write(`✖ 未知选项:${first}\\n\\n`)\n try {\n createCLI().parse(['node', 'vobs', '--help'])\n } catch {\n // 同上\n }\n process.exitCode = 1\n return\n }\n\n // Let cac read the full process.argv so single-shot commands dispatch correctly\n try {\n createCLI().parse()\n } catch (error) {\n /*\n * cac 对**已匹配子命令**的未知选项/缺值会抛 `CACError`。此前它一路冒到\n * `bin/vobs.js` 的顶层 `await start(...)`(无 try/catch),用户看到的是\n * 半屏 Node 栈而不是一句可读的错误。\n */\n const message = error instanceof Error ? error.message : String(error)\n process.stderr.write(`✖ ${message}\\n`)\n process.exitCode = 1\n }\n}\n"],"mappings":"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","names":["resolve","execSync","join","existsSync","resolve","existsSync","resolve","readFileSync","readFileSync","resolve","execSync","resolve","p","resolve","p","existsSync","readFileSync","writeFileSync","execSync","createServer","dirname","resolve","p","readFileSync","resolve","writeFileSync","existsSync","build","dirname","error","createServer","text","execSync","result","readFile","writeFile","error","visit","text","readFile","relative","writeFile","pc","pc","error"]}
@@ -46,7 +46,7 @@ function timestamp() {
46
46
  }
47
47
  __name(timestamp, "timestamp");
48
48
  function info(msg) {
49
- console.log(`${timestamp()} ${import_picocolors.default.cyan("\u2139")} ${msg}`);
49
+ console.error(`${timestamp()} ${import_picocolors.default.cyan("\u2139")} ${msg}`);
50
50
  }
51
51
  __name(info, "info");
52
52
  function success(msg) {
@@ -54,7 +54,7 @@ function success(msg) {
54
54
  }
55
55
  __name(success, "success");
56
56
  function warn(msg) {
57
- console.log(`${timestamp()} ${import_picocolors.default.yellow("\u26A0")} ${msg}`);
57
+ console.error(`${timestamp()} ${import_picocolors.default.yellow("\u26A0")} ${msg}`);
58
58
  }
59
59
  __name(warn, "warn");
60
60
  function error(msg) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts"],"sourcesContent":["import pc from 'picocolors'\n\nfunction timestamp(): string {\n return pc.dim(`[${new Date().toLocaleTimeString()}]`)\n}\n\nexport function info(msg: string): void {\n console.log(`${timestamp()} ${pc.cyan('ℹ')} ${msg}`)\n}\n\nexport function success(msg: string): void {\n console.log(`${timestamp()} ${pc.green('✔')} ${msg}`)\n}\n\nexport function warn(msg: string): void {\n console.log(`${timestamp()} ${pc.yellow('⚠')} ${msg}`)\n}\n\nexport function error(msg: string): void {\n console.error(`${timestamp()} ${pc.red('✖')} ${msg}`)\n}\n\nexport function step(msg: string): void {\n console.log(`\\n ${pc.bold(pc.cyan(msg))}`)\n}\n\nexport const logger = { info, success, warn, error, step }"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAe;AAEf,SAAS,YAAoB;AAC3B,SAAO,kBAAAA,QAAG,IAAI,KAAI,oBAAI,KAAK,GAAE,mBAAmB,CAAC,GAAG;AACtD;AAFS;AAIF,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,KAAK,QAAG,CAAC,IAAI,GAAG,EAAE;AACrD;AAFgB;AAIT,SAAS,QAAQ,KAAmB;AACzC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,MAAM,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,OAAO,QAAG,CAAC,IAAI,GAAG,EAAE;AACvD;AAFgB;AAIT,SAAS,MAAM,KAAmB;AACvC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,IAAI,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI;AAAA,IAAO,kBAAAA,QAAG,KAAK,kBAAAA,QAAG,KAAK,GAAG,CAAC,CAAC,EAAE;AAC5C;AAFgB;AAIT,IAAM,SAAS,EAAE,MAAM,SAAS,MAAM,OAAO,KAAK;","names":["pc"]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts"],"sourcesContent":["import pc from 'picocolors'\n\n/*\n * 诊断/日志一律走 **stderr**,stdout 只留给**数据**。\n *\n * 为什么这不是洁癖:`vobs check --json` 的输出是给 AI 与开发台面板消费的机器接口,\n * 而 `--json --write` 时 `logger.info('报告写入 …')` 会先往 stdout 打一行带时间戳的\n * `[14:24:23] ℹ …`,于是 `JSON.parse(stdout)` 直接失败(实测\n * `.artifacts/probe-audit-cli-check.mjs`:同一脚本里 `--json` 可 parse、`--json --write` 不可)。\n * `warn` 同理。\n *\n * 注意:`error` 本来就走 stderr;`success`/`step` 保持 stdout(它们是给人看的**主输出**,\n * 不是旁路日志),`check` 的成功行也仍是 stdout。\n */\nfunction timestamp(): string {\n return pc.dim(`[${new Date().toLocaleTimeString()}]`)\n}\n\nexport function info(msg: string): void {\n console.error(`${timestamp()} ${pc.cyan('ℹ')} ${msg}`)\n}\n\nexport function success(msg: string): void {\n console.log(`${timestamp()} ${pc.green('✔')} ${msg}`)\n}\n\nexport function warn(msg: string): void {\n console.error(`${timestamp()} ${pc.yellow('⚠')} ${msg}`)\n}\n\nexport function error(msg: string): void {\n console.error(`${timestamp()} ${pc.red('✖')} ${msg}`)\n}\n\nexport function step(msg: string): void {\n console.log(`\\n ${pc.bold(pc.cyan(msg))}`)\n}\n\nexport const logger = { info, success, warn, error, step }"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAe;AAcf,SAAS,YAAoB;AAC3B,SAAO,kBAAAA,QAAG,IAAI,KAAI,oBAAI,KAAK,GAAE,mBAAmB,CAAC,GAAG;AACtD;AAFS;AAIF,SAAS,KAAK,KAAmB;AACtC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,KAAK,QAAG,CAAC,IAAI,GAAG,EAAE;AACvD;AAFgB;AAIT,SAAS,QAAQ,KAAmB;AACzC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,MAAM,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,OAAO,QAAG,CAAC,IAAI,GAAG,EAAE;AACzD;AAFgB;AAIT,SAAS,MAAM,KAAmB;AACvC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,kBAAAA,QAAG,IAAI,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI;AAAA,IAAO,kBAAAA,QAAG,KAAK,kBAAAA,QAAG,KAAK,GAAG,CAAC,CAAC,EAAE;AAC5C;AAFgB;AAIT,IAAM,SAAS,EAAE,MAAM,SAAS,MAAM,OAAO,KAAK;","names":["pc"]}
@@ -8,7 +8,7 @@ function timestamp() {
8
8
  }
9
9
  __name(timestamp, "timestamp");
10
10
  function info(msg) {
11
- console.log(`${timestamp()} ${pc.cyan("\u2139")} ${msg}`);
11
+ console.error(`${timestamp()} ${pc.cyan("\u2139")} ${msg}`);
12
12
  }
13
13
  __name(info, "info");
14
14
  function success(msg) {
@@ -16,7 +16,7 @@ function success(msg) {
16
16
  }
17
17
  __name(success, "success");
18
18
  function warn(msg) {
19
- console.log(`${timestamp()} ${pc.yellow("\u26A0")} ${msg}`);
19
+ console.error(`${timestamp()} ${pc.yellow("\u26A0")} ${msg}`);
20
20
  }
21
21
  __name(warn, "warn");
22
22
  function error(msg) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logger.ts"],"sourcesContent":["import pc from 'picocolors'\n\nfunction timestamp(): string {\n return pc.dim(`[${new Date().toLocaleTimeString()}]`)\n}\n\nexport function info(msg: string): void {\n console.log(`${timestamp()} ${pc.cyan('ℹ')} ${msg}`)\n}\n\nexport function success(msg: string): void {\n console.log(`${timestamp()} ${pc.green('✔')} ${msg}`)\n}\n\nexport function warn(msg: string): void {\n console.log(`${timestamp()} ${pc.yellow('⚠')} ${msg}`)\n}\n\nexport function error(msg: string): void {\n console.error(`${timestamp()} ${pc.red('✖')} ${msg}`)\n}\n\nexport function step(msg: string): void {\n console.log(`\\n ${pc.bold(pc.cyan(msg))}`)\n}\n\nexport const logger = { info, success, warn, error, step }"],"mappings":";;;;AAAA,OAAO,QAAQ;AAEf,SAAS,YAAoB;AAC3B,SAAO,GAAG,IAAI,KAAI,oBAAI,KAAK,GAAE,mBAAmB,CAAC,GAAG;AACtD;AAFS;AAIF,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,GAAG,KAAK,QAAG,CAAC,IAAI,GAAG,EAAE;AACrD;AAFgB;AAIT,SAAS,QAAQ,KAAmB;AACzC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,GAAG,MAAM,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,GAAG,OAAO,QAAG,CAAC,IAAI,GAAG,EAAE;AACvD;AAFgB;AAIT,SAAS,MAAM,KAAmB;AACvC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,GAAG,IAAI,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI;AAAA,IAAO,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,EAAE;AAC5C;AAFgB;AAIT,IAAM,SAAS,EAAE,MAAM,SAAS,MAAM,OAAO,KAAK;","names":[]}
1
+ {"version":3,"sources":["../../src/utils/logger.ts"],"sourcesContent":["import pc from 'picocolors'\n\n/*\n * 诊断/日志一律走 **stderr**,stdout 只留给**数据**。\n *\n * 为什么这不是洁癖:`vobs check --json` 的输出是给 AI 与开发台面板消费的机器接口,\n * 而 `--json --write` 时 `logger.info('报告写入 …')` 会先往 stdout 打一行带时间戳的\n * `[14:24:23] ℹ …`,于是 `JSON.parse(stdout)` 直接失败(实测\n * `.artifacts/probe-audit-cli-check.mjs`:同一脚本里 `--json` 可 parse、`--json --write` 不可)。\n * `warn` 同理。\n *\n * 注意:`error` 本来就走 stderr;`success`/`step` 保持 stdout(它们是给人看的**主输出**,\n * 不是旁路日志),`check` 的成功行也仍是 stdout。\n */\nfunction timestamp(): string {\n return pc.dim(`[${new Date().toLocaleTimeString()}]`)\n}\n\nexport function info(msg: string): void {\n console.error(`${timestamp()} ${pc.cyan('ℹ')} ${msg}`)\n}\n\nexport function success(msg: string): void {\n console.log(`${timestamp()} ${pc.green('✔')} ${msg}`)\n}\n\nexport function warn(msg: string): void {\n console.error(`${timestamp()} ${pc.yellow('⚠')} ${msg}`)\n}\n\nexport function error(msg: string): void {\n console.error(`${timestamp()} ${pc.red('✖')} ${msg}`)\n}\n\nexport function step(msg: string): void {\n console.log(`\\n ${pc.bold(pc.cyan(msg))}`)\n}\n\nexport const logger = { info, success, warn, error, step }"],"mappings":";;;;AAAA,OAAO,QAAQ;AAcf,SAAS,YAAoB;AAC3B,SAAO,GAAG,IAAI,KAAI,oBAAI,KAAK,GAAE,mBAAmB,CAAC,GAAG;AACtD;AAFS;AAIF,SAAS,KAAK,KAAmB;AACtC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,GAAG,KAAK,QAAG,CAAC,IAAI,GAAG,EAAE;AACvD;AAFgB;AAIT,SAAS,QAAQ,KAAmB;AACzC,UAAQ,IAAI,GAAG,UAAU,CAAC,IAAI,GAAG,MAAM,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,GAAG,OAAO,QAAG,CAAC,IAAI,GAAG,EAAE;AACzD;AAFgB;AAIT,SAAS,MAAM,KAAmB;AACvC,UAAQ,MAAM,GAAG,UAAU,CAAC,IAAI,GAAG,IAAI,QAAG,CAAC,IAAI,GAAG,EAAE;AACtD;AAFgB;AAIT,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI;AAAA,IAAO,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAC,EAAE;AAC5C;AAFgB;AAIT,IAAM,SAAS,EAAE,MAAM,SAAS,MAAM,OAAO,KAAK;","names":[]}
@@ -0,0 +1,47 @@
1
+ var __VOBS_CJS_FILE_URL = require("url").pathToFileURL(__filename).href;
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // packages/cli/src/version.ts
23
+ var version_exports = {};
24
+ __export(version_exports, {
25
+ cliVersion: () => cliVersion
26
+ });
27
+ module.exports = __toCommonJS(version_exports);
28
+ var import_node_fs = require("fs");
29
+ var cached;
30
+ function cliVersion() {
31
+ if (cached !== void 0) return cached;
32
+ try {
33
+ const manifest = JSON.parse(
34
+ (0, import_node_fs.readFileSync)(new URL("../package.json", __VOBS_CJS_FILE_URL), "utf8")
35
+ );
36
+ cached = manifest.version ?? "0.0.0";
37
+ } catch {
38
+ cached = "0.0.0";
39
+ }
40
+ return cached;
41
+ }
42
+ __name(cliVersion, "cliVersion");
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ cliVersion
46
+ });
47
+ //# sourceMappingURL=version.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/version.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\n\n/**\n * CLI 版本号的**单一来源**:直接读本包的 `package.json`。\n *\n * 此前版本号在三处各自硬编码,且都与 `package.json` 不符:\n * - `banner.ts` 的 `𝗩𝗢𝗕𝗦 𝗖𝗟𝗜 𝘃𝟭.𝟬` 常量 —— 这就是 `vobs --version` 的**全部**输出;\n * - `cli.ts` 的 `cli.version('1.0.0')` —— `--help` 头部显示 `vobs/1.0.0`;\n * - `init.ts` 的 `vobsVersion: '1.0.0'` —— 写进脚手架产物。\n * 同一个仓库的 `commands/dsh.ts` 早就有正确的\"读 package.json\"实现,所以这不是能力问题,\n * 而是没人从**外部**看过 CLI 的版本输出(三处不一致也正因如此从未被发现)。\n */\nlet cached: string | undefined\n\nexport function cliVersion(): string {\n if (cached !== undefined) return cached\n try {\n const manifest = JSON.parse(\n readFileSync(new URL('../package.json', import.meta.url), 'utf8')\n ) as { version?: string }\n cached = manifest.version ?? '0.0.0'\n } catch {\n // 读不到 package.json(被打包成单文件等)时不要谎报一个像真版本号的常量\n cached = '0.0.0'\n }\n return cached\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAA6B;AAY7B,IAAI;AAEG,SAAS,aAAqB;AACnC,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI;AACF,UAAM,WAAW,KAAK;AAAA,UACpB,6BAAa,IAAI,IAAI,mBAAmB,mBAAe,GAAG,MAAM;AAAA,IAClE;AACA,aAAS,SAAS,WAAW;AAAA,EAC/B,QAAQ;AAEN,aAAS;AAAA,EACX;AACA,SAAO;AACT;AAZgB;","names":[]}
@@ -0,0 +1,3 @@
1
+ declare function cliVersion(): string;
2
+
3
+ export { cliVersion };
@@ -0,0 +1,3 @@
1
+ declare function cliVersion(): string;
2
+
3
+ export { cliVersion };