# Agent deployment guide

This service publishes static files from a ZIP archive. The management API is at `https://deploy.sites.tzxys.cn`; the exact request contract is in [`/openapi.json`](../openapi.json). Sign in or register on the management site, then generate a personal Agent token in the account menu. Use it through a secure environment variable. Never include it in a repository, built output, ZIP file, log, or final answer. New projects are private by default; this only limits who can manage them, not who can visit their site URLs. Any signed-in user can update or delete a public project and manage its domains. Existing projects are public and have no recorded creator.

## 1. Understand the source

Identify whether the user provided a ready ZIP, a static folder, or a frontend project. For a frontend project, inspect the lockfile and build script, install missing dependencies when needed, and build the static output. A Node SSR application needs a static export before it can run here. In path mode, build assets for the project's base path; the default subdomain mode accepts root-relative asset paths.

## 2. Optional review before packaging

If source files are available, review the project before making the ZIP. Build once when output analysis is needed; if you change the source, build again before packaging. These are suggestions, not deployment gates:

- Compare output size with previous builds when available. Identify the largest files and unexpected `node_modules`, source archives, test fixtures, maps, videos, or duplicate assets.
- Review large JavaScript and CSS bundles. Remove unused dependencies or split code only when the change preserves behavior and brings a meaningful reduction.
- Review large JPEG and PNG images. Resize oversized sources and consider WebP or AVIF where quality and browser support fit. Keep SVG for appropriate vector artwork. Avoid automatic conversion of every image.
- Review fonts and other binary assets. Prefer a suitable web format such as WOFF2 and include only needed files. JPEG, WebP, AVIF, WOFF2, MP4, and ZIP are already compressed formats; another ZIP or HTTP compression pass usually offers little benefit.
- Check that public build output contains no secrets, `.env` files, private keys, or unintended internal documents. Stop if a secret would be published.

When an improvement is safe and clearly useful, make it in the source project, rebuild, and explain the change. If its benefit or visual effect is uncertain, report the suggestion and continue with the requested deployment. For a ready ZIP without source, inspect what is possible and state the limitation.

Gateway HTTP compression is separate from ZIP packaging. The ZIP only transports files to this service.

## 3. Package the static output

The archive root must contain `index.html`. Package the build output directory itself, not the whole source repository:

```bash
cd /path/to/project/dist
zip -qr /tmp/site.zip . -x '.DS_Store' 'node_modules/*' '.git/*'
zipinfo -1 /tmp/site.zip | grep -x index.html
```

The server rejects unsafe paths, excessive file counts, and archives that exceed upload or actual extracted-size limits.

## 4. Authenticate and deploy

Use your personal Agent token as `AUTO_DEPLOY_TOKEN` and `https://deploy.sites.tzxys.cn` as the base URL. The examples below use `curl`; any HTTP client that can send JSON and multipart file uploads works. Creating a project with `"visibility":"public"` makes it editable by all signed-in users; omit that field for a private project.

Keep the token out of process arguments when using the shell:

```bash
deploy_curl() {
  printf 'header = "Authorization: Bearer %s"\n' "$AUTO_DEPLOY_TOKEN" |
    curl --silent --show-error --fail --config - "$@"
}
```

List projects and identify an exact ID before updating or deleting:

```bash
deploy_curl https://deploy.sites.tzxys.cn/api/projects
```

Create a project, then publish the ZIP using the returned ID:

```bash
deploy_curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"name":"my-site"}' \
  https://deploy.sites.tzxys.cn/api/projects

deploy_curl -X POST \
  -F 'file=@/tmp/site.zip' \
  https://deploy.sites.tzxys.cn/api/projects/PROJECT_ID/deploy
```

For an existing project, list first and upload to its exact ID. The list contains your private projects and all public projects. The `POST /api/deploy` shortcut creates a new private project in the default subdomain mode, even when its name matches an existing one. Delete only when the user requested deletion:

```bash
deploy_curl -X DELETE \
  https://deploy.sites.tzxys.cn/api/projects/PROJECT_ID
```

After publishing, report the project name, project ID, URL, and deployment key. Open the returned URL once to confirm that the site responds.

## 5. Optional custom domain

The domain owner first creates an A record pointing the chosen hostname to this server. Then attach the hostname to a project:

```bash
deploy_curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{"domain":"www.example.com"}' \
  https://deploy.sites.tzxys.cn/api/projects/PROJECT_ID/domains
```

The domain initially has `pending` status. The host worker checks DNS, obtains a certificate through HTTP-01, configures Nginx, and changes the status to `active`. Check `GET /api/projects` for status or an error. A failed domain can be retried through `POST /api/projects/PROJECT_ID/domains/DOMAIN_ID/retry`. Attach only domains the user controls. Wildcard certificates require DNS-01 and are managed separately.
