// SPEC: PJ2026-01060307 控制面模块化 draft-2026-06-25-p0. catalog module for scripts/src/artifact-registry.ts.

// Moved mechanically from scripts/src/artifact-registry.ts:249-880 for #903.

import { createHash } from "node:crypto";
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { runCommand, type CommandResult } from "../command";
import { readConfig, type UniDeskConfig, repoRoot, rootPath } from "../config";
import { startJob } from "../jobs";
import {
  compareDeployJsonExecutorMirrors,
  deployJsonCommitImage,
  deployJsonDriftResult,
  deployJsonSourceOfTruth,
  hasDeployJsonExecutorContract,
  k3sManifestExecutorMirror,
  parseDeployJsonServiceContractBase64,
  readDeployJsonServiceContractFromFile,
  type DeployJsonExecutorMirror,
  type DeployJsonServiceContract,
} from "../deploy-json-contract";
import { k3sGuardShellLines } from "../k3s-target-guard";
import { composeRuntimeEnvValue } from "../runtime-env";

import type { ArtifactConsumerSpec, AuthHealthGate, RuntimeSecretRequirement } from "./types";

export const baiduNetdiskRuntimeSecretRequirements: RuntimeSecretRequirement[] = [
  { sourceEnvName: "UNIDESK_BAIDU_NETDISK_CLIENT_ID", containerEnvName: "BAIDU_NETDISK_CLIENT_ID" },
  { sourceEnvName: "UNIDESK_BAIDU_NETDISK_CLIENT_SECRET", containerEnvName: "BAIDU_NETDISK_CLIENT_SECRET" },
  { sourceEnvName: "UNIDESK_BAIDU_NETDISK_TOKEN_KEY", containerEnvName: "BAIDU_NETDISK_TOKEN_KEY" },
];

export const baiduNetdiskAuthHealthGate: AuthHealthGate = {
  requiredFields: ["configured", "clientIdConfigured", "clientSecretConfigured", "tokenKeyConfigured", "loggedIn"],
  recoveryHint: "Restore UNIDESK_BAIDU_NETDISK_CLIENT_ID, UNIDESK_BAIDU_NETDISK_CLIENT_SECRET, and UNIDESK_BAIDU_NETDISK_TOKEN_KEY in /root/.unidesk/.state/docker-compose.env, recreate only baidu-netdisk with the canonical env file, then verify microservice health baidu-netdisk.",
};

