Skip to content

Deploy to xCloud skill: revised plan — orchestrate the existing Public API (supersedes #34) #35

Description

@neobuilds

Supersedes the implementation plan in #34. The product direction there is approved — a
"Deploy this application to xCloud" capability for Lovable, Replit, and similar agent
panels is worth building. This issue replaces the plan, which duplicates capabilities
the Public API already ships and is built on one incorrect premise about the .xcloud
contract.

Two independent reviews of #34 converged on the same three defects. This issue merges
them and records the code/API evidence behind each.

Position

xcloud:deploy-app is an orchestrator over the existing Public API, not a second
deployment engine.

It owns only what the backend cannot see:

  • the local working tree in the coding panel;
  • the handoff of that code into a Git repository xCloud can read;
  • secret classification;
  • platform-specific install/connection quirks.

Detection, native-versus-Docker routing, deployment status semantics, and site
provisioning stay server-side, where they already are.

Evidence: what the API already provides

Every operation #34 lists under its "MCP/API capability gate" is already exposed.

#34 capability gate item Already shipped
Git/Lovable site creation POST /servers/{uuid}/sites/git/auto, .../sites/git (site_type: lovable exists)
Custom Docker/Compose site creation POST /servers/{uuid}/sites/git/docker (docker.mode: compose|dockerfile, compose_file, dockerfile_path, container_port, build_target)
Repository and branch selection repository.{provider_uuid, full_name, url, branch, deploy_key_uuid}
Environment/secret configuration env_file_content, env_file_path
Primary/exposed port configuration port, docker.container_port
Deployment trigger POST /sites/{uuid}/git/deploy
Deployment status and logs GET /sites/{uuid}/status, GET /sites/{uuid}/deployment-logs, GET /servers/{uuid}/tasks, poll_url
Domain and SSL setup domain.{mode, name, ssl_provider}, the ssl-certificates operations
Safe retries Idempotency-Key on every create

No new Public API operation is required. #34's Phase 1 ("add the smallest Public API
operation(s)") should be closed as unnecessary.

Two further findings resolve open questions in #34 outright:

1. The routing table #34 wants to write in Markdown is already an API response.
POST /git/detect returns repository_access.status with actionable next_actions,
detection.supported, a compatibility verdict against a specific server_uuid,
compatibility.docker_deployable, and deploy_via: docker_compose. GET /sites/{uuid}/status
returns deploy_state, terminal, progress_percentage, error_message, and failed_steps
with documented semantics — including that a non-empty failed_steps on a deployed site is
a warning, not a failure. A Markdown reimplementation of either will drift from the backend
within one release.

2. site_type: lovable is nodejs minus the database. In xCloud:
GitSiteMigrationJob treats isNodejs() and isLovable() as one branch; the only
divergence is DatabaseProvider::NULL plus suppressed database name/user/prefix generation,
and a hidden database block in the frontend Git repo config. Both appear in
SiteType::gitDeployableValues(). #34's proposed audit of this is unnecessary — the rule is:
use nodejs unless the project is Lovable-origin and needs no xCloud-provisioned database.

Corrections to #34

1. Remove .xcloud as the customer-repository contract

.xcloud/.xcloud-config.yaml is the OneClick catalog template manifest. In xCloud it is
consumed by TemplateManifest / TemplateNovaService and hydrated from the curated
xCloudDev/app-templates catalog. It carries catalog concerns — category, icon, generated
values, credentials, post-install messages.

The Git-Docker deployment path never reads it. CustomDockerComposeSite reads
git_info.compose_file from site meta — the value set by the docker.compose_file API
parameter — and writes its own compose file server-side under the site user's home.

So #34's acceptance criterion "reuses the existing .xcloud structure rather than inventing
a competing manifest"
is inverted: placing a OneClick catalog manifest into an ordinary
customer repository is the new invention. The skill should generate a plain
docker-compose.yml (or reuse the repo's own) and pass its path.

2. Do not reimplement backend detection

#34 specifies client-side framework/runtime detection, build/start command inference, port
discovery, and a Lovable native-versus-Docker decision table. /git/detect and
/sites/git/auto already perform all of it, and git/auto already routes Dockerfile and
Compose repositories.

This also contradicts #34's own out-of-scope line, "No duplicate standalone Lovable/Replit
deployment engines are introduced."

If Lovable or Replit repositories detect poorly, fix the detector in xCloud — that
improvement reaches the dashboard flow too, which a skill-local heuristic never will.

3. Drop the Python validator

#34 requires keeping the plugin's bash/curl/jq runtime footprint, then specifies
scripts/validate-xcloud-deployment.py. Resolve toward bash: Compose validation is
docker compose config plus jq assertions over its output.

Missing from #34: the repository synchronization gate

MCP deploys from a Git repository. It does not deploy from uncommitted workspace files in a
Lovable or Replit panel. #34 does not mention this in any of its five phases, yet it is the
single most likely point of failure for the literal request "deploy the application currently
open."

Before any deployment the skill must:

  1. Identify the remote repository. If none exists, stop and ask — panels frequently have
    no push credential, and this is a hard stop, not a recoverable branch.
  2. Detect uncommitted changes relevant to deployment.
  3. Create or select a branch.
  4. Commit and push the required files with explicit approval, naming each file.
  5. Verify xCloud can read that exact commit by calling /git/detect and clearing any
    repository_access.next_actions before proceeding.

Private repositories without a connected provider need the deploy-key sequence
(prepare → add public key to the repo → verify → adopt), which requires repository write
access the panel may not hold. The skill must detect and surface that, not fail deep in
provisioning.

Missing from #34: the secrets gate

env_file_content exists, which is precisely why forwarding secrets needs an explicit
contract rather than a default behavior.

Rules to ratify in Phase 1:

  • The agent may forward non-secret build configuration and values the user supplies
    deliberately in-turn.
  • The agent must not bulk-read a local .env and forward it; must not echo any secret
    value into chat, logs, or a commit.
  • The coding panel's secret store stays authoritative. The agent names the required keys and
    asks for them.
  • Open question for the xCloud backend: whether to offer write-only secret submission or
    secret references, so that a retry does not re-transmit plaintext.

Revised delivery plan

Phase 1 — Contract audit (~2 days, mostly documentation)

  • Empirically verify skill installation and remote MCP OAuth inside real Lovable and real
    Replit.
    This is the only genuine unknown remaining, and it gates every compatibility
    claim the plugin makes.
  • Document the Git handoff contract (above).
  • Ratify the secrets contract (above).
  • Record lovable = nodejs − database as the site-type rule.
  • Confirm .xcloud is excluded from customer repositories.

Exit criterion: one page describing the repository handoff and the secret boundary. No
code.

Phase 2 — Repository sync + native Git MVP

Supports exactly one task: Deploy this repository to xCloud.

  1. Inspect the local project.
  2. Run the repository synchronization gate; push the required commit with approval.
  3. Call /git/detect; clear repository_access.next_actions.
  4. Select an eligible server via servers_index — the user chooses, never silently.
  5. Call /sites/git/auto with confirm: true and an Idempotency-Key.
  6. Poll /sites/{uuid}/status until terminal; branch on deploy_state; treat non-empty
    failed_steps on a deployed site as a warning.
  7. Verify the external HTTPS URL and return it.

Exit criterion: a single-Node-application fixture deploys end to end with no generated
Dockerfile and no manual SSH.

This delivers most of the customer value without shipping a template generator.

Phase 3 — Docker extension

  • Reuse an existing Dockerfile or Compose file first.
  • Generate deployment files only when the native path is incompatible and none exist.
  • /sites/git/auto stays the default; /sites/git/docker only when explicit
    compose_file, dockerfile_path, container_port, or host port values must be pinned.
  • Preserve Add project-aware Deploy to xCloud skill for Lovable and Replit agents #34's stack constraints: one public entry point, TLS and routing left to xCloud,
    private database/cache ports, named volumes for durable state, health checks valid for the
    exact images used, workers preserved, no committed secrets, immutable image tags, no
    one-shot service that can block provisioning indefinitely.
  • Do not silently self-host a managed SaaS dependency. For Supabase and similar, determine
    whether the application expects the managed service or requires a user decision.

Exit criterion: a multi-service fixture produces a validated stack with no unresolved
placeholders, no committed secrets, no public database port, and no mutable production tag.

Phase 4 — Platform adapters and distribution

  • Thin Lovable and Replit reference documents — install steps, MCP connection, and
    platform quirks only. No separate engines.
  • Real end-to-end deployment tests from inside each panel.
  • Publish a compatibility claim for a panel only after that test passes there.
  • Plugin metadata, marketplace artifacts, routing inventory, skill inventory, docs, release
    notes.

Acceptance criteria (replacing #34's)

  • xcloud:deploy-app calls /git/detect, /sites/git/auto, /sites/git/docker, and
    /sites/{uuid}/status; it does not reimplement detection, routing, or status semantics.
  • Existing skills remain the source of truth for their domains: xcloud:servers
    (servers, site creation), xcloud:sites (Git settings, deployments, logs, domains,
    lifecycle), xcloud:ssl (certificates), xcloud:wordpress (WordPress management),
    xcloud:account (identity reads).
  • MCP OAuth is the default first-run path; no long-lived token is ever requested in chat.
  • The skill generates no OneClick catalog metadata in customer repositories.
  • Routing follows /git/detect's deploy_via and compatibility verdict, and asks the
    user when detection.supported is false rather than defaulting to Docker.
  • site_type selection follows the documented rule: nodejs unless Lovable-origin with
    no xCloud-provisioned database.
  • The skill never deploys a commit xCloud cannot read, and never pushes without naming
    the files it is committing.
  • The skill stops and asks when no remote repository or no push credential exists.
  • No local .env value is transmitted, logged, or committed without explicit per-value
    approval.
  • Live site creation, deployment, secret submission, destructive replacement, and DNS
    changes each require explicit confirmation showing team, server, domain,
    repository/branch, and deployment path.
  • Deployment success is reported only after deploy_state is terminal and external
    HTTPS is verified.
  • Generated Compose stacks satisfy the Phase 3 constraints; connection strings use the
    actual configured secrets and survive special characters.
  • Runtime footprint stays bash/curl/jq.
  • Fixtures cover: Lovable SPA, Lovable + Supabase, Replit Node, Replit Python,
    multi-service app with database and worker.
  • Any material ported from Asif2BD/xCloud-Docker-Deploy-Skill preserves its Apache-2.0
    attribution and notices.
  • Panel compatibility is claimed only where an end-to-end deployment has been run.
  • Plugin metadata, distribution artifacts, versioning, docs, and routing inventory
    include the sixth capability.

Out of scope

  • Replacing the existing xCloud MCP server or the operational skills.
  • Adding Public API operations for this feature — none are missing.
  • A second detection engine, or a per-platform deployment engine.
  • Placing the OneClick catalog manifest into customer repositories.
  • Silently migrating a managed SaaS dependency to a self-hosted replacement.
  • Deploying over ad hoc SSH.

Estimate

Roughly 1.5–2 weeks to a working Phase 2, against the month the original five-phase plan
implies. The reduction comes from deleting the capability-gate research, the manifest work,
and the client-side detection engine — not from cutting scope the customer sees.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions