@sfmc-bds/cli 0.2.0-beta.6 → 0.2.0-beta.8

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 (68) hide show
  1. package/dist/argv-parse.d.ts +0 -2
  2. package/dist/argv-parse.d.ts.map +1 -1
  3. package/dist/argv-parse.js +1 -5
  4. package/dist/argv-parse.js.map +2 -2
  5. package/dist/cli-gate.d.ts.map +1 -1
  6. package/dist/cli-gate.js +0 -2
  7. package/dist/cli-gate.js.map +2 -2
  8. package/dist/command-surface.d.ts +5 -12
  9. package/dist/command-surface.d.ts.map +1 -1
  10. package/dist/command-surface.js +6 -62
  11. package/dist/command-surface.js.map +2 -2
  12. package/dist/help-text.d.ts.map +1 -1
  13. package/dist/help-text.js +6 -10
  14. package/dist/help-text.js.map +2 -2
  15. package/dist/i18n/locales/en.d.ts +9 -87
  16. package/dist/i18n/locales/en.d.ts.map +1 -1
  17. package/dist/i18n/locales/en.js +9 -90
  18. package/dist/i18n/locales/en.js.map +2 -2
  19. package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
  20. package/dist/i18n/locales/zh-CN.js +9 -90
  21. package/dist/i18n/locales/zh-CN.js.map +2 -2
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -4
  25. package/dist/index.js.map +2 -2
  26. package/dist/main.js +3 -6
  27. package/dist/main.js.map +2 -2
  28. package/dist/module-commands.d.ts +6 -25
  29. package/dist/module-commands.d.ts.map +1 -1
  30. package/dist/module-commands.js +107 -127
  31. package/dist/module-commands.js.map +2 -2
  32. package/dist/module-pack-build.d.ts.map +1 -1
  33. package/dist/module-pack-build.js +4 -0
  34. package/dist/module-pack-build.js.map +2 -2
  35. package/dist/module-toggle.d.ts +33 -0
  36. package/dist/module-toggle.d.ts.map +1 -0
  37. package/dist/module-toggle.js +28 -0
  38. package/dist/module-toggle.js.map +7 -0
  39. package/dist/pack-lifecycle.d.ts.map +1 -1
  40. package/dist/pack-lifecycle.js +4 -0
  41. package/dist/pack-lifecycle.js.map +2 -2
  42. package/dist/remote-agent.js +5 -5
  43. package/dist/remote-agent.js.map +2 -2
  44. package/dist/repl.d.ts +0 -2
  45. package/dist/repl.d.ts.map +1 -1
  46. package/dist/repl.js +2 -31
  47. package/dist/repl.js.map +2 -2
  48. package/dist/runtime.d.ts +4 -13
  49. package/dist/runtime.d.ts.map +1 -1
  50. package/dist/runtime.js +15 -27
  51. package/dist/runtime.js.map +2 -2
  52. package/dist/services.d.ts +0 -2
  53. package/dist/services.d.ts.map +1 -1
  54. package/dist/services.js +0 -4
  55. package/dist/services.js.map +2 -2
  56. package/package.json +6 -6
  57. package/dist/module-publish.d.ts +0 -69
  58. package/dist/module-publish.d.ts.map +0 -1
  59. package/dist/module-publish.js +0 -478
  60. package/dist/module-publish.js.map +0 -7
  61. package/dist/module-watch.d.ts +0 -32
  62. package/dist/module-watch.d.ts.map +0 -1
  63. package/dist/module-watch.js +0 -171
  64. package/dist/module-watch.js.map +0 -7
  65. package/dist/module-wizard.d.ts +0 -12
  66. package/dist/module-wizard.d.ts.map +0 -1
  67. package/dist/module-wizard.js +0 -297
  68. package/dist/module-wizard.js.map +0 -7
