| Server IP : 3.147.158.171 / Your IP : 216.73.216.216 Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.21 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /tsai/repo/builder/backend/configs/ |
Upload File : |
{
"name": "Create Site (scike.ai)",
"description": "Create a new WordPress site on the scike.ai server with SSL via certbot",
"parameters": [
{
"name": "PARAM_SLUG",
"label": "Site Slug (e.g., mysite)",
"type": "text",
"required": true
},
{
"name": "PARAM_SITE_NAME",
"label": "Site Name (e.g., My New Site)",
"type": "text",
"required": true
},
{
"name": "PARAM_ADMIN_EMAIL",
"label": "Admin Email (default: admin@scike.ai)",
"type": "text",
"required": false
},
{
"name": "PARAM_FAVICON_CHAR",
"label": "Favicon Character (default: first letter of slug)",
"type": "text",
"required": false
},
{
"name": "PARAM_FAVICON_BG",
"label": "Favicon Background Color",
"type": "color",
"required": false,
"options": [
{ "value": "azure", "hex": "#0074e9", "label": "Azure" },
{ "value": "blue", "hex": "#5a64ff", "label": "Blue" },
{ "value": "violet", "hex": "#944aff", "label": "Violet" },
{ "value": "magenta", "hex": "#d200d2", "label": "Magenta" },
{ "value": "rose", "hex": "#e80074", "label": "Rose" },
{ "value": "red", "hex": "#ef0000", "label": "Red" },
{ "value": "orange", "hex": "#bc5d00", "label": "Orange" },
{ "value": "yellow", "hex": "#7b7b00", "label": "Yellow" },
{ "value": "chartreuse", "hex": "#418700", "label": "Chartreuse" },
{ "value": "green", "hex": "#038b00", "label": "Green" },
{ "value": "spring-green", "hex": "#008942", "label": "Spring Green" },
{ "value": "cyan", "hex": "#008585", "label": "Cyan" },
{ "value": "black", "hex": "#000000", "label": "Black" },
{ "value": "gray", "hex": "#6b7280", "label": "Gray" }
]
},
{
"name": "PARAM_FAVICON_FG",
"label": "Favicon Text Color",
"type": "color",
"required": false,
"options": [
{ "value": "white", "hex": "#ffffff", "label": "White" },
{ "value": "black", "hex": "#000000", "label": "Black" },
{ "value": "gray", "hex": "#6b7280", "label": "Gray" }
]
}
],
"steps": [
{
"name": "Check PHP CLI",
"step_type": "shell",
"command": "which php && php --version",
"timeout": 30
},
{
"name": "Check WP-CLI",
"step_type": "shell",
"command": "which wp && wp --version",
"timeout": 30
},
{
"name": "Check MySQL CLI",
"step_type": "shell",
"command": "which mysql && mysql --version",
"timeout": 30
},
{
"name": "Check site directory does not exist",
"step_type": "shell",
"command": "if [ -d \"/data/tsai/sites/scike-${PARAM_SLUG}\" ]; then echo \"Error: Site directory /data/tsai/sites/scike-${PARAM_SLUG} already exists\" && exit 1; fi && echo \"Directory check passed\"",
"timeout": 30
},
{
"name": "Check database does not exist",
"step_type": "shell",
"command": "if mysql -u root -p1@dolphin -e \"USE scike_${PARAM_DB_SLUG}\" 2>/dev/null; then echo \"Error: Database scike_${PARAM_DB_SLUG} already exists\" && exit 1; fi && echo \"Database check passed\"",
"timeout": 30
},
{
"name": "Inspect parameters",
"step_type": "shell",
"command": "echo \"Creating site: slug=${PARAM_SLUG}, wp_domain=${PARAM_SLUG}.scike.ai, cb_domain=chat-${PARAM_SLUG}.scike.ai\"",
"timeout": 10
},
{
"name": "Create MySQL database",
"step_type": "shell",
"command": "mysql -u root -p1@dolphin -e \"CREATE DATABASE IF NOT EXISTS scike_${PARAM_DB_SLUG}\"",
"timeout": 60
},
{
"name": "Download WordPress core",
"step_type": "shell",
"command": "mkdir -p /data/tsai/sites/scike-${PARAM_SLUG} && wp core download --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 180
},
{
"name": "Generate wp-config.php",
"step_type": "shell",
"command": "wp config create --path=/data/tsai/sites/scike-${PARAM_SLUG} --dbname=scike_${PARAM_DB_SLUG} --dbuser=root --dbpass=1@dolphin --dbhost=localhost",
"timeout": 60
},
{
"name": "Configure JWT Auth and URLs in wp-config.php",
"step_type": "shell",
"command": "wp config set JWT_AUTH_SECRET_KEY \"$(openssl rand -base64 32)\" --path=/data/tsai/sites/scike-${PARAM_SLUG} && wp config set JWT_AUTH_CORS_ENABLE true --raw --path=/data/tsai/sites/scike-${PARAM_SLUG} && wp config set WP_HOME \"https://${PARAM_SLUG}.scike.ai\" --path=/data/tsai/sites/scike-${PARAM_SLUG} && wp config set WP_SITEURL \"https://${PARAM_SLUG}.scike.ai\" --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Install WordPress",
"step_type": "shell",
"command": "wp core install --path=/data/tsai/sites/scike-${PARAM_SLUG} --url=\"https://${PARAM_SLUG}.scike.ai\" --title=\"${PARAM_SITE_NAME}\" --admin_user=admin --admin_password=33Friday@33 --admin_email=${PARAM_ADMIN_EMAIL:-admin@scike.ai} --skip-email",
"timeout": 120
},
{
"name": "Generate admin password reset URL",
"step_type": "shell",
"command": "wp eval 'echo \"PASSWORD_RESET_URL=\" . network_site_url(\"wp-login.php?action=rp&key=\" . get_password_reset_key(get_user_by(\"login\",\"admin\")) . \"&login=admin\", \"login\") . \"\\n\";' --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 30
},
{
"name": "Install JWT Auth plugin",
"step_type": "shell",
"command": "wp plugin install jwt-authentication-for-wp-rest-api --activate --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 120
},
{
"name": "Install tsai-plugin",
"step_type": "shell",
"command": "ln -sfn ../../../../plugins/tsai-plugin /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/plugins/tsai-plugin && wp plugin activate tsai-plugin --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 120
},
{
"name": "Set TSAI plugin defaults",
"step_type": "shell",
"command": "wp option update tsai_api_url 'https://api.scike.ai/api/v1' --path=/data/tsai/sites/scike-${PARAM_SLUG} && wp option update tsai_ratings_enabled 0 --path=/data/tsai/sites/scike-${PARAM_SLUG} && wp option update tsai_status_message 'Under Construction' --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Install tsai-compliance plugin",
"step_type": "shell",
"command": "ln -sfn ../../../../plugins/tsai-compliance /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/plugins/tsai-compliance && wp plugin activate tsai-compliance --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 120
},
{
"name": "Install SMTP Mailer plugin",
"step_type": "shell",
"command": "ln -sfn ../../../../plugins/smtp-mailer /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/plugins/smtp-mailer && wp plugin activate smtp-mailer --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 120
},
{
"name": "Configure SMTP Mailer (Microsoft 365 relay)",
"step_type": "shell",
"command": "PW_B64=$(php -d error_reporting=0 -r 'include \"/data/tsai/store/web/sites/default/settings.php\"; echo base64_encode($config[\"smtp.settings\"][\"smtp_password\"] ?? \"\");') && if [ -z \"$PW_B64\" ]; then echo \"Error: could not read SMTP password from store settings.php\" && exit 1; fi && wp option update smtp_mailer_options \"{\\\"smtp_host\\\":\\\"smtp.office365.com\\\",\\\"smtp_auth\\\":\\\"true\\\",\\\"smtp_username\\\":\\\"john@scike.ai\\\",\\\"smtp_password\\\":\\\"$PW_B64\\\",\\\"type_of_encryption\\\":\\\"tls\\\",\\\"smtp_port\\\":\\\"587\\\",\\\"from_email\\\":\\\"support@scike.ai\\\",\\\"from_name\\\":\\\"${PARAM_SITE_NAME}\\\",\\\"force_from_address\\\":\\\"1\\\",\\\"disable_ssl_verification\\\":\\\"\\\"}\" --format=json --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Install twentytwentyfive-tsai theme",
"step_type": "shell",
"command": "ln -sfn ../../../../themes/twentytwentyfive-tsai /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/themes/twentytwentyfive-tsai && wp theme activate twentytwentyfive-tsai --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Create WordPress service user",
"step_type": "shell",
"command": "wp user create service service@scike.ai --role=administrator --user_pass='09775e5b883684ce91f36c43f149d52e0768e40b' --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Create WordPress symlink in /data/www/html",
"step_type": "shell",
"command": "ln -s /data/tsai/sites/scike-${PARAM_SLUG} /data/www/html/${PARAM_SLUG}.scike.ai",
"timeout": 30
},
{
"name": "Set permalink structure",
"step_type": "shell",
"command": "wp option update permalink_structure \"/%postname%/\" --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Create .htaccess for permalinks and JWT auth",
"step_type": "shell",
"command": "cat > /data/tsai/sites/scike-${PARAM_SLUG}/.htaccess << 'EOF'\n# BEGIN WordPress\n<IfModule mod_rewrite.c>\nRewriteEngine On\nRewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\nRewriteBase /\nRewriteRule ^index\\.php$ - [L]\nRewriteCond %{REQUEST_FILENAME} !-f\nRewriteCond %{REQUEST_FILENAME} !-d\nRewriteRule . /index.php [L]\n</IfModule>\n# END WordPress\nEOF",
"timeout": 30
},
{
"name": "Symlink WP apps from cb-build",
"step_type": "shell",
"command": "mkdir -p /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/uploads/tsai && for app in banner sas player; do ln -sfn /data/cb-build/wp-shared/$app /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/uploads/tsai/$app; done",
"timeout": 60
},
{
"name": "Set uploads directory permissions for Apache",
"step_type": "shell",
"command": "sudo chgrp -R apache /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/uploads && sudo find /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/uploads -type d -exec chmod g+ws {} \\; && sudo find /data/tsai/sites/scike-${PARAM_SLUG}/wp-content/uploads -type f -exec chmod g+w {} \\;",
"timeout": 30
},
{
"name": "Write welcome post content",
"step_type": "shell",
"command": "cat > /tmp/welcome-post.html << CONTENT\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">Your Sites</h2>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Here are the links to your new sites. Bookmark these for quick access:</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:list -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li><strong>Chatbot:</strong> <a href=\"https://chat-${PARAM_SLUG}.scike.ai\">https://chat-${PARAM_SLUG}.scike.ai</a></li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>WordPress Admin:</strong> <a href=\"https://${PARAM_SLUG}.scike.ai/wp-admin/\">https://${PARAM_SLUG}.scike.ai/wp-admin/</a></li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><strong>WordPress Site:</strong> <a href=\"https://${PARAM_SLUG}.scike.ai\">https://${PARAM_SLUG}.scike.ai</a></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">TSAI Plugin Shortcodes</h2>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>The TSAI plugin provides shortcodes you can use in any page or post to embed chatbot widgets.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">[tsai_banner] — Banner / Affiliates Widget</h3>\n<!-- /wp:heading -->\n\n<!-- wp:list -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li><code>mode</code>: inline (default), modal, newtab</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>banner_id</code>: affiliates (default), affiliates-mini</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>theme</code>: dark (default), light</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>width</code>, <code>height</code>, <code>label</code></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">[tsai_sas] — Sales & Support Chat Widget</h3>\n<!-- /wp:heading -->\n\n<!-- wp:list -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li><code>mode</code>: inline, modal (default), newtab</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>name</code>: character slug (default: alma)</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>width</code>, <code>height</code>, <code>label</code></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">[tsai_player] — Player App</h3>\n<!-- /wp:heading -->\n\n<!-- wp:list -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li><code>mode</code>: inline (default), modal, newtab</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>route</code>: path within player (e.g., <code>character/alma</code>)</li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><code>width</code>, <code>height</code>, <code>label</code></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:heading {\"level\":3} -->\n<h3 class=\"wp-block-heading\">Examples</h3>\n<!-- /wp:heading -->\n\n<!-- wp:code -->\n<pre class=\"wp-block-code\"><code>[tsai_sas mode=\"modal\" name=\"alma\" label=\"Chat with Alma\"]\n[tsai_banner theme=\"light\"]\n[tsai_player mode=\"inline\" route=\"character/alma\" height=\"800px\"]</code></pre>\n<!-- /wp:code -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">Customizing Your Site</h2>\n<!-- /wp:heading -->\n\n<!-- wp:list -->\n<ul class=\"wp-block-list\"><!-- wp:list-item -->\n<li><a href=\"https://wordpress.org/documentation/article/wordpress-block-editor/\">WordPress Block Editor Guide</a></li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><a href=\"https://learn.wordpress.org/tutorials/\">WordPress Tutorials</a></li>\n<!-- /wp:list-item -->\n\n<!-- wp:list-item -->\n<li><a href=\"https://wordpress.org/support/\">WordPress Support</a></li>\n<!-- /wp:list-item --></ul>\n<!-- /wp:list -->\n\n<!-- wp:paragraph -->\n<p><em>Installation completed: $(date)</em></p>\n<!-- /wp:paragraph -->\nCONTENT",
"timeout": 30
},
{
"name": "Create welcome post",
"step_type": "shell",
"command": "wp post create /tmp/welcome-post.html --post_type=post --post_title=\"Welcome to ${PARAM_SITE_NAME}\" --post_status=private --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Create archive page",
"step_type": "shell",
"command": "wp post create --post_type=page --post_title='Archives' --post_name=archives --post_status=publish --post_content='<!-- wp:archives {\"showPostCounts\":true} /-->' --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Configure navigation menu (Archives + Schedule)",
"step_type": "shell",
"command": "wp post create --post_type=wp_navigation --post_status=publish --post_title='Navigation' --post_content='<!-- wp:page-list /--> <!-- wp:navigation-link {\"label\":\"Schedule\",\"url\":\"/schedule/\",\"kind\":\"custom\",\"isTopLevelLink\":true} /-->' --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Generate and deploy favicon",
"step_type": "shell",
"command": "CHAR=${PARAM_FAVICON_CHAR:-$(echo ${PARAM_SLUG} | cut -c1 | tr '[:lower:]' '[:upper:]')} && BG=${PARAM_FAVICON_BG:-azure} && FG=${PARAM_FAVICON_FG:-white} && /data/tsai/builder/backend/venv/bin/python /data/tsai/builder/backend/scripts/generate_favicon.py \"$CHAR\" \"$BG\" \"$FG\" /data/tsai/sites/scike-${PARAM_SLUG}/favicon.svg",
"timeout": 60
},
{
"name": "Register favicon as WordPress Site Icon",
"step_type": "shell",
"command": "ICON_ID=$(wp media import /data/tsai/sites/scike-${PARAM_SLUG}/favicon.png --title='Site Icon' --porcelain --path=/data/tsai/sites/scike-${PARAM_SLUG}) && wp option update site_icon $ICON_ID --path=/data/tsai/sites/scike-${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Create Drupal user",
"step_type": "shell",
"command": "curl --fail-with-body -X POST http://127.0.0.1:8000/api/v1/cms/user/ -H \"Content-Type: application/json\" -d \"{\\\"username\\\": \\\"${PARAM_SLUG}\\\", \\\"email_domain\\\": \\\"scike.ai\\\"}\"",
"timeout": 60
},
{
"name": "Assign site_owner role to Drupal user",
"step_type": "shell",
"command": "/data/tsai/drupal/vendor/bin/drush --root=/data/tsai/drupal/web user:role:add site_owner ${PARAM_SLUG}",
"timeout": 60
},
{
"name": "Create Drupal file storage directories",
"step_type": "shell",
"command": "sudo mkdir -p /data/tsai/drupal/web/sites/default/files/scike/${PARAM_SLUG}/{create,edit,variant,upload} && sudo chown -R apache:apache /data/tsai/drupal/web/sites/default/files/scike/${PARAM_SLUG} && sudo find /data/tsai/drupal/web/sites/default/files/scike/${PARAM_SLUG} -type d -exec chmod g+ws {} \\;",
"timeout": 30
},
{
"name": "Add site config to API",
"step_type": "shell",
"command": "curl --fail-with-body -X POST http://127.0.0.1:8000/api/v1/site/add/ -H \"Content-Type: application/json\" -d \"{\\\"cb_host\\\": \\\"chat-${PARAM_SLUG}.scike.ai\\\", \\\"wp_host\\\": \\\"https://${PARAM_SLUG}.scike.ai\\\", \\\"wp_dir\\\": \\\"scike-${PARAM_SLUG}\\\", \\\"slug\\\": \\\"${PARAM_SLUG}\\\", \\\"drupal_user\\\": \\\"${PARAM_SLUG}\\\"}\"",
"timeout": 60
},
{
"name": "Register site with article/comment cron",
"step_type": "shell",
"command": "ENV_FILE=/data/tsai/api/cron/tsai-cron.env\nif [ ! -f \"$ENV_FILE\" ]; then echo \"ERROR: $ENV_FILE not found; ${PARAM_SLUG} would never post\" >&2; exit 1; fi\nif ! grep -qE '^SITES=\"[^\"]*\"$' \"$ENV_FILE\"; then echo \"ERROR: no SITES=\\\"...\\\" line in $ENV_FILE\" >&2; exit 1; fi\n. \"$ENV_FILE\"\nfor s in $SITES; do\n if [ \"$s\" = \"${PARAM_SLUG}\" ]; then echo \"Already registered with cron: ${PARAM_SLUG}\"; exit 0; fi\ndone\ncp \"$ENV_FILE\" \"$ENV_FILE.bak\"\nsed -i 's/^SITES=\"\\(.*\\)\"$/SITES=\"\\1 ${PARAM_SLUG}\"/' \"$ENV_FILE\"\n. \"$ENV_FILE\"\nfor s in $SITES; do\n if [ \"$s\" = \"${PARAM_SLUG}\" ]; then echo \"Registered with cron: SITES=\\\"$SITES\\\"\"; exit 0; fi\ndone\necho \"ERROR: failed to add ${PARAM_SLUG} to SITES in $ENV_FILE\" >&2; exit 1",
"timeout": 30
},
{
"name": "Trigger site index rebuild",
"step_type": "shell",
"command": "curl -s -X POST http://127.0.0.1:8000/api/v1/site/index/rebuild/",
"timeout": 15,
"continue_on_failure": true
}
],
"stop_on_failure": true
}