///|
const SUITE_STATUS_FILE = "suite-status.json"

///|
fn moongate_product_state_path(root : String, product_id : String) -> String {
  @moonsuite.product_home_for_workspace_root(root, product_id).state_path
}

///|
fn moongate_product_tmp_path(root : String, product_id : String) -> String {
  @moonsuite.product_home_for_workspace_root(root, product_id).tmp_path
}

///|
fn moongate_product_artifact_path(
  root : String,
  product_id : String,
  relative_path : String,
) -> String {
  @moonsuite.product_artifact_for_workspace_root(
    root, product_id, relative_path,
  )
}

///|
priv struct SuiteLegacyDriftCandidate {
  product : String
  legacy_path : String
  probe_path : String
  canonical_path : String
  scope : String
  reason : String
}

///|
fn moongate_moonclaw_providers_file() -> String {
  moongate_moonclaw_providers_file_for_workspace_root(
    moongate_active_workspace_root(),
  )
}

///|
fn moongate_moonclaw_providers_file_for_workspace_root(root : String) -> String {
  @moonsuite.product_artifact_for_workspace_root(
    root, "moonclaw", "providers.json",
  )
}

///|
fn moongate_moonclaw_models_file() -> String {
  moongate_moonclaw_models_file_for_workspace_root(
    moongate_active_workspace_root(),
  )
}

///|
fn moongate_moonclaw_models_file_for_workspace_root(root : String) -> String {
  @moonsuite.product_artifact_for_workspace_root(
    root, "moonclaw", "models/models.json",
  )
}

///|
fn moongate_moonclaw_config_file() -> String {
  moongate_moonclaw_config_file_for_workspace_root(
    moongate_active_workspace_root(),
  )
}

///|
fn moongate_moonclaw_config_file_for_workspace_root(root : String) -> String {
  @moonsuite.product_artifact_for_workspace_root(
    root, "moonclaw", "moonclaw.json",
  )
}

///|
pub fn moongate_moonflow_adapter_capability_json() -> Json {
  {
    "adapter_id": "moongate-v1",
    "product_id": "moongate",
    "protocol": "moonflow.adapter.v1",
    "operations": [
      "capability-probe", "route-ai-request", "record-ai-session", "reconcile-usage",
    ],
    "authority_classes": [
      "observe", "cognitive-maintenance", "sandbox-execution", "workspace-mutation",
    ],
    "supports_cancel": false,
    "supports_reconcile": true,
    "receipt_contracts": [
      "moongate.ai-session.v1", "moongate.route-receipt.v1", "moongate.usage-receipt.v1",
    ],
    "fallback_visible": true,
    "usage_visible": true,
    "redaction_required": true,
  }
}

///|
pub fn moongate_suite_manifest_json(
  host? : String = @suite.default_host(),
  port? : Int = @suite.default_port(),
  model? : String = @suite.default_model(),
) -> Json {
  let manifest = {
    "contract": Json::string(@suite.manifest_contract()),
    "service": Json::string(@suite.service_name()),
    "project": Json::string(@suite.project_name()),
    "version": Json::string(@suite.version()),
    "role": Json::string("network-edge"),
    "defaultHost": Json::string(@suite.normalize_host(host)),
    "defaultPort": Json::number(port.to_double()),
    "baseUrl": Json::string(moongate_base_url(host, port)),
    "openaiBaseUrl": Json::string(moongate_openai_base_url(host, port)),
    "anthropicBaseUrl": Json::string(moongate_base_url(host, port)),
    "claudeDesktopBaseUrl": Json::string(
      moongate_claude_desktop_base_url(host, port),
    ),
    "defaultModel": if model.trim().is_empty() {
      Json::null()
    } else {
      Json::string(model)
    },
    "statusFile": Json::string(default_moongate_suite_status_path()),
    "capabilities": moongate_suite_capabilities_json(),
    "moonflowAdapter": moongate_moonflow_adapter_capability_json(),
    "modelsUrl": Json::string("\{moongate_openai_base_url(host, port)}/models"),
    "routes": Json::array(
      moongate_suite_routes().map(fn(route) { Json::string(route) }),
    ),
    "frameworkApps": moongate_framework_apps_json(),
    "uiSections": moongate_ui_sections_json(),
    "uiEndpoints": moongate_ui_endpoints_json(),
    "uiReadinessCards": moongate_ui_readiness_cards_json(),
    "apps": Json::array([
      suite_app_json(
        "moondesk",
        "primary-operator-shell",
        "Use MoonDesk as the preferred desktop control surface for gateway health, provider setup, model catalog, and traffic counters.",
        priority=0,
      ),
      suite_app_json(
        "moonclaw",
        "agent-runtime",
        "Use moongate as the OpenAI-compatible or Anthropic-compatible local edge for agent provider calls.",
        priority=10,
      ),
      suite_app_json(
        "moonbook",
        "durable-output",
        "Store generated reports and proxy usage summaries outside moongate.",
        priority=20,
      ),
      suite_app_json(
        "moontown",
        "scheduler-control-plane",
        "Watch moongate health/status/stats as the network edge for standing goals.",
        priority=30,
      ),
    ]),
    "agentClients": moongate_suite_agent_clients_json(host, port, model),
    "suiteIntegrations": moongate_suite_integrations_json(host, port, model),
    "commands": moongate_suite_commands_json(port, model),
    "cli": moongate_suite_commands_json(port, model),
  }
  moongate_merge_suite_fields(
    manifest,
    moongate_suite_shared_fields(host, port),
  )
  Json::object(manifest)
}

///|
pub fn moongate_suite_status_json(
  host? : String = @suite.default_host(),
  port? : Int = @suite.default_port(),
  model? : String = @suite.default_model(),
  status? : String = "configured",
  ready? : Bool = true,
) -> Json {
  let status_json = {
    "contract": Json::string(@suite.status_contract()),
    "modelRouteContract": Json::string(@pipeline.ModelRoute.id()),
    "runReceiptContract": Json::string(@pipeline.RunReceipt.id()),
    "service": Json::string(@suite.service_name()),
    "status": Json::string(status),
    "ready": Json::boolean(ready),
    "manifest": moongate_suite_manifest_json(host~, port~, model~),
    "statusPath": Json::string(default_moongate_suite_status_path()),
  }
  Json::object(status_json)
}

