load-config.sh 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #!/bin/bash
  2. # load-config.sh - Load .oac configuration file
  3. # Searches for .oac in current directory, then ~/.oac
  4. # Exports configuration as environment variables
  5. set -euo pipefail
  6. # Find config file
  7. CONFIG_FILE=""
  8. if [[ -f ".oac" ]]; then
  9. CONFIG_FILE=".oac"
  10. elif [[ -f "${HOME}/.oac" ]]; then
  11. CONFIG_FILE="${HOME}/.oac"
  12. fi
  13. # If no config file found, return defaults
  14. if [[ -z "$CONFIG_FILE" ]]; then
  15. cat <<EOF
  16. {
  17. "status": "no_config",
  18. "message": "No .oac config file found. Using defaults.",
  19. "config": {
  20. "version": "1.0",
  21. "context": {
  22. "auto_download": false,
  23. "categories": ["core", "openagents-repo"],
  24. "update_check": true,
  25. "cache_days": 7
  26. },
  27. "cleanup": {
  28. "auto_prompt": true,
  29. "session_days": 7,
  30. "task_days": 30,
  31. "external_days": 7
  32. },
  33. "workflow": {
  34. "auto_approve": false,
  35. "verbose": false
  36. },
  37. "external_scout": {
  38. "enabled": true,
  39. "cache_enabled": true,
  40. "sources": ["context7"]
  41. }
  42. }
  43. }
  44. EOF
  45. exit 0
  46. fi
  47. # Parse config file (simple key-value parsing)
  48. declare -A CONFIG
  49. while IFS= read -r line; do
  50. # Skip comments and empty lines
  51. if [[ "$line" =~ ^[[:space:]]*# ]] || [[ -z "$line" ]]; then
  52. continue
  53. fi
  54. # Parse key: value pairs
  55. if [[ "$line" =~ ^([a-z_\.]+):[[:space:]]*(.+)$ ]]; then
  56. key="${BASH_REMATCH[1]}"
  57. value="${BASH_REMATCH[2]}"
  58. # Trim quotes from value
  59. value="${value#\"}"
  60. value="${value%\"}"
  61. value="${value# }"
  62. value="${value% }"
  63. CONFIG["$key"]="$value"
  64. fi
  65. done < "$CONFIG_FILE"
  66. # Helper function to get config value with default
  67. get_config() {
  68. local key=$1
  69. local default=$2
  70. echo "${CONFIG[$key]:-$default}"
  71. }
  72. # Helper function to convert string to boolean JSON
  73. to_bool() {
  74. local value=$1
  75. if [[ "$value" == "true" ]] || [[ "$value" == "yes" ]] || [[ "$value" == "1" ]]; then
  76. echo "true"
  77. else
  78. echo "false"
  79. fi
  80. }
  81. # Helper function to convert comma-separated string to JSON array
  82. to_array() {
  83. local value=$1
  84. local items=()
  85. IFS=',' read -ra items <<< "$value"
  86. local json_array="["
  87. local first=true
  88. for item in "${items[@]}"; do
  89. item="${item# }"
  90. item="${item% }"
  91. if [[ "$first" == "true" ]]; then
  92. first=false
  93. else
  94. json_array+=", "
  95. fi
  96. json_array+="\"$item\""
  97. done
  98. json_array+="]"
  99. echo "$json_array"
  100. }
  101. # Extract configuration values
  102. VERSION=$(get_config "version" "1.0")
  103. # Context settings
  104. CONTEXT_AUTO_DOWNLOAD=$(to_bool "$(get_config "context.auto_download" "false")")
  105. CONTEXT_CATEGORIES=$(to_array "$(get_config "context.categories" "core,openagents-repo")")
  106. CONTEXT_UPDATE_CHECK=$(to_bool "$(get_config "context.update_check" "true")")
  107. CONTEXT_CACHE_DAYS=$(get_config "context.cache_days" "7")
  108. # Cleanup settings
  109. CLEANUP_AUTO_PROMPT=$(to_bool "$(get_config "cleanup.auto_prompt" "true")")
  110. CLEANUP_SESSION_DAYS=$(get_config "cleanup.session_days" "7")
  111. CLEANUP_TASK_DAYS=$(get_config "cleanup.task_days" "30")
  112. CLEANUP_EXTERNAL_DAYS=$(get_config "cleanup.external_days" "7")
  113. # Workflow settings
  114. WORKFLOW_AUTO_APPROVE=$(to_bool "$(get_config "workflow.auto_approve" "false")")
  115. WORKFLOW_VERBOSE=$(to_bool "$(get_config "workflow.verbose" "false")")
  116. # External scout settings
  117. EXTERNAL_SCOUT_ENABLED=$(to_bool "$(get_config "external_scout.enabled" "true")")
  118. EXTERNAL_SCOUT_CACHE_ENABLED=$(to_bool "$(get_config "external_scout.cache_enabled" "true")")
  119. EXTERNAL_SCOUT_SOURCES=$(to_array "$(get_config "external_scout.sources" "context7")")
  120. # Validate configuration
  121. VALIDATION_ERRORS=()
  122. # Validate version
  123. if [[ "$VERSION" != "1.0" ]]; then
  124. VALIDATION_ERRORS+=("Invalid version: $VERSION (expected 1.0)")
  125. fi
  126. # Validate numeric values
  127. if ! [[ "$CONTEXT_CACHE_DAYS" =~ ^[0-9]+$ ]]; then
  128. VALIDATION_ERRORS+=("Invalid context.cache_days: must be a number")
  129. fi
  130. if ! [[ "$CLEANUP_SESSION_DAYS" =~ ^[0-9]+$ ]]; then
  131. VALIDATION_ERRORS+=("Invalid cleanup.session_days: must be a number")
  132. fi
  133. if ! [[ "$CLEANUP_TASK_DAYS" =~ ^[0-9]+$ ]]; then
  134. VALIDATION_ERRORS+=("Invalid cleanup.task_days: must be a number")
  135. fi
  136. if ! [[ "$CLEANUP_EXTERNAL_DAYS" =~ ^[0-9]+$ ]]; then
  137. VALIDATION_ERRORS+=("Invalid cleanup.external_days: must be a number")
  138. fi
  139. # If validation errors, output error JSON
  140. if [[ ${#VALIDATION_ERRORS[@]} -gt 0 ]]; then
  141. ERRORS_JSON="["
  142. first=true
  143. for error in "${VALIDATION_ERRORS[@]}"; do
  144. if [[ "$first" == "true" ]]; then
  145. first=false
  146. else
  147. ERRORS_JSON+=", "
  148. fi
  149. ERRORS_JSON+="\"$error\""
  150. done
  151. ERRORS_JSON+="]"
  152. cat <<EOF
  153. {
  154. "status": "validation_error",
  155. "message": "Configuration validation failed",
  156. "errors": $ERRORS_JSON,
  157. "configFile": "$CONFIG_FILE"
  158. }
  159. EOF
  160. exit 1
  161. fi
  162. # Export as environment variables
  163. export OAC_CONTEXT_AUTO_DOWNLOAD="$CONTEXT_AUTO_DOWNLOAD"
  164. export OAC_CONTEXT_CATEGORIES="$(get_config "context.categories" "core,openagents-repo")"
  165. export OAC_CONTEXT_UPDATE_CHECK="$CONTEXT_UPDATE_CHECK"
  166. export OAC_CONTEXT_CACHE_DAYS="$CONTEXT_CACHE_DAYS"
  167. export OAC_CLEANUP_AUTO_PROMPT="$CLEANUP_AUTO_PROMPT"
  168. export OAC_CLEANUP_SESSION_DAYS="$CLEANUP_SESSION_DAYS"
  169. export OAC_CLEANUP_TASK_DAYS="$CLEANUP_TASK_DAYS"
  170. export OAC_CLEANUP_EXTERNAL_DAYS="$CLEANUP_EXTERNAL_DAYS"
  171. export OAC_WORKFLOW_AUTO_APPROVE="$WORKFLOW_AUTO_APPROVE"
  172. export OAC_WORKFLOW_VERBOSE="$WORKFLOW_VERBOSE"
  173. export OAC_EXTERNAL_SCOUT_ENABLED="$EXTERNAL_SCOUT_ENABLED"
  174. export OAC_EXTERNAL_SCOUT_CACHE_ENABLED="$EXTERNAL_SCOUT_CACHE_ENABLED"
  175. export OAC_EXTERNAL_SCOUT_SOURCES="$(get_config "external_scout.sources" "context7")"
  176. # Output JSON with loaded config
  177. cat <<EOF
  178. {
  179. "status": "success",
  180. "message": "Configuration loaded successfully",
  181. "configFile": "$CONFIG_FILE",
  182. "config": {
  183. "version": "$VERSION",
  184. "context": {
  185. "auto_download": $CONTEXT_AUTO_DOWNLOAD,
  186. "categories": $CONTEXT_CATEGORIES,
  187. "update_check": $CONTEXT_UPDATE_CHECK,
  188. "cache_days": $CONTEXT_CACHE_DAYS
  189. },
  190. "cleanup": {
  191. "auto_prompt": $CLEANUP_AUTO_PROMPT,
  192. "session_days": $CLEANUP_SESSION_DAYS,
  193. "task_days": $CLEANUP_TASK_DAYS,
  194. "external_days": $CLEANUP_EXTERNAL_DAYS
  195. },
  196. "workflow": {
  197. "auto_approve": $WORKFLOW_AUTO_APPROVE,
  198. "verbose": $WORKFLOW_VERBOSE
  199. },
  200. "external_scout": {
  201. "enabled": $EXTERNAL_SCOUT_ENABLED,
  202. "cache_enabled": $EXTERNAL_SCOUT_CACHE_ENABLED,
  203. "sources": $EXTERNAL_SCOUT_SOURCES
  204. }
  205. }
  206. }
  207. EOF