@sfmc-bds/cli 0.1.0 → 0.2.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/README.md +7 -1
  2. package/dist/cli-result.d.ts +12 -0
  3. package/dist/cli-result.d.ts.map +1 -0
  4. package/dist/cli-result.js +15 -0
  5. package/dist/cli-result.js.map +7 -0
  6. package/dist/commands-behavior-pack.d.ts +11 -42
  7. package/dist/commands-behavior-pack.d.ts.map +1 -1
  8. package/dist/commands-behavior-pack.js +40 -159
  9. package/dist/commands-behavior-pack.js.map +7 -1
  10. package/dist/commands-reload.d.ts +9 -0
  11. package/dist/commands-reload.d.ts.map +1 -0
  12. package/dist/commands-reload.js +30 -0
  13. package/dist/commands-reload.js.map +7 -0
  14. package/dist/commands.d.ts +7 -0
  15. package/dist/commands.d.ts.map +1 -1
  16. package/dist/commands.js +182 -172
  17. package/dist/commands.js.map +7 -1
  18. package/dist/i18n/index.d.ts +26 -0
  19. package/dist/i18n/index.d.ts.map +1 -0
  20. package/dist/i18n/index.js +107 -0
  21. package/dist/i18n/index.js.map +7 -0
  22. package/dist/i18n/locales/en.d.ts +381 -0
  23. package/dist/i18n/locales/en.d.ts.map +1 -0
  24. package/dist/i18n/locales/en.js +393 -0
  25. package/dist/i18n/locales/en.js.map +7 -0
  26. package/dist/i18n/locales/zh-CN.d.ts +4 -0
  27. package/dist/i18n/locales/zh-CN.d.ts.map +1 -0
  28. package/dist/i18n/locales/zh-CN.js +379 -0
  29. package/dist/i18n/locales/zh-CN.js.map +7 -0
  30. package/dist/i18n/types.d.ts +7 -0
  31. package/dist/i18n/types.d.ts.map +1 -0
  32. package/dist/i18n/types.js +17 -0
  33. package/dist/i18n/types.js.map +7 -0
  34. package/dist/index.d.ts +5 -11
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +51 -43
  37. package/dist/index.js.map +7 -1
  38. package/dist/interactive-prompts.d.ts +8 -0
  39. package/dist/interactive-prompts.d.ts.map +1 -0
  40. package/dist/interactive-prompts.js +57 -0
  41. package/dist/interactive-prompts.js.map +7 -0
  42. package/dist/locale-command.d.ts +3 -0
  43. package/dist/locale-command.d.ts.map +1 -0
  44. package/dist/locale-command.js +19 -0
  45. package/dist/locale-command.js.map +7 -0
  46. package/dist/logs.d.ts +22 -4
  47. package/dist/logs.d.ts.map +1 -1
  48. package/dist/logs.js +208 -193
  49. package/dist/logs.js.map +7 -1
  50. package/dist/main.js +135 -173
  51. package/dist/main.js.map +7 -1
  52. package/dist/module-commands.d.ts +43 -4
  53. package/dist/module-commands.d.ts.map +1 -1
  54. package/dist/module-commands.js +440 -327
  55. package/dist/module-commands.js.map +7 -1
  56. package/dist/module-fingerprint.d.ts +7 -0
  57. package/dist/module-fingerprint.d.ts.map +1 -0
  58. package/dist/module-fingerprint.js +31 -0
  59. package/dist/module-fingerprint.js.map +7 -0
  60. package/dist/module-wizard.d.ts +14 -0
  61. package/dist/module-wizard.d.ts.map +1 -0
  62. package/dist/module-wizard.js +313 -0
  63. package/dist/module-wizard.js.map +7 -0
  64. package/dist/pack-lifecycle.d.ts +95 -0
  65. package/dist/pack-lifecycle.d.ts.map +1 -0
  66. package/dist/pack-lifecycle.js +634 -0
  67. package/dist/pack-lifecycle.js.map +7 -0
  68. package/dist/pack-update/bindings.d.ts +12 -0
  69. package/dist/pack-update/bindings.d.ts.map +1 -0
  70. package/dist/pack-update/bindings.js +64 -0
  71. package/dist/pack-update/bindings.js.map +7 -0
  72. package/dist/pack-update/config.d.ts +22 -0
  73. package/dist/pack-update/config.d.ts.map +1 -0
  74. package/dist/pack-update/config.js +141 -0
  75. package/dist/pack-update/config.js.map +7 -0
  76. package/dist/pack-update/providers/curseforge.d.ts +23 -0
  77. package/dist/pack-update/providers/curseforge.d.ts.map +1 -0
  78. package/dist/pack-update/providers/curseforge.js +209 -0
  79. package/dist/pack-update/providers/curseforge.js.map +7 -0
  80. package/dist/pack-update/providers/index.d.ts +16 -0
  81. package/dist/pack-update/providers/index.d.ts.map +1 -0
  82. package/dist/pack-update/providers/index.js +37 -0
  83. package/dist/pack-update/providers/index.js.map +7 -0
  84. package/dist/pack-update/service.d.ts +21 -0
  85. package/dist/pack-update/service.d.ts.map +1 -0
  86. package/dist/pack-update/service.js +567 -0
  87. package/dist/pack-update/service.js.map +7 -0
  88. package/dist/pack-update/types.d.ts +126 -0
  89. package/dist/pack-update/types.d.ts.map +1 -0
  90. package/dist/pack-update/types.js +8 -0
  91. package/dist/pack-update/types.js.map +7 -0
  92. package/dist/pack-update/version-policy.d.ts +80 -0
  93. package/dist/pack-update/version-policy.d.ts.map +1 -0
  94. package/dist/pack-update/version-policy.js +216 -0
  95. package/dist/pack-update/version-policy.js.map +7 -0
  96. package/dist/registry.d.ts +12 -4
  97. package/dist/registry.d.ts.map +1 -1
  98. package/dist/registry.js +73 -106
  99. package/dist/registry.js.map +7 -1
  100. package/dist/remote-agent.d.ts.map +1 -1
  101. package/dist/remote-agent.js +160 -176
  102. package/dist/remote-agent.js.map +7 -1
  103. package/dist/repl.d.ts +4 -0
  104. package/dist/repl.d.ts.map +1 -1
  105. package/dist/repl.js +683 -605
  106. package/dist/repl.js.map +7 -1
  107. package/dist/runtime.d.ts +40 -14
  108. package/dist/runtime.d.ts.map +1 -1
  109. package/dist/runtime.js +185 -62
  110. package/dist/runtime.js.map +7 -1
  111. package/dist/services.d.ts +2 -0
  112. package/dist/services.d.ts.map +1 -1
  113. package/dist/services.js +251 -238
  114. package/dist/services.js.map +7 -1
  115. package/dist/sfmc-modules-root.d.ts +24 -0
  116. package/dist/sfmc-modules-root.d.ts.map +1 -0
  117. package/dist/sfmc-modules-root.js +70 -0
  118. package/dist/sfmc-modules-root.js.map +7 -0
  119. package/dist/theme.d.ts +4 -0
  120. package/dist/theme.d.ts.map +1 -1
  121. package/dist/theme.js +134 -48
  122. package/dist/theme.js.map +7 -1
  123. package/dist/wizard.d.ts.map +1 -1
  124. package/dist/wizard.js +363 -438
  125. package/dist/wizard.js.map +7 -1
  126. package/dist/world-packs.d.ts +22 -0
  127. package/dist/world-packs.d.ts.map +1 -0
  128. package/dist/world-packs.js +872 -0
  129. package/dist/world-packs.js.map +7 -0
  130. package/package.json +10 -10
  131. package/dist/dispatcher.d.ts +0 -13
  132. package/dist/dispatcher.d.ts.map +0 -1
  133. package/dist/dispatcher.js +0 -23
  134. package/dist/dispatcher.js.map +0 -1
  135. package/dist/terminal.d.ts +0 -3
  136. package/dist/terminal.d.ts.map +0 -1
  137. package/dist/terminal.js +0 -178
  138. package/dist/terminal.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,43 +1,51 @@
1
- /**
2
- * sfmc/ public runtime surface (Stage J — minimum entry design)
3
- *
4
- * This is the clean API that downstream callers (future sfmc-cil commands,
5
- * external scripts, CI tooling) consume to manage the runtime stack
6
- * without re-implementing process lifecycle logic.
7
- *
8
- * Design:
9
- * - Single process tree. sfmc/ does not spawn itself recursively — it spawns
10
- * the actual services (db-server, qq-bridge, bds-tools, BDS).
11
- * - `IS_SEA` / `ROOT` from runtime.ts describe the deployment shape so callers
12
- * can adapt (path lookup, config dir).
13
- * - Service lifecycle goes through ServiceRegistry (start/stop/restart/status).
14
- * - Module manifest from db-server is exposed via `readModuleManifest()` so
15
- * callers can show enabled modules + per-module state.
16
- *
17
- * Re-exports are deliberately thin: each item is a stable contract. Internal
18
- * helpers (LogLine buffers, child-process piping) are NOT re-exported.
19
- */
20
- export { ROOT, IS_SEA, spawnService, spawnServiceSync } from "./runtime.js";
21
- export { SERVICE_NAMES, refreshServices, startAll, stopAll, forceStopAll, serviceStatus, services, START_ORDER, } from "./services.js";
22
- export { pushLog, onLog, getAllLogs, getRecentLogs } from "./logs.js";
23
- /**
24
- * Reads the manifest emitted by the behavior pack build, if present.
25
- * Returns null when no manifest exists (e.g. behavior pack hasn't been built).
26
- */
27
- export async function readModuleManifest() {
28
- const fs = await import("node:fs/promises");
29
- const path = await import("node:path");
30
- const { ROOT } = await import("./runtime.js");
31
- const manifestPath = path.join(ROOT, "modules", "_manifests", "module-manifests.json");
32
- try {
33
- const text = await fs.readFile(manifestPath, "utf8");
34
- return JSON.parse(text);
35
- }
36
- catch {
37
- return null;
38
- }
39
- }
40
- export { startRepl, HELP } from "./repl.js";
41
- export { runWizard } from "./wizard.js";
42
- export { cmdModuleList, cmdModuleInstall, cmdModuleUninstall, cmdModuleVerify, cmdModuleInfo } from "./module-commands.js";
43
- //# sourceMappingURL=index.js.map
1
+ import { ROOT, isMonorepoLayout, isRuntimeInitialized, resolveServiceScript, resolveFetchModule, spawnService, spawnServiceSync } from "./runtime.js";
2
+ import {
3
+ SERVICE_NAMES,
4
+ refreshServices,
5
+ startAll,
6
+ stopAll,
7
+ forceStopAll,
8
+ serviceStatus,
9
+ services,
10
+ START_ORDER
11
+ } from "./services.js";
12
+ import { pushLog, onLog, getAllLogs, getRecentLogs } from "./logs.js";
13
+ import { startRepl, getHelp, HELP } from "./repl.js";
14
+ import { t, getLocale, setLocale, initLocale } from "./i18n/index.js";
15
+ import { runWizard } from "./wizard.js";
16
+ import { cmdModuleList, cmdModuleInstall, cmdModuleUninstall, cmdModuleVerify, cmdModuleInfo } from "./module-commands.js";
17
+ export {
18
+ HELP,
19
+ ROOT,
20
+ SERVICE_NAMES,
21
+ START_ORDER,
22
+ cmdModuleInfo,
23
+ cmdModuleInstall,
24
+ cmdModuleList,
25
+ cmdModuleUninstall,
26
+ cmdModuleVerify,
27
+ forceStopAll,
28
+ getAllLogs,
29
+ getHelp,
30
+ getLocale,
31
+ getRecentLogs,
32
+ initLocale,
33
+ isMonorepoLayout,
34
+ isRuntimeInitialized,
35
+ onLog,
36
+ pushLog,
37
+ refreshServices,
38
+ resolveFetchModule,
39
+ resolveServiceScript,
40
+ runWizard,
41
+ serviceStatus,
42
+ services,
43
+ setLocale,
44
+ spawnService,
45
+ spawnServiceSync,
46
+ startAll,
47
+ startRepl,
48
+ stopAll,
49
+ t
50
+ };
51
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1,7 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAkB,MAAM,cAAc,CAAC;AAE5F,OAAO,EACL,aAAa,EAGb,eAAe,EACf,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAkD,MAAM,WAAW,CAAC;AAEtH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,uBAAuB,CAAC,CAAC;IACvF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "sourcesContent": ["/**\n * sfmc/ public runtime surface (Stage J \u2014 minimum entry design)\n *\n * This is the clean API that downstream callers (CLI commands,\n * external scripts, CI tooling) consume to manage the runtime stack\n * without re-implementing process lifecycle logic.\n *\n * Design:\n * - Single process tree. sfmc/ does not spawn itself recursively \u2014 it spawns\n * the actual services (db-server, qq-bridge, bds-tools, BDS).\n * - `ROOT` from runtime.ts describes the deployment root so callers\n * can adapt (path lookup, config dir).\n * - Service lifecycle goes through ServiceRegistry (start/stop/restart/status).\n *\n * Re-exports are deliberately thin: each item is a stable contract. Internal\n * helpers (LogLine buffers, child-process piping) are NOT re-exported.\n */\n\nexport { ROOT, isMonorepoLayout, isRuntimeInitialized, resolveServiceScript, resolveFetchModule, spawnService, spawnServiceSync, type ServiceId } from \"./runtime.js\";\n\nexport {\n SERVICE_NAMES,\n type ServiceName,\n type ServiceStatus,\n refreshServices,\n startAll,\n stopAll,\n forceStopAll,\n serviceStatus,\n services,\n START_ORDER,\n} from \"./services.js\";\n\nexport { pushLog, onLog, getAllLogs, getRecentLogs, type UnifiedLog, type LogLevel, type LogSource } from \"./logs.js\";\n\nexport { startRepl, getHelp, HELP } from \"./repl.js\";\nexport { t, getLocale, setLocale, initLocale, type Locale } from \"./i18n/index.js\";\nexport { runWizard } from \"./wizard.js\";\nexport { cmdModuleList, cmdModuleInstall, cmdModuleUninstall, cmdModuleVerify, cmdModuleInfo } from \"./module-commands.js\";\n"],
5
+ "mappings": "AAkBA,SAAS,MAAM,kBAAkB,sBAAsB,sBAAsB,oBAAoB,cAAc,wBAAwC;AAEvJ;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,SAAS,OAAO,YAAY,qBAAqE;AAE1G,SAAS,WAAW,SAAS,YAAY;AACzC,SAAS,GAAG,WAAW,WAAW,kBAA+B;AACjE,SAAS,iBAAiB;AAC1B,SAAS,eAAe,kBAAkB,oBAAoB,iBAAiB,qBAAqB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ /** 与 init 向导一致:文本输入或系统文件夹选择器。 */
2
+ export declare function pickDirectory(message: string, defaultDirectory: string): Promise<string>;
3
+ /** Windows 文件夹选择器;非 Windows 或失败时返回 null。 */
4
+ export declare function pickDirectoryDialog(title: string, defaultDirectory: string): string | null;
5
+ export declare function ensureDirectory(directory: string): boolean;
6
+ /** 将用户输入规范为绝对路径(兼容含 # 的 Windows 路径)。 */
7
+ export declare function resolveUserPath(input: string, base?: string): string;
8
+ //# sourceMappingURL=interactive-prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive-prompts.d.ts","sourceRoot":"","sources":["../src/interactive-prompts.ts"],"names":[],"mappings":"AAMA,iCAAiC;AACjC,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAa9F;AAED,4CAA4C;AAC5C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqB1F;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAO1D;AAED,wCAAwC;AACxC,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAgB,GAAG,MAAM,CAE3E"}
@@ -0,0 +1,57 @@
1
+ import { isCancel, select, text } from "@clack/prompts";
2
+ import { execFileSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { t } from "./i18n/index.js";
6
+ async function pickDirectory(message, defaultDirectory) {
7
+ const method = await select({
8
+ message,
9
+ options: [
10
+ { value: "text", label: t("prompt.enterPath"), hint: defaultDirectory },
11
+ { value: "browse", label: t("prompt.browse"), hint: t("prompt.browseHint") }
12
+ ]
13
+ });
14
+ if (isCancel(method)) return defaultDirectory;
15
+ if (method === "browse") return pickDirectoryDialog(message, defaultDirectory) ?? defaultDirectory;
16
+ const selected = await text({ message, initialValue: defaultDirectory });
17
+ return isCancel(selected) || !selected ? defaultDirectory : selected;
18
+ }
19
+ function pickDirectoryDialog(title, defaultDirectory) {
20
+ if (process.platform !== "win32") return null;
21
+ const escape = (value) => value.replace(/'/g, "''");
22
+ const script = [
23
+ "Add-Type -AssemblyName System.Windows.Forms",
24
+ "$dialog = New-Object System.Windows.Forms.FolderBrowserDialog",
25
+ `$dialog.Description = '${escape(title)}'`,
26
+ `$dialog.SelectedPath = '${escape(defaultDirectory)}'`,
27
+ "if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $dialog.SelectedPath }"
28
+ ].join("; ");
29
+ try {
30
+ const output = execFileSync("powershell.exe", ["-NoProfile", "-STA", "-Command", script], {
31
+ encoding: "utf-8",
32
+ timeout: 3e4,
33
+ windowsHide: true
34
+ });
35
+ return output.trim() || null;
36
+ } catch {
37
+ return null;
38
+ }
39
+ }
40
+ function ensureDirectory(directory) {
41
+ try {
42
+ fs.mkdirSync(directory, { recursive: true });
43
+ return fs.statSync(directory).isDirectory();
44
+ } catch {
45
+ return false;
46
+ }
47
+ }
48
+ function resolveUserPath(input, base = process.cwd()) {
49
+ return path.resolve(base, input.trim());
50
+ }
51
+ export {
52
+ ensureDirectory,
53
+ pickDirectory,
54
+ pickDirectoryDialog,
55
+ resolveUserPath
56
+ };
57
+ //# sourceMappingURL=interactive-prompts.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/interactive-prompts.ts"],
4
+ "sourcesContent": ["import { isCancel, select, text } from \"@clack/prompts\";\nimport { execFileSync } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { t } from \"./i18n/index.js\";\n\n/** \u4E0E init \u5411\u5BFC\u4E00\u81F4\uFF1A\u6587\u672C\u8F93\u5165\u6216\u7CFB\u7EDF\u6587\u4EF6\u5939\u9009\u62E9\u5668\u3002 */\nexport async function pickDirectory(message: string, defaultDirectory: string): Promise<string> {\n const method = await select({\n message,\n options: [\n { value: \"text\", label: t(\"prompt.enterPath\"), hint: defaultDirectory },\n { value: \"browse\", label: t(\"prompt.browse\"), hint: t(\"prompt.browseHint\") },\n ],\n });\n if (isCancel(method)) return defaultDirectory;\n if (method === \"browse\") return pickDirectoryDialog(message, defaultDirectory) ?? defaultDirectory;\n\n const selected = await text({ message, initialValue: defaultDirectory });\n return isCancel(selected) || !selected ? defaultDirectory : selected;\n}\n\n/** Windows \u6587\u4EF6\u5939\u9009\u62E9\u5668\uFF1B\u975E Windows \u6216\u5931\u8D25\u65F6\u8FD4\u56DE null\u3002 */\nexport function pickDirectoryDialog(title: string, defaultDirectory: string): string | null {\n if (process.platform !== \"win32\") return null;\n const escape = (value: string): string => value.replace(/'/g, \"''\");\n const script = [\n \"Add-Type -AssemblyName System.Windows.Forms\",\n \"$dialog = New-Object System.Windows.Forms.FolderBrowserDialog\",\n `$dialog.Description = '${escape(title)}'`,\n `$dialog.SelectedPath = '${escape(defaultDirectory)}'`,\n \"if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { Write-Output $dialog.SelectedPath }\",\n ].join(\"; \");\n\n try {\n const output = execFileSync(\"powershell.exe\", [\"-NoProfile\", \"-STA\", \"-Command\", script], {\n encoding: \"utf-8\",\n timeout: 30_000,\n windowsHide: true,\n });\n return output.trim() || null;\n } catch {\n return null;\n }\n}\n\nexport function ensureDirectory(directory: string): boolean {\n try {\n fs.mkdirSync(directory, { recursive: true });\n return fs.statSync(directory).isDirectory();\n } catch {\n return false;\n }\n}\n\n/** \u5C06\u7528\u6237\u8F93\u5165\u89C4\u8303\u4E3A\u7EDD\u5BF9\u8DEF\u5F84\uFF08\u517C\u5BB9\u542B # \u7684 Windows \u8DEF\u5F84\uFF09\u3002 */\nexport function resolveUserPath(input: string, base = process.cwd()): string {\n return path.resolve(base, input.trim());\n}\n"],
5
+ "mappings": "AAAA,SAAS,UAAU,QAAQ,YAAY;AACvC,SAAS,oBAAoB;AAC7B,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,SAAS;AAGlB,eAAsB,cAAc,SAAiB,kBAA2C;AAC9F,QAAM,SAAS,MAAM,OAAO;AAAA,IAC1B;AAAA,IACA,SAAS;AAAA,MACP,EAAE,OAAO,QAAQ,OAAO,EAAE,kBAAkB,GAAG,MAAM,iBAAiB;AAAA,MACtE,EAAE,OAAO,UAAU,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,mBAAmB,EAAE;AAAA,IAC7E;AAAA,EACF,CAAC;AACD,MAAI,SAAS,MAAM,EAAG,QAAO;AAC7B,MAAI,WAAW,SAAU,QAAO,oBAAoB,SAAS,gBAAgB,KAAK;AAElF,QAAM,WAAW,MAAM,KAAK,EAAE,SAAS,cAAc,iBAAiB,CAAC;AACvE,SAAO,SAAS,QAAQ,KAAK,CAAC,WAAW,mBAAmB;AAC9D;AAGO,SAAS,oBAAoB,OAAe,kBAAyC;AAC1F,MAAI,QAAQ,aAAa,QAAS,QAAO;AACzC,QAAM,SAAS,CAAC,UAA0B,MAAM,QAAQ,MAAM,IAAI;AAClE,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA,0BAA0B,OAAO,KAAK,CAAC;AAAA,IACvC,2BAA2B,OAAO,gBAAgB,CAAC;AAAA,IACnD;AAAA,EACF,EAAE,KAAK,IAAI;AAEX,MAAI;AACF,UAAM,SAAS,aAAa,kBAAkB,CAAC,cAAc,QAAQ,YAAY,MAAM,GAAG;AAAA,MACxF,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf,CAAC;AACD,WAAO,OAAO,KAAK,KAAK;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAAgB,WAA4B;AAC1D,MAAI;AACF,OAAG,UAAU,WAAW,EAAE,WAAW,KAAK,CAAC;AAC3C,WAAO,GAAG,SAAS,SAAS,EAAE,YAAY;AAAA,EAC5C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,OAAe,OAAO,QAAQ,IAAI,GAAW;AAC3E,SAAO,KAAK,QAAQ,MAAM,MAAM,KAAK,CAAC;AACxC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,3 @@
1
+ /** `sfmc locale [zh-CN|en]` — 查看或设置 CLI 语言并写入 runtime.json。 */
2
+ export declare function cmdLocale(args: string[]): string;
3
+ //# sourceMappingURL=locale-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locale-command.d.ts","sourceRoot":"","sources":["../src/locale-command.ts"],"names":[],"mappings":"AAIA,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAWhD"}
@@ -0,0 +1,19 @@
1
+ import { getLocale, normalizeLocale, persistLocale, t } from "./i18n/index.js";
2
+ import { ROOT } from "./runtime.js";
3
+ import { c } from "./theme.js";
4
+ function cmdLocale(args) {
5
+ const raw = args[0];
6
+ if (!raw) {
7
+ return c.text(t("locale.current", { locale: getLocale() }));
8
+ }
9
+ const locale = normalizeLocale(raw);
10
+ if (!locale) {
11
+ return c.red(t("locale.invalid", { value: raw })) + "\n" + c.dim(t("locale.usage"));
12
+ }
13
+ persistLocale(ROOT, locale);
14
+ return c.green(t("locale.set", { locale }));
15
+ }
16
+ export {
17
+ cmdLocale
18
+ };
19
+ //# sourceMappingURL=locale-command.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/locale-command.ts"],
4
+ "sourcesContent": ["import { getLocale, normalizeLocale, persistLocale, t } from \"./i18n/index.js\";\nimport { ROOT } from \"./runtime.js\";\nimport { c } from \"./theme.js\";\n\n/** `sfmc locale [zh-CN|en]` \u2014 \u67E5\u770B\u6216\u8BBE\u7F6E CLI \u8BED\u8A00\u5E76\u5199\u5165 runtime.json\u3002 */\nexport function cmdLocale(args: string[]): string {\n const raw = args[0];\n if (!raw) {\n return c.text(t(\"locale.current\", { locale: getLocale() }));\n }\n const locale = normalizeLocale(raw);\n if (!locale) {\n return c.red(t(\"locale.invalid\", { value: raw })) + \"\\n\" + c.dim(t(\"locale.usage\"));\n }\n persistLocale(ROOT, locale);\n return c.green(t(\"locale.set\", { locale }));\n}\n"],
5
+ "mappings": "AAAA,SAAS,WAAW,iBAAiB,eAAe,SAAS;AAC7D,SAAS,YAAY;AACrB,SAAS,SAAS;AAGX,SAAS,UAAU,MAAwB;AAChD,QAAM,MAAM,KAAK,CAAC;AAClB,MAAI,CAAC,KAAK;AACR,WAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,QAAQ,UAAU,EAAE,CAAC,CAAC;AAAA,EAC5D;AACA,QAAM,SAAS,gBAAgB,GAAG;AAClC,MAAI,CAAC,QAAQ;AACX,WAAO,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,IAAI,CAAC,CAAC,IAAI,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC;AAAA,EACpF;AACA,gBAAc,MAAM,MAAM;AAC1B,SAAO,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;AAC5C;",
6
+ "names": []
7
+ }
package/dist/logs.d.ts CHANGED
@@ -5,6 +5,11 @@
5
5
  * 保持向后兼容的 pushLog / onLog / getAllLogs / getRecentLogs API
6
6
  * (services.ts 捕获子进程 stdout 后调用 pushLog 汇聚到此)。
7
7
  *
8
+ * 落盘策略(与子进程自写文件分工,避免重复):
9
+ * - db / qq / update → 子进程已写 `.sfmc/logs/{db,qq,bds-update}.log`,此处跳过
10
+ * - bds / llbot → `.sfmc/logs/{bds,llbot}.log`(外部进程无自带 file sink)
11
+ * - 其余(system / pack / …) → `.sfmc/logs/sfmc.log`
12
+ *
8
13
  * formatLog 保留 theme.ts (chalk) 配色,比共享包的纯 ANSI 版本视觉更丰富。
9
14
  */
10
15
  import { type LogEntry, type LogLevel as SharedLogLevel } from "@sfmc-bds/sdk/logs";
@@ -12,7 +17,7 @@ export type LogLevel = SharedLogLevel;
12
17
  export type LogSource = string;
13
18
  export interface UnifiedLog extends LogEntry {
14
19
  }
15
- /** 推送一条日志到内存缓冲 (services.ts 捕获子进程 stdout 后调用) */
20
+ /** 推送一条日志到内存缓冲,并按策略落盘 */
16
21
  export declare function pushLog(text: string, source: LogSource, level: LogLevel): void;
17
22
  /** 订阅新日志事件,返回取消订阅函数 */
18
23
  export declare function onLog(fn: (log: UnifiedLog) => void): () => void;
@@ -22,14 +27,27 @@ export declare function getAllLogs(): UnifiedLog[];
22
27
  export declare function getRecentLogs(n: number, levels: LogLevel[], sources: LogSource[]): UnifiedLog[];
23
28
  /** 从原始文本推断日志级别 (委托共享包) */
24
29
  export declare function inferLevel(text: string): LogLevel;
30
+ export interface SourceMeta {
31
+ value: string;
32
+ /** 显示名,尽量 8 宽对齐 */
33
+ name: string;
34
+ paint: (s: string) => string;
35
+ }
36
+ export declare const SOURCE_META: SourceMeta[];
37
+ export declare function formatSourceTag(source: string): string;
25
38
  /** 格式化日志用于 REPL 展示 (用 theme.ts chalk 配色) */
26
39
  export declare function formatLog(l: UnifiedLog): string;
27
40
  /** 字符串在终端的可见宽度 (strip ANSI 后按 CJK 宽度累加) */
28
41
  export declare function visibleWidth(s: string): number;
29
42
  /**
30
- * 按终端可见宽度换行,后续行左侧缩进 indent 个空格。
31
- * 保留 ANSI 颜色码:换行时先 reset 避免缩进空格带色,新行恢复颜色状态。
32
- * 宽字符(CJK)按 2 列计算,避免中文行换行位置偏后。
43
+ * 日志前缀可见宽度(时间 + 源 + 级别 + 尾空格),供悬挂缩进对齐正文起点。
44
+ * formatLog 拼接顺序保持一致。
45
+ */
46
+ export declare function logPrefixWidth(l: UnifiedLog): number;
47
+ /**
48
+ * 按终端可见宽度换行;显式 \\n 与软换行的后续行一律左侧缩进 indent 列。
49
+ * 保留 ANSI:换行时 reset,新行恢复当前颜色状态(可多层叠加)。
50
+ * 宽字符(CJK)按 2 列;cols 预留 1 列,避免 Windows Terminal 边界再软折到第 0 列。
33
51
  */
34
52
  export declare function wrapLogLine(s: string, indent: number): string;
35
53
  //# sourceMappingURL=logs.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,QAAQ,IAAI,cAAc,EAChC,MAAM,oBAAoB,CAAC;AAI5B,MAAM,MAAM,QAAQ,GAAG,cAAc,CAAC;AACtC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAC/B,MAAM,WAAW,UAAW,SAAQ,QAAQ;CAAG;AAI/C,iDAAiD;AACjD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAE9E;AAED,uBAAuB;AACvB,wBAAgB,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI,CAE/D;AAED,qBAAqB;AACrB,wBAAgB,UAAU,IAAI,UAAU,EAAE,CAEzC;AAED,oCAAoC;AACpC,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,CAE/F;AAED,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAuCD,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAgC/C;AAmDD,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9C;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoC7D"}
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,QAAQ,IAAI,cAAc,EAChC,MAAM,oBAAoB,CAAC;AAK5B,MAAM,MAAM,QAAQ,GAAG,cAAc,CAAC;AACtC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAC/B,MAAM,WAAW,UAAW,SAAQ,QAAQ;CAAG;AA+B/C,yBAAyB;AACzB,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAU9E;AAED,uBAAuB;AACvB,wBAAgB,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,IAAI,GAAG,MAAM,IAAI,CAE/D;AAED,qBAAqB;AACrB,wBAAgB,UAAU,IAAI,UAAU,EAAE,CAEzC;AAED,oCAAoC;AACpC,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,CAE/F;AAED,0BAA0B;AAC1B,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAMD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,WAAW,EAAE,UAAU,EASnC,CAAC;AAEF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD;AAiCD,4CAA4C;AAC5C,wBAAgB,SAAS,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAoB/C;AAuCD,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAK9C;AAkBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAiBpD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAa7D"}