Files
gh-atxp-dev-claude-cloud/commands/deploy.md
2025-11-29 17:59:09 +08:00

6.2 KiB

name, description
name description
deploy Deploy the current working directory as a Claude agent to cloud.atxp.ai

Deploy Command

This command packages and deploys the current working directory to cloud.atxp.ai.

Prerequisites

  • ATXP_CONNECTION_STRING environment variable must be set with your ATXP connection URL
  • The connection string should contain a connection_token query parameter
  • curl and jq must be available in your PATH

IMPORTANT: When this command is complete, share the uploaded instance URL with the user! The URL is in this format: https://cloud.atxp.ai/${instanceId}.

Steps

1. Extract the connection token from ATXP_CONNECTION_STRING

The connection token is a query parameter in the connection URL:

# Extract connection_token from the URL
CONNECTION_TOKEN=$(echo "$ATXP_CONNECTION_STRING" | grep -o 'connection_token=[^&]*' | cut -d= -f2)

if [ -z "$CONNECTION_TOKEN" ]; then
  echo "Error: Could not extract connection_token from ATXP_CONNECTION_STRING"
  exit 1
fi

2. Create a zip file of the current directory

# Create a temporary zip file (using mktemp for security)
TEMP_BASE=$(mktemp /tmp/deploy-XXXXXX)
ZIP_FILE="${TEMP_BASE}.zip"
rm "$TEMP_BASE"  # Remove the temporary placeholder
echo "Creating deployment package..."

# Zip the current directory, excluding common files and sensitive data
zip -r "$ZIP_FILE" . \
  -x ".git/*" \
  -x "node_modules/*" \
  -x "*/node_modules/*" \
  -x ".atxp-instance" \
  -x ".DS_Store" \
  -x "*/.DS_Store" \
  -x ".env.local" \
  -x ".env.*.local" \
  -x "*/.env.local" \
  -x "*/.env.*.local" \
  -x ".env.development" \
  -x "*/.env.development" \
  -x ".env.test" \
  -x "*/.env.test" \
  -x ".npmrc" \
  -x "*/.npmrc" \
  -x ".netrc" \
  -x "*/.netrc" \
  -x ".aws/*" \
  -x "*/.aws/*" \
  -x "*.pem" \
  -x "*.key" \
  -x "*.p12" \
  -x "*.pfx" \
  > /dev/null

echo "Package created: $(du -h "$ZIP_FILE" | cut -f1)"

3. Check for existing instance ID

The instance ID is stored in .atxp-instance in the current directory:

INSTANCE_FILE=".atxp-instance"
INSTANCE_ID=""

if [ -f "$INSTANCE_FILE" ]; then
  INSTANCE_ID=$(cat "$INSTANCE_FILE")
  echo "Found existing instance: $INSTANCE_ID"
fi

4. Upload to cloud.atxp.ai

Create the authorization header using Basic Auth:

# Create Basic Auth header: base64(TOKEN:)
AUTH_HEADER="Authorization: Basic $(echo -n "${CONNECTION_TOKEN}:" | base64)"

Upload the zip file (create new or update existing):

if [ -z "$INSTANCE_ID" ]; then
  # Create new instance
  echo "Deploying new instance..."
  RESPONSE=$(curl -X POST https://cloud.atxp.ai/upload \
    -H "$AUTH_HEADER" \
    -F "file=@$ZIP_FILE" \
    -s)
else
  # Update existing instance
  echo "Updating instance $INSTANCE_ID..."
  RESPONSE=$(curl -X POST "https://cloud.atxp.ai/upload/$INSTANCE_ID" \
    -H "$AUTH_HEADER" \
    -F "file=@$ZIP_FILE" \
    -s)
fi

# Clean up temporary zip file
rm "$ZIP_FILE"

5. Parse response and store instance ID

# Check if upload was successful
SUCCESS=$(echo "$RESPONSE" | jq -r '.success')

if [ "$SUCCESS" = "true" ]; then
  INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.instanceId')
  MESSAGE=$(echo "$RESPONSE" | jq -r '.message')

  # Store instance ID for future deploys
  echo "$INSTANCE_ID" > "$INSTANCE_FILE"

  echo "✓ Deployment successful!"
  echo "Instance ID: $INSTANCE_ID"
  echo "$MESSAGE"