///|
pub async fn moongate_suite_drift_report_json(
  suite_root? : String = ".",
  global_tmp_root? : String = "/tmp",
) -> Json {
  let root = moongate_normalize_suite_root(suite_root)
  let global_tmp = moongate_trim_root(global_tmp_root)
  let findings = []
  for candidate in moongate_suite_legacy_drift_candidates(root, global_tmp) {
    let detected = @fsx.exists(candidate.probe_path)
    findings.push(
      moongate_suite_drift_finding_json(
        candidate.product,
        candidate.legacy_path,
        candidate.probe_path,
        candidate.canonical_path,
        candidate.scope,
        candidate.reason,
        detected,
      ),
    )
  }
  Json::object({
    "contract": Json::string("moongate.suite.drift.v1"),
    "suiteRoot": Json::string(root),
    "contractSource": Json::string("vectie/moonlib/moonsuite"),
    "role": Json::string("validator-reporter"),
    "globalTmpRoot": Json::string(global_tmp),
    "canonical": moongate_suite_canonical_paths_json(root),
    "findings": Json::array(findings),
    "summary": Json::object({
      "total": Json::number(findings.length().to_double()),
      "detected": Json::number(
        findings
        .filter(fn(finding) {
          match finding {
            Object(obj) => obj["detected"] == Json::boolean(true)
            _ => false
          }
        })
        .length()
        .to_double(),
      ),
    }),
  })
}

///|
fn moongate_trim_root(root : String) -> String {
  let trimmed = root.trim().to_owned()
  if trimmed == "" {
    "."
  } else {
    trimmed
  }
}

///|
fn moongate_normalize_suite_root(root : String) -> String {
  let workspace_root = moongate_trim_root(root)
  @moonsuite.suite_root_for_workspace_root(workspace_root)
}

///|
fn moongate_suite_canonical_paths_json(root : String) -> Json {
  let suite_root = moongate_normalize_suite_root(root)
  Json::object({
    "suiteState": Json::string(@moonsuite.state_dir(suite_root)),
    "books": Json::string(@moonsuite.books_root(suite_root)),
    "tmp": Json::string(@moonsuite.tmp_root(suite_root)),
    "productRegistry": Json::string(
      @moonsuite.product_registry_path(suite_root),
    ),
    "moondeskHome": Json::string(
      moongate_product_state_path(suite_root, "moondesk"),
    ),
    "moonbookHome": Json::string(
      moongate_product_state_path(suite_root, "moonbook"),
    ),
    "moonwikiHome": Json::string(
      moongate_product_state_path(suite_root, "moonwiki"),
    ),
    "mooncodeHome": Json::string(
      moongate_product_state_path(suite_root, "mooncode"),
    ),
    "moongateHome": Json::string(
      moongate_product_state_path(suite_root, "moongate"),
    ),
    "moonclawHome": Json::string(
      moongate_product_state_path(suite_root, "moonclaw"),
    ),
    "moontownHome": Json::string(
      moongate_product_state_path(suite_root, "moontown"),
    ),
    "moonroboHome": Json::string(
      moongate_product_state_path(suite_root, "moonrobo"),
    ),
    "moonfishHome": Json::string(
      moongate_product_state_path(suite_root, "moonfish"),
    ),
    "moonmoonHome": Json::string(
      moongate_product_state_path(suite_root, "moonmoon"),
    ),
    "moonchatHome": Json::string(
      moongate_product_state_path(suite_root, "moonchat"),
    ),
    "moonvisHome": Json::string(
      moongate_product_state_path(suite_root, "moonvis"),
    ),
    "bookkeeperHome": Json::string(
      moongate_product_state_path(suite_root, "bookkeeper"),
    ),
    "lepusaHome": Json::string(
      moongate_product_state_path(suite_root, "lepusa"),
    ),
    "rabbitaHome": Json::string(
      moongate_product_state_path(suite_root, "rabbita"),
    ),
    "moonroboGatewayCommands": Json::string(
      moongate_product_artifact_path(suite_root, "moonrobo", "gateway-commands"),
    ),
    "moonroboRoboLoops": Json::string(
      moongate_product_artifact_path(suite_root, "moonrobo", "robo-loops"),
    ),
    "moonroboProofSessions": Json::string(
      moongate_product_artifact_path(suite_root, "moonrobo", "proof-sessions"),
    ),
    "moonroboSdkE1Snapshot": Json::string(
      @pathx.join(
        moongate_product_tmp_path(suite_root, "moonrobo"),
        "sdk-e1/snapshot.json",
      ),
    ),
    "moonroboSdkE1Command": Json::string(
      @pathx.join(
        moongate_product_tmp_path(suite_root, "moonrobo"),
        "sdk-e1/command.json",
      ),
    ),
    "moonclawProviders": Json::string(
      moongate_product_artifact_path(suite_root, "moonclaw", "providers.json"),
    ),
    "moonclawModels": Json::string(
      moongate_product_artifact_path(
        suite_root, "moonclaw", "models/models.json",
      ),
    ),
    "moonclawConfig": Json::string(
      moongate_product_artifact_path(suite_root, "moonclaw", "moonclaw.json"),
    ),
    "mooncodeSessions": Json::string(
      moongate_product_artifact_path(
        suite_root, "moonclaw", "mooncode/sessions",
      ),
    ),
  })
}