@@ -1 +1 @@
1
- {"version":3,"file":"module-commands.d.ts","sourceRoot":"","sources":["../src/module-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module-commands.d.ts","sourceRoot":"","sources":["../src/module-commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAwB,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAmBvE,uCAAuC;AACvC,eAAO,MAAM,gBAAgB,YAAI,QAAQ,EAAE,KAAK,CAAU,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,IAAI,aAAa,CAE7E;AAED,wBAAwB;AACxB,eAAO,MAAM,6BAA6B,YAAI,OAAO,EAAE,QAAQ,CAAU,CAAC;AAE1E,yCAAyC;AACzC,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,MAAM,EAAE,CAEhF;AAED,6BAA6B;AAC7B,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEtE;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,GAAE,WAAoB,GAAG,MAAM,CAK9D;AAmFD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCpE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAO1D;AAKD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DrE;AAKD,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BnE;AAKD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAerE;AAqHD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAIxE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAIzE;AAqCD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgDtE;AAKD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BxE;AAuBD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCpG;AAED,uDAAuD;AACvD,wBAAgB,0BAA0B,IAAI,MAAM,EAAE,CAWrD"}
@@ -1,8 +1,13 @@
1
1
  import fs from "node:fs/promises";
2
- import { existsSync, readdirSync } from "node:fs";
2
+ import { existsSync, lstatSync, readdirSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { spawn } from "node:child_process";
5
- import { configPath, modulePath, readJson } from "@sfmc-bds/sdk/node/config";
5
+ import {
6
+ configPath,
7
+ modulePath,
8
+ readJson,
9
+ writeJson
10
+ } from "@sfmc-bds/sdk/node/config";
6
11
  import {
7
12
  isDevAccentModuleSub,
8
13
  listVisibleModuleSubs
@@ -12,6 +17,11 @@ import { t } from "./i18n/index.js";
12
17
  import { c } from "./theme.js";
13
18
  import { ROOT, resolveFetchModule } from "./runtime.js";
14
19
  import { dirFingerprint } from "./module-fingerprint.js";
20
+ import {
21
+ applyLockEnabled,
22
+ finalizeToggle,
23
+ resolveToggleTarget
24
+ } from "./module-toggle.js";
15
25
  import {
16
26
  DEFAULT_REGISTRY_REPO,
17
27
  DEFAULT_REGISTRY_TAG,
@@ -22,27 +32,7 @@ const MODULE_CMD_NAMES = ["module", "mod"];
22
32
  function isModuleCommand(cmd) {
23
33
  return !!cmd && MODULE_CMD_NAMES.includes(cmd);
24
34
  }
25
- function paintModuleCmdAlias(paint) {
26
- return MODULE_CMD_NAMES.map((name) => paint(name)).join("/");
27
- }
28
- const ALL_MODULE_SUBCOMMANDS = [
29
- "list",
30
- "search",
31
- "install",
32
- "uninstall",
33
- "verify",
34
- "info",
35
- "enable",
36
- "disable",
37
- "link",
38
- "create",
39
- "dev",
40
- "build",
41
- "reload"
42
- ];
43
- const DEV_ACCENT_MODULE_SUBCOMMANDS = ["create", "dev", "build", "reload"];
44
- const MODULE_SUBCOMMANDS = ALL_MODULE_SUBCOMMANDS;
45
- const DEV_MODULE_SUBCOMMANDS = DEV_ACCENT_MODULE_SUBCOMMANDS;
35
+ const DEV_ACCENT_MODULE_SUBCOMMANDS = ["build", "reload"];
46
36
  function getVisibleModuleSubcommands(mode) {
47
37
  return listVisibleModuleSubs(mode);
48
38
  }
@@ -161,7 +151,7 @@ async function cmdModuleSearch(args) {
161
151
  return c.red(
162
152
  `
163
153
  Registry empty or unreachable (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}).
164
- Check network, or install with an explicit source: sfmc mod install <id> --from github:owner/repo@tag
154
+ Check network, or: mod install <id> --from github:owner/repo@tag
165
155
  `
166
156
  );
167
157
  }
@@ -263,11 +253,45 @@ async function cmdModuleVerify(args) {
263
253
  function readDbConfig() {
264
254
  return readJson(configPath(ROOT, "db_config.json")) ?? {};
265
255
  }
266
- async function postModuleToggle(id, action) {
256
+ function moduleLockPath() {
257
+ return modulePath(path.join(ROOT, "modules"), "module-lock.json");
258
+ }
259
+ function catalogPathOnDisk() {
260
+ return modulePath(path.join(ROOT, "modules"), "catalog.json");
261
+ }
262
+ function buildToggleCandidates(installed) {
263
+ const catalog = readJson(catalogPathOnDisk()) ?? {};
264
+ const rows = Array.isArray(catalog.modules) ? catalog.modules : [];
265
+ const byLogical = /* @__PURE__ */ new Map();
266
+ for (const raw of rows) {
267
+ if (!raw || typeof raw !== "object") continue;
268
+ const id = String(raw.id || "").trim();
269
+ if (id) byLogical.set(id, raw);
270
+ }
271
+ return installed.map((m) => {
272
+ const logicalId = typeof m.manifest?.id === "string" && m.manifest.id ? m.manifest.id : m.id;
273
+ const raw = byLogical.get(logicalId);
274
+ const configKeyRaw = raw ? String(raw.configKey || raw.config_key || "").trim() : "";
275
+ const canDisable = raw ? raw.canDisable !== false : true;
276
+ const out = { logicalId, folderId: m.id, canDisable };
277
+ if (configKeyRaw) out.configKey = configKeyRaw;
278
+ return out;
279
+ });
280
+ }
281
+ function writeLocalModuleEnabled(logicalId, enabled) {
282
+ const lockPath = moduleLockPath();
283
+ const lock = readJson(lockPath) ?? {
284
+ version: 1,
285
+ modules: {}
286
+ };
287
+ applyLockEnabled(lock, logicalId, enabled);
288
+ writeJson(lockPath, lock);
289
+ }
290
+ async function notifyDbToggle(logicalId, action) {
267
291
  const cfg = readDbConfig();
268
292
  const port = cfg.db_port ?? 3001;
269
293
  const token = cfg.http_auth || "";
270
- const url = `http://127.0.0.1:${port}/api/sfmc/modules/${encodeURIComponent(id)}/${action}`;
294
+ const url = `http://127.0.0.1:${port}/api/sfmc/modules/${encodeURIComponent(logicalId)}/${action}`;
271
295
  let res;
272
296
  try {
273
297
  res = await fetch(url, {
@@ -278,9 +302,7 @@ async function postModuleToggle(id, action) {
278
302
  }
279
303
  });
280
304
  } catch (err) {
281
- return failResult(
282
- c.red(t("mod.dbUnreachable", { url, message: err.message }))
283
- );
305
+ return { ok: false, reason: "unreachable", detail: err.message };
284
306
  }
285
307
  const text = await res.text();
286
308
  let body;
@@ -291,24 +313,62 @@ async function postModuleToggle(id, action) {
291
313
  }
292
314
  if (!res.ok) {
293
315
  const err = body?.error ?? `HTTP ${res.status}`;
294
- return failResult(c.red(t("mod.toggleFailed", { action, id, err })));
316
+ return { ok: false, reason: "http", detail: err };
295
317
  }
296
- const ok = body?.success !== false;
297
- if (ok) {
298
- const label = action === "enable" ? t("mod.action.enabled") : t("mod.action.disabled");
299
- return okResult(c.green(t("mod.toggleOk", { label, id })));
318
+ if (body?.success === false) {
319
+ return { ok: false, reason: "http", detail: text };
300
320
  }
301
- return failResult(c.red(t("mod.toggleBadBody", { action, id, text })));
321
+ return { ok: true };
322
+ }
323
+ async function cmdModuleToggle(query, action) {
324
+ const installed = await scanInstalled();
325
+ const target = resolveToggleTarget(query, buildToggleCandidates(installed));
326
+ if (!target) {
327
+ return failResult(c.red(t("mod.notInstalled", { id: query })));
328
+ }
329
+ if (action === "disable" && !target.canDisable) {
330
+ return failResult(c.red(t("mod.cannotDisable", { id: target.logicalId })));
331
+ }
332
+ const enabled = action === "enable";
333
+ try {
334
+ writeLocalModuleEnabled(target.logicalId, enabled);
335
+ } catch (err) {
336
+ return failResult(
337
+ c.red(t("mod.toggleLockFailed", { id: target.logicalId, message: err.message }))
338
+ );
339
+ }
340
+ const notify = await notifyDbToggle(target.logicalId, action);
341
+ const fin = finalizeToggle(true, notify);
342
+ const label = action === "enable" ? t("mod.action.enabled") : t("mod.action.disabled");
343
+ const head = c.green(t("mod.toggleOk", { label, id: target.logicalId }));
344
+ if (!fin.warnNotify) {
345
+ return okResult(head);
346
+ }
347
+ const detail = notify.ok === false ? notify.detail ?? notify.reason : "";
348
+ const warn = c.yellow(t("mod.toggleDbSkipped", { detail }));
349
+ return okResult(`${head}
350
+ ${warn}`);
302
351
  }
303
352
  async function cmdModuleEnable(args) {
304
353
  const id = args[0];
305
354
  if (!id) return failResult(c.yellow(t("mod.enable.usage")));
306
- return postModuleToggle(id, "enable");
355
+ return cmdModuleToggle(id, "enable");
307
356
  }
308
357
  async function cmdModuleDisable(args) {
309
358
  const id = args[0];
310
359
  if (!id) return failResult(c.yellow(t("mod.disable.usage")));
311
- return postModuleToggle(id, "disable");
360
+ return cmdModuleToggle(id, "disable");
361
+ }
362
+ function validateFromScheme(from) {
363
+ if (from === "local" || from.startsWith("local:") || from.startsWith("dir:") || from.startsWith("npm:") || from.startsWith("tgz:") || from.startsWith("zip:") || from.startsWith("github:")) {
364
+ return null;
365
+ }
366
+ if (existsSync(from)) {
367
+ const st = lstatSync(from);
368
+ if (st.isDirectory()) return null;
369
+ return `--from \u88F8\u8DEF\u5F84\u987B\u4E3A\u76EE\u5F55\uFF08\u6587\u4EF6\u8BF7\u7528 --from local:<tgz|zip>\uFF09: ${from}`;
370
+ }
371
+ return t("mod.fromUnknown", { value: from });
312
372
  }
313
373
  async function cmdModuleInstall(args) {
314
374
  const flags = parseFlags(args);
@@ -325,6 +385,10 @@ async function cmdModuleInstall(args) {
325
385
  if (positional.length === 0) {
326
386
  return c.yellow(t("mod.install.usage"));
327
387
  }
388
+ if (flags.from) {
389
+ const err = validateFromScheme(flags.from);
390
+ if (err) return c.red(err);
391
+ }
328
392
  const fetchScript = resolveFetchModule();
329
393
  if (!fetchScript) {
330
394
  return c.red(t("mod.fetchMissing"));
@@ -352,29 +416,6 @@ async function cmdModuleInstall(args) {
352
416
  proc.on("error", (e) => resolve(c.red(`spawn failed: ${e.message}`)));
353
417
  });
354
418
  }
355
- async function cmdModuleLink(args) {
356
- const flags = parseFlags(args);
357
- const positional = [];
358
- for (let i = 0; i < args.length; i++) {
359
- if (args[i] === "--from" || args[i] === "--sha256") {
360
- i++;
361
- continue;
362
- }
363
- if (args[i]?.startsWith("--from=") || args[i]?.startsWith("--sha256=")) continue;
364
- if (args[i]?.startsWith("--")) continue;
365
- positional.push(args[i]);
366
- }
367
- if (positional.length === 0) {
368
- const { runModuleLinkWizard } = await import("./module-wizard.js");
369
- return runModuleLinkWizard();
370
- }
371
- const id = positional[0];
372
- if (!flags.from) {
373
- return c.red(t("mod.linkNeedsFrom"));
374
- }
375
- const installArgs = [id, "--link", "--from", flags.from];
376
- return cmdModuleInstall(installArgs);
377
- }
378
419
  async function cmdModuleUninstall(args) {
379
420
  const id = args[0];
380
421
  if (!id) return c.yellow(t("mod.uninstall.usage"));
@@ -415,46 +456,6 @@ function parseFlags(args) {
415
456
  }
416
457
  return flags;
417
458
  }
418
- async function cmdModuleTest(args) {
419
- let fromRaw = null;
420
- const passthrough = [];
421
- for (let i = 0; i < args.length; i++) {
422
- const a = args[i];
423
- if (a === "--from") {
424
- fromRaw = args[++i] ?? null;
425
- } else if (a?.startsWith("--from=")) {
426
- fromRaw = a.slice("--from=".length);
427
- } else if (a === "--help" || a === "-h") {
428
- return c.dim("\u7528\u6CD5: mod test [--from local[:<path>]] [-- <args>]\n \u900F\u4F20\u7ED9\u6A21\u5757\u4ED3\u7684 npm test\u3002");
429
- } else {
430
- passthrough.push(a);
431
- }
432
- }
433
- const { resolveLocalModuleRoot } = await import("./module-watch.js");
434
- const cwd = resolveLocalModuleRoot({ from: fromRaw, cwd: process.cwd() });
435
- if (!existsSync(cwd)) {
436
- return c.red(`[mod test] \u8DEF\u5F84\u4E0D\u5B58\u5728: ${cwd}`);
437
- }
438
- if (!existsSync(path.join(cwd, "package.json"))) {
439
- return c.yellow(`[mod test] \u672A\u627E\u5230 package.json: ${cwd}
440
- \u63D0\u793A\uFF1A\u8FDB\u5165\u6A21\u5757\u4ED3\u6839\u76EE\u5F55\uFF0C\u6216\u7528 --from local:<path> \u6307\u5411\u3002`);
441
- }
442
- const isWin = process.platform === "win32";
443
- const cmd = isWin ? "cmd.exe" : "npm";
444
- const subArgs = isWin ? ["/c", "npm", "test", "--", ...passthrough] : ["test", "--", ...passthrough];
445
- return new Promise((resolve) => {
446
- const proc = spawn(cmd, subArgs, {
447
- cwd,
448
- stdio: "inherit",
449
- env: process.env
450
- });
451
- proc.on("exit", (code) => {
452
- resolve(code === 0 ? "" : `
453
- [mod test] exit ${code}`);
454
- });
455
- proc.on("error", (e) => resolve(c.red(`[mod test] spawn failed: ${e.message}`)));
456
- });
457
- }
458
459
  async function dispatchModuleCommand(sub, args) {
459
460
  switch (sub) {
460
461
  case "list":
@@ -482,27 +483,12 @@ async function dispatchModuleCommand(sub, args) {
482
483
  const { cmdModuleReload } = await import("./module-pack-build.js");
483
484
  return cmdModuleReload(args);
484
485
  }
485
- case "create": {
486
- const { runModuleCreateWizard } = await import("./module-wizard.js");
487
- return runModuleCreateWizard();
488
- }
489
- case "link":
490
- return cmdModuleLink(args);
491
- case "dev": {
492
- const { runModuleDevWizard } = await import("./module-wizard.js");
493
- return runModuleDevWizard();
494
- }
495
- case "watch": {
496
- const { cmdModuleWatch } = await import("./module-watch.js");
497
- return cmdModuleWatch(args);
498
- }
499
- case "test": {
500
- return cmdModuleTest(args);
501
- }
502
- case "publish": {
503
- const { cmdModulePublish } = await import("./module-publish.js");
504
- return cmdModulePublish(args);
505
- }
486
+ case "test":
487
+ case "watch":
488
+ case "publish":
489
+ return c.yellow(
490
+ `[mod ${sub}] \u5DF2\u79FB\u81F3 VS Code/Cursor \u6269\u5C55\u300CSFMC Module\u300D\u4E0E @sfmc-bds/devkit\uFF1B\u8FD0\u7EF4\u8BF7\u7528 mod build|reload|install\u3002`
491
+ );
506
492
  default:
507
493
  return c.yellow(moduleUsage());
508
494
  }
@@ -517,19 +503,14 @@ function listInstalledModuleIdsSync() {
517
503
  }
518
504
  }
519
505
  export {
520
- ALL_MODULE_SUBCOMMANDS,
521
506
  DEV_ACCENT_MODULE_SUBCOMMANDS,
522
- DEV_MODULE_SUBCOMMANDS,
523
507
  MODULE_CMD_NAMES,
524
- MODULE_SUBCOMMANDS,
525
508
  cmdModuleDisable,
526
509
  cmdModuleEnable,
527
510
  cmdModuleInfo,
528
511
  cmdModuleInstall,
529
- cmdModuleLink,
530
512
  cmdModuleList,
531
513
  cmdModuleSearch,
532
- cmdModuleTest,
533
514
  cmdModuleUninstall,
534
515
  cmdModuleVerify,
535
516
  dispatchModuleCommand,
@@ -538,7 +519,6 @@ export {
538
519
  isModuleCommand,
539
520
  listInstalledModuleIdsSync,
540
521
  moduleUsage,
541
- paintModuleCmdAlias,
542
522
  scanAndWarnUnknown
543
523
  };
544
524
  //# sourceMappingURL=module-commands.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/module-commands.ts"],
4
- "sourcesContent": ["/**\n * sfmc module-commands \u2014 runtime CLI for inspecting and managing modules\n * already on disk under `modules/packages/<id>/`.\n *\n * \u9876\u5C42\u547D\u4EE4\u522B\u540D:`module` / `mod`(\u7531 main.ts / repl.ts \u5171\u540C\u8BC6\u522B)\u3002\n * \u5B50\u547D\u4EE4\u901A\u9053\u95E8\u7981\u89C1 command-surface.ts\uFF08dispatch \u524D\u7531 main/repl \u5224\u5B9A\uFF09\u3002\n */\n\nimport fs from \"node:fs/promises\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport { configPath, modulePath, readJson, type DBConfig, type ModuleLock } from \"@sfmc-bds/sdk/node/config\";\nimport {\n isDevAccentModuleSub,\n listVisibleModuleSubs,\n type CommandMode,\n} from \"./command-surface.js\";\nimport { failResult, okResult, type CliResult } from \"./cli-result.js\";\nimport { t } from \"./i18n/index.js\";\nimport { c } from \"./theme.js\";\nimport { ROOT, resolveFetchModule } from \"./runtime.js\";\nimport { dirFingerprint } from \"./module-fingerprint.js\";\nimport {\n DEFAULT_REGISTRY_REPO,\n DEFAULT_REGISTRY_TAG,\n findUnknownModules,\n resolveRegistryIndex,\n} from \"./registry.js\";\n\n/** \u9876\u5C42\u547D\u4EE4\u540D(\u4E3B\u540D + \u77ED\u522B\u540D),\u4F9B HELP / \u8865\u5168 / \u5206\u53D1\u5171\u7528\u3002 */\nexport const MODULE_CMD_NAMES = [\"module\", \"mod\"] as const;\n\nexport type ModuleCmdName = (typeof MODULE_CMD_NAMES)[number];\n\n/** \u5224\u65AD\u662F\u5426\u4E3A module \u9876\u5C42\u547D\u4EE4(\u542B\u522B\u540D);\u907F\u514D main/repl \u518D\u786C\u7F16\u7801 case\u3002 */\nexport function isModuleCommand(cmd: string | undefined): cmd is ModuleCmdName {\n return !!cmd && (MODULE_CMD_NAMES as readonly string[]).includes(cmd);\n}\n\n/** \u67D3\u8272\u540E\u7684 HELP \u524D\u7F00,\u907F\u514D HELP \u786C\u7F16\u7801 module/mod\u3002 */\nexport function paintModuleCmdAlias(paint: (name: string) => string): string {\n return MODULE_CMD_NAMES.map((name) => paint(name)).join(\"/\");\n}\n\n/** @deprecated \u4F7F\u7528 listVisibleModuleSubs(mode)\uFF1B\u4FDD\u7559\u5168\u96C6\u4F9B\u8C03\u8BD5\u3002 */\nexport const ALL_MODULE_SUBCOMMANDS = [\n \"list\",\n \"search\",\n \"install\",\n \"uninstall\",\n \"verify\",\n \"info\",\n \"enable\",\n \"disable\",\n \"link\",\n \"create\",\n \"dev\",\n \"build\",\n \"reload\",\n] as const;\n\n/** \u5F00\u53D1\u8005\u6837\u5F0F\u5B50\u547D\u4EE4\uFF08\u84DD\u6807\uFF0C\u975E\u95E8\u7981\uFF09\u3002 */\nexport const DEV_ACCENT_MODULE_SUBCOMMANDS = [\"create\", \"dev\", \"build\", \"reload\"] as const;\n\n/** @deprecated \u4F7F\u7528 ALL_MODULE_SUBCOMMANDS \u6216 listVisibleModuleSubs\u3002 */\nexport const MODULE_SUBCOMMANDS = ALL_MODULE_SUBCOMMANDS;\n\n/** @deprecated \u4F7F\u7528 DEV_ACCENT_MODULE_SUBCOMMANDS / isDevAccentModuleSub\u3002 */\nexport const DEV_MODULE_SUBCOMMANDS = DEV_ACCENT_MODULE_SUBCOMMANDS;\n\nexport type ModuleSubcommand = (typeof ALL_MODULE_SUBCOMMANDS)[number];\n\n/** \u5F53\u524D\u901A\u9053\u4E0B\u53EF\u89C1\u7684 module \u5B50\u547D\u4EE4\uFF08\u81EA\u52A8\u8865\u5168 / usage\uFF09\u3002 */\nexport function getVisibleModuleSubcommands(mode: CommandMode): readonly string[] {\n return listVisibleModuleSubs(mode);\n}\n\n/** sub \u662F\u5426\u4E3A\u5F00\u53D1\u8005\u84DD\u6807\uFF08help \u7740\u8272\uFF09\u3002 */\nexport function isDeveloperSubcommand(sub: string | undefined): boolean {\n return isDevAccentModuleSub(sub);\n}\n\n/** Usage \u884C\u4E3B\u540D|\u522B\u540D(\u4E0E MODULE_CMD_NAMES \u540C\u6E90,\u907F\u514D\u4E0E HELP \u6F02\u79FB)\u3002 */\nexport function moduleUsage(mode: CommandMode = \"argv\"): string {\n return t(\"mod.usage\", {\n cmds: MODULE_CMD_NAMES.join(\"|\"),\n subs: getVisibleModuleSubcommands(mode).join(\"|\"),\n });\n}\n\n/** Where modules live on disk. */\nfunction modulesDir(): string {\n return path.join(ROOT, \"modules\", \"packages\");\n}\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nfunction shortHash(h: string): string {\n return h.slice(0, 8) + \"\u2026\" + h.slice(-8);\n}\n\ninterface ModuleManifest {\n schemaVersion?: number;\n id?: string;\n handlers?: string[];\n routes?: Array<{ method: string; path: string; handler: string }>;\n migrations?: Array<{ name: string; version: number }>;\n notes?: string;\n}\n\ninterface InstalledModule {\n id: string;\n path: string;\n manifest: ModuleManifest | null;\n totalBytes: number;\n fileCount: number;\n fingerprint: string;\n}\n\n/** Enumerate every installed module by scanning `modules/packages/<id>/`. */\nasync function scanInstalled(): Promise<InstalledModule[]> {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const out: InstalledModule[] = [];\n for (const e of entries) {\n if (!e.isDirectory()) continue;\n const id = e.name;\n const modPath = path.join(dir, id);\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n let manifest: ModuleManifest | null = null;\n if (existsSync(manifestPath)) {\n try {\n manifest = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as ModuleManifest;\n } catch {\n /* corrupt manifest is not fatal \u2014 just skip its fields */\n }\n }\n const { totalBytes, fileCount } = await dirSize(modPath);\n const fingerprint = await dirFingerprint(modPath);\n out.push({ id, path: modPath, manifest, totalBytes, fileCount, fingerprint });\n }\n out.sort((a, b) => a.id.localeCompare(b.id));\n return out;\n}\n\nasync function dirSize(dir: string): Promise<{ totalBytes: number; fileCount: number }> {\n let totalBytes = 0;\n let fileCount = 0;\n async function walk(p: string): Promise<void> {\n for (const e of await fs.readdir(p, { withFileTypes: true })) {\n const child = path.join(p, e.name);\n if (e.isDirectory()) await walk(child);\n else if (e.isFile()) {\n const s = await fs.stat(child);\n totalBytes += s.size;\n fileCount++;\n }\n }\n }\n await walk(dir);\n return { totalBytes, fileCount };\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * list\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleList(_args: string[]): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) {\n return c.dim(t(\"mod.noneInstalled\", { dir: modulesDir() }));\n }\n const lock =\n (readJson<ModuleLock>(modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n const ids = installed.map((m) => m.id);\n const unknown = new Set(await findUnknownModules(ids));\n const lines: string[] = [c.bold(`\\n${t(\"mod.list.title\")}`), c.dim(` ${modulesDir()}`)];\n const header = ` ${\"id\".padEnd(24)}${\"state\".padEnd(8)}${\"files\".padEnd(8)}${\"size\".padEnd(10)}${\"fingerprint\"}`;\n lines.push(c.dim(header));\n for (const m of installed) {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const enabled = lock.modules?.[logicalId]?.enabled === true;\n const stateCol = (enabled ? c.green(\"on\") : c.dim(\"off\")).padEnd(8);\n let mark: string;\n if (!m.manifest) {\n mark = c.yellow(\"\u25CB\");\n } else if (unknown.has(m.id)) {\n mark = c.yellow(\"?\");\n } else {\n mark = enabled ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n }\n const idLabel = logicalId !== m.id ? `${m.id}(${logicalId})` : m.id;\n lines.push(\n ` ${mark} ${idLabel.padEnd(22)}${stateCol}${String(m.fileCount).padEnd(8)}${fmtBytes(m.totalBytes).padEnd(10)}${shortHash(m.fingerprint)}`\n );\n }\n lines.push(c.dim(`\\n tip: ${MODULE_CMD_NAMES[1] ?? \"mod\"} enable|disable <logicalId>`));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Walk `modules/packages/<id>/` and print a one-line yellow warning for each\n * id that isn't in the first-party registry. Intended for the REPL startup\n * hook so users immediately see modules they installed from somewhere else.\n *\n * Best-effort: registry unreachable \u2192 no warning (no false positives).\n */\nexport async function scanAndWarnUnknown(): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) return \"\";\n const unknown = await findUnknownModules(installed.map((m) => m.id));\n if (unknown.length === 0) return \"\";\n const list = unknown.map((id) => ` ${c.yellow(\"?\")} ${id}`).join(\"\\n\");\n return `${c.yellow(\"[sfmc] modules installed from unknown publisher \u2014 verify before use:\")}\\n${list}\\n`;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * search \u2014 \u62C9\u53D6 first-party registry;\u5E26 id \u67E5\u5355\u6761 registry info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/**\n * \u62C9\u53D6 first-party registry \u6A21\u5757\u5217\u8868;\u5E26 id \u65F6\u5C55\u793A\u8BE5\u6761\u76EE\u7684 registry info\u3002\n * \u4E0E\u672C\u5730 `info`(\u5DF2\u5B89\u88C5\u78C1\u76D8\u8BE6\u60C5)\u533A\u5206:`search` \u770B registry,`info` \u770B\u672C\u673A packages\u3002\n */\nexport async function cmdModuleSearch(args: string[]): Promise<string> {\n const query = args[0];\n const { index, stale } = await resolveRegistryIndex({ force: true });\n const ids = Object.keys(index).sort((a, b) => a.localeCompare(b));\n\n if (ids.length === 0) {\n return c.red(\n `\\nRegistry empty or unreachable (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}).\\n` +\n `Check network, or install with an explicit source: sfmc mod install <id> --from github:owner/repo@tag\\n`\n );\n }\n\n const staleNote = stale ? c.yellow(\" (offline \u2014 showing cached index)\\n\") : \"\";\n\n /* \u65E0\u53C2\u6570:\u5217\u51FA\u5168\u90E8 */\n if (!query) {\n const installed = new Set(listInstalledModuleIdsSync());\n const lines: string[] = [\n c.bold(`\\nFirst-party registry (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}) \u2014 ${ids.length} modules`),\n ];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(c.dim(` ${\"id\".padEnd(28)}${\"source\".padEnd(40)}local`));\n for (const id of ids) {\n const e = index[id]!;\n const src = `${e.repo}@${e.tag}`;\n const local = installed.has(id) ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n lines.push(` ${local} ${id.padEnd(26)}${src.padEnd(40)}${installed.has(id) ? \"installed\" : \"\"}`);\n }\n lines.push(c.dim(`\\n tip: sfmc mod search <id> \u2192 registry info`));\n lines.push(c.dim(` sfmc mod install <id> \u2192 download + catalog sync`));\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n /* \u5E26 id:\u67E5\u5355\u6761 registry info */\n const entry = index[query];\n if (!entry) {\n const hints = ids.filter((id) => id.includes(query) || query.includes(id)).slice(0, 8);\n const hintBlock =\n hints.length > 0\n ? c.dim(`\\n Did you mean:\\n`) + hints.map((h) => ` ${h}`).join(\"\\n\")\n : c.dim(`\\n Known ids: ${ids.slice(0, 12).join(\", \")}${ids.length > 12 ? \", \u2026\" : \"\"}`);\n return c.red(t(\"mod.notInRegistry\", { query })) + hintBlock + \"\\n\";\n }\n\n const installedPath = path.join(modulesDir(), query);\n const isInstalled = existsSync(installedPath);\n const lines: string[] = [c.bold(`\\n${query}`)];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(` registry : ${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}`);\n lines.push(` repo : ${entry.repo}`);\n lines.push(` tag : ${entry.tag}`);\n lines.push(` source : github:${entry.repo}@${entry.tag}`);\n lines.push(` github : https://github.com/${entry.repo}/tree/${entry.tag}`);\n lines.push(\n ` local : ${isInstalled ? c.green(`installed @ ${installedPath}`) : c.dim(\"not installed\")}`\n );\n\n if (!isInstalled) {\n lines.push(c.dim(`\\n install: sfmc mod install ${query}`));\n } else {\n lines.push(c.dim(`\\n details: sfmc mod info ${query}`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleInfo(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.info.usage\"));\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalledAt\", { id, path: path.join(modulesDir(), id) }));\n const lines: string[] = [c.bold(`\\n${id}`)];\n lines.push(` path : ${m.path}`);\n lines.push(` files : ${m.fileCount}`);\n lines.push(` size : ${fmtBytes(m.totalBytes)}`);\n lines.push(` fingerprint : ${m.fingerprint}`);\n if (m.manifest) {\n lines.push(` schemaVer : ${m.manifest.schemaVersion ?? \"(none)\"}`);\n lines.push(` routes : ${m.manifest.routes?.length ?? 0}`);\n if (m.manifest.routes?.length) {\n for (const r of m.manifest.routes) lines.push(c.dim(` ${r.method.padEnd(7)} ${r.path.padEnd(36)} ${r.handler}`));\n }\n lines.push(` migrations : ${m.manifest.migrations?.length ?? 0}`);\n if (m.manifest.migrations?.length) {\n for (const mg of m.manifest.migrations) lines.push(c.dim(` v${mg.version} ${mg.name}`));\n }\n if (m.manifest.notes) lines.push(` notes : ${c.dim(m.manifest.notes)}`);\n } else {\n lines.push(c.yellow(` manifest : (missing or unreadable)`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * verify\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleVerify(args: string[]): Promise<string> {\n const id = args[0];\n if (id) {\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalled\", { id }));\n return c.green(t(\"mod.verifyOk\", { id, fp: m.fingerprint }));\n }\n const all = await scanInstalled();\n const lines = [c.bold(\"\\nVerifying installed modules\")];\n for (const m of all) {\n lines.push(` ${m.id.padEnd(28)} ${shortHash(m.fingerprint)}`);\n }\n if (all.length === 0) lines.push(c.dim(\" (none)\"));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to tools/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * enable / disable \u2014 talk to db-server over loopback HTTP\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nfunction readDbConfig(): DBConfig {\n return (readJson<DBConfig>(configPath(ROOT, \"db_config.json\")) ?? {}) as DBConfig;\n}\n\nasync function postModuleToggle(id: string, action: \"enable\" | \"disable\"): Promise<CliResult> {\n const cfg = readDbConfig();\n const port = cfg.db_port ?? 3001;\n const token = cfg.http_auth || \"\";\n const url = `http://127.0.0.1:${port}/api/sfmc/modules/${encodeURIComponent(id)}/${action}`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n });\n } catch (err) {\n return failResult(\n c.red(t(\"mod.dbUnreachable\", { url, message: (err as Error).message }))\n );\n }\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n if (!res.ok) {\n const err = (body as { error?: string })?.error ?? `HTTP ${res.status}`;\n return failResult(c.red(t(\"mod.toggleFailed\", { action, id, err })));\n }\n const ok = (body as { success?: boolean })?.success !== false;\n if (ok) {\n const label = action === \"enable\" ? t(\"mod.action.enabled\") : t(\"mod.action.disabled\");\n return okResult(c.green(t(\"mod.toggleOk\", { label, id })));\n }\n return failResult(c.red(t(\"mod.toggleBadBody\", { action, id, text })));\n}\n\nexport async function cmdModuleEnable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (!id) return failResult(c.yellow(t(\"mod.enable.usage\")));\n return postModuleToggle(id, \"enable\");\n}\n\nexport async function cmdModuleDisable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (!id) return failResult(c.yellow(t(\"mod.disable.usage\")));\n return postModuleToggle(id, \"disable\");\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to tools/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleInstall(args: string[]): Promise<string> {\n // \u652F\u6301: install <id> [id2 ...] [--from ...] [--link]\n const flags = parseFlags(args);\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\" || args[i] === \"--sha256\") {\n i++;\n continue;\n }\n if (args[i]?.startsWith(\"--from=\") || args[i]?.startsWith(\"--sha256=\")) continue;\n if (args[i]?.startsWith(\"--\")) continue;\n positional.push(args[i]!);\n }\n if (positional.length === 0) {\n return c.yellow(t(\"mod.install.usage\"));\n }\n\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n return c.red(t(\"mod.fetchMissing\"));\n }\n const sub = [\"install\", ...positional];\n if (flags.from) sub.push(\"--from\", flags.from);\n if (flags.sha256) sub.push(\"--sha256\", flags.sha256);\n if (flags.link) sub.push(\"--link\");\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, ...sub], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/**\n * `mod link [id] --from dir:\u2026|local:\u2026`\n * - \u6709 id\uFF1A\u7B49\u4EF7 `install <id> --link --from \u2026`\uFF08\u5FC5\u987B\u5E26 --from\uFF09\n * - \u65E0 id\uFF1A\u4EA4\u4E92\u8BE2\u95EE\u672C\u5730\u5305\u8DEF\u5F84\u5E76 link\n */\nexport async function cmdModuleLink(args: string[]): Promise<string> {\n const flags = parseFlags(args);\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\" || args[i] === \"--sha256\") {\n i++;\n continue;\n }\n if (args[i]?.startsWith(\"--from=\") || args[i]?.startsWith(\"--sha256=\")) continue;\n if (args[i]?.startsWith(\"--\")) continue;\n positional.push(args[i]!);\n }\n\n if (positional.length === 0) {\n const { runModuleLinkWizard } = await import(\"./module-wizard.js\");\n return runModuleLinkWizard();\n }\n\n const id = positional[0]!;\n if (!flags.from) {\n return c.red(t(\"mod.linkNeedsFrom\"));\n }\n const installArgs = [id, \"--link\", \"--from\", flags.from];\n return cmdModuleInstall(installArgs);\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * uninstall\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleUninstall(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.uninstall.usage\"));\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n // \u56DE\u9000:\u4EC5\u5220\u76EE\u5F55(\u65E7\u884C\u4E3A)\n const target = path.join(modulesDir(), id);\n if (!existsSync(target)) return c.yellow(t(\"mod.notInstalledFolder\", { id, path: target }));\n await fs.rm(target, { recursive: true, force: true });\n return c.green(t(\"mod.removed\", { id, path: target }));\n }\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, \"uninstall\", id], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * CLI flag parsing\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\ninterface InstallFlags {\n from: string | null;\n sha256: string | null;\n link: boolean;\n}\n\nfunction parseFlags(args: string[]): InstallFlags {\n const flags: InstallFlags = { from: null, sha256: null, link: false };\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\") flags.from = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--from=\")) flags.from = args[i]!.slice(\"--from=\".length);\n else if (args[i] === \"--sha256\") flags.sha256 = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--sha256=\")) flags.sha256 = args[i]!.slice(\"--sha256=\".length);\n else if (args[i] === \"--link\") flags.link = true;\n }\n return flags;\n}\n\n/**\n * `sfmc mod test` \u2014 \u59D4\u6258\u6A21\u5757\u4ED3\u7684 test runner\uFF08node --test + @sfmc-bds/sdk/testing\uFF09\u3002\n * \u89E3\u6790 --from local[:path] \u89C4\u5219\u4E0E watch \u4E00\u81F4\uFF1B\u7F3A\u7701 cwd\u3002\n * \u900F\u4F20 npm test\uFF1A\u8BA9\u6A21\u5757\u4ED3\u7684 `scripts.test` \u81EA\u5DF1\u51B3\u5B9A\u600E\u4E48\u8DD1\uFF08node --test / tsx / vitest \u7B49\uFF09\u3002\n */\nexport async function cmdModuleTest(args: string[]): Promise<string> {\n let fromRaw: string | null = null;\n const passthrough: string[] = [];\n for (let i = 0; i < args.length; i++) {\n const a = args[i];\n if (a === \"--from\") {\n fromRaw = args[++i] ?? null;\n } else if (a?.startsWith(\"--from=\")) {\n fromRaw = a.slice(\"--from=\".length);\n } else if (a === \"--help\" || a === \"-h\") {\n return c.dim(\"\u7528\u6CD5: mod test [--from local[:<path>]] [-- <args>]\\n \u900F\u4F20\u7ED9\u6A21\u5757\u4ED3\u7684 npm test\u3002\");\n } else {\n passthrough.push(a!);\n }\n }\n\n /* \u89E3\u6790 cwd\uFF08\u4E0E watch \u5171\u7528 resolveLocalModuleRoot \u89C4\u5219\uFF09\u3002 */\n const { resolveLocalModuleRoot } = await import(\"./module-watch.js\");\n const cwd = resolveLocalModuleRoot({ from: fromRaw, cwd: process.cwd() });\n\n if (!existsSync(cwd)) {\n return c.red(`[mod test] \u8DEF\u5F84\u4E0D\u5B58\u5728: ${cwd}`);\n }\n if (!existsSync(path.join(cwd, \"package.json\"))) {\n return c.yellow(`[mod test] \u672A\u627E\u5230 package.json: ${cwd}\\n \u63D0\u793A\uFF1A\u8FDB\u5165\u6A21\u5757\u4ED3\u6839\u76EE\u5F55\uFF0C\u6216\u7528 --from local:<path> \u6307\u5411\u3002`);\n }\n\n /* Windows \u7528 cmd /c npm \u900F\u4F20 npm.cmd\uFF08\u907F\u514D shell:true \u7684 DEP0190 \u5B89\u5168\u8B66\u544A\uFF09\u3002 */\n const isWin = process.platform === \"win32\";\n const cmd = isWin ? \"cmd.exe\" : \"npm\";\n const subArgs = isWin ? [\"/c\", \"npm\", \"test\", \"--\", ...passthrough] : [\"test\", \"--\", ...passthrough];\n\n return new Promise<string>((resolve) => {\n const proc = spawn(cmd, subArgs, {\n cwd,\n stdio: \"inherit\",\n env: process.env,\n });\n proc.on(\"exit\", (code) => {\n resolve(code === 0 ? \"\" : `\\n[mod test] exit ${code}`);\n });\n proc.on(\"error\", (e) => resolve(c.red(`[mod test] spawn failed: ${e.message}`)));\n });\n}\n\n/**\n * \u7EDF\u4E00\u5206\u53D1 module/mod \u5B50\u547D\u4EE4 \u2014\u2014 CLI(`main.ts`)\u4E0E REPL(`repl.ts`)\u5171\u7528,\n * \u907F\u514D\u4E24\u5904 switch \u6F02\u79FB\u3002\n *\n * \u901A\u9053\u95E8\u7981\uFF08external/repl\uFF09\u7531\u8C03\u7528\u65B9\u5728 dispatch \u524D\u7ECF command-surface \u5224\u5B9A\uFF1B\n * \u672C\u51FD\u6570\u53EA\u8D1F\u8D23\u5B50\u547D\u4EE4\u8DEF\u7531\u3002`remove` \u4F5C\u4E3A uninstall \u7684\u540C\u4E49\u522B\u540D\u4FDD\u7559\u3002\n */\nexport async function dispatchModuleCommand(sub: string | undefined, args: string[]): Promise<string> {\n switch (sub) {\n case \"list\":\n return cmdModuleList(args);\n case \"search\":\n return cmdModuleSearch(args);\n case \"install\":\n return cmdModuleInstall(args);\n case \"uninstall\":\n case \"remove\":\n return cmdModuleUninstall(args);\n case \"verify\":\n return cmdModuleVerify(args);\n case \"info\":\n return cmdModuleInfo(args);\n case \"enable\":\n return (await cmdModuleEnable(args)).message;\n case \"disable\":\n return (await cmdModuleDisable(args)).message;\n case \"build\": {\n const { cmdModuleBuild } = await import(\"./module-pack-build.js\");\n return cmdModuleBuild(args);\n }\n case \"reload\": {\n const { cmdModuleReload } = await import(\"./module-pack-build.js\");\n return cmdModuleReload(args);\n }\n case \"create\": {\n const { runModuleCreateWizard } = await import(\"./module-wizard.js\");\n return runModuleCreateWizard();\n }\n case \"link\":\n return cmdModuleLink(args);\n case \"dev\": {\n const { runModuleDevWizard } = await import(\"./module-wizard.js\");\n return runModuleDevWizard();\n }\n case \"watch\": {\n const { cmdModuleWatch } = await import(\"./module-watch.js\");\n return cmdModuleWatch(args);\n }\n case \"test\": {\n return cmdModuleTest(args);\n }\n case \"publish\": {\n const { cmdModulePublish } = await import(\"./module-publish.js\");\n return cmdModulePublish(args);\n }\n default:\n return c.yellow(moduleUsage());\n }\n}\n\n/** \u540C\u6B65\u679A\u4E3E\u5DF2\u5B89\u88C5\u6A21\u5757 id,\u4F9B REPL Tab \u8865\u5168(\u4E0D\u8BFB fingerprint,\u5C3D\u91CF\u8F7B\u91CF)\u3002 */\nexport function listInstalledModuleIdsSync(): string[] {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * sfmc module-commands \u2014 runtime CLI for inspecting and managing modules\n * already on disk under `modules/packages/<id>/`.\n *\n * \u9876\u5C42\u547D\u4EE4\u522B\u540D:`module` / `mod`(\u7531 main.ts / repl.ts \u5171\u540C\u8BC6\u522B)\u3002\n * \u5B50\u547D\u4EE4\u901A\u9053\u95E8\u7981\u89C1 command-surface.ts\uFF08dispatch \u524D\u7531 main/repl \u5224\u5B9A\uFF09\u3002\n */\n\nimport fs from \"node:fs/promises\";\nimport { existsSync, lstatSync, readdirSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { spawn } from \"node:child_process\";\nimport {\n configPath,\n modulePath,\n readJson,\n writeJson,\n type Catalog,\n type DBConfig,\n type ModuleLock,\n} from \"@sfmc-bds/sdk/node/config\";\nimport {\n isDevAccentModuleSub,\n listVisibleModuleSubs,\n type CommandMode,\n} from \"./command-surface.js\";\nimport { failResult, okResult, type CliResult } from \"./cli-result.js\";\nimport { t } from \"./i18n/index.js\";\nimport { c } from \"./theme.js\";\nimport { ROOT, resolveFetchModule } from \"./runtime.js\";\nimport { dirFingerprint } from \"./module-fingerprint.js\";\nimport {\n applyLockEnabled,\n finalizeToggle,\n resolveToggleTarget,\n type ToggleCandidate,\n type ToggleNotify,\n} from \"./module-toggle.js\";\nimport {\n DEFAULT_REGISTRY_REPO,\n DEFAULT_REGISTRY_TAG,\n findUnknownModules,\n resolveRegistryIndex,\n} from \"./registry.js\";\n\n/** \u9876\u5C42\u547D\u4EE4\u540D(\u4E3B\u540D + \u77ED\u522B\u540D),\u4F9B\u5E2E\u52A9 / \u8865\u5168 / \u5206\u53D1\u5171\u7528\u3002 */\nexport const MODULE_CMD_NAMES = [\"module\", \"mod\"] as const;\n\nexport type ModuleCmdName = (typeof MODULE_CMD_NAMES)[number];\n\n/** \u5224\u65AD\u662F\u5426\u4E3A module \u9876\u5C42\u547D\u4EE4(\u542B\u522B\u540D);\u907F\u514D main/repl \u518D\u786C\u7F16\u7801 case\u3002 */\nexport function isModuleCommand(cmd: string | undefined): cmd is ModuleCmdName {\n return !!cmd && (MODULE_CMD_NAMES as readonly string[]).includes(cmd);\n}\n\n/** \u5F00\u53D1\u8005\u6837\u5F0F\u5B50\u547D\u4EE4\uFF08\u84DD\u6807\uFF0C\u975E\u95E8\u7981\uFF09\u3002 */\nexport const DEV_ACCENT_MODULE_SUBCOMMANDS = [\"build\", \"reload\"] as const;\n\n/** \u5F53\u524D\u901A\u9053\u4E0B\u53EF\u89C1\u7684 module \u5B50\u547D\u4EE4\uFF08\u81EA\u52A8\u8865\u5168 / usage\uFF09\u3002 */\nexport function getVisibleModuleSubcommands(mode: CommandMode): readonly string[] {\n return listVisibleModuleSubs(mode);\n}\n\n/** sub \u662F\u5426\u4E3A\u5F00\u53D1\u8005\u84DD\u6807\uFF08help \u7740\u8272\uFF09\u3002 */\nexport function isDeveloperSubcommand(sub: string | undefined): boolean {\n return isDevAccentModuleSub(sub);\n}\n\n/** Usage \u884C\u4E3B\u540D|\u522B\u540D(\u4E0E MODULE_CMD_NAMES \u540C\u6E90,\u907F\u514D\u4E0E\u5E2E\u52A9\u6587\u6848\u6F02\u79FB)\u3002 */\nexport function moduleUsage(mode: CommandMode = \"argv\"): string {\n return t(\"mod.usage\", {\n cmds: MODULE_CMD_NAMES.join(\"|\"),\n subs: getVisibleModuleSubcommands(mode).join(\"|\"),\n });\n}\n\n/** Where modules live on disk. */\nfunction modulesDir(): string {\n return path.join(ROOT, \"modules\", \"packages\");\n}\n\nfunction fmtBytes(n: number): string {\n if (n < 1024) return `${n} B`;\n if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;\n return `${(n / 1024 / 1024).toFixed(2)} MB`;\n}\n\nfunction shortHash(h: string): string {\n return h.slice(0, 8) + \"\u2026\" + h.slice(-8);\n}\n\ninterface ModuleManifest {\n schemaVersion?: number;\n id?: string;\n handlers?: string[];\n routes?: Array<{ method: string; path: string; handler: string }>;\n migrations?: Array<{ name: string; version: number }>;\n notes?: string;\n}\n\ninterface InstalledModule {\n id: string;\n path: string;\n manifest: ModuleManifest | null;\n totalBytes: number;\n fileCount: number;\n fingerprint: string;\n}\n\n/** Enumerate every installed module by scanning `modules/packages/<id>/`. */\nasync function scanInstalled(): Promise<InstalledModule[]> {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n const entries = await fs.readdir(dir, { withFileTypes: true });\n const out: InstalledModule[] = [];\n for (const e of entries) {\n if (!e.isDirectory()) continue;\n const id = e.name;\n const modPath = path.join(dir, id);\n const manifestPath = path.join(modPath, \"sapi\", \"manifest.json\");\n let manifest: ModuleManifest | null = null;\n if (existsSync(manifestPath)) {\n try {\n manifest = JSON.parse(await fs.readFile(manifestPath, \"utf8\")) as ModuleManifest;\n } catch {\n /* corrupt manifest is not fatal \u2014 just skip its fields */\n }\n }\n const { totalBytes, fileCount } = await dirSize(modPath);\n const fingerprint = await dirFingerprint(modPath);\n out.push({ id, path: modPath, manifest, totalBytes, fileCount, fingerprint });\n }\n out.sort((a, b) => a.id.localeCompare(b.id));\n return out;\n}\n\nasync function dirSize(dir: string): Promise<{ totalBytes: number; fileCount: number }> {\n let totalBytes = 0;\n let fileCount = 0;\n async function walk(p: string): Promise<void> {\n for (const e of await fs.readdir(p, { withFileTypes: true })) {\n const child = path.join(p, e.name);\n if (e.isDirectory()) await walk(child);\n else if (e.isFile()) {\n const s = await fs.stat(child);\n totalBytes += s.size;\n fileCount++;\n }\n }\n }\n await walk(dir);\n return { totalBytes, fileCount };\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * list\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleList(_args: string[]): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) {\n return c.dim(t(\"mod.noneInstalled\", { dir: modulesDir() }));\n }\n const lock =\n (readJson<ModuleLock>(modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\")) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n const ids = installed.map((m) => m.id);\n const unknown = new Set(await findUnknownModules(ids));\n const lines: string[] = [c.bold(`\\n${t(\"mod.list.title\")}`), c.dim(` ${modulesDir()}`)];\n const header = ` ${\"id\".padEnd(24)}${\"state\".padEnd(8)}${\"files\".padEnd(8)}${\"size\".padEnd(10)}${\"fingerprint\"}`;\n lines.push(c.dim(header));\n for (const m of installed) {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const enabled = lock.modules?.[logicalId]?.enabled === true;\n const stateCol = (enabled ? c.green(\"on\") : c.dim(\"off\")).padEnd(8);\n let mark: string;\n if (!m.manifest) {\n mark = c.yellow(\"\u25CB\");\n } else if (unknown.has(m.id)) {\n mark = c.yellow(\"?\");\n } else {\n mark = enabled ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n }\n const idLabel = logicalId !== m.id ? `${m.id}(${logicalId})` : m.id;\n lines.push(\n ` ${mark} ${idLabel.padEnd(22)}${stateCol}${String(m.fileCount).padEnd(8)}${fmtBytes(m.totalBytes).padEnd(10)}${shortHash(m.fingerprint)}`\n );\n }\n lines.push(c.dim(`\\n tip: ${MODULE_CMD_NAMES[1] ?? \"mod\"} enable|disable <logicalId>`));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/**\n * Walk `modules/packages/<id>/` and print a one-line yellow warning for each\n * id that isn't in the first-party registry. Intended for the REPL startup\n * hook so users immediately see modules they installed from somewhere else.\n *\n * Best-effort: registry unreachable \u2192 no warning (no false positives).\n */\nexport async function scanAndWarnUnknown(): Promise<string> {\n const installed = await scanInstalled();\n if (installed.length === 0) return \"\";\n const unknown = await findUnknownModules(installed.map((m) => m.id));\n if (unknown.length === 0) return \"\";\n const list = unknown.map((id) => ` ${c.yellow(\"?\")} ${id}`).join(\"\\n\");\n return `${c.yellow(\"[sfmc] modules installed from unknown publisher \u2014 verify before use:\")}\\n${list}\\n`;\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * search \u2014 \u62C9\u53D6 first-party registry;\u5E26 id \u67E5\u5355\u6761 registry info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/**\n * \u62C9\u53D6 first-party registry \u6A21\u5757\u5217\u8868;\u5E26 id \u65F6\u5C55\u793A\u8BE5\u6761\u76EE\u7684 registry info\u3002\n * \u4E0E\u672C\u5730 `info`(\u5DF2\u5B89\u88C5\u78C1\u76D8\u8BE6\u60C5)\u533A\u5206:`search` \u770B registry,`info` \u770B\u672C\u673A packages\u3002\n */\nexport async function cmdModuleSearch(args: string[]): Promise<string> {\n const query = args[0];\n const { index, stale } = await resolveRegistryIndex({ force: true });\n const ids = Object.keys(index).sort((a, b) => a.localeCompare(b));\n\n if (ids.length === 0) {\n return c.red(\n `\\nRegistry empty or unreachable (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}).\\n` +\n `Check network, or: mod install <id> --from github:owner/repo@tag\\n`\n );\n }\n\n const staleNote = stale ? c.yellow(\" (offline \u2014 showing cached index)\\n\") : \"\";\n\n /* \u65E0\u53C2\u6570:\u5217\u51FA\u5168\u90E8 */\n if (!query) {\n const installed = new Set(listInstalledModuleIdsSync());\n const lines: string[] = [\n c.bold(`\\nFirst-party registry (${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}) \u2014 ${ids.length} modules`),\n ];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(c.dim(` ${\"id\".padEnd(28)}${\"source\".padEnd(40)}local`));\n for (const id of ids) {\n const e = index[id]!;\n const src = `${e.repo}@${e.tag}`;\n const local = installed.has(id) ? c.green(\"\u25CF\") : c.dim(\"\u25CB\");\n lines.push(` ${local} ${id.padEnd(26)}${src.padEnd(40)}${installed.has(id) ? \"installed\" : \"\"}`);\n }\n lines.push(c.dim(`\\n tip: sfmc mod search <id> \u2192 registry info`));\n lines.push(c.dim(` sfmc mod install <id> \u2192 download + catalog sync`));\n return lines.join(\"\\n\") + \"\\n\";\n }\n\n /* \u5E26 id:\u67E5\u5355\u6761 registry info */\n const entry = index[query];\n if (!entry) {\n const hints = ids.filter((id) => id.includes(query) || query.includes(id)).slice(0, 8);\n const hintBlock =\n hints.length > 0\n ? c.dim(`\\n Did you mean:\\n`) + hints.map((h) => ` ${h}`).join(\"\\n\")\n : c.dim(`\\n Known ids: ${ids.slice(0, 12).join(\", \")}${ids.length > 12 ? \", \u2026\" : \"\"}`);\n return c.red(t(\"mod.notInRegistry\", { query })) + hintBlock + \"\\n\";\n }\n\n const installedPath = path.join(modulesDir(), query);\n const isInstalled = existsSync(installedPath);\n const lines: string[] = [c.bold(`\\n${query}`)];\n if (staleNote) lines.push(staleNote.trimEnd());\n lines.push(` registry : ${DEFAULT_REGISTRY_REPO}@${DEFAULT_REGISTRY_TAG}`);\n lines.push(` repo : ${entry.repo}`);\n lines.push(` tag : ${entry.tag}`);\n lines.push(` source : github:${entry.repo}@${entry.tag}`);\n lines.push(` github : https://github.com/${entry.repo}/tree/${entry.tag}`);\n lines.push(\n ` local : ${isInstalled ? c.green(`installed @ ${installedPath}`) : c.dim(\"not installed\")}`\n );\n\n if (!isInstalled) {\n lines.push(c.dim(`\\n install: sfmc mod install ${query}`));\n } else {\n lines.push(c.dim(`\\n details: sfmc mod info ${query}`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * info\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleInfo(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.info.usage\"));\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalledAt\", { id, path: path.join(modulesDir(), id) }));\n const lines: string[] = [c.bold(`\\n${id}`)];\n lines.push(` path : ${m.path}`);\n lines.push(` files : ${m.fileCount}`);\n lines.push(` size : ${fmtBytes(m.totalBytes)}`);\n lines.push(` fingerprint : ${m.fingerprint}`);\n if (m.manifest) {\n lines.push(` schemaVer : ${m.manifest.schemaVersion ?? \"(none)\"}`);\n lines.push(` routes : ${m.manifest.routes?.length ?? 0}`);\n if (m.manifest.routes?.length) {\n for (const r of m.manifest.routes) lines.push(c.dim(` ${r.method.padEnd(7)} ${r.path.padEnd(36)} ${r.handler}`));\n }\n lines.push(` migrations : ${m.manifest.migrations?.length ?? 0}`);\n if (m.manifest.migrations?.length) {\n for (const mg of m.manifest.migrations) lines.push(c.dim(` v${mg.version} ${mg.name}`));\n }\n if (m.manifest.notes) lines.push(` notes : ${c.dim(m.manifest.notes)}`);\n } else {\n lines.push(c.yellow(` manifest : (missing or unreadable)`));\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * verify\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleVerify(args: string[]): Promise<string> {\n const id = args[0];\n if (id) {\n const all = await scanInstalled();\n const m = all.find((x) => x.id === id);\n if (!m) return c.red(t(\"mod.notInstalled\", { id }));\n return c.green(t(\"mod.verifyOk\", { id, fp: m.fingerprint }));\n }\n const all = await scanInstalled();\n const lines = [c.bold(\"\\nVerifying installed modules\")];\n for (const m of all) {\n lines.push(` ${m.id.padEnd(28)} ${shortHash(m.fingerprint)}`);\n }\n if (all.length === 0) lines.push(c.dim(\" (none)\"));\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to tools/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * enable / disable \u2014 \u672C\u5730\u5199 module-lock.json\uFF1Bdb \u5728\u7EBF\u65F6 best-effort \u70ED\u540C\u6B65\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nfunction readDbConfig(): DBConfig {\n return (readJson<DBConfig>(configPath(ROOT, \"db_config.json\")) ?? {}) as DBConfig;\n}\n\nfunction moduleLockPath(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"module-lock.json\");\n}\n\nfunction catalogPathOnDisk(): string {\n return modulePath(path.join(ROOT, \"modules\"), \"catalog.json\");\n}\n\n/** \u5DF2\u88C5\u5305 + catalog \u6295\u5F71 \u2192 \u542F\u505C\u5019\u9009\uFF08canDisable \u4E0E db \u540C\u6E90\uFF1A\u7701\u7565\u89C6\u4E3A\u53EF\u7981\u7528\uFF09\u3002 */\nfunction buildToggleCandidates(installed: InstalledModule[]): ToggleCandidate[] {\n const catalog = (readJson<Catalog>(catalogPathOnDisk()) ?? {}) as Catalog;\n const rows = Array.isArray(catalog.modules) ? catalog.modules : [];\n const byLogical = new Map<string, Record<string, unknown>>();\n for (const raw of rows) {\n if (!raw || typeof raw !== \"object\") continue;\n const id = String((raw as Record<string, unknown>).id || \"\").trim();\n if (id) byLogical.set(id, raw as Record<string, unknown>);\n }\n return installed.map((m) => {\n const logicalId = typeof m.manifest?.id === \"string\" && m.manifest.id ? m.manifest.id : m.id;\n const raw = byLogical.get(logicalId);\n const configKeyRaw = raw ? String(raw.configKey || raw.config_key || \"\").trim() : \"\";\n const canDisable = raw ? raw.canDisable !== false : true;\n const out: ToggleCandidate = { logicalId, folderId: m.id, canDisable };\n if (configKeyRaw) out.configKey = configKeyRaw;\n return out;\n });\n}\n\nfunction writeLocalModuleEnabled(logicalId: string, enabled: boolean): void {\n const lockPath = moduleLockPath();\n const lock =\n (readJson<ModuleLock>(lockPath) ?? {\n version: 1,\n modules: {},\n }) as ModuleLock;\n applyLockEnabled(lock, logicalId, enabled);\n writeJson(lockPath, lock);\n}\n\nasync function notifyDbToggle(logicalId: string, action: \"enable\" | \"disable\"): Promise<ToggleNotify> {\n const cfg = readDbConfig();\n const port = cfg.db_port ?? 3001;\n const token = cfg.http_auth || \"\";\n const url = `http://127.0.0.1:${port}/api/sfmc/modules/${encodeURIComponent(logicalId)}/${action}`;\n let res: Response;\n try {\n res = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n },\n });\n } catch (err) {\n return { ok: false, reason: \"unreachable\", detail: (err as Error).message };\n }\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n if (!res.ok) {\n const err = (body as { error?: string })?.error ?? `HTTP ${res.status}`;\n return { ok: false, reason: \"http\", detail: err };\n }\n if ((body as { success?: boolean })?.success === false) {\n return { ok: false, reason: \"http\", detail: text };\n }\n return { ok: true };\n}\n\nasync function cmdModuleToggle(query: string, action: \"enable\" | \"disable\"): Promise<CliResult> {\n const installed = await scanInstalled();\n const target = resolveToggleTarget(query, buildToggleCandidates(installed));\n if (!target) {\n return failResult(c.red(t(\"mod.notInstalled\", { id: query })));\n }\n if (action === \"disable\" && !target.canDisable) {\n return failResult(c.red(t(\"mod.cannotDisable\", { id: target.logicalId })));\n }\n\n const enabled = action === \"enable\";\n try {\n writeLocalModuleEnabled(target.logicalId, enabled);\n } catch (err) {\n return failResult(\n c.red(t(\"mod.toggleLockFailed\", { id: target.logicalId, message: (err as Error).message }))\n );\n }\n\n const notify = await notifyDbToggle(target.logicalId, action);\n const fin = finalizeToggle(true, notify);\n const label = action === \"enable\" ? t(\"mod.action.enabled\") : t(\"mod.action.disabled\");\n const head = c.green(t(\"mod.toggleOk\", { label, id: target.logicalId }));\n if (!fin.warnNotify) {\n return okResult(head);\n }\n const detail = notify.ok === false ? (notify.detail ?? notify.reason) : \"\";\n const warn = c.yellow(t(\"mod.toggleDbSkipped\", { detail }));\n return okResult(`${head}\\n${warn}`);\n}\n\nexport async function cmdModuleEnable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (!id) return failResult(c.yellow(t(\"mod.enable.usage\")));\n return cmdModuleToggle(id, \"enable\");\n}\n\nexport async function cmdModuleDisable(args: string[]): Promise<CliResult> {\n const id = args[0];\n if (!id) return failResult(c.yellow(t(\"mod.disable.usage\")));\n return cmdModuleToggle(id, \"disable\");\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * install \u2014 shells out to tools/fetch-module.mjs\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/**\n * \u9884\u68C0 --from \u53D6\u503C\u662F\u5426\u662F\u5408\u6CD5 scheme\uFF1A\n * - npm:@scope/name / npm:<name>\n * - local[:<path>] / local\n * - tgz:<path>\n * - zip:<path>\n * - dir:<abs path>\n * - github:<owner>/<repo>[@tag]\n * - \u88F8\u8DEF\u5F84\uFF1A\u5FC5\u987B\u5B58\u5728\u4E14\u4E3A\u76EE\u5F55\uFF08\u88F8\u6587\u4EF6\u5E94\u8F6C tgz:/zip:\uFF09\n * \u8FD4\u56DE null \u8868\u793A\u5408\u6CD5\uFF1B\u5426\u5219\u8FD4\u56DE\u7528\u6237\u53EF\u8BFB\u7684\u9519\u8BEF\u6587\u6848\u3002\n */\nfunction validateFromScheme(from: string): string | null {\n if (\n from === \"local\" ||\n from.startsWith(\"local:\") ||\n from.startsWith(\"dir:\") ||\n from.startsWith(\"npm:\") ||\n from.startsWith(\"tgz:\") ||\n from.startsWith(\"zip:\") ||\n from.startsWith(\"github:\")\n ) {\n return null;\n }\n if (existsSync(from)) {\n const st = lstatSync(from);\n if (st.isDirectory()) return null;\n return `--from \u88F8\u8DEF\u5F84\u987B\u4E3A\u76EE\u5F55\uFF08\u6587\u4EF6\u8BF7\u7528 --from local:<tgz|zip>\uFF09: ${from}`;\n }\n return t(\"mod.fromUnknown\", { value: from });\n}\n\nexport async function cmdModuleInstall(args: string[]): Promise<string> {\n // \u652F\u6301: install <id> [id2 ...] [--from ...] [--link] [--sha256 ...]\n const flags = parseFlags(args);\n const positional: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\" || args[i] === \"--sha256\") {\n i++;\n continue;\n }\n if (args[i]?.startsWith(\"--from=\") || args[i]?.startsWith(\"--sha256=\")) continue;\n if (args[i]?.startsWith(\"--\")) continue;\n positional.push(args[i]!);\n }\n if (positional.length === 0) {\n return c.yellow(t(\"mod.install.usage\"));\n }\n\n /* scheme \u9884\u68C0\uFF1A\u907F\u514D\u62FC\u5199\u9519\u8BEF\u5EF6\u8FDF\u5230\u5B50\u8FDB\u7A0B\u62A5\u9519 */\n if (flags.from) {\n const err = validateFromScheme(flags.from);\n if (err) return c.red(err);\n }\n\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n return c.red(t(\"mod.fetchMissing\"));\n }\n const sub = [\"install\", ...positional];\n if (flags.from) sub.push(\"--from\", flags.from);\n if (flags.sha256) sub.push(\"--sha256\", flags.sha256);\n if (flags.link) sub.push(\"--link\");\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, ...sub], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * uninstall\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\nexport async function cmdModuleUninstall(args: string[]): Promise<string> {\n const id = args[0];\n if (!id) return c.yellow(t(\"mod.uninstall.usage\"));\n const fetchScript = resolveFetchModule();\n if (!fetchScript) {\n // \u56DE\u9000:\u4EC5\u5220\u76EE\u5F55(\u65E7\u884C\u4E3A)\n const target = path.join(modulesDir(), id);\n if (!existsSync(target)) return c.yellow(t(\"mod.notInstalledFolder\", { id, path: target }));\n await fs.rm(target, { recursive: true, force: true });\n return c.green(t(\"mod.removed\", { id, path: target }));\n }\n return new Promise<string>((resolve) => {\n const proc = spawn(process.execPath, [fetchScript, \"uninstall\", id], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: { ...process.env, SFMC_ROOT: ROOT },\n });\n let out = \"\";\n proc.stdout?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.stderr?.on(\"data\", (d: Buffer) => {\n out += d.toString();\n });\n proc.on(\"exit\", (code) => {\n resolve(out + (code === 0 ? \"\" : `\\n[exit ${code}]`));\n });\n proc.on(\"error\", (e) => resolve(c.red(`spawn failed: ${e.message}`)));\n });\n}\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n * CLI flag parsing\n * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\ninterface InstallFlags {\n from: string | null;\n sha256: string | null;\n link: boolean;\n}\n\nfunction parseFlags(args: string[]): InstallFlags {\n const flags: InstallFlags = { from: null, sha256: null, link: false };\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--from\") flags.from = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--from=\")) flags.from = args[i]!.slice(\"--from=\".length);\n else if (args[i] === \"--sha256\") flags.sha256 = args[++i] ?? null;\n else if (args[i]?.startsWith(\"--sha256=\")) flags.sha256 = args[i]!.slice(\"--sha256=\".length);\n else if (args[i] === \"--link\") flags.link = true;\n }\n return flags;\n}\n\n/**\n * \u7EDF\u4E00\u5206\u53D1 module/mod \u5B50\u547D\u4EE4 \u2014\u2014 CLI(`main.ts`)\u4E0E REPL(`repl.ts`)\u5171\u7528,\n * \u907F\u514D\u4E24\u5904 switch \u6F02\u79FB\u3002\n *\n * \u901A\u9053\u95E8\u7981\uFF08argv/repl\uFF09\u7531\u8C03\u7528\u65B9\u5728 dispatch \u524D\u7ECF command-surface \u5224\u5B9A\uFF1B\n * \u672C\u51FD\u6570\u53EA\u8D1F\u8D23\u5B50\u547D\u4EE4\u8DEF\u7531\u3002`remove` \u4F5C\u4E3A uninstall \u7684\u540C\u4E49\u522B\u540D\u4FDD\u7559\u3002\n *\n * \u4F5C\u8005\u5411 test/watch/publish \u5DF2\u8FC1\u81F3 VS Code \u6269\u5C55\u4E0E @sfmc-bds/devkit\u3002\n */\nexport async function dispatchModuleCommand(sub: string | undefined, args: string[]): Promise<string> {\n switch (sub) {\n case \"list\":\n return cmdModuleList(args);\n case \"search\":\n return cmdModuleSearch(args);\n case \"install\":\n return cmdModuleInstall(args);\n case \"uninstall\":\n case \"remove\":\n return cmdModuleUninstall(args);\n case \"verify\":\n return cmdModuleVerify(args);\n case \"info\":\n return cmdModuleInfo(args);\n case \"enable\":\n return (await cmdModuleEnable(args)).message;\n case \"disable\":\n return (await cmdModuleDisable(args)).message;\n case \"build\": {\n const { cmdModuleBuild } = await import(\"./module-pack-build.js\");\n return cmdModuleBuild(args);\n }\n case \"reload\": {\n const { cmdModuleReload } = await import(\"./module-pack-build.js\");\n return cmdModuleReload(args);\n }\n case \"test\":\n case \"watch\":\n case \"publish\":\n return c.yellow(\n `[mod ${sub}] \u5DF2\u79FB\u81F3 VS Code/Cursor \u6269\u5C55\u300CSFMC Module\u300D\u4E0E @sfmc-bds/devkit\uFF1B\u8FD0\u7EF4\u8BF7\u7528 mod build|reload|install\u3002`\n );\n default:\n return c.yellow(moduleUsage());\n }\n}\n\n/** \u540C\u6B65\u679A\u4E3E\u5DF2\u5B89\u88C5\u6A21\u5757 id,\u4F9B REPL Tab \u8865\u5168(\u4E0D\u8BFB fingerprint,\u5C3D\u91CF\u8F7B\u91CF)\u3002 */\nexport function listInstalledModuleIdsSync(): string[] {\n const dir = modulesDir();\n if (!existsSync(dir)) return [];\n try {\n return readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory())\n .map((e) => e.name)\n .sort((a, b) => a.localeCompare(b));\n } catch {\n return [];\n }\n}"],
5
+ "mappings": "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",
6
6
  "names": ["lines", "all"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module-pack-build.d.ts","sourceRoot":"","sources":["../src/module-pack-build.ts"],"names":[],"mappings":"AA2YA;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCrE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDrE"}
1
+ {"version":3,"file":"module-pack-build.d.ts","sourceRoot":"","sources":["../src/module-pack-build.ts"],"names":[],"mappings":"AA+YA;;;GAGG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwCrE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAmDrE"}
@@ -64,6 +64,10 @@ async function bundleBehaviorPackScript() {
64
64
  logLevel: "warning",
65
65
  sourcemap: false,
66
66
  external: ["@minecraft/*"],
67
+ // BDS host 启动:与 module-loader barrel 分离(DIP),须在模块 register 之前执行
68
+ banner: {
69
+ js: 'import { installHostBootstrap } from "@sfmc-bds/sdk/module-loader/install";\ninstallHostBootstrap();\n'
70
+ },
67
71
  tsconfigRaw: JSON.stringify({
68
72
  compilerOptions: {
69
73
  module: "ESNext",