@vobs/cli 1.7.8 → 1.8.1

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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/generate.ts","../../src/utils/logger.ts","../../src/utils/file.ts"],"sourcesContent":["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 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}"],"mappings":"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","names":["resolve","resolve"]}
1
+ {"version":3,"sources":["../../src/commands/generate.ts","../../src/utils/logger.ts","../../src/utils/file.ts"],"sourcesContent":["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 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}"],"mappings":"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","names":["resolve","resolve"]}
@@ -55,7 +55,7 @@ function timestamp() {
55
55
  }
56
56
  __name(timestamp, "timestamp");
57
57
  function info(msg) {
58
- console.log(`${timestamp()} ${import_picocolors.default.cyan("\u2139")} ${msg}`);
58
+ console.error(`${timestamp()} ${import_picocolors.default.cyan("\u2139")} ${msg}`);
59
59
  }
60
60
  __name(info, "info");
61
61
  function success(msg) {
@@ -63,7 +63,7 @@ function success(msg) {
63
63
  }
64
64
  __name(success, "success");
65
65
  function warn(msg) {
66
- console.log(`${timestamp()} ${import_picocolors.default.yellow("\u26A0")} ${msg}`);
66
+ console.error(`${timestamp()} ${import_picocolors.default.yellow("\u26A0")} ${msg}`);
67
67
  }
68
68
  __name(warn, "warn");
69
69
  function error(msg) {
@@ -167,6 +167,23 @@ function addPackage(targetDir, pm, pkg, dev) {
167
167
  }
168
168
  __name(addPackage, "addPackage");
169
169
 
170
+ // packages/cli/src/version.ts
171
+ var import_node_fs3 = require("fs");
172
+ var cached;
173
+ function cliVersion() {
174
+ if (cached !== void 0) return cached;
175
+ try {
176
+ const manifest = JSON.parse(
177
+ (0, import_node_fs3.readFileSync)(new URL("../package.json", __VOBS_CJS_FILE_URL), "utf8")
178
+ );
179
+ cached = manifest.version ?? "0.0.0";
180
+ } catch {
181
+ cached = "0.0.0";
182
+ }
183
+ return cached;
184
+ }
185
+ __name(cliVersion, "cliVersion");
186
+
170
187
  // packages/cli/src/commands/init.ts
171
188
  async function initCommand(options) {
172
189
  const projectName = options.name || await p.text({
@@ -212,7 +229,7 @@ async function initCommand(options) {
212
229
  name: projectName,
213
230
  packageName: projectName.toLowerCase().replace(/\s+/g, "-"),
214
231
  typescript: useTypescript,
215
- vobsVersion: "1.0.0"
232
+ vobsVersion: cliVersion()
216
233
  });
217
234
  logger.success("Project scaffolded");
218
235
  logger.step("Installing dependencies...");
@@ -364,7 +381,7 @@ async function addCommand(options) {
364
381
  __name(addCommand, "addCommand");
365
382
 
366
383
  // packages/cli/src/commands/dsh.ts
367
- var import_node_fs3 = require("fs");
384
+ var import_node_fs4 = require("fs");
368
385
  var import_promises = require("fs/promises");
369
386
  var import_node_child_process3 = require("child_process");
370
387
  var import_node_http = require("http");
@@ -375,7 +392,7 @@ var PLATFORM_MODULES = ["react", "react-dom"];
375
392
  var vobsVersion = /* @__PURE__ */ __name(() => {
376
393
  try {
377
394
  const manifest = JSON.parse(
378
- (0, import_node_fs3.readFileSync)(new URL("../../package.json", __VOBS_CJS_FILE_URL), "utf8")
395
+ (0, import_node_fs4.readFileSync)(new URL("../../package.json", __VOBS_CJS_FILE_URL), "utf8")
379
396
  );
380
397
  return manifest.version ?? "1.7.5";
381
398
  } catch {
@@ -417,7 +434,7 @@ async function dshInitCommand(target, options) {
417
434
  "dsh-plugin"
418
435
  );
419
436
  ensureDir(targetDir);
420
- (0, import_node_fs3.writeFileSync)(
437
+ (0, import_node_fs4.writeFileSync)(
421
438
  (0, import_node_path5.resolve)(targetDir, ".gitignore"),
422
439
  ["node_modules/", "*.log", "*.tsbuildinfo", "", "# lib/ \u662F\u6784\u5EFA\u4EA7\u7269\uFF0C\u5FC5\u987B\u63D0\u4EA4\uFF1ADSH \u5B89\u88C5\u65F6\u4E0D\u4F1A\u6784\u5EFA\u4F60\u7684\u5305\u3002", ""].join("\n"),
423
440
  "utf8"
@@ -444,7 +461,7 @@ __name(dshInitCommand, "dshInitCommand");
444
461
  async function dshBuildCommand() {
445
462
  const projectDir = process.cwd();
446
463
  const configFile = (0, import_node_path5.resolve)(projectDir, "vite.config.ts");
447
- if (!(0, import_node_fs3.existsSync)(configFile)) {
464
+ if (!(0, import_node_fs4.existsSync)(configFile)) {
448
465
  logger.error("\u5F53\u524D\u76EE\u5F55\u6CA1\u6709 vite.config.ts\uFF0C\u8BF7\u5728\u63D2\u4EF6\u9879\u76EE\u6839\u76EE\u5F55\u8FD0\u884C\u3002");
449
466
  process.exitCode = 1;
450
467
  return;
@@ -467,7 +484,7 @@ async function dshBuildCommand() {
467
484
  logger.info("\u6784\u5EFA Host \u4EA7\u7269 \u2026");
468
485
  const hostTarget = (0, import_node_path5.resolve)(projectDir, hostEntry.replace(/^\.\//u, ""));
469
486
  const hostEntrySource = (0, import_node_path5.resolve)(projectDir, "src", "host", "index.ts");
470
- if (!(0, import_node_fs3.existsSync)(hostEntrySource)) {
487
+ if (!(0, import_node_fs4.existsSync)(hostEntrySource)) {
471
488
  logger.warn(`\u6CA1\u6709\u627E\u5230 ${hostEntrySource}\uFF0C\u8DF3\u8FC7 Host \u6784\u5EFA\u3002`);
472
489
  return;
473
490
  }
@@ -580,7 +597,7 @@ async function dshDevCommand(options) {
580
597
  packageRoot = (0, import_node_path5.dirname)((0, import_node_path5.dirname)(projectRequire.resolve("@vobs/dsh")));
581
598
  }
582
599
  const candidate = (0, import_node_path5.join)(packageRoot, "dist", "preview.js");
583
- previewFile = (0, import_node_fs3.existsSync)(candidate) ? candidate : void 0;
600
+ previewFile = (0, import_node_fs4.existsSync)(candidate) ? candidate : void 0;
584
601
  } catch {
585
602
  previewFile = void 0;
586
603
  }
@@ -652,7 +669,7 @@ data: 1
652
669
  return;
653
670
  }
654
671
  if (url === "/client.js") {
655
- if (!(0, import_node_fs3.existsSync)(clientFile)) {
672
+ if (!(0, import_node_fs4.existsSync)(clientFile)) {
656
673
  response.writeHead(503, { "content-type": "text/plain; charset=utf-8" });
657
674
  response.end(`\u8FD8\u6CA1\u6709\u4EA7\u7269\uFF1A${clientEntry}
658
675
  ${buildError ?? ""}`);
@@ -673,7 +690,7 @@ ${buildError ?? ""}`);
673
690
  __name(dshDevCommand, "dshDevCommand");
674
691
  function readManifest(dir) {
675
692
  try {
676
- return JSON.parse((0, import_node_fs3.readFileSync)((0, import_node_path5.resolve)(dir, "package.json"), "utf8"));
693
+ return JSON.parse((0, import_node_fs4.readFileSync)((0, import_node_path5.resolve)(dir, "package.json"), "utf8"));
677
694
  } catch {
678
695
  return void 0;
679
696
  }
@@ -696,10 +713,10 @@ function collectIssues(dir) {
696
713
  result.errors.push("\u7F3A\u5C11 dsh.bundle.patch \u2014\u2014 DSH \u4E0D\u4F1A\u628A\u8FD9\u4E2A\u5305\u5F53\u4F5C\u7EC4\u5408\u5305\uFF08bundle\uFF09");
697
714
  } else {
698
715
  const patchPath = (0, import_node_path5.resolve)(dir, bundle.patch.replace(/^\.\//u, ""));
699
- if (!(0, import_node_fs3.existsSync)(patchPath)) {
716
+ if (!(0, import_node_fs4.existsSync)(patchPath)) {
700
717
  result.errors.push(`dsh.bundle.patch \u6307\u5411\u7684 ${bundle.patch} \u4E0D\u5B58\u5728`);
701
718
  } else {
702
- const text5 = (0, import_node_fs3.readFileSync)(patchPath, "utf8");
719
+ const text5 = (0, import_node_fs4.readFileSync)(patchPath, "utf8");
703
720
  if (!text5.includes("insert:")) result.errors.push("cordis.patch.yml \u91CC\u6CA1\u6709 insert: \u6BB5\u843D\uFF0C\u63D2\u4EF6\u884C\u4E0D\u4F1A\u8FDB\u7EC4\u5408\u6811");
704
721
  else if (name !== "" && !text5.includes(name)) {
705
722
  result.warnings.push(`cordis.patch.yml \u91CC\u6CA1\u6709\u51FA\u73B0\u5305\u540D ${name}\uFF0C\u786E\u8BA4 insert \u7684 name \u5199\u5BF9\u4E86`);
@@ -713,7 +730,7 @@ function collectIssues(dir) {
713
730
  const hostEntry = exportsField["."];
714
731
  const clientEntry = exportsField["./client"];
715
732
  if (typeof hostEntry !== "string") result.errors.push('exports["."] \u672A\u58F0\u660E \u2014\u2014 DSH \u52A0\u8F7D\u4E0D\u5230 Host \u4FA7\u63D2\u4EF6');
716
- else if (!(0, import_node_fs3.existsSync)((0, import_node_path5.resolve)(dir, hostEntry.replace(/^\.\//u, "")))) {
733
+ else if (!(0, import_node_fs4.existsSync)((0, import_node_path5.resolve)(dir, hostEntry.replace(/^\.\//u, "")))) {
717
734
  result.errors.push(`exports["."] \u6307\u5411\u7684 ${hostEntry} \u4E0D\u5B58\u5728\uFF0C\u5148\u6784\u5EFA`);
718
735
  } else result.passed.push("Host \u5165\u53E3\u5B58\u5728");
719
736
  if (typeof clientEntry !== "string") result.errors.push('exports["./client"] \u672A\u58F0\u660E \u2014\u2014 \u9875\u9762\u62FF\u4E0D\u5230\u5BA2\u6237\u7AEF bundle');
@@ -731,10 +748,10 @@ function collectIssues(dir) {
731
748
  } else result.passed.push("\u6CA1\u6709 workspace: \u534F\u8BAE\u4F9D\u8D56");
732
749
  if (typeof clientEntry === "string") {
733
750
  const clientPath = (0, import_node_path5.resolve)(dir, clientEntry.replace(/^\.\//u, ""));
734
- if (!(0, import_node_fs3.existsSync)(clientPath)) {
751
+ if (!(0, import_node_fs4.existsSync)(clientPath)) {
735
752
  result.errors.push(`\u5BA2\u6237\u7AEF\u4EA7\u7269 ${clientEntry} \u4E0D\u5B58\u5728\uFF0C\u5148\u8FD0\u884C\u6784\u5EFA`);
736
753
  } else {
737
- const code = (0, import_node_fs3.readFileSync)(clientPath, "utf8");
754
+ const code = (0, import_node_fs4.readFileSync)(clientPath, "utf8");
738
755
  const loads = (code.match(/__ModuleLoader__\.load\(/gu) ?? []).length;
739
756
  if (loads !== 1) result.errors.push(`\u5BA2\u6237\u7AEF\u4EA7\u7269\u91CC __ModuleLoader__.load \u51FA\u73B0 ${loads} \u6B21\uFF0C\u5E94\u4E3A 1 \u6B21\uFF08\u5148\u6784\u5EFA\uFF09`);
740
757
  else result.passed.push("\u4EA7\u7269\u5F62\u6001\u662F DSH \u5BA2\u6237\u7AEF\u6A21\u5757\u534F\u8BAE");
@@ -785,7 +802,7 @@ function buildInstallSpec(options) {
785
802
  if (options.spec !== void 0) return { spec: options.spec };
786
803
  if (options.from !== void 0) {
787
804
  const target = (0, import_node_path5.resolve)(options.from);
788
- if (!(0, import_node_fs3.existsSync)(target)) return { error: `--from \u6307\u5411\u7684\u8DEF\u5F84\u4E0D\u5B58\u5728\uFF1A${target}` };
805
+ if (!(0, import_node_fs4.existsSync)(target)) return { error: `--from \u6307\u5411\u7684\u8DEF\u5F84\u4E0D\u5B58\u5728\uFF1A${target}` };
789
806
  return { spec: target };
790
807
  }
791
808
  if (options.repo !== void 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/index.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"],"sourcesContent":["export { initCommand } from './init.js'\nexport { devCommand } from './dev.js'\nexport { buildCommand } from './build.js'\nexport { generateCommand } from './generate.js'\nexport { addCommand } from './add.js'\nexport { dshCommand, collectIssues, buildInstallSpec, type DshOptions } from './dsh.js'","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"],"mappings":"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","names":["import_node_path","import_node_child_process","pc","Handlebars","join","import_node_fs","import_node_path","import_vite","import_node_path","p","p","import_node_fs","import_node_child_process","import_node_path","p","build","error","text","result"]}
1
+ {"version":3,"sources":["../../src/commands/index.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"],"sourcesContent":["export { initCommand } from './init.js'\nexport { devCommand } from './dev.js'\nexport { buildCommand } from './build.js'\nexport { generateCommand } from './generate.js'\nexport { addCommand } from './add.js'\nexport { dshCommand, collectIssues, buildInstallSpec, type DshOptions } from './dsh.js'","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"],"mappings":"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","names":["import_node_path","import_node_child_process","pc","Handlebars","join","import_node_fs","import_node_path","import_node_fs","import_vite","import_node_path","p","p","import_node_fs","import_node_child_process","import_node_path","p","build","error","text","result"]}
@@ -13,7 +13,7 @@ function timestamp() {
13
13
  }
14
14
  __name(timestamp, "timestamp");
15
15
  function info(msg) {
16
- console.log(`${timestamp()} ${pc.cyan("\u2139")} ${msg}`);
16
+ console.error(`${timestamp()} ${pc.cyan("\u2139")} ${msg}`);
17
17
  }
18
18
  __name(info, "info");
19
19
  function success(msg) {
@@ -21,7 +21,7 @@ function success(msg) {
21
21
  }
22
22
  __name(success, "success");
23
23
  function warn(msg) {
24
- console.log(`${timestamp()} ${pc.yellow("\u26A0")} ${msg}`);
24
+ console.error(`${timestamp()} ${pc.yellow("\u26A0")} ${msg}`);
25
25
  }
26
26
  __name(warn, "warn");
27
27
  function error(msg) {
@@ -125,6 +125,23 @@ function addPackage(targetDir, pm, pkg, dev) {
125
125
  }
126
126
  __name(addPackage, "addPackage");
127
127
 
128
+ // packages/cli/src/version.ts
129
+ import { readFileSync as readFileSync2 } from "fs";
130
+ var cached;
131
+ function cliVersion() {
132
+ if (cached !== void 0) return cached;
133
+ try {
134
+ const manifest = JSON.parse(
135
+ readFileSync2(new URL("../package.json", import.meta.url), "utf8")
136
+ );
137
+ cached = manifest.version ?? "0.0.0";
138
+ } catch {
139
+ cached = "0.0.0";
140
+ }
141
+ return cached;
142
+ }
143
+ __name(cliVersion, "cliVersion");
144
+
128
145
  // packages/cli/src/commands/init.ts
129
146
  async function initCommand(options) {
130
147
  const projectName = options.name || await p.text({
@@ -170,7 +187,7 @@ async function initCommand(options) {
170
187
  name: projectName,
171
188
  packageName: projectName.toLowerCase().replace(/\s+/g, "-"),
172
189
  typescript: useTypescript,
173
- vobsVersion: "1.0.0"
190
+ vobsVersion: cliVersion()
174
191
  });
175
192
  logger.success("Project scaffolded");
176
193
  logger.step("Installing dependencies...");
@@ -322,7 +339,7 @@ async function addCommand(options) {
322
339
  __name(addCommand, "addCommand");
323
340
 
324
341
  // packages/cli/src/commands/dsh.ts
325
- import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
342
+ import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
326
343
  import { readFile } from "fs/promises";
327
344
  import { execSync as execSync3, spawnSync } from "child_process";
328
345
  import { createServer as createServer2 } from "http";
@@ -333,7 +350,7 @@ var PLATFORM_MODULES = ["react", "react-dom"];
333
350
  var vobsVersion = /* @__PURE__ */ __name(() => {
334
351
  try {
335
352
  const manifest = JSON.parse(
336
- readFileSync2(new URL("../../package.json", import.meta.url), "utf8")
353
+ readFileSync3(new URL("../../package.json", import.meta.url), "utf8")
337
354
  );
338
355
  return manifest.version ?? "1.7.5";
339
356
  } catch {
@@ -631,7 +648,7 @@ ${buildError ?? ""}`);
631
648
  __name(dshDevCommand, "dshDevCommand");
632
649
  function readManifest(dir) {
633
650
  try {
634
- return JSON.parse(readFileSync2(resolve5(dir, "package.json"), "utf8"));
651
+ return JSON.parse(readFileSync3(resolve5(dir, "package.json"), "utf8"));
635
652
  } catch {
636
653
  return void 0;
637
654
  }
@@ -657,7 +674,7 @@ function collectIssues(dir) {
657
674
  if (!existsSync3(patchPath)) {
658
675
  result.errors.push(`dsh.bundle.patch \u6307\u5411\u7684 ${bundle.patch} \u4E0D\u5B58\u5728`);
659
676
  } else {
660
- const text5 = readFileSync2(patchPath, "utf8");
677
+ const text5 = readFileSync3(patchPath, "utf8");
661
678
  if (!text5.includes("insert:")) result.errors.push("cordis.patch.yml \u91CC\u6CA1\u6709 insert: \u6BB5\u843D\uFF0C\u63D2\u4EF6\u884C\u4E0D\u4F1A\u8FDB\u7EC4\u5408\u6811");
662
679
  else if (name !== "" && !text5.includes(name)) {
663
680
  result.warnings.push(`cordis.patch.yml \u91CC\u6CA1\u6709\u51FA\u73B0\u5305\u540D ${name}\uFF0C\u786E\u8BA4 insert \u7684 name \u5199\u5BF9\u4E86`);
@@ -692,7 +709,7 @@ function collectIssues(dir) {
692
709
  if (!existsSync3(clientPath)) {
693
710
  result.errors.push(`\u5BA2\u6237\u7AEF\u4EA7\u7269 ${clientEntry} \u4E0D\u5B58\u5728\uFF0C\u5148\u8FD0\u884C\u6784\u5EFA`);
694
711
  } else {
695
- const code = readFileSync2(clientPath, "utf8");
712
+ const code = readFileSync3(clientPath, "utf8");
696
713
  const loads = (code.match(/__ModuleLoader__\.load\(/gu) ?? []).length;
697
714
  if (loads !== 1) result.errors.push(`\u5BA2\u6237\u7AEF\u4EA7\u7269\u91CC __ModuleLoader__.load \u51FA\u73B0 ${loads} \u6B21\uFF0C\u5E94\u4E3A 1 \u6B21\uFF08\u5148\u6784\u5EFA\uFF09`);
698
715
  else result.passed.push("\u4EA7\u7269\u5F62\u6001\u662F DSH \u5BA2\u6237\u7AEF\u6A21\u5757\u534F\u8BAE");