dump-config.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. /**
  2. * `dsh --dump-config` / `dsh web --dump-config` — print the composed config
  3. * tree without booting: the shipped base, the surface overlay, and (unless
  4. * `--dump-default-config`) the `--config` or personal overlay, composed
  5. * through the include's own patch algorithm so the printed tree is exactly
  6. * what that surface would mount. `!!js` expressions print verbatim,
  7. * unevaluated — the dump shows composition, not one process's environment.
  8. * Launcher-provided boot-context values (session identity, CLI-flag patches)
  9. * are per-invocation facts outside the config tree and do not appear.
  10. * @module @deepseek-ai/dsh/dump-config
  11. */
  12. import { basename, join } from 'node:path'
  13. import { fileURLToPath } from 'node:url'
  14. import {
  15. loadOverlayPatches,
  16. loadPersonalPatches,
  17. PERSONAL_CONFIG_FILENAME,
  18. renderConfigDump,
  19. type ConfigDumpLayer,
  20. } from '@deepseek-ai/dsh-app-boot'
  21. import { resolveDshHome } from '@deepseek-ai/dsh-paths'
  22. const NAME = 'dsh'
  23. const BASE_CONFIG = fileURLToPath(new URL('../config/base.cordis.yml', import.meta.url))
  24. const SURFACE_OVERLAYS = {
  25. tui: fileURLToPath(new URL('../config/tui.cordis.yml', import.meta.url)),
  26. web: fileURLToPath(new URL('../config/web.cordis.yml', import.meta.url)),
  27. } as const
  28. /* v8 ignore start -- composition over the unit-tested renderConfigDump; the
  29. built-bin e2e drives this path end to end */
  30. /**
  31. * Print one surface's composed config tree to stdout, with a comment
  32. * separator naming the file each section of rows comes from (and the layers
  33. * that patched it).
  34. * @param surface - which surface overlay to compose over the shared base.
  35. * @param defaultOnly - stop at the surface overlay (no `--config`/personal layer).
  36. * @param config - the `--config` overlay path composed instead of the personal
  37. * one, or `undefined` to use `$DSH_HOME/config.yaml`.
  38. */
  39. export function runDumpConfig(surface: 'tui' | 'web', defaultOnly: boolean, config?: string): void {
  40. const overlay = SURFACE_OVERLAYS[surface]
  41. const layers: ConfigDumpLayer[] = [
  42. { label: basename(overlay), patches: loadOverlayPatches(NAME, overlay) },
  43. ]
  44. if (!defaultOnly) {
  45. if (config === undefined) {
  46. const personal = loadPersonalPatches(NAME)
  47. // The personal file may be absent; the shipped layers still print.
  48. if (personal !== undefined) {
  49. layers.push({ label: join(resolveDshHome(), PERSONAL_CONFIG_FILENAME), patches: personal })
  50. }
  51. } else {
  52. layers.push({ label: config, patches: loadOverlayPatches(NAME, config) })
  53. }
  54. }
  55. process.stdout.write(renderConfigDump(NAME, BASE_CONFIG, layers))
  56. }
  57. /* v8 ignore stop */