///|
async fn moongate_suite_legacy_drift_candidates(
  root : String,
  global_tmp_root : String,
) -> Array[SuiteLegacyDriftCandidate] {
  let candidates = [
    moongate_suite_root_drift_candidate(
      root,
      "moontown",
      ".moontown",
      moongate_product_state_path(root, "moontown"),
      "MoonTown runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moondesk",
      ".moondesk",
      moongate_product_state_path(root, "moondesk"),
      "MoonDesk runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonbook",
      ".moonbook",
      moongate_product_state_path(root, "moonbook"),
      "MoonBook runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonwiki",
      ".moonwiki",
      moongate_product_state_path(root, "moonwiki"),
      "MoonWiki runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "mooncode",
      ".mooncode",
      moongate_product_state_path(root, "mooncode"),
      "MoonCode runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonclaw",
      ".moonclaw",
      moongate_product_state_path(root, "moonclaw"),
      "MoonClaw runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moondesk",
      ".moontown/moondesk-daemon",
      moongate_product_state_path(root, "moondesk"),
      "MoonDesk daemon state belongs under the MoonDesk product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonclaw",
      "moonclaw-jobs",
      moongate_product_artifact_path(root, "moonclaw", "jobs"),
      "MoonClaw jobs belong under the MoonClaw product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moongate",
      "moongate",
      moongate_product_state_path(root, "moongate"),
      "MoonGate state belongs under the MoonGate product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonfish",
      ".moonfish",
      moongate_product_state_path(root, "moonfish"),
      "MoonFish runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonmoon",
      ".moonmoon",
      moongate_product_state_path(root, "moonmoon"),
      "MoonMoon runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonchat",
      ".moonchat",
      moongate_product_state_path(root, "moonchat"),
      "MoonChat runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonvis",
      ".moonvis",
      moongate_product_state_path(root, "moonvis"),
      "MoonVis runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "bookkeeper",
      ".bookkeeper",
      moongate_product_state_path(root, "bookkeeper"),
      "Bookkeeper runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "lepusa",
      ".lepusa",
      moongate_product_state_path(root, "lepusa"),
      "Lepusa runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "rabbita",
      ".rabbita",
      moongate_product_state_path(root, "rabbita"),
      "Rabbita runtime state belongs under the MoonSuite product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonrobo",
      "runs/gateway-commands",
      moongate_product_artifact_path(root, "moonrobo", "gateway-commands"),
      "MoonRobo gateway commands belong under the MoonRobo product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonrobo",
      "runs/robo-loops",
      moongate_product_artifact_path(root, "moonrobo", "robo-loops"),
      "MoonRobo loop artifacts belong under the MoonRobo product home.",
    ),
    moongate_suite_root_drift_candidate(
      root,
      "moonrobo",
      "runs/proof-sessions",
      moongate_product_artifact_path(root, "moonrobo", "proof-sessions"),
      "MoonRobo proof sessions belong under the MoonRobo product home.",
    ),
    moongate_suite_global_tmp_drift_candidate(
      global_tmp_root,
      "moonrobo",
      "moonrobo-sdk-e1-bridge-snapshot-test.json",
      @pathx.join(
        moongate_product_tmp_path(root, "moonrobo"),
        "sdk-e1/snapshot.json",
      ),
      "MoonRobo SDK E1 snapshots belong under the suite product tmp home.",
    ),
    moongate_suite_global_tmp_drift_candidate(
      global_tmp_root,
      "moonrobo",
      "moonrobo-sdk-e1-bridge-command-test.json",
      @pathx.join(
        moongate_product_tmp_path(root, "moonrobo"),
        "sdk-e1/command.json",
      ),
      "MoonRobo SDK E1 commands belong under the suite product tmp home.",
    ),
  ]
  for candidate in moongate_suite_book_drift_candidates(root) {
    candidates.push(candidate)
  }
  candidates
}

///|
async fn moongate_suite_book_drift_candidates(
  root : String,
) -> Array[SuiteLegacyDriftCandidate] {
  let books_root = @moonsuite.books_root(root)
  if !@fsx.exists(books_root) {
    return []
  }
  let entries = @fsx.list_directory(books_root) catch { _ => return [] }
  let candidates : Array[SuiteLegacyDriftCandidate] = []
  for entry in entries {
    let book_root = entry.path
    let book_id = @pathx.basename(book_root).to_owned()
    candidates.push(
      moongate_suite_book_drift_candidate(
        book_root,
        book_id,
        "moonclaw",
        ".moonclaw/providers.json",
        @moonsuite.product_artifact_for_workspace_root(
          book_root, "moonclaw", "providers.json",
        ),
        "Book-local MoonClaw provider manifests belong under the MoonClaw product home.",
      ),
    )
    candidates.push(
      moongate_suite_book_drift_candidate(
        book_root,
        book_id,
        "moonclaw",
        ".moonclaw/mooncode/sessions",
        @moonsuite.product_artifact_for_workspace_root(
          book_root, "moonclaw", "mooncode/sessions",
        ),
        "Book-local MoonCode sidecar sessions belong under the MoonClaw product home.",
      ),
    )
  }
  candidates
}

///|
fn moongate_suite_book_drift_candidate(
  book_root : String,
  book_id : String,
  product : String,
  legacy_relative_path : String,
  canonical_path : String,
  reason : String,
) -> SuiteLegacyDriftCandidate {
  let legacy_path = @pathx.join(
    @pathx.join("books", book_id),
    legacy_relative_path,
  )
  {
    product,
    legacy_path,
    probe_path: @pathx.join(book_root, legacy_relative_path),
    canonical_path,
    scope: "book-root",
    reason,
  }
}

///|
fn moongate_suite_root_drift_candidate(
  root : String,
  product : String,
  legacy_path : String,
  canonical_path : String,
  reason : String,
) -> SuiteLegacyDriftCandidate {
  {
    product,
    legacy_path,
    probe_path: @pathx.join(root, legacy_path),
    canonical_path,
    scope: "suite-root",
    reason,
  }
}

///|
fn moongate_suite_global_tmp_drift_candidate(
  global_tmp_root : String,
  product : String,
  legacy_filename : String,
  canonical_path : String,
  reason : String,
) -> SuiteLegacyDriftCandidate {
  let probe_path = @pathx.join(global_tmp_root, legacy_filename)
  {
    product,
    legacy_path: probe_path,
    probe_path,
    canonical_path,
    scope: "global-tmp",
    reason,
  }
}

///|
fn moongate_suite_drift_finding_json(
  product : String,
  legacy_path : String,
  probe_path : String,
  canonical_path : String,
  scope : String,
  reason : String,
  detected : Bool,
) -> Json {
  Json::object({
    "product": Json::string(product),
    "status": Json::string(if detected { "drift" } else { "clear" }),
    "detected": Json::boolean(detected),
    "legacyPath": Json::string(legacy_path),
    "probePath": Json::string(probe_path),
    "canonicalPath": Json::string(canonical_path),
    "scope": Json::string(scope),
    "source": Json::string("moongate"),
    "contractSource": Json::string("vectie/moonlib/moonsuite"),
    "reason": Json::string(reason),
  })
}

///|
pub async fn write_moongate_suite_status(
  path? : String = default_moongate_suite_status_path(),
  host? : String = @suite.default_host(),
  port? : Int = @suite.default_port(),
  model? : String = @suite.default_model(),
  status? : String = "configured",
  ready? : Bool = true,
) -> String {
  let dir = @pathx.dirname(path)
  @fsx.make_directory(dir, recursive=true, exists_ok=true)
  let json = moongate_suite_status_json(host~, port~, model~, status~, ready~).stringify(
    indent=2,
  )
  @fsx.write_to_file(path, json)
  path
}