else
  echo "✗ Deployment failed"
  echo "$RESPONSE" | jq -r '.message // .error // .'
  exit 1
fi

6. Remember to share the instance URL with the user!

Again, the URL is in this format: https://cloud.atxp.ai/${instanceId}.

Complete Script

Here's the complete deployment script:

#!/bin/bash

# Extract connection token
CONNECTION_TOKEN=$(echo "$ATXP_CONNECTION_STRING" | grep -o 'connection_token=[^&]*' | cut -d= -f2)

if [ -z "$CONNECTION_TOKEN" ]; then
  echo "Error: Could not extract connection_token from ATXP_CONNECTION_STRING"
  exit 1
fi

# Create zip file (using mktemp for security)
TEMP_BASE=$(mktemp /tmp/deploy-XXXXXX)
ZIP_FILE="${TEMP_BASE}.zip"
rm "$TEMP_BASE"  # Remove the temporary placeholder
echo "Creating deployment package..."
zip -r "$ZIP_FILE" . \
  -x ".git/*" \
  -x "node_modules/*" \
  -x "*/node_modules/*" \
  -x ".atxp-instance" \
  -x ".DS_Store" \
  -x "*/.DS_Store" \
  -x ".env.local" \
  -x ".env.*.local" \
  -x "*/.env.local" \
  -x "*/.env.*.local" \
  -x ".env.development" \
  -x "*/.env.development" \
  -x ".env.test" \
  -x "*/.env.test" \
  -x ".npmrc" \
  -x "*/.npmrc" \
  -x ".netrc" \
  -x "*/.netrc" \
  -x ".aws/*" \
  -x "*/.aws/*" \
  -x "*.pem" \
  -x "*.key" \
  -x "*.p12" \
  -x "*.pfx" \
  > /dev/null
echo "Package created: $(du -h "$ZIP_FILE" | cut -f1)"

# Check for existing instance
INSTANCE_FILE=".atxp-instance"
INSTANCE_ID=""
if [ -f "$INSTANCE_FILE" ]; then
  INSTANCE_ID=$(cat "$INSTANCE_FILE")
  echo "Found existing instance: $INSTANCE_ID"
fi

# Create auth header
AUTH_HEADER="Authorization: Basic $(echo -n "${CONNECTION_TOKEN}:" | base64)"

# Upload
if [ -z "$INSTANCE_ID" ]; then
  echo "Deploying new instance..."
  RESPONSE=$(curl -X POST https://cloud.atxp.ai/upload \
    -H "$AUTH_HEADER" \
    -F "file=@$ZIP_FILE" \
    -s)
else
  echo "Updating instance $INSTANCE_ID..."
  RESPONSE=$(curl -X POST "https://cloud.atxp.ai/upload/$INSTANCE_ID" \
    -H "$AUTH_HEADER" \
    -F "file=@$ZIP_FILE" \
    -s)
fi

# Clean up
rm "$ZIP_FILE"

# Parse response
SUCCESS=$(echo "$RESPONSE" | jq -r '.success')

if [ "$SUCCESS" = "true" ]; then
  INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.instanceId')
  MESSAGE=$(echo "$RESPONSE" | jq -r '.message')

  echo "$INSTANCE_ID" > "$INSTANCE_FILE"

  echo "✓ Deployment successful!"
  echo "Instance ID: $INSTANCE_ID"
  echo "$MESSAGE"
else
  echo "✗ Deployment failed"
  echo "$RESPONSE" | jq -r '.message // .error // .'
  exit 1
fi

Error Handling

Possible errors:

  • 400 Bad Request: Invalid file type or no file uploaded
  • 401 Unauthorized: Invalid or missing connection token
  • 403 Forbidden: Trying to update an instance you don't own
  • 404 Not Found: Instance ID not found (stored ID may be stale)
  • 500 Internal Server Error: Server error during upload

If you receive a 404 error on update, delete the .atxp-instance file and try again to create a new instance.