export const artifactConsumerSpecs: Record<string, ArtifactConsumerSpec> = {
  "auth-broker": {
    serviceId: "auth-broker",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/auth-broker",
    dockerfile: "src/components/microservices/auth-broker/Dockerfile",
    prodLiveApply: "supervisor-only",
    prodLiveBlockReason: "auth-broker is registered for source/contract/profile dry-run only; live production apply requires a separate credential mounting and exposure review.",
    devLiveApply: "supervisor-only",
    devLiveBlockReason: "auth-broker DEV live apply requires explicit operator authorization after reviewing credential mounting, private exposure, and dry-run evidence.",
    targets: {
      dev: {
        targetImage: "auth-broker",
        targetCommitImage: (commit: string) => `auth-broker:${commit}`,
        deployRef: "deploy.json#environments.dev.services.auth-broker",
        compose: {
          serviceName: "auth-broker",
          containerName: "auth-broker-backend",
          deployEnvPrefix: "UNIDESK_AUTH_BROKER_DEPLOY",
          healthProbeCommand: "auth-broker --healthcheck",
          requireHealthCommit: false,
        },
      },
      prod: {
        targetImage: "auth-broker",
        targetCommitImage: (commit: string) => `auth-broker:${commit}`,
        deployRef: "deploy.json#environments.prod.services.auth-broker",
        compose: {
          serviceName: "auth-broker",
          containerName: "auth-broker-backend",
          deployEnvPrefix: "UNIDESK_AUTH_BROKER_DEPLOY",
          healthProbeCommand: "auth-broker --healthcheck",
          requireHealthCommit: false,
        },
      },
    },
  },
  "backend-core": {
    serviceId: "backend-core",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/backend-core",
    dockerfile: "src/components/backend-core/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      prod: {
        targetImage: "unidesk-backend-core",
        targetCommitImage: (commit: string) => `unidesk-backend-core:${commit}`,
        deployRef: "deploy.json#environments.prod.services.backend-core",
        compose: {
          serviceName: "backend-core",
          containerName: "unidesk-backend-core",
          deployEnvPrefix: "UNIDESK_DEPLOY",
          healthProbeCommand: "if command -v backend-core >/dev/null 2>&1; then backend-core --fetch-json http://127.0.0.1:8080/health --require-ok; elif command -v bun >/dev/null 2>&1; then bun -e \"fetch('http://127.0.0.1:8080/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"; else exit 1; fi",
          requireHealthCommit: false,
        },
      },
    },
  },
  "dev:backend-core": {
    serviceId: "backend-core",
    environment: "dev",
    kind: "d601-k3s",
    registryRepository: "unidesk/backend-core",
    dockerfile: "src/components/backend-core/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "unidesk-backend-core:dev",
        targetCommitImage: (commit: string) => `unidesk-backend-core:${commit}`,
        deployRef: "origin/master:deploy.json#environments.dev.services.backend-core",
        k3s: {
          namespace: "unidesk-dev",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-core.k8s.yaml",
          deploymentName: "backend-core-dev",
          serviceName: "backend-core-dev",
          servicePort: 8080,
          containerName: "backend-core",
          healthPath: "/health",
          applySelector: "app.kubernetes.io/name=backend-core",
          podLabelSelector: "app.kubernetes.io/name=backend-core,app.kubernetes.io/component=core,unidesk.ai/environment=dev",
        },
      },
    },
  },
  "baidu-netdisk": {
    serviceId: "baidu-netdisk",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/baidu-netdisk",
    dockerfile: "src/components/microservices/baidu-netdisk/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "baidu-netdisk",
        targetCommitImage: (commit: string) => `baidu-netdisk:${commit}`,
        deployRef: "deploy.json#environments.dev.services.baidu-netdisk",
        compose: {
          serviceName: "baidu-netdisk",
          containerName: "baidu-netdisk-backend",
          deployEnvPrefix: "UNIDESK_BAIDU_NETDISK_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4244/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
          requiredRuntimeSecrets: baiduNetdiskRuntimeSecretRequirements,
          authHealthGate: baiduNetdiskAuthHealthGate,
        },
      },
      prod: {
        targetImage: "baidu-netdisk",
        targetCommitImage: (commit: string) => `baidu-netdisk:${commit}`,
        deployRef: "deploy.json#environments.prod.services.baidu-netdisk",
        compose: {
          serviceName: "baidu-netdisk",
          containerName: "baidu-netdisk-backend",
          deployEnvPrefix: "UNIDESK_BAIDU_NETDISK_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4244/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
          requiredRuntimeSecrets: baiduNetdiskRuntimeSecretRequirements,
          authHealthGate: baiduNetdiskAuthHealthGate,
        },
      },
    },
  },
  "code-queue-mgr": {
    serviceId: "code-queue-mgr",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/code-queue-mgr",
    dockerfile: "src/components/microservices/code-queue-mgr/Dockerfile",
    prodLiveApply: "supervisor-only",
    prodLiveBlockReason: "code-queue-mgr is the main-server Code Queue control-plane sidecar; live production apply requires explicit supervisor confirmation.",
    targets: {
      dev: {
        targetImage: "code-queue-mgr",
        targetCommitImage: (commit: string) => `code-queue-mgr:${commit}`,
        deployRef: "deploy.json#environments.dev.services.code-queue-mgr",
        compose: {
          serviceName: "code-queue-mgr",
          containerName: "code-queue-mgr-backend",
          deployEnvPrefix: "UNIDESK_CODE_QUEUE_MGR_DEPLOY",
          healthProbeCommand: "code-queue-mgr --print-health",
          requireHealthCommit: true,
        },
      },
      prod: {
        targetImage: "code-queue-mgr",
        targetCommitImage: (commit: string) => `code-queue-mgr:${commit}`,
        deployRef: "deploy.json#environments.prod.services.code-queue-mgr",
        compose: {
          serviceName: "code-queue-mgr",
          containerName: "code-queue-mgr-backend",
          deployEnvPrefix: "UNIDESK_CODE_QUEUE_MGR_DEPLOY",
          healthProbeCommand: "code-queue-mgr --print-health",
          requireHealthCommit: true,
        },
      },
    },
  },
  "decision-center": {
    serviceId: "decision-center",
    environment: "prod",
    kind: "d601-k3s",
    registryRepository: "unidesk/decision-center",
    dockerfile: "src/components/microservices/decision-center/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "unidesk-decision-center:dev",
        targetCommitImage: (commit: string) => `unidesk-decision-center:${commit}`,
        deployRef: "deploy.json#environments.dev.services.decision-center",
        k3s: {
          namespace: "unidesk-dev",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-decision-center.k8s.yaml",
          deploymentName: "decision-center-dev",
          serviceName: "decision-center-dev",
          servicePort: 4277,
          containerName: "decision-center",
          healthPath: "/health",
          podLabelSelector: "app.kubernetes.io/name=decision-center,unidesk.ai/environment=dev",
        },
      },
      prod: {
        targetImage: "unidesk-decision-center:d601",
        targetCommitImage: (commit: string) => `unidesk-decision-center:${commit}`,
        deployRef: "deploy.json#environments.prod.services.decision-center",
        k3s: {
          namespace: "unidesk",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/decision-center.k8s.yaml",
          deploymentName: "decision-center",
          serviceName: "decision-center",
          servicePort: 4277,
          containerName: "decision-center",
          healthPath: "/health",
        },
      },
    },
  },
  "mdtodo": {
    serviceId: "mdtodo",
    environment: "prod",
    kind: "d601-k3s",
    registryRepository: "unidesk/mdtodo",
    dockerfile: "src/components/microservices/mdtodo/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "unidesk-mdtodo:dev",
        targetCommitImage: (commit: string) => `unidesk-mdtodo:${commit}`,
        deployRef: "deploy.json#environments.dev.services.mdtodo",
        k3s: {
          namespace: "unidesk-dev",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-mdtodo.k8s.yaml",
          deploymentName: "mdtodo-dev",
          serviceName: "mdtodo-dev",
          servicePort: 4267,
          containerName: "mdtodo",
          healthPath: "/health",
          podLabelSelector: "app.kubernetes.io/name=mdtodo,unidesk.ai/environment=dev",
        },
      },
      prod: {
        targetImage: "unidesk-mdtodo:d601",
        targetCommitImage: (commit: string) => `unidesk-mdtodo:${commit}`,
        deployRef: "deploy.json#environments.prod.services.mdtodo",
        k3s: {
          namespace: "unidesk",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/mdtodo.k8s.yaml",
          deploymentName: "mdtodo",
          serviceName: "mdtodo",
          servicePort: 4267,
          containerName: "mdtodo",
          healthPath: "/health",
        },
      },
    },
  },
  "claudeqq": {
    serviceId: "claudeqq",
    environment: "prod",
    kind: "d601-k3s",
    registryRepository: "unidesk/claudeqq",
    dockerfile: "claudeqq/Dockerfile",
    sourceRepo: "https://gitee.com/lyon1998/agent_skills",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "unidesk-claudeqq:dev",
        targetCommitImage: (commit: string) => `unidesk-claudeqq:${commit}`,
        deployRef: "deploy.json#environments.dev.services.claudeqq",
        k3s: {
          namespace: "unidesk-dev",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-claudeqq.k8s.yaml",
          deploymentName: "claudeqq-dev",
          serviceName: "claudeqq-dev",
          servicePort: 3290,
          containerName: "claudeqq",
          healthPath: "/health",
          podLabelSelector: "app.kubernetes.io/name=claudeqq,unidesk.ai/environment=dev",
        },
      },
      prod: {
        targetImage: "unidesk-claudeqq:d601",
        targetCommitImage: (commit: string) => `unidesk-claudeqq:${commit}`,
        deployRef: "deploy.json#environments.prod.services.claudeqq",
        k3s: {
          namespace: "unidesk",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/claudeqq.k8s.yaml",
          deploymentName: "claudeqq",
          serviceName: "claudeqq",
          servicePort: 3290,
          containerName: "claudeqq",
          healthPath: "/health",
        },
      },
    },
  },
  "code-queue": {
    serviceId: "code-queue",
    environment: "dev",
    kind: "d601-k3s",
    registryRepository: "unidesk/code-queue",
    dockerfile: "src/components/microservices/code-queue/Dockerfile",
    prodLiveApply: "unsupported",
    prodLiveBlockReason: "code-queue is dev-only for artifact consumer validation and has no production artifact deploy, production rollout, or production manifest mutation target.",
    devLiveApply: "supervisor-only",
    devLiveBlockReason: "Code Queue DEV live apply is self-bootstrap sensitive: a running Code Queue task may plan only dry-run evidence. A human operator or supervisor must explicitly authorize DEV apply outside Code Queue after reviewing the CI artifact digest and dry-run target list.",
    targets: {
      dev: {
        targetImage: "unidesk-code-queue:dev",
        targetCommitImage: (commit: string) => `unidesk-code-queue:${commit}`,
        deployRef: "deploy.json#environments.dev.services.code-queue",
        k3s: {
          namespace: "unidesk-dev",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-code-queue.k8s.yaml",
          deploymentName: "code-queue-scheduler-dev",
          extraDeployments: [
            { name: "d601-dev-provider-egress-proxy", containerName: "provider-egress-proxy" },
            "code-queue-read-dev",
            "code-queue-write-dev",
          ],
          serviceName: "code-queue-scheduler-dev",
          servicePort: 4222,
          containerName: "code-queue",
          healthPath: "/health",
          podLabelSelector: "app.kubernetes.io/name=code-queue,app.kubernetes.io/component=scheduler,unidesk.ai/environment=dev",
        },
      },
    },
  },
  "frontend": {
    serviceId: "frontend",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/frontend",
    dockerfile: "src/components/frontend/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      prod: {
        targetImage: "unidesk-frontend",
        targetCommitImage: (commit: string) => `unidesk-frontend:${commit}`,
        deployRef: "deploy.json#environments.prod.services.frontend",
        compose: {
          serviceName: "frontend",
          containerName: "unidesk-frontend",
          deployEnvPrefix: "UNIDESK_FRONTEND_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:8080/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
        },
      },
    },
  },
  "findjob": {
    serviceId: "findjob",
    environment: "prod",
    kind: "d601-compose",
    sourceRepo: "https://gitee.com/Lyon1998/findjob",
    registryRepository: "unidesk/findjob",
    dockerfile: "Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "findjob-server",
        targetCommitImage: (commit: string) => `findjob-server:${commit}`,
        deployRef: "deploy.json#environments.dev.services.findjob",
        compose: {
          serviceName: "server",
          containerName: "findjob-server",
          deployEnvPrefix: "UNIDESK_FINDJOB_DEPLOY",
          workDir: "/home/ubuntu/findjob",
          composeFile: "docker-compose.yml",
          projectHint: "findjob",
          healthProbeCommand: "curl -fsS --max-time 12 http://127.0.0.1:3254/api/health",
          requireHealthCommit: false,
        },
      },
      prod: {
        targetImage: "findjob-server",
        targetCommitImage: (commit: string) => `findjob-server:${commit}`,
        deployRef: "deploy.json#environments.prod.services.findjob",
        compose: {
          serviceName: "server",
          containerName: "findjob-server",
          deployEnvPrefix: "UNIDESK_FINDJOB_DEPLOY",
          workDir: "/home/ubuntu/findjob",
          composeFile: "docker-compose.yml",
          projectHint: "findjob",
          healthProbeCommand: "curl -fsS --max-time 12 http://127.0.0.1:3254/api/health",
          requireHealthCommit: false,
        },
      },
    },
  },
  "k3sctl-adapter": {
    serviceId: "k3sctl-adapter",
    environment: "prod",
    kind: "d601-compose",
    registryRepository: "unidesk/k3sctl-adapter",
    dockerfile: "src/components/microservices/k3sctl-adapter/Dockerfile",
    prodLiveApply: "supervisor-only",
    prodLiveBlockReason: "k3sctl-adapter is an infrastructure control bridge; this executor exposes artifact consumer plan/dry-run only. Real production deployment requires supervisor confirmation outside this task.",
    targets: {
      prod: {
        targetImage: "unidesk-k3sctl-adapter:d601",
        targetCommitImage: (commit: string) => `unidesk-k3sctl-adapter:${commit}`,
        deployRef: "deploy.json#environments.prod.services.k3sctl-adapter",
        compose: {
          serviceName: "k3sctl-adapter",
          containerName: "k3sctl-adapter",
          deployEnvPrefix: "UNIDESK_K3SCTL_ADAPTER_DEPLOY",
          workDir: "/home/ubuntu/cq-deploy",
          composeFile: "src/components/microservices/k3sctl-adapter/docker-compose.d601.yml",
          projectHint: "k3sctl-adapter",
          healthProbeCommand: "curl -fsS --max-time 10 http://127.0.0.1:4266/health",
          requireHealthCommit: false,
        },
      },
    },
  },
  "met-nonlinear": {
    serviceId: "met-nonlinear",
    environment: "prod",
    kind: "d601-compose",
    sourceRepo: "https://github.com/pikasTech/met_nonlinear",
    registryRepository: "unidesk/met-nonlinear",
    dockerfile: "docker/unidesk/Dockerfile.ml",
    prodLiveApply: "unsupported",
    prodLiveBlockReason: "met-nonlinear is blocked for live artifact deploy because config.json points at docker/unidesk/Dockerfile.ml while the compose service is met-nonlinear-ts. The current compose contract does not let CD prove that the recreated long-running container image label equals the requested commit.",
    runtimeVerification: "blocked",
    runtimeVerificationBlockReason: "D601 direct artifact consumer is implemented, but this service's registered Dockerfile is the ML image contract while the long-running Compose service is met-nonlinear-ts. Publish a labeled artifact that matches the running service image contract before live deploy, or update the service contract to a server Dockerfile.",
    targets: {
      dev: {
        targetImage: "met-nonlinear-ml:tf26",
        targetCommitImage: (commit: string) => `met-nonlinear-ml:${commit}`,
        deployRef: "deploy.json#environments.dev.services.met-nonlinear",
        compose: {
          serviceName: "met-nonlinear-ts",
          containerName: "met-nonlinear-ts",
          deployEnvPrefix: "UNIDESK_MET_NONLINEAR_DEPLOY",
          workDir: "/home/ubuntu/met_nonlinear",
          composeFile: "docker-compose.unidesk.yml",
          projectHint: "met-nonlinear",
          healthProbeCommand: "curl -fsS --max-time 20 http://127.0.0.1:3288/health",
          requireHealthCommit: false,
        },
      },
      prod: {
        targetImage: "met-nonlinear-ml:tf26",
        targetCommitImage: (commit: string) => `met-nonlinear-ml:${commit}`,
        deployRef: "deploy.json#environments.prod.services.met-nonlinear",
        compose: {
          serviceName: "met-nonlinear-ts",
          containerName: "met-nonlinear-ts",
          deployEnvPrefix: "UNIDESK_MET_NONLINEAR_DEPLOY",
          workDir: "/home/ubuntu/met_nonlinear",
          composeFile: "docker-compose.unidesk.yml",
          projectHint: "met-nonlinear",
          healthProbeCommand: "curl -fsS --max-time 20 http://127.0.0.1:3288/health",
          requireHealthCommit: false,
        },
      },
    },
  },
  "oa-event-flow": {
    serviceId: "oa-event-flow",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/oa-event-flow",
    dockerfile: "src/components/microservices/oa-event-flow/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "oa-event-flow",
        targetCommitImage: (commit: string) => `oa-event-flow:${commit}`,
        deployRef: "deploy.json#environments.dev.services.oa-event-flow",
        compose: {
          serviceName: "oa-event-flow",
          containerName: "oa-event-flow-backend",
          deployEnvPrefix: "UNIDESK_OA_EVENT_FLOW_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4255/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
        },
      },
      prod: {
        targetImage: "oa-event-flow",
        targetCommitImage: (commit: string) => `oa-event-flow:${commit}`,
        deployRef: "deploy.json#environments.prod.services.oa-event-flow",
        compose: {
          serviceName: "oa-event-flow",
          containerName: "oa-event-flow-backend",
          deployEnvPrefix: "UNIDESK_OA_EVENT_FLOW_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4255/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
        },
      },
    },
  },
  "project-manager": {
    serviceId: "project-manager",
    environment: "prod",
    kind: "compose",
    registryRepository: "unidesk/project-manager",
    dockerfile: "src/components/microservices/project-manager/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "project-manager",
        targetCommitImage: (commit: string) => `project-manager:${commit}`,
        deployRef: "deploy.json#environments.dev.services.project-manager",
        compose: {
          serviceName: "project-manager",
          containerName: "project-manager-backend",
          deployEnvPrefix: "UNIDESK_PROJECT_MANAGER_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4233/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
        },
      },
      prod: {
        targetImage: "project-manager",
        targetCommitImage: (commit: string) => `project-manager:${commit}`,
        deployRef: "deploy.json#environments.prod.services.project-manager",
        compose: {
          serviceName: "project-manager",
          containerName: "project-manager-backend",
          deployEnvPrefix: "UNIDESK_PROJECT_MANAGER_DEPLOY",
          healthProbeCommand: "bun -e \"fetch('http://127.0.0.1:4233/health').then(async r=>{const text=await r.text(); console.log(text); process.exit(r.ok?0:1)}).catch(e=>{console.error(e); process.exit(1)})\"",
          requireHealthCommit: true,
        },
      },
    },
  },
  "pipeline": {
    serviceId: "pipeline",
    environment: "prod",
    kind: "d601-compose",
    sourceRepo: "https://github.com/pikasTech/pipeline",
    registryRepository: "unidesk/pipeline",
    dockerfile: "Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "pipeline-v2-control",
        targetCommitImage: (commit: string) => `pipeline-v2-control:${commit}`,
        deployRef: "deploy.json#environments.dev.services.pipeline",
        compose: {
          serviceName: "pipeline-control",
          containerName: "pipeline-v2-control",
          deployEnvPrefix: "UNIDESK_PIPELINE_DEPLOY",
          workDir: "/home/ubuntu/pipeline",
          composeFile: "docker-compose.yml",
          projectHint: "pipeline",
          healthProbeCommand: "curl -fsS --max-time 20 http://127.0.0.1:18082/health",
          requireHealthCommit: false,
        },
      },
      prod: {
        targetImage: "pipeline-v2-control",
        targetCommitImage: (commit: string) => `pipeline-v2-control:${commit}`,
        deployRef: "deploy.json#environments.prod.services.pipeline",
        compose: {
          serviceName: "pipeline-control",
          containerName: "pipeline-v2-control",
          deployEnvPrefix: "UNIDESK_PIPELINE_DEPLOY",
          workDir: "/home/ubuntu/pipeline",
          composeFile: "docker-compose.yml",
          projectHint: "pipeline",
          healthProbeCommand: "curl -fsS --max-time 20 http://127.0.0.1:18082/health",
          requireHealthCommit: false,
        },
      },
    },
  },
  "dev:frontend": {
    serviceId: "frontend",
    environment: "dev",
    kind: "d601-k3s",
    registryRepository: "unidesk/frontend",
    dockerfile: "src/components/frontend/Dockerfile",
    prodLiveApply: "enabled",
    targets: {
      dev: {
        targetImage: "unidesk-frontend:dev",
        targetCommitImage: (commit: string) => `unidesk-frontend:${commit}`,
        deployRef: "origin/master:deploy.json#environments.dev.services.frontend",
        k3s: {
          namespace: "unidesk-dev",
          manifestRepoPath: "src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-core.k8s.yaml",
          deploymentName: "frontend-dev",
          serviceName: "frontend-dev",
          servicePort: 8080,
          containerName: "frontend",
          healthPath: "/health",
          applySelector: "app.kubernetes.io/name=frontend",
          podLabelSelector: "app.kubernetes.io/name=frontend,app.kubernetes.io/component=web,unidesk.ai/environment=dev",
        },
      },
    },
  },
};