///|
pub fn default_moongate_suite_status_path() -> String {
  default_moongate_suite_status_path_for_workspace_root(
    moongate_active_workspace_root(),
  )
}

///|
pub fn default_moongate_suite_status_path_for_workspace_root(
  root : String,
) -> String {
  @pathx.join(
    @moonsuite.state_dir(@moonsuite.suite_root_for_workspace_root(root)),
    SUITE_STATUS_FILE,
  )
}

///|
fn default_moongate_dir() -> String {
  moongate_product_home_for_workspace_root(moongate_active_workspace_root())
}

///|
fn moongate_active_workspace_root() -> String {
  let configured = @os.getenv("MOONSUITE_WORKSPACE_ROOT") catch { _ => None }
  match configured {
    Some(root) if !root.trim().is_empty() => root
    _ => {
      let app_data = @os.getenv("LEPUSA_APP_DATA_DIR") catch { _ => None }
      match app_data {
        Some(root) if !root.trim().is_empty() => root
        _ => @os.cwd() catch { _ => "." }
      }
    }
  }
}

///|
pub fn moongate_product_home_for_workspace_root(root : String) -> String {
  @moonsuite.product_home_for_workspace_root(root, "moongate").state_path
}

///|
fn moongate_suite_capabilities_json() -> Json {
  Json::array(
    moongate_suite_capabilities().map(fn(capability) {
      Json::string(capability)
    }),
  )
}

///|
fn moongate_suite_shared_fields(host : String, port : Int) -> Map[String, Json] {
  let base_url = moongate_base_url(host, port)
  {
    "healthUrl": Json::string("\{base_url}/health"),
    "statusUrl": Json::string("\{base_url}/status"),
    "statsUrl": Json::string("\{base_url}/stats"),
    "metricsUrl": Json::string("\{base_url}/metrics"),
    "dashboardUrl": Json::string("\{base_url}/"),
    "usageLogsUrl": Json::string("\{base_url}/usage/logs"),
    "usageSummaryUrl": Json::string("\{base_url}/usage/summary"),
    "usageSummaryByAppUrl": Json::string("\{base_url}/usage/summary/by-app"),
    "usageTrendsUrl": Json::string("\{base_url}/usage/trends"),
    "usageProviderLimitsUrl": Json::string("\{base_url}/usage/provider-limits"),
    "usageProviderStatsUrl": Json::string("\{base_url}/usage/provider-stats"),
    "usageModelStatsUrl": Json::string("\{base_url}/usage/model-stats"),
    "usageDataSourcesUrl": Json::string("\{base_url}/usage/data-sources"),
    "usageSyncSessionUrl": Json::string("\{base_url}/usage/sync-session"),
    "usageModelPricingUrl": Json::string("\{base_url}/usage/model-pricing"),
    "providerPresetsUrl": Json::string("\{base_url}/providers/presets"),
    "usageRequestDetailUrl": Json::string(
      "\{base_url}/usage/request-detail/{request_id}",
    ),
    "streamCheckProviderUrl": Json::string(
      "\{base_url}/proxy/stream-check/provider",
    ),
    "streamCheckAllProvidersUrl": Json::string(
      "\{base_url}/proxy/stream-check/all",
    ),
    "streamCheckConfigUrl": Json::string(
      "\{base_url}/proxy/stream-check/config",
    ),
    "configStatusUrl": Json::string("\{base_url}/config/status"),
    "usageStoreDir": Json::string(default_moongate_stats_dir()),
    "usageRequestLogsFile": Json::string(
      @pathx.join(default_moongate_stats_dir(), MOONGATE_REQUEST_LOGS_FILE),
    ),
    "usageSessionSyncFile": Json::string(
      @pathx.join(default_moongate_stats_dir(), MOONGATE_SESSION_SYNC_FILE),
    ),
    "usageModelPricingFile": Json::string(
      @pathx.join(default_moongate_stats_dir(), MOONGATE_MODEL_PRICING_FILE),
    ),
    "usageOpencodeDbFile": Json::string(default_opencode_db_path()),
    "usageOpencodeExportFile": Json::string(default_opencode_export_path()),
  }
}

///|
fn moongate_merge_suite_fields(
  target : Map[String, Json],
  fields : Map[String, Json],
) -> Unit {
  for key in fields.keys() {
    match fields.get(key) {
      Some(value) => target[key] = value
      None => ()
    }
  }
}

///|
fn moongate_base_url(host : String, port : Int) -> String {
  @suite.base_url(host, port)
}

///|
fn moongate_openai_base_url(host : String, port : Int) -> String {
  @suite.openai_base_url(host, port)
}

///|
fn moongate_claude_desktop_base_url(host : String, port : Int) -> String {
  @suite.claude_desktop_base_url(host, port)
}

///|
fn suite_app_json(
  id : String,
  role : String,
  usage : String,
  priority? : Int = 100,
) -> Json {
  Json::object({
    "id": Json::string(id),
    "role": Json::string(role),
    "usage": Json::string(usage),
    "priority": Json::number(priority.to_double()),
  })
}

