paths.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import { existsSync, mkdirSync } from 'node:fs';
  2. import { homedir } from 'node:os';
  3. import { dirname, join } from 'node:path';
  4. function getDefaultOpenCodeConfigDir(): string {
  5. const userConfigDir = process.env.XDG_CONFIG_HOME
  6. ? process.env.XDG_CONFIG_HOME
  7. : join(homedir(), '.config');
  8. return join(userConfigDir, 'opencode');
  9. }
  10. function getCustomOpenCodeConfigDir(): string | undefined {
  11. const configDir = process.env.OPENCODE_CONFIG_DIR?.trim();
  12. return configDir || undefined;
  13. }
  14. /**
  15. * Get the OpenCode plugin config directory.
  16. *
  17. * Resolution order:
  18. * 1. OPENCODE_CONFIG_DIR (custom OpenCode directory)
  19. * 2. XDG_CONFIG_HOME/opencode
  20. * 3. ~/.config/opencode
  21. */
  22. export function getConfigDir(): string {
  23. const customConfigDir = getCustomOpenCodeConfigDir();
  24. if (customConfigDir) {
  25. return customConfigDir;
  26. }
  27. return getDefaultOpenCodeConfigDir();
  28. }
  29. /**
  30. * Get OpenCode config directories in read/search order.
  31. *
  32. * Resolution order:
  33. * 1. OPENCODE_CONFIG_DIR (if set)
  34. * 2. XDG_CONFIG_HOME/opencode or ~/.config/opencode
  35. *
  36. * Duplicate entries are removed.
  37. */
  38. export function getConfigSearchDirs(): string[] {
  39. const dirs = [getCustomOpenCodeConfigDir(), getDefaultOpenCodeConfigDir()];
  40. return dirs.filter((dir, index): dir is string => {
  41. return Boolean(dir) && dirs.indexOf(dir) === index;
  42. });
  43. }
  44. export function getOpenCodeConfigPaths(): string[] {
  45. const configDir = getDefaultOpenCodeConfigDir();
  46. return [join(configDir, 'opencode.json'), join(configDir, 'opencode.jsonc')];
  47. }
  48. export function getConfigJson(): string {
  49. return getOpenCodeConfigPaths()[0];
  50. }
  51. export function getConfigJsonc(): string {
  52. return getOpenCodeConfigPaths()[1];
  53. }
  54. export function getLiteConfig(): string {
  55. return join(getConfigDir(), 'oh-my-opencode-slim.json');
  56. }
  57. export function getLiteConfigJsonc(): string {
  58. return join(getConfigDir(), 'oh-my-opencode-slim.jsonc');
  59. }
  60. export function getExistingLiteConfigPath(): string {
  61. const jsonPath = getLiteConfig();
  62. if (existsSync(jsonPath)) return jsonPath;
  63. const jsoncPath = getLiteConfigJsonc();
  64. if (existsSync(jsoncPath)) return jsoncPath;
  65. return jsonPath;
  66. }
  67. export function getExistingConfigPath(): string {
  68. const jsonPath = getConfigJson();
  69. if (existsSync(jsonPath)) return jsonPath;
  70. const jsoncPath = getConfigJsonc();
  71. if (existsSync(jsoncPath)) return jsoncPath;
  72. return jsonPath;
  73. }
  74. export function ensureConfigDir(): void {
  75. const configDir = getConfigDir();
  76. if (!existsSync(configDir)) {
  77. mkdirSync(configDir, { recursive: true });
  78. }
  79. }
  80. /**
  81. * Ensure the directory for OpenCode's main config file exists.
  82. */
  83. export function ensureOpenCodeConfigDir(): void {
  84. const configDir = dirname(getConfigJson());
  85. if (!existsSync(configDir)) {
  86. mkdirSync(configDir, { recursive: true });
  87. }
  88. }