createos-fullstack-skills (#4)

This commit is contained in:
pratikbin
2026-02-19 16:35:27 +05:30
parent 773aa1177c
commit b95d993851
7 changed files with 1088 additions and 877 deletions
+1077 -180
View File
File diff suppressed because it is too large Load Diff
+2 -7
View File
@@ -92,13 +92,10 @@ For image/upload projects:
"type": "vcs",
"status": "active",
"createdAt": "2025-01-15T10:30:00Z",
"url": "https://my-app.nodeops.app"
"url": "https://my-app.createos.io"
}
```
**Note:** Always use the `url` field from the response. Never construct URLs manually - the domain may vary.
```
---
### List Projects
@@ -259,10 +256,8 @@ For image/upload projects:
"image": "nginx:latest",
"createdAt": "2025-01-15T10:30:00Z",
"deployedAt": "2025-01-15T10:35:00Z",
"url": "https://my-app.nodeops.app"
"url": "https://deployment-hash.createos.io"
}
**Important:** The `url` field contains the actual live URL. Always share this exact URL with users - never construct URLs manually.
```
**Deployment Statuses:** `queued`, `building`, `deploying`, `deployed`, `failed`, `sleeping`
-428
View File
@@ -1,428 +0,0 @@
# CreateOS Core Skills Reference
Detailed documentation for all CreateOS operations. Load this reference when you need specifics beyond the quick start.
---
## Project Management
### Create Projects
#### Project Types
| Type | Description | Best For |
|------|-------------|----------|
| `vcs` | GitHub-connected repository | Production apps with CI/CD |
| `image` | Docker container deployment | Pre-built images, complex deps |
| `upload` | Direct file upload | Quick prototypes, static sites |
#### VCS Project
```json
CreateProject({
"uniqueName": "my-nextjs-app",
"displayName": "My Next.js Application",
"type": "vcs",
"source": {
"vcsName": "github",
"vcsInstallationId": "12345678",
"vcsRepoId": "98765432"
},
"settings": {
"framework": "nextjs",
"runtime": "node:20",
"port": 3000,
"directoryPath": ".",
"installCommand": "npm install",
"buildCommand": "npm run build",
"runCommand": "npm start",
"buildVars": {"NODE_ENV": "production"},
"runEnvs": {"DATABASE_URL": "postgresql://..."},
"ignoreBranches": ["develop", "feature/*"],
"hasDockerfile": false,
"useBuildAI": false
},
"appId": "optional-app-uuid",
"enabledSecurityScan": true
})
```
**Prerequisites**: GitHub account connected, repository access granted
**Pitfalls**: Incorrect `vcsRepoId` causes failures; missing `port` fails health checks; `buildVars` (build-time) vs `runEnvs` (runtime)
#### Image Project
```json
CreateProject({
"uniqueName": "my-api-service",
"displayName": "My API Service",
"type": "image",
"source": {},
"settings": {
"port": 8080,
"runEnvs": {"API_KEY": "secret", "LOG_LEVEL": "info"}
}
})
```
#### Upload Project
```json
CreateProject({
"uniqueName": "quick-prototype",
"displayName": "Quick Prototype",
"type": "upload",
"source": {},
"settings": {
"framework": "express",
"runtime": "node:20",
"port": 3000,
"installCommand": "npm install",
"buildCommand": "npm run build",
"buildDir": "dist",
"useBuildAI": true
}
})
```
### Update Project Settings
```json
UpdateProjectSettings(project_id, {
"framework": "nextjs",
"runtime": "node:22",
"port": 3000,
"installCommand": "npm ci",
"buildCommand": "npm run build",
"runCommand": "npm start",
"buildDir": ".next",
"buildVars": {"NODE_ENV": "production"},
"runEnvs": {"NEW_VAR": "value"},
"ignoreBranches": ["wip/*"],
"hasDockerfile": false,
"useBuildAI": false
})
```
**Edge cases**: Changing `runtime` triggers rebuild; changing `port` requires redeployment; `ignoreBranches` affects future pushes only
### Project Lifecycle
| Operation | Tool |
|-----------|------|
| List | `ListProjects(limit?, offset?, name?, type?, status?, app?)` |
| Get | `GetProject(project_id)` |
| Update | `UpdateProject(project_id, {displayName, description?, enabledSecurityScan?})` |
| Delete | `DeleteProject(project_id)` — async |
| Check name | `CheckProjectUniqueName({uniqueName})` |
### Project Transfer
```
1. Owner: GetProjectTransferUri(project_id) → {uri, token} (valid 6 hours)
2. Owner: Share URI with recipient
3. Recipient: TransferProject(project_id, token)
4. Audit: ListProjectTransferHistory(project_id)
```
---
## Deployments
### Trigger Deployments
**VCS Projects** — Push to GitHub (auto) or manual:
```json
TriggerLatestDeployment(project_id, branch?)
```
**Image Projects**:
```json
CreateDeployment(project_id, {"image": "nginx:latest"})
```
**Upload Projects**:
```json
// Text files
UploadDeploymentFiles(project_id, {
"files": [
{"path": "package.json", "content": "{...}"},
{"path": "index.js", "content": "..."}
]
})
// Binary files (base64)
UploadDeploymentBase64Files(project_id, {
"files": [{"path": "logo.png", "content": "iVBORw0KGgo..."}]
})
// ZIP archive
UploadDeploymentZip(project_id, {file: zipBinaryData})
```
**Limits**: Max 100 files per upload; use ZIP for larger projects
### Deployment States
```
queued → building → deploying → deployed
↓ ↓
failed sleeping
```
| State | Actions |
|-------|---------|
| `queued` | Cancel |
| `building` | Cancel, View logs |
| `deploying` | Wait |
| `deployed` | Assign to env |
| `failed` | Retry, View logs |
| `sleeping` | Wake up |
### Deployment Operations
| Operation | Tool |
|-----------|------|
| List | `ListDeployments(project_id, limit?, offset?)` |
| Get | `GetDeployment(project_id, deployment_id)` |
| Retry | `RetriggerDeployment(project_id, deployment_id, settings?)` |
| Cancel | `CancelDeployment(project_id, deployment_id)` |
| Delete | `DeleteDeployment(project_id, deployment_id)` |
| Wake | `WakeupDeployment(project_id, deployment_id)` |
| Download | `DownloadDeployment(project_id, deployment_id)` — upload only |
### Debug with Logs
```json
// Build logs
GetBuildLogs(project_id, deployment_id, skip?)
// Runtime logs
GetDeploymentLogs(project_id, deployment_id, since-seconds?)
// Environment logs
GetProjectEnvironmentLogs(project_id, environment_id, since-seconds?)
```
---
## Environments
### Create Environment
**VCS Project** (branch required):
```json
CreateProjectEnvironment(project_id, {
"displayName": "Production",
"uniqueName": "production",
"description": "Live production environment",
"branch": "main",
"isAutoPromoteEnabled": true,
"resources": {"cpu": 500, "memory": 1024, "replicas": 2},
"settings": {
"runEnvs": {
"NODE_ENV": "production",
"DATABASE_URL": "postgresql://..."
}
}
})
```
**Image Project** (no branch):
```json
CreateProjectEnvironment(project_id, {
"displayName": "Production",
"uniqueName": "production",
"resources": {"cpu": 500, "memory": 1024, "replicas": 2},
"settings": {"runEnvs": {"NODE_ENV": "production"}}
})
```
### Resource Limits
| Resource | Min | Max | Unit |
|----------|-----|-----|------|
| CPU | 200 | 500 | millicores |
| Memory | 500 | 1024 | MB |
| Replicas | 1 | 3 | instances |
```json
UpdateProjectEnvironmentResources(project_id, environment_id, {
"cpu": 500, "memory": 1024, "replicas": 3
})
```
**Notes**: Replicas > 1 requires stateless app; memory exceeded = OOM kill; CPU exceeded = throttle
### Environment Variables
```json
UpdateProjectEnvironmentEnvironmentVariables(project_id, environment_id, {
"runEnvs": {
"DATABASE_URL": "postgresql://...",
"API_KEY": "secret"
},
"port": 8080 // Image projects only
})
```
### Deployment Assignment
```json
AssignDeploymentToProjectEnvironment(project_id, environment_id, {
"deploymentId": "deployment-uuid"
})
```
Use for: rollbacks, blue-green switching, canary releases
---
## Domains
### Add Custom Domain
```json
CreateDomain(project_id, {
"name": "api.mycompany.com",
"environmentId": "optional-env-uuid"
})
```
Response includes CNAME target for DNS configuration.
### Verification Flow
1. `CreateDomain` → Status: pending
2. Configure DNS CNAME at registrar
3. Wait for propagation (up to 48h)
4. `RefreshDomain(project_id, domain_id)` → Status: active
### Domain Operations
| Operation | Tool |
|-----------|------|
| List | `ListDomains(project_id)` |
| Verify | `RefreshDomain(project_id, domain_id)` |
| Assign | `UpdateDomainEnvironment(project_id, domain_id, {environmentId})` |
| Delete | `DeleteDomain(project_id, domain_id)` |
---
## GitHub Integration
### Connect Account
```json
InstallGithubApp({
"installationId": 12345678,
"code": "oauth-code-from-github"
})
```
### Repository Discovery
```json
ListConnectedGithubAccounts()
ListGithubRepositories(installation_id)
ListGithubRepositoryBranches(installation_id, "owner/repo")
GetGithubRepositoryContent(installation_id, {"repository": "owner/repo", "branch": "main"})
```
### Auto-Deploy Config
```json
// Ignore branches
UpdateProjectSettings(project_id, {"ignoreBranches": ["develop", "feature/*"]})
// Auto-promote to environment
CreateProjectEnvironment(project_id, {"branch": "main", "isAutoPromoteEnabled": true, ...})
```
---
## Analytics
### Comprehensive Analytics
```json
GetProjectEnvironmentAnalytics(project_id, environment_id, {
"start": 1704067200, "end": 1704070800
})
```
### Individual Metrics
| Metric | Tool |
|--------|------|
| Overall | `GetProjectEnvironmentAnalyticsOverallRequests` |
| RPM | `GetProjectEnvironmentAnalyticsRPM` |
| Success % | `GetProjectEnvironmentAnalyticsSuccessPercentage` |
| Time series | `GetProjectEnvironmentAnalyticsRequestsOverTime` |
| Top paths | `GetProjectEnvironmentAnalyticsTopHitPaths` |
| Errors | `GetProjectEnvironmentAnalyticsTopErrorPaths` |
| Distribution | `GetEnvAnalyticsReqDistribution` |
---
## Security
### Vulnerability Scanning
```json
// Enable
UpdateProject(project_id, {"enabledSecurityScan": true})
// Trigger
TriggerSecurityScan(project_id, deployment_id)
// View
GetSecurityScan(project_id, deployment_id)
// Download report
GetSecurityScanDownloadUri(project_id, deployment_id)
// Retry
RetriggerSecurityScan(project_id, deployment_id)
```
---
## Apps (Organization)
### Group Projects
```json
CreateApp({"name": "E-Commerce Platform", "description": "...", "color": "#3B82F6"})
AddProjectsToApp(app_id, {"projectIds": ["uuid1", "uuid2"]})
RemoveProjectsFromApp(app_id, {"projectIds": ["uuid1"]})
ListProjectsByApp(app_id)
```
Deleting app unassigns projects (doesn't delete them).
---
## API Keys
```json
// Create (key shown only once!)
CreateAPIKey({"name": "prod-key", "description": "...", "expiryAt": "2025-12-31T23:59:59Z"})
// List
ListAPIKeys()
// Revoke
RevokeAPIKey(api_key_id)
```
---
## User & Quotas
```json
GetCurrentUser()
GetQuotas() // {projects: {used, limit}, ...}
GetSupportedProjectTypes()
```
@@ -128,7 +128,7 @@ app.get("/mcp", async (req, res) => {
app.listen(3000);
```
**MCP Endpoint:** Fetch project URL from `GetProject(project_id)` response, then append `/mcp` (e.g., if `url` is `https://mcp-server.nodeops.app`, MCP endpoint is `https://mcp-server.nodeops.app/mcp`)
**MCP Endpoint:** `https://{uniqueName}.createos.io/mcp`
---
@@ -341,7 +341,7 @@ app.listen(3000);
"runCommand": "python bot.py",
"runEnvs": {
"TELEGRAM_TOKEN": "${TELEGRAM_TOKEN}",
"WEBHOOK_URL": "${DEPLOYMENT_URL}/webhook" // Set after deployment - get URL from GetProject response
"WEBHOOK_URL": "https://telegram-bot.createos.io/webhook"
}
}
}
@@ -1,108 +0,0 @@
# CreateOS Troubleshooting Guide
Quick reference for diagnosing and resolving common issues.
---
## Common Errors
| Error | Diagnosis | Solution |
|-------|-----------|----------|
| Build failed | `GetBuildLogs` | Fix code errors, check dependencies |
| Runtime crash | `GetDeploymentLogs` | Check startup errors, missing env vars |
| Health check fail | App not responding on port | Verify `port` setting matches app |
| 502 Bad Gateway | App crashed after deploy | Check logs, increase memory if OOM |
| Domain pending | DNS not propagated | Wait 24-48h, verify CNAME record |
| Quota exceeded | `GetQuotas` | Upgrade plan or delete unused |
| Deployment sleeping | Idle timeout | `WakeupDeployment` or add keep-alive |
---
## Debugging Workflow
1. **Check deployment status**:
```json
GetDeployment(project_id, deployment_id)
```
2. **If `building` or `failed`** — check build logs:
```json
GetBuildLogs(project_id, deployment_id)
```
3. **If `deployed` but errors** — check runtime logs:
```json
GetDeploymentLogs(project_id, deployment_id, 300)
```
4. **If 502/503 errors** — check resources:
- Memory too low → OOM kills → increase memory
- CPU throttled → slow responses → increase CPU
---
## Edge Cases
### High-Load Scenarios
- Max 3 replicas per environment
- Consider external load balancer for higher scale
- Monitor RPM via `GetProjectEnvironmentAnalyticsRPM`
### Monorepo Projects
- Set `directoryPath` to subdirectory in settings
- Use `GetGithubRepositoryContent` to explore structure
### Private npm/pip Packages
- Add auth tokens to `buildVars`:
```json
"buildVars": {"NPM_TOKEN": "..."}
```
- Include `.npmrc` or `pip.conf` in repo
### Long-Running Builds
- Build timeout: 15 minutes
- Use `hasDockerfile: true` for complex builds
- Pre-build images and use image project type
### Sleeping Deployments
Deployments sleep after idle timeout. Options:
1. `WakeupDeployment(project_id, deployment_id)` — manual wake
2. Add health check endpoint that gets pinged regularly
3. Use external uptime monitor to keep alive
---
## Best Practices
### Security
1. Never hardcode secrets — use `runEnvs`
2. Enable security scanning on projects
3. Rotate API keys with reasonable expiry
4. Use environment isolation for different secrets
### Performance
1. Start small, scale based on metrics
2. Use 2+ replicas for production availability
3. Monitor analytics for error spikes
4. Use `npm ci` over `npm install` for faster builds
### Reliability
1. Test auto-promote in staging first
2. Keep previous deployments for rollbacks
3. Ensure `port` matches app's actual listen port
4. Handle sleeping deployments appropriately
### Organization
1. Group related projects with Apps
2. Use naming convention: `{app}-{service}-{env}`
3. Document environments clearly
4. Clean up unused projects and deployments
+7 -17
View File
@@ -86,12 +86,10 @@ EOF
local result
result=$(api_check POST "/v1/projects" "$payload")
local project_id
project_id=$(echo "$result" | jq -r '.data.id // .id // empty')
local project_url
project_url=$(echo "$result" | jq -r '.data.url // .url // empty')
project_id=$(echo "$result" | jq -r '.data.id // empty')
success "Agent deployed! Project ID: $project_id"
[ -n "$project_url" ] && echo "URL: $project_url" || echo "URL: Fetch via GetProject($project_id)"
echo "URL: https://$name.createos.io"
}
# Deploy MCP Server
@@ -137,12 +135,10 @@ EOF
local result
result=$(api_check POST "/v1/projects" "$payload")
local project_id
project_id=$(echo "$result" | jq -r '.data.id // .id // empty')
local project_url
project_url=$(echo "$result" | jq -r '.data.url // .url // empty')
project_id=$(echo "$result" | jq -r '.data.id // empty')
success "MCP Server deployed! Project ID: $project_id"
[ -n "$project_url" ] && echo "MCP Endpoint: ${project_url}/sse" || echo "MCP Endpoint: Fetch via GetProject($project_id), append /sse"
echo "MCP Endpoint: https://$name.createos.io/sse"
}
# Deploy FastAPI Service
@@ -183,13 +179,7 @@ EOF
local result
result=$(api_check POST "/v1/projects" "$payload")
local project_id
project_id=$(echo "$result" | jq -r '.data.id // .id // empty')
local project_url
project_url=$(echo "$result" | jq -r '.data.url // .url // empty')
success "API deployed! Project ID: $project_id"
[ -n "$project_url" ] && echo "URL: $project_url" || echo "URL: Fetch via GetProject($project_id)"
success "API deployed! URL: https://$name.createos.io"
}
# Deploy Bot (Docker image)
-135
View File
@@ -1,135 +0,0 @@
#!/bin/bash
# Skill Validation Script for CreateOS
set -e
SKILL_DIR="$(cd "$(dirname "$0")/.." && pwd)"
ERRORS=0
echo "=== CreateOS Skill Validation ==="
echo ""
# 1. Check SKILL.md exists and has required fields
echo "1. Checking SKILL.md structure..."
if [ ! -f "$SKILL_DIR/SKILL.md" ]; then
echo " ❌ SKILL.md not found"
ERRORS=$((ERRORS + 1))
else
# Check frontmatter
if ! head -20 "$SKILL_DIR/SKILL.md" | grep -q "^name:"; then
echo " ❌ Missing 'name' in frontmatter"
ERRORS=$((ERRORS + 1))
else
echo " ✅ name field present"
fi
if ! head -20 "$SKILL_DIR/SKILL.md" | grep -q "^description:"; then
echo " ❌ Missing 'description' in frontmatter"
ERRORS=$((ERRORS + 1))
else
echo " ✅ description field present"
fi
if ! head -20 "$SKILL_DIR/SKILL.md" | grep -q "^allowed-tools:"; then
echo " ⚠️ Missing 'allowed-tools' (optional but recommended)"
else
echo " ✅ allowed-tools field present"
fi
fi
# 2. Check line count
echo ""
echo "2. Checking SKILL.md length..."
LINES=$(wc -l < "$SKILL_DIR/SKILL.md")
if [ "$LINES" -gt 500 ]; then
echo " ❌ SKILL.md is $LINES lines (should be <500)"
ERRORS=$((ERRORS + 1))
else
echo " ✅ SKILL.md is $LINES lines (under 500 limit)"
fi
# 3. Check description length
echo ""
echo "3. Checking description length..."
DESC_LEN=$(grep "^description:" "$SKILL_DIR/SKILL.md" | head -1 | wc -c)
if [ "$DESC_LEN" -gt 1024 ]; then
echo " ❌ Description is $DESC_LEN chars (max 1024)"
ERRORS=$((ERRORS + 1))
else
echo " ✅ Description is $DESC_LEN chars (under 1024 limit)"
fi
# 4. Check for hardcoded URLs
echo ""
echo "4. Checking for hardcoded createos.io URLs..."
HARDCODED=$(grep -r "createos\.io" "$SKILL_DIR" --include="*.md" --include="*.json" --include="*.sh" --include="*.py" 2>/dev/null | grep -v "NEVER construct" | grep -v "like \`https" | grep -v "tests/validate" || true)
if [ -n "$HARDCODED" ]; then
echo " ❌ Found hardcoded URLs:"
echo "$HARDCODED" | head -5
ERRORS=$((ERRORS + 1))
else
echo " ✅ No hardcoded createos.io URLs found"
fi
# 5. Check references exist
echo ""
echo "5. Checking reference files..."
for ref in "core-skills.md" "deployment-patterns.md" "api-reference.md" "troubleshooting.md"; do
if [ -f "$SKILL_DIR/references/$ref" ]; then
echo " ✅ references/$ref exists"
else
echo " ❌ references/$ref missing"
ERRORS=$((ERRORS + 1))
fi
done
# 6. Check config exists
echo ""
echo "6. Checking config..."
if [ -f "$SKILL_DIR/config/config.json" ]; then
if python3 -c "import json; json.load(open('$SKILL_DIR/config/config.json'))" 2>/dev/null; then
echo " ✅ config/config.json is valid JSON"
else
echo " ❌ config/config.json is invalid JSON"
ERRORS=$((ERRORS + 1))
fi
else
echo " ❌ config/config.json missing"
ERRORS=$((ERRORS + 1))
fi
# 7. Check scripts are executable
echo ""
echo "7. Checking scripts..."
for script in "deploy.sh" "quick-deploy.sh"; do
if [ -f "$SKILL_DIR/scripts/$script" ]; then
if [ -x "$SKILL_DIR/scripts/$script" ] || head -1 "$SKILL_DIR/scripts/$script" | grep -q "^#!/"; then
echo " ✅ scripts/$script exists"
else
echo " ⚠️ scripts/$script missing shebang"
fi
else
echo " ❌ scripts/$script missing"
ERRORS=$((ERRORS + 1))
fi
done
# 8. Check no duplicate content
echo ""
echo "8. Checking for README.md (should not exist)..."
if [ -f "$SKILL_DIR/README.md" ]; then
echo " ⚠️ README.md exists (not needed for skills)"
else
echo " ✅ No README.md (correct for skills)"
fi
# Summary
echo ""
echo "=== Validation Summary ==="
if [ "$ERRORS" -eq 0 ]; then
echo "✅ All checks passed! Skill is ready."
exit 0
else
echo "$ERRORS error(s) found. Please fix before using."
exit 1
fi