///|
fn moongate_suite_agent_clients_json(
  host : String,
  port : Int,
  model : String,
) -> Json {
  let base_url = moongate_base_url(host, port)
  let openai_base_url = moongate_openai_base_url(host, port)
  let claude_desktop_base_url = moongate_claude_desktop_base_url(host, port)
  let codex_install = if model.trim().is_empty() {
    "moongate codex install --port \{port} --model "
  } else {
    "moongate codex install --port \{port} --model \{model}"
  }
  Json::array([
    suite_agent_client_json(
      "codex", "codex", "openai-responses", openai_base_url, "POST /v1/responses",
      codex_install, "Codex config.toml managed provider block using the Responses API.",
    ),
    suite_agent_client_json(
      "claude-code", "claude", "anthropic-compatible", base_url, "POST /v1/messages",
      "", "Claude Code and Anthropic-compatible clients using MoonGate provider routing.",
    ),
    suite_agent_client_json(
      "claude-desktop",
      "claude-desktop",
      "anthropic-compatible",
      claude_desktop_base_url,
      "POST /claude-desktop/v1/messages",
      "moongate claude-desktop install --port \{port}",
      "Claude Desktop gateway profile with optional local bearer token.",
    ),
    suite_agent_client_json(
      "openclaw",
      "openclaw",
      "openai-compatible",
      "\{base_url}/openclaw/v1",
      "POST /openclaw/v1/chat/completions",
      "moongate provider openclaw import-live",
      "OpenClaw chat completions and OpenClaw config/provider management routes.",
    ),
    suite_agent_client_json(
      "opencode", "opencode", "openai-compatible", openai_base_url, "POST /v1/chat/completions",
      "moongate provider opencode import-live", "OpenCode provider import, proxy routing, and session usage sync.",
    ),
    suite_agent_client_json(
      "gemini",
      "gemini",
      "gemini-compatible",
      "\{base_url}/gemini",
      "ANY /gemini/v1beta/*path",
      "",
      "Gemini-compatible proxy routes with native usage accounting.",
    ),
    suite_agent_client_json(
      "github-copilot", "copilot", "copilot-auth", base_url, "GET /copilot/models",
      "moongate copilot login", "GitHub Copilot OAuth, model catalog, token, and usage endpoints.",
    ),
    suite_agent_client_json(
      "openai-compatible", "codex", "openai-compatible", openai_base_url, "POST /v1/chat/completions",
      "", "Generic OpenAI-compatible clients using MoonGate as the local provider edge.",
    ),
  ])
}

///|
fn suite_agent_client_json(
  id : String,
  app_type : String,
  protocol : String,
  base_url : String,
  primary_route : String,
  setup_command : String,
  usage : String,
) -> Json {
  Json::object({
    "id": Json::string(id),
    "appType": Json::string(app_type),
    "protocol": Json::string(protocol),
    "baseUrl": Json::string(base_url),
    "primaryRoute": Json::string(primary_route),
    "setupCommand": Json::string(setup_command),
    "usage": Json::string(usage),
  })
}

///|
fn moongate_suite_integrations_json(
  host : String,
  port : Int,
  model : String,
) -> Json {
  let base_url = moongate_base_url(host, port)
  let openai_base_url = moongate_openai_base_url(host, port)
  let moonclaw_openai_base_url = "\{base_url}/openclaw/v1"
  let anthropic_base_url = base_url
  let claude_desktop_base_url = moongate_claude_desktop_base_url(host, port)
  let moonclaw_models_file = moongate_moonclaw_models_file()
  let moonclaw_config_file = moongate_moonclaw_config_file()
  let moonclaw_providers_file = moongate_moonclaw_providers_file()
  let moonclaw_providers_write_command = "moongate suite write-moonclaw-providers --path \{moonclaw_providers_file}"
  Json::object({
    "moonclaw": Json::object({
      "priority": Json::number(10.0),
      "role": Json::string("agent-provider-edge"),
      "openaiBaseUrl": Json::string(moonclaw_openai_base_url),
      "anthropicBaseUrl": Json::string(anthropic_base_url),
      "defaultModel": Json::string(model),
      "moonclawModelConfig": moonclaw_model_config_json(
        moonclaw_openai_base_url, model,
      ),
      "moonclawModelsJson": Json::array([
        moonclaw_model_config_json(moonclaw_openai_base_url, model),
      ]),
      "moonclawModelsPathCandidates": Json::array([
        Json::string(moonclaw_models_file),
      ]),
      "moonclawProviderName": Json::string("moongate"),
      "moonclawProviderModelId": Json::string(model),
      "moonclawProviderConfigPaths": Json::array([
        Json::string(moonclaw_models_file),
        Json::string(moonclaw_config_file),
      ]),
      "moonclawProvidersFileJson": moonclaw_providers_file_json(
        moonclaw_openai_base_url, model,
      ),
      "moonclawProvidersFileCommand": Json::string(
        "moongate suite moonclaw-providers",
      ),
      "moonclawProvidersFileWriteCommand": Json::string(
        moonclaw_providers_write_command,
      ),
      "healthUrl": Json::string("\{base_url}/health"),
      "dashboardUrl": Json::string("\{base_url}/"),
      "metricsUrl": Json::string("\{base_url}/metrics"),
      "usageSummaryUrl": Json::string("\{base_url}/usage/summary"),
      "usageLogsUrl": Json::string("\{base_url}/usage/logs"),
      "providerPresetsUrl": Json::string("\{base_url}/providers/presets"),
      "streamCheckAllProvidersUrl": Json::string(
        "\{base_url}/proxy/stream-check/all",
      ),
      "env": Json::object({
        "OPENAI_BASE_URL": Json::string(moonclaw_openai_base_url),
        "ANTHROPIC_BASE_URL": Json::string(anthropic_base_url),
        "OPENAI_API_KEY": Json::string("moongate-local"),
      }),
    }),
    "moonbook": Json::object({
      "priority": Json::number(20.0),
      "role": Json::string("durable-usage-output"),
      "usageSummaryUrl": Json::string("\{base_url}/usage/summary"),
      "usageLogsUrl": Json::string("\{base_url}/usage/logs"),
      "usageTrendsUrl": Json::string("\{base_url}/usage/trends"),
      "usageDataSourcesUrl": Json::string("\{base_url}/usage/data-sources"),
      "usageRequestLogsFile": Json::string(
        @pathx.join(default_moongate_stats_dir(), MOONGATE_REQUEST_LOGS_FILE),
      ),
      "usageModelPricingFile": Json::string(
        @pathx.join(default_moongate_stats_dir(), MOONGATE_MODEL_PRICING_FILE),
      ),
      "cli": Json::string("moongate"),
      "moondeskAdapterPackage": Json::string(
        "vectie/moondesk/adapters/moonbook",
      ),
      "moontownAdapterPackage": Json::string(
        "vectie/moontown/adapters/moonbook",
      ),
    }),
    "moontown": Json::object({
      "priority": Json::number(30.0),
      "role": Json::string("scheduler-network-watch"),
      "healthUrl": Json::string("\{base_url}/health"),
      "dashboardUrl": Json::string("\{base_url}/"),
      "statusUrl": Json::string("\{base_url}/status"),
      "statsUrl": Json::string("\{base_url}/stats"),
      "metricsUrl": Json::string("\{base_url}/metrics"),
      "streamCheckAllProvidersUrl": Json::string(
        "\{base_url}/proxy/stream-check/all",
      ),
      "usageProviderLimitsUrl": Json::string(
        "\{base_url}/usage/provider-limits",
      ),
      "suiteStatusFile": Json::string(default_moongate_suite_status_path()),
      "moonclawProviderManifestPath": Json::string(moonclaw_providers_file),
      "moonclawProviderManifestCommand": Json::string("moongate"),
      "moonclawProviderManifestArgs": Json::array([
        Json::string("suite"),
        Json::string("write-moonclaw-providers"),
        Json::string("--path"),
        Json::string(moonclaw_providers_file),
      ]),
      "moonclawProviderManifestFullCommand": Json::string(
        moonclaw_providers_write_command,
      ),
      "moonclawProviderManifestTarget": Json::string("moonbook"),
      "moonbookProviderManifestPath": Json::string(moonclaw_providers_file),
      "moonbookProviderManifestCommand": Json::string("moongate"),
      "moonbookProviderManifestArgs": Json::array([
        Json::string("suite"),
        Json::string("write-moonclaw-providers"),
        Json::string("--path"),
        Json::string(moonclaw_providers_file),
      ]),
      "moonbookProviderManifestFullCommand": Json::string(
        moonclaw_providers_write_command,
      ),
      "adapterPackages": Json::array([
        Json::string("vectie/moontown/adapters/moonclaw"),
        Json::string("vectie/moontown/adapters/moonbook"),
      ]),
    }),
    "moondesk": Json::object({
      "priority": Json::number(0.0),
      "role": Json::string("primary-operator-dashboard"),
      "suiteStatusFile": Json::string(default_moongate_suite_status_path()),
      "dashboardUrl": Json::string("\{base_url}/"),
      "healthUrl": Json::string("\{base_url}/health"),
      "statusUrl": Json::string("\{base_url}/status"),
      "statsUrl": Json::string("\{base_url}/stats"),
      "metricsUrl": Json::string("\{base_url}/metrics"),
      "modelsUrl": Json::string("\{openai_base_url}/models"),
      "providerPresetsUrl": Json::string("\{base_url}/providers/presets"),
      "claudeDesktopBaseUrl": Json::string(claude_desktop_base_url),
      "streamCheckProviderUrl": Json::string(
        "\{base_url}/proxy/stream-check/provider",
      ),
      "streamCheckAllProvidersUrl": Json::string(
        "\{base_url}/proxy/stream-check/all",
      ),
      "streamCheckConfigUrl": Json::string(
        "\{base_url}/proxy/stream-check/config",
      ),
      "configStatusUrl": Json::string("\{base_url}/config/status"),
      "adapterPackages": Json::array([
        Json::string("vectie/moondesk/adapters/moonclaw"),
        Json::string("vectie/moondesk/adapters/moonbook"),
        Json::string("vectie/moondesk/adapters/moontown"),
      ]),
    }),
  })
}

///|
fn moonclaw_providers_file_json(
  openai_base_url : String,
  model : String,
) -> Json {
  let models = if model.trim().is_empty() {
    []
  } else {
    [
      Json::object({
        "id": Json::string(model),
        "name": Json::string("moongate/\{model}"),
        "reasoning": Json::boolean(true),
        "input": Json::array([Json::string("text"), Json::string("image")]),
      }),
    ]
  }
  Json::object({
    "providers": Json::object({
      "moongate": Json::object({
        "baseUrl": Json::string(openai_base_url),
        "api": Json::string("openai"),
        "apiKey": Json::string("moongate-local"),
        "models": Json::array(models),
      }),
    }),
  })
}

///|
pub fn moongate_moonclaw_providers_file_json(
  host? : String = @suite.default_host(),
  port? : Int = @suite.default_port(),
  model? : String = @suite.default_model(),
) -> Json {
  moonclaw_providers_file_json(
    "\{moongate_base_url(host, port)}/openclaw/v1",
    model,
  )
}

///|
pub async fn write_moongate_moonclaw_providers_file(
  path? : String = default_moongate_moonclaw_providers_file_path(),
  host? : String = @suite.default_host(),
  port? : Int = @suite.default_port(),
  model? : String = @suite.default_model(),
) -> String {
  let dir = @pathx.dirname(path)
  @fsx.make_directory(dir, recursive=true, exists_ok=true)
  let existing = @fsx.read_file(path) catch { _ => "" }
  let parsed = @json.parse(existing) catch { _ => Json::object({}) }
  let root = match parsed {
    Object(root) => root
    _ => {}
  }
  let providers = match root.get("providers") {
    Some(Object(providers)) => providers
    _ => {}
  }
  guard moongate_moonclaw_providers_file_json(host~, port~, model~)
    is { "providers": { "moongate": provider, .. }, .. } else {
    return path
  }
  providers["moongate"] = provider
  root["providers"] = Json::object(providers)
  atomic_write_store_file(path, Json::object(root).stringify(indent=2) + "\n")
  path
}

///|
pub fn default_moongate_moonclaw_providers_file_path() -> String {
  moongate_moonclaw_providers_file()
}

///|
pub fn default_moongate_moonclaw_providers_file_path_for_workspace_root(
  root : String,
) -> String {
  moongate_moonclaw_providers_file_for_workspace_root(root)
}

///|
fn moonclaw_model_config_json(openai_base_url : String, model : String) -> Json {
  Json::object({
    "name": Json::string("moongate/\{model}"),
    "description": Json::string(
      "MoonGate local OpenAI-compatible proxy model for the Moon suite.",
    ),
    "model_name": Json::string(model),
    "model_type": Json::string("saas/openai"),
    "api_key": Json::string("moongate-local"),
    "base_url": Json::string(openai_base_url),
    "safe_zone_tokens": Json::number(200000.0),
  })
}

///|
fn moongate_suite_capabilities() -> Array[String] {
  [
    "openai-compatible-proxy", "anthropic-compatible-proxy", "claude-desktop-gateway",
    "gemini-compatible-proxy", "moongate-usage-statistics", "moongate-stream-check",
    "session-usage-sync", "provider-model-catalog", "provider-presets", "moongate-skills-management",
    "suite-discovery", "executable-capability-projection", "exact-capability-resolution",
    "codex-config-install",
  ]
}

///|
fn moongate_suite_commands_json(port : Int, model : String) -> Json {
  let moonclaw_providers_write_command = "moongate suite write-moonclaw-providers --path \{moongate_moonclaw_providers_file()}"
  let codex_install_command = if model.trim().is_empty() {
    "moongate codex install --port \{port} --model "
  } else {
    "moongate codex install --port \{port} --model \{model}"
  }
  Json::object({
    "start": Json::string("moongate start --port \{port}"),
    "health": Json::string("moongate health"),
    "status": Json::string("moongate status"),
    "stats": Json::string("moongate stats"),
    "usageLogs": Json::string("moongate usage logs"),
    "usageSummary": Json::string("moongate usage summary"),
    "usageApps": Json::string("moongate usage apps"),
    "usageTrends": Json::string("moongate usage trends"),
    "usageLimits": Json::string(
      "moongate usage limits --provider-id  --app-type ",
    ),
    "usageProviders": Json::string("moongate usage providers"),
    "usageModels": Json::string("moongate usage models"),
    "usageSources": Json::string("moongate usage sources"),
    "usageSync": Json::string("moongate usage sync"),
    "usagePricing": Json::string("moongate usage pricing"),
    "usageDetail": Json::string(
      "moongate usage detail --request-id ",
    ),
    "providerPresets": Json::string(
      "moongate provider presets list --app-type ",
    ),
    "streamCheckProvider": Json::string(
      "moongate stream-check provider --app-type  --provider-id ",
    ),
    "streamCheckAll": Json::string(
      "moongate stream-check all --app-type ",
    ),
    "streamCheckConfig": Json::string("moongate stream-check config"),
    "streamCheckConfigSet": Json::string(
      "moongate stream-check config set --timeout-secs ",
    ),
    "codexInstall": Json::string(codex_install_command),
    "copilotAuthStatus": Json::string("moongate copilot status"),
    "copilotLogin": Json::string("moongate copilot login"),
    "claudeDesktopInstall": Json::string(
      "moongate claude-desktop install --port \{port}",
    ),
    "skillsList": Json::string("moongate skills installed"),
    "skillsSearch": Json::string("moongate skills search --query "),
    "skillsInstall": Json::string(
      "moongate skills install-unified --directory  --app-type ",
    ),
    "skillsRepos": Json::string("moongate skills repos"),
    "updateTrayMenu": Json::string("moongate runtime tray-menu update"),
    "suiteManifest": Json::string("moongate suite manifest"),
    "suiteStatus": Json::string("moongate suite status"),
    "suiteDrift": Json::string("moongate suite drift --root "),
    "suiteCapabilities": Json::string(
      "moongate suite capabilities --root ",
    ),
    "suiteCapabilityResolve": Json::string(
      "moongate suite capability-resolve --root  --product  --operation ",
    ),
    "suiteWriteStatus": Json::string("moongate suite write-status"),
    "moonclawProviders": Json::string("moongate suite moonclaw-providers"),
    "moonclawProvidersWrite": Json::string(moonclaw_providers_write_command),
  })
}

///|
fn moongate_suite_routes() -> Array[String] {
  [
    "GET /", "GET /ui/rabbita", "GET /assets/moongate.css", "GET /assets/moongate-core.js",
    "GET /assets/moonsuite-i18n.js", "GET /assets/moongate-frameworks.js", "GET /assets/moongate-usage.js",
    "GET /assets/moongate-setup.js", "GET /assets/moongate-suite.js", "GET /assets/moongate-resilience.js",
    "GET /assets/moongate.js", "GET /assets/moongate-operations.js", "GET /participant/register",
    "GET /control/bootstrap", "GET /suite/manifest", "GET /suite/status", "GET /suite/drift",
    "GET /suite/capabilities", "GET /suite/capabilities/resolve", "POST /suite/status/write",
    "GET /suite/moonclaw-providers", "POST /suite/moonclaw-providers/write", "GET /health",
    "GET /status", "GET /stats", "GET /metrics", "GET /operations/monitor", "POST /benchmark/deterministic",
    "POST /benchmark/live", "GET /routing/policies", "POST /routing/policies/configure",
    "POST /routing/policies/shadow", "POST /routing/policies/activate", "POST /routing/policies/rollback",
    "GET /usage/logs", "GET /usage/summary", "GET /usage/summary/by-app", "GET /usage/provider-stats",
    "GET /usage/trends", "GET /usage/provider-limits", "GET /usage/model-stats",
    "GET /usage/data-sources", "POST /usage/sync-session", "GET /usage/model-pricing",
    "POST /usage/model-pricing", "DELETE /usage/model-pricing", "GET /usage/request-detail/*path",
    "GET /usage/provider-usage", "GET /usage/balance", "GET /usage/subscription-quota",
    "GET /usage/codex-oauth-quota", "GET /usage/codex-oauth-models", "GET /usage/coding-plan-quota",
    "POST /usage/test-script", "POST /proxy/stream-check/provider", "POST /proxy/stream-check/all",
    "GET /proxy/stream-check/config", "POST /proxy/stream-check/config", "GET /providers/presets",
    "GET /v1/models", "GET /claude-desktop/v1/models", "POST /v1/messages", "POST /claude-desktop/v1/messages",
    "POST /v1/responses", "POST /v1/responses/compact", "POST /v1/chat/completions",
    "POST /openclaw/v1/chat/completions", "GET /openclaw/v1/models", "GET /auth/status",
    "GET /auth/accounts", "POST /auth/login", "POST /auth/poll", "DELETE /auth/account",
    "POST /auth/default-account", "POST /auth/logout", "GET /copilot/status", "GET /copilot/accounts",
    "GET /copilot/authenticated", "POST /copilot/device-flow", "POST /copilot/poll-auth",
    "POST /copilot/poll-account", "POST /copilot/logout", "DELETE /copilot/account",
    "POST /copilot/default-account", "GET /copilot/token", "GET /copilot/models",
    "GET /copilot/usage", "POST /runtime/open-external", "POST /runtime/clipboard/text",
    "POST /runtime/updates/check", "POST /runtime/tray-menu/update", "GET /runtime/portable-mode",
    "GET /tools/versions", "POST /tools/lifecycle-action", "GET /tools/probe", "POST /runtime/window-theme",
    "POST /runtime/lightweight-mode/enter", "POST /runtime/lightweight-mode/exit",
    "GET /runtime/lightweight-mode", "POST /files/dialogs/save", "POST /config/files/export",
    "POST /config/files/import", "POST /backups/db", "GET /backups/db", "POST /backups/db/restore",
    "POST /backups/db/rename", "DELETE /backups/db/delete", "GET /deeplinks/parse",
    "POST /deeplinks/merge", "POST /deeplinks/import", "POST /sync/webdav/test",
    "POST /sync/webdav/upload", "POST /sync/webdav/download", "POST /sync/webdav/settings",
    "GET /sync/webdav/remote-info", "POST /sync/s3/test", "POST /sync/s3/upload",
    "POST /sync/s3/download", "POST /sync/s3/settings", "GET /sync/s3/remote-info",
    "GET /sessions", "GET /sessions/messages", "POST /sessions/terminal", "POST /sessions/delete",
    "POST /sessions/delete-many", "GET /providers/omo/file", "GET /providers/omo/current",
    "POST /providers/omo/disable", "GET /providers/omo-slim/file", "GET /providers/omo-slim/current",
    "POST /providers/omo-slim/disable", "POST /files/dialogs/open", "POST /files/dialogs/open-zip",
    "GET /skills/installed", "GET /skills/backups", "POST /skills/backups/delete",
    "POST /skills/backups/restore", "POST /skills/install-unified", "POST /skills/uninstall-unified",
    "POST /skills/toggle-app", "GET /skills/unmanaged", "POST /skills/import-apps",
    "GET /skills/discover", "GET /skills/updates", "POST /skills/update", "POST /skills/migrate-storage",
    "GET /skills/search", "GET /skills", "GET /skills/app", "GET /skills/repos",
    "POST /skills/repos", "POST /skills/repos/remove", "POST /skills/install-zip",
    "GET /proxy/status", "POST /proxy/start", "POST /proxy/stop", "POST /proxy/stop-with-restore",
    "GET|POST /proxy/global-config", "GET|POST /proxy/global-url", "POST /proxy/test-url",
    "GET /proxy/upstream-status", "GET /proxy/local-proxies", "GET|POST /proxy/app-config",
    "GET|POST /proxy/default-cost-multiplier", "GET|POST /proxy/pricing-model-source",
    "GET /proxy/provider-health", "GET|POST /proxy/circuit-breaker-config", "GET /proxy/circuit-breaker-stats",
    "POST /proxy/reset-circuit-breaker", "GET|POST|DELETE /proxy/failover-queue",
    "GET /proxy/available-failover-providers", "GET|POST /proxy/auto-failover-enabled",
    "GET|POST /proxy/takeover-status", "GET /proxy/running", "POST /proxy/switch-provider",
    "POST /proxy/sync-current-providers-live", "POST /proxy/import-default-config",
    "GET /providers", "GET /providers/current", "DELETE /providers/current", "GET /bindings",
    "POST /bindings", "DELETE /bindings", "POST /providers", "POST /providers/update",
    "DELETE /providers", "DELETE /providers/live", "POST /providers/switch", "GET /providers/live-settings",
    "POST /providers/terminal", "GET /providers/live-ids", "GET /providers/live-provider",
    "POST /providers/import-live", "GET /providers/universal", "GET /providers/universal/item",
    "POST /providers/universal", "DELETE /providers/universal", "POST /providers/universal/sync",
    "POST /providers/test-endpoints", "POST /providers/sort-order", "GET /providers/endpoints/list",
    "POST /providers/endpoints", "DELETE /providers/endpoints", "POST /providers/endpoints/touch",
    "GET /config/claude/status", "GET /config/status", "GET /providers/claude-desktop/status",
    "GET /providers/claude-desktop/default-routes", "POST /providers/claude-desktop/import",
    "POST /providers/claude-desktop/official", "GET /config/claude-code/path", "GET /config/dir",
    "POST /config/folder/open", "POST /files/directories/pick", "GET /config/app-path",
    "GET /config/app-folder/open", "GET /config/snippets/claude", "POST /config/snippets/claude",
    "GET /config/snippets", "POST /config/snippets", "POST /config/snippets/extract",
    "GET /config/env/conflicts", "POST /config/env/delete", "POST /config/env/restore",
    "GET /mcp/claude/status", "GET /mcp/claude/config", "POST /mcp/claude/servers",
    "DELETE /mcp/claude/servers", "GET /mcp/validate", "GET /mcp/config", "POST /mcp/config/servers",
    "DELETE /mcp/config/servers", "POST /mcp/enabled", "GET /mcp/servers", "POST /mcp/servers",
    "DELETE /mcp/servers", "POST /mcp/apps/toggle", "POST /mcp/import-apps", "GET /prompts",
    "POST /prompts", "DELETE /prompts", "POST /prompts/enable", "POST /prompts/import-file",
    "GET /prompts/current-file", "GET /settings", "POST /settings", "POST /runtime/restart",
    "POST /runtime/updates/install-restart", "GET /settings/app-config-dir", "POST /settings/app-config-dir",
    "POST /settings/auto-launch", "GET /settings/auto-launch", "GET /settings/rectifier",
    "POST /settings/rectifier", "GET /settings/optimizer", "POST /settings/optimizer",
    "GET /settings/copilot-optimizer", "POST /settings/copilot-optimizer", "GET /settings/log",
    "POST /settings/log", "GET /plugin/claude/status", "GET /plugin/claude/config",
    "POST /plugin/claude/config", "GET /plugin/claude/applied", "POST /plugin/claude/onboarding-skip",
    "POST /plugin/claude/onboarding-skip/clear", "GET /workspace/memory", "GET /workspace/memory/file",
    "POST /workspace/memory/write", "GET /workspace/memory/search", "POST /workspace/memory/delete",
    "DELETE /workspace/memory/file", "GET /workspace/files", "POST /workspace/files/read",
    "POST /workspace/files", "POST /workspace/open", "GET /openclaw/config-health",
    "GET /openclaw/default-model", "POST /openclaw/default-model", "GET /openclaw/model-catalog",
    "POST /openclaw/model-catalog", "GET /openclaw/agents-defaults", "POST /openclaw/agents-defaults",
    "GET /openclaw/env", "POST /openclaw/env", "GET /openclaw/tools", "POST /openclaw/tools",
    "GET /hermes/model-config", "GET /hermes/memory", "POST /hermes/memory", "GET /hermes/memory-limits",
    "POST /hermes/memory-enabled", "POST /hermes/web-ui", "POST /hermes/dashboard",
    "POST /config/models", "ANY /gemini/v1beta/*path", "ANY /gemini/v1/*path",
  ]
}