100xprism 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +196 -0
- package/VERSION +1 -0
- package/adapters/antigravity.sh +14 -0
- package/adapters/claude-code.sh +160 -0
- package/adapters/codex.sh +13 -0
- package/adapters/copilot.sh +13 -0
- package/adapters/cursor.sh +13 -0
- package/adapters/gemini.sh +13 -0
- package/adapters/lib/__pycache__/modules.cpython-312.pyc +0 -0
- package/adapters/lib/modules.py +592 -0
- package/adapters/lib/shared.sh +83 -0
- package/adapters/lib/sync_plugins.py +113 -0
- package/adapters/windsurf.sh +15 -0
- package/bin/100xprism.js +29 -0
- package/get.sh +24 -0
- package/install-project.sh +82 -0
- package/install.sh +281 -0
- package/lib/adapters/windows.js +429 -0
- package/lib/bootstrap.js +33 -0
- package/lib/init.js +19 -0
- package/lib/install.js +18 -0
- package/lib/migrate.js +52 -0
- package/lib/platform.js +22 -0
- package/lib/update.js +29 -0
- package/modules/_lib/reference.md +77 -0
- package/modules/a11y-auditor/SKILL.md +151 -0
- package/modules/ab-test-setup/SKILL.md +266 -0
- package/modules/ab-test-setup/evals/evals.json +105 -0
- package/modules/ab-test-setup/references/sample-size-guide.md +263 -0
- package/modules/ab-test-setup/references/test-templates.md +277 -0
- package/modules/ad-creative/SKILL.md +362 -0
- package/modules/ad-creative/evals/evals.json +90 -0
- package/modules/ad-creative/references/generative-tools.md +637 -0
- package/modules/ad-creative/references/platform-specs.md +213 -0
- package/modules/ai-seo/SKILL.md +398 -0
- package/modules/ai-seo/evals/evals.json +90 -0
- package/modules/ai-seo/references/content-patterns.md +285 -0
- package/modules/ai-seo/references/platform-ranking-factors.md +152 -0
- package/modules/analytics-tracking/SKILL.md +309 -0
- package/modules/analytics-tracking/evals/evals.json +90 -0
- package/modules/analytics-tracking/references/event-library.md +260 -0
- package/modules/analytics-tracking/references/ga4-implementation.md +300 -0
- package/modules/analytics-tracking/references/gtm-implementation.md +390 -0
- package/modules/architect/SKILL.md +282 -0
- package/modules/branch/SKILL.md +105 -0
- package/modules/churn-prevention/SKILL.md +424 -0
- package/modules/churn-prevention/evals/evals.json +93 -0
- package/modules/churn-prevention/references/cancel-flow-patterns.md +316 -0
- package/modules/churn-prevention/references/dunning-playbook.md +408 -0
- package/modules/cloud-security/SKILL.md +240 -0
- package/modules/cold-email/SKILL.md +178 -0
- package/modules/cold-email/evals/evals.json +94 -0
- package/modules/cold-email/references/benchmarks.md +83 -0
- package/modules/cold-email/references/follow-up-sequences.md +81 -0
- package/modules/cold-email/references/frameworks.md +90 -0
- package/modules/cold-email/references/personalization.md +79 -0
- package/modules/cold-email/references/subject-lines.md +53 -0
- package/modules/commit/SKILL.md +195 -0
- package/modules/competitor-alternatives/SKILL.md +256 -0
- package/modules/competitor-alternatives/evals/evals.json +93 -0
- package/modules/competitor-alternatives/references/content-architecture.md +271 -0
- package/modules/competitor-alternatives/references/templates.md +223 -0
- package/modules/connect/SKILL.md +894 -0
- package/modules/content-strategy/SKILL.md +359 -0
- package/modules/content-strategy/evals/evals.json +90 -0
- package/modules/context-dump/SKILL.md +67 -0
- package/modules/copy-editing/SKILL.md +447 -0
- package/modules/copy-editing/evals/evals.json +89 -0
- package/modules/copy-editing/references/plain-english-alternatives.md +394 -0
- package/modules/copywriting/SKILL.md +271 -0
- package/modules/copywriting/evals/evals.json +111 -0
- package/modules/copywriting/references/cold-email-benchmarks.md +83 -0
- package/modules/copywriting/references/cold-email-follow-ups.md +81 -0
- package/modules/copywriting/references/cold-email-frameworks.md +90 -0
- package/modules/copywriting/references/cold-email-personalization.md +79 -0
- package/modules/copywriting/references/cold-email-subject-lines.md +53 -0
- package/modules/copywriting/references/copy-frameworks.md +344 -0
- package/modules/copywriting/references/email-copy-guidelines.md +113 -0
- package/modules/copywriting/references/email-types.md +515 -0
- package/modules/copywriting/references/natural-transitions.md +272 -0
- package/modules/copywriting/references/sequence-templates.md +168 -0
- package/modules/data-query/SKILL.md +58 -0
- package/modules/data-viz/SKILL.md +225 -0
- package/modules/db/SKILL.md +205 -0
- package/modules/db/db-engines/_router.md +24 -0
- package/modules/db/db-engines/athena.md +16 -0
- package/modules/db/db-engines/cloud-sql.md +16 -0
- package/modules/db/db-engines/databricks.md +14 -0
- package/modules/db/db-engines/oracle.md +14 -0
- package/modules/db/db-engines/postgres.md +15 -0
- package/modules/db/db-engines/presto.md +14 -0
- package/modules/db/db-engines/snowflake.md +14 -0
- package/modules/docs/SKILL.md +100 -0
- package/modules/email-sequence/SKILL.md +309 -0
- package/modules/email-sequence/evals/evals.json +93 -0
- package/modules/email-sequence/references/copy-guidelines.md +113 -0
- package/modules/email-sequence/references/email-types.md +515 -0
- package/modules/email-sequence/references/sequence-templates.md +168 -0
- package/modules/enterprise-design/SKILL.md +75 -0
- package/modules/eval/SKILL.md +105 -0
- package/modules/figma-translator/SKILL.md +49 -0
- package/modules/fix-bugs/SKILL.md +104 -0
- package/modules/form-cro/SKILL.md +429 -0
- package/modules/form-cro/evals/evals.json +90 -0
- package/modules/free-tool-strategy/SKILL.md +178 -0
- package/modules/free-tool-strategy/evals/evals.json +90 -0
- package/modules/free-tool-strategy/references/tool-types.md +217 -0
- package/modules/gate/SKILL.md +232 -0
- package/modules/grill-me/SKILL.md +59 -0
- package/modules/interaction-engineer/SKILL.md +49 -0
- package/modules/issue/SKILL.md +272 -0
- package/modules/launch/SKILL.md +345 -0
- package/modules/launch-strategy/SKILL.md +353 -0
- package/modules/launch-strategy/evals/evals.json +91 -0
- package/modules/lint/SKILL.md +126 -0
- package/modules/marketing-ideas/SKILL.md +167 -0
- package/modules/marketing-ideas/evals/evals.json +90 -0
- package/modules/marketing-ideas/references/ideas-by-category.md +366 -0
- package/modules/marketing-psychology/SKILL.md +455 -0
- package/modules/marketing-psychology/evals/evals.json +88 -0
- package/modules/motion-designer/SKILL.md +214 -0
- package/modules/onboarding-cro/SKILL.md +220 -0
- package/modules/onboarding-cro/evals/evals.json +92 -0
- package/modules/onboarding-cro/references/experiments.md +258 -0
- package/modules/orchestrate/SKILL.md +77 -0
- package/modules/page-cro/SKILL.md +182 -0
- package/modules/page-cro/evals/evals.json +111 -0
- package/modules/page-cro/references/experiments.md +248 -0
- package/modules/page-cro/references/paywall-experiments.md +164 -0
- package/modules/paid-ads/SKILL.md +315 -0
- package/modules/paid-ads/evals/evals.json +90 -0
- package/modules/paid-ads/references/ad-copy-templates.md +207 -0
- package/modules/paid-ads/references/audience-targeting.md +243 -0
- package/modules/paid-ads/references/platform-setup-checklists.md +277 -0
- package/modules/paywall-upgrade-cro/SKILL.md +227 -0
- package/modules/paywall-upgrade-cro/evals/evals.json +93 -0
- package/modules/paywall-upgrade-cro/references/experiments.md +164 -0
- package/modules/popup-cro/SKILL.md +453 -0
- package/modules/popup-cro/evals/evals.json +94 -0
- package/modules/pr/SKILL.md +203 -0
- package/modules/pricing-strategy/SKILL.md +231 -0
- package/modules/pricing-strategy/evals/evals.json +90 -0
- package/modules/pricing-strategy/references/research-methods.md +152 -0
- package/modules/pricing-strategy/references/tier-structure.md +232 -0
- package/modules/product-marketing-context/SKILL.md +241 -0
- package/modules/product-marketing-context/evals/evals.json +85 -0
- package/modules/programmatic-seo/SKILL.md +238 -0
- package/modules/programmatic-seo/evals/evals.json +94 -0
- package/modules/programmatic-seo/references/playbooks.md +308 -0
- package/modules/push/SKILL.md +202 -0
- package/modules/referral-program/SKILL.md +255 -0
- package/modules/referral-program/evals/evals.json +89 -0
- package/modules/referral-program/references/affiliate-programs.md +164 -0
- package/modules/referral-program/references/program-examples.md +143 -0
- package/modules/release/SKILL.md +293 -0
- package/modules/revops/SKILL.md +343 -0
- package/modules/revops/evals/evals.json +91 -0
- package/modules/revops/references/automation-playbooks.md +290 -0
- package/modules/revops/references/lifecycle-definitions.md +278 -0
- package/modules/revops/references/routing-rules.md +203 -0
- package/modules/revops/references/scoring-models.md +247 -0
- package/modules/sales-enablement/SKILL.md +349 -0
- package/modules/sales-enablement/evals/evals.json +91 -0
- package/modules/sales-enablement/references/deck-frameworks.md +263 -0
- package/modules/sales-enablement/references/demo-scripts.md +355 -0
- package/modules/sales-enablement/references/objection-library.md +270 -0
- package/modules/sales-enablement/references/one-pager-templates.md +208 -0
- package/modules/schema-markup/SKILL.md +179 -0
- package/modules/schema-markup/evals/evals.json +87 -0
- package/modules/schema-markup/references/schema-examples.md +398 -0
- package/modules/security/SKILL.md +138 -0
- package/modules/seo-audit/SKILL.md +412 -0
- package/modules/seo-audit/evals/evals.json +136 -0
- package/modules/seo-audit/references/ai-writing-detection.md +200 -0
- package/modules/seo-audit/references/content-patterns.md +285 -0
- package/modules/seo-audit/references/platform-ranking-factors.md +152 -0
- package/modules/signup-flow-cro/SKILL.md +359 -0
- package/modules/signup-flow-cro/evals/evals.json +88 -0
- package/modules/site-architecture/SKILL.md +357 -0
- package/modules/site-architecture/evals/evals.json +88 -0
- package/modules/site-architecture/references/mermaid-templates.md +216 -0
- package/modules/site-architecture/references/navigation-patterns.md +305 -0
- package/modules/site-architecture/references/site-type-templates.md +293 -0
- package/modules/social-content/SKILL.md +278 -0
- package/modules/social-content/evals/evals.json +92 -0
- package/modules/social-content/references/platforms.md +170 -0
- package/modules/social-content/references/post-templates.md +177 -0
- package/modules/social-content/references/reverse-engineering.md +195 -0
- package/modules/spec/SKILL.md +81 -0
- package/modules/subagents/SKILL.md +123 -0
- package/modules/techdebt/SKILL.md +71 -0
- package/modules/terminal-setup/SKILL.md +49 -0
- package/modules/test/SKILL.md +493 -0
- package/modules/test/references/e2e-patterns.md +294 -0
- package/modules/update-claude-md/SKILL.md +52 -0
- package/modules/visual-system-architect/SKILL.md +53 -0
- package/package.json +44 -0
- package/plugins/plugins.json +43 -0
- package/shell/aliases.sh +24 -0
- package/shell/check-update.sh +212 -0
- package/templates/.env.example +199 -0
- package/templates/docker-compose.md +46 -0
- package/templates/node-frontend.md +56 -0
- package/templates/node-fullstack.md +59 -0
- package/templates/python-api.md +57 -0
- package/update.sh +231 -0
|
@@ -0,0 +1,894 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: connect
|
|
3
|
+
description: Connect, authenticate, and verify any SaaS CLI tool. Reads credentials from `.env`. Never prints secrets.
|
|
4
|
+
category: data
|
|
5
|
+
tier: on-demand
|
|
6
|
+
slash_command: /connect
|
|
7
|
+
model: haiku
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Connect — SaaS CLI Connection Manager
|
|
11
|
+
|
|
12
|
+
Connect, authenticate, and verify any SaaS CLI tool. Reads credentials from `.env`. Never prints secrets.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
/connect # status dashboard — all services
|
|
18
|
+
/connect <service> # install + authenticate + test one service
|
|
19
|
+
/connect <service> test # test existing auth only (no re-auth)
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Supported services:** `github` · `aws` · `gcp` · `azure` · `vercel` · `netlify` · `railway` · `heroku` · `flyio` · `supabase` · `planetscale` · `firebase` · `stripe` · `cloudflare` · `docker` · `terraform` · `sentry` · `datadog` · `jira` · `linear` · `slack` · `notion` · `npm` · `pypi` · `digitalocean` · `render` · `mongodb`
|
|
23
|
+
|
|
24
|
+
## Do NOT ask for permission. Do NOT print credential values. Do NOT skip checks.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Phase 0 — Bootstrap
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")
|
|
32
|
+
ENV_FILE="$PROJECT_ROOT/.env"
|
|
33
|
+
|
|
34
|
+
# Load .env if it exists
|
|
35
|
+
if [ -f "$ENV_FILE" ]; then
|
|
36
|
+
set -a; source "$ENV_FILE"; set +a
|
|
37
|
+
echo ".env loaded from $ENV_FILE"
|
|
38
|
+
else
|
|
39
|
+
echo "No .env found at $ENV_FILE"
|
|
40
|
+
echo "→ Copy .env.example to .env and fill in your credentials:"
|
|
41
|
+
echo " cp .env.example .env && \$EDITOR .env"
|
|
42
|
+
fi
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Detect the requested service from the argument (e.g. `/connect github` → SERVICE=github).
|
|
46
|
+
If no argument, run Phase 3 (status dashboard) for ALL services.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Phase 1 — Helper functions (reference, do not run)
|
|
51
|
+
|
|
52
|
+
These patterns are used in each service section below.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Check if a CLI is installed
|
|
56
|
+
check_cli() { command -v "$1" &>/dev/null && echo "✅ $1 installed" || echo "❌ $1 not found"; }
|
|
57
|
+
|
|
58
|
+
# Check if an env var is set (no value printed)
|
|
59
|
+
check_env() { [ -n "${!1}" ] && echo "✅ $1 set" || echo "❌ $1 missing — add to .env"; }
|
|
60
|
+
|
|
61
|
+
# Install via Homebrew
|
|
62
|
+
brew_install() { brew install "$1" && echo "✅ $1 installed" || echo "❌ install failed"; }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 2 — Service sections
|
|
68
|
+
|
|
69
|
+
Run ONLY the section matching the requested SERVICE. If `/connect` with no arg, run status checks for all.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### SERVICE: github
|
|
74
|
+
|
|
75
|
+
**Required env vars:** `GITHUB_TOKEN`
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
check_cli gh
|
|
79
|
+
check_env GITHUB_TOKEN
|
|
80
|
+
|
|
81
|
+
# Install if missing
|
|
82
|
+
if ! command -v gh &>/dev/null; then
|
|
83
|
+
echo "Installing GitHub CLI..."
|
|
84
|
+
brew install gh
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Authenticate using token from .env
|
|
88
|
+
if [ -n "$GITHUB_TOKEN" ]; then
|
|
89
|
+
echo "$GITHUB_TOKEN" | gh auth login --with-token
|
|
90
|
+
gh auth status
|
|
91
|
+
else
|
|
92
|
+
echo "❌ GITHUB_TOKEN not set in .env"
|
|
93
|
+
echo "→ Create a token at: https://github.com/settings/tokens"
|
|
94
|
+
echo "→ Add to .env: GITHUB_TOKEN=ghp_..."
|
|
95
|
+
fi
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
### SERVICE: aws
|
|
101
|
+
|
|
102
|
+
**Required env vars:** `AWS_ACCESS_KEY_ID` · `AWS_SECRET_ACCESS_KEY` · `AWS_DEFAULT_REGION`
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
check_cli aws
|
|
106
|
+
check_env AWS_ACCESS_KEY_ID
|
|
107
|
+
check_env AWS_SECRET_ACCESS_KEY
|
|
108
|
+
check_env AWS_DEFAULT_REGION
|
|
109
|
+
|
|
110
|
+
if ! command -v aws &>/dev/null; then
|
|
111
|
+
brew install awscli
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
if [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then
|
|
115
|
+
aws configure set aws_access_key_id "$AWS_ACCESS_KEY_ID"
|
|
116
|
+
aws configure set aws_secret_access_key "$AWS_SECRET_ACCESS_KEY"
|
|
117
|
+
aws configure set default.region "${AWS_DEFAULT_REGION:-us-east-1}"
|
|
118
|
+
echo "Testing connection..."
|
|
119
|
+
aws sts get-caller-identity
|
|
120
|
+
else
|
|
121
|
+
echo "❌ AWS credentials not set in .env"
|
|
122
|
+
echo "→ Create at: https://console.aws.amazon.com/iam/home#/security_credentials"
|
|
123
|
+
echo "→ Add to .env: AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... AWS_DEFAULT_REGION=us-east-1"
|
|
124
|
+
fi
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### SERVICE: gcp
|
|
130
|
+
|
|
131
|
+
**Required env vars:** `GCP_PROJECT_ID` · `GOOGLE_APPLICATION_CREDENTIALS` (path to service account JSON)
|
|
132
|
+
**Optional:** `GCP_REGION`
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
check_cli gcloud
|
|
136
|
+
check_env GCP_PROJECT_ID
|
|
137
|
+
check_env GOOGLE_APPLICATION_CREDENTIALS
|
|
138
|
+
|
|
139
|
+
if ! command -v gcloud &>/dev/null; then
|
|
140
|
+
brew install google-cloud-sdk
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
if [ -n "$GOOGLE_APPLICATION_CREDENTIALS" ] && [ -f "$GOOGLE_APPLICATION_CREDENTIALS" ]; then
|
|
144
|
+
gcloud auth activate-service-account --key-file="$GOOGLE_APPLICATION_CREDENTIALS"
|
|
145
|
+
gcloud config set project "${GCP_PROJECT_ID}"
|
|
146
|
+
gcloud auth list
|
|
147
|
+
echo "✅ GCP authenticated as service account"
|
|
148
|
+
elif [ -n "$GCP_PROJECT_ID" ]; then
|
|
149
|
+
echo "No service account key found — falling back to Application Default Credentials"
|
|
150
|
+
gcloud auth application-default login
|
|
151
|
+
gcloud config set project "$GCP_PROJECT_ID"
|
|
152
|
+
else
|
|
153
|
+
echo "❌ GCP credentials not set in .env"
|
|
154
|
+
echo "→ Create service account at: https://console.cloud.google.com/iam-admin/serviceaccounts"
|
|
155
|
+
echo "→ Download JSON key, then add to .env:"
|
|
156
|
+
echo " GCP_PROJECT_ID=my-project"
|
|
157
|
+
echo " GOOGLE_APPLICATION_CREDENTIALS=/path/to/key.json"
|
|
158
|
+
fi
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### SERVICE: azure
|
|
164
|
+
|
|
165
|
+
**Required env vars:** `AZURE_CLIENT_ID` · `AZURE_CLIENT_SECRET` · `AZURE_TENANT_ID` · `AZURE_SUBSCRIPTION_ID`
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
check_cli az
|
|
169
|
+
check_env AZURE_CLIENT_ID
|
|
170
|
+
check_env AZURE_CLIENT_SECRET
|
|
171
|
+
check_env AZURE_TENANT_ID
|
|
172
|
+
check_env AZURE_SUBSCRIPTION_ID
|
|
173
|
+
|
|
174
|
+
if ! command -v az &>/dev/null; then
|
|
175
|
+
brew install azure-cli
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
if [ -n "$AZURE_CLIENT_ID" ] && [ -n "$AZURE_CLIENT_SECRET" ] && [ -n "$AZURE_TENANT_ID" ]; then
|
|
179
|
+
az login --service-principal \
|
|
180
|
+
--username "$AZURE_CLIENT_ID" \
|
|
181
|
+
--password "$AZURE_CLIENT_SECRET" \
|
|
182
|
+
--tenant "$AZURE_TENANT_ID"
|
|
183
|
+
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
|
|
184
|
+
az account show
|
|
185
|
+
else
|
|
186
|
+
echo "❌ Azure service principal credentials not set in .env"
|
|
187
|
+
echo "→ Create at: https://portal.azure.com/#blade/Microsoft_AAD_RegisteredApps"
|
|
188
|
+
echo "→ Add to .env: AZURE_CLIENT_ID=... AZURE_CLIENT_SECRET=... AZURE_TENANT_ID=... AZURE_SUBSCRIPTION_ID=..."
|
|
189
|
+
fi
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### SERVICE: vercel
|
|
195
|
+
|
|
196
|
+
**Required env vars:** `VERCEL_TOKEN`
|
|
197
|
+
**Optional:** `VERCEL_ORG_ID` · `VERCEL_PROJECT_ID`
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
check_cli vercel
|
|
201
|
+
check_env VERCEL_TOKEN
|
|
202
|
+
|
|
203
|
+
if ! command -v vercel &>/dev/null; then
|
|
204
|
+
npm install -g vercel
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
if [ -n "$VERCEL_TOKEN" ]; then
|
|
208
|
+
# vercel CLI uses VERCEL_TOKEN env var automatically
|
|
209
|
+
vercel whoami
|
|
210
|
+
echo "✅ Vercel authenticated"
|
|
211
|
+
else
|
|
212
|
+
echo "❌ VERCEL_TOKEN not set in .env"
|
|
213
|
+
echo "→ Create at: https://vercel.com/account/tokens"
|
|
214
|
+
echo "→ Add to .env: VERCEL_TOKEN=..."
|
|
215
|
+
fi
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
### SERVICE: netlify
|
|
221
|
+
|
|
222
|
+
**Required env vars:** `NETLIFY_AUTH_TOKEN`
|
|
223
|
+
**Optional:** `NETLIFY_SITE_ID`
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
check_cli netlify
|
|
227
|
+
check_env NETLIFY_AUTH_TOKEN
|
|
228
|
+
|
|
229
|
+
if ! command -v netlify &>/dev/null; then
|
|
230
|
+
npm install -g netlify-cli
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
if [ -n "$NETLIFY_AUTH_TOKEN" ]; then
|
|
234
|
+
NETLIFY_AUTH_TOKEN="$NETLIFY_AUTH_TOKEN" netlify status
|
|
235
|
+
echo "✅ Netlify authenticated"
|
|
236
|
+
else
|
|
237
|
+
echo "❌ NETLIFY_AUTH_TOKEN not set in .env"
|
|
238
|
+
echo "→ Create at: https://app.netlify.com/user/applications#personal-access-tokens"
|
|
239
|
+
echo "→ Add to .env: NETLIFY_AUTH_TOKEN=..."
|
|
240
|
+
fi
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### SERVICE: railway
|
|
246
|
+
|
|
247
|
+
**Required env vars:** `RAILWAY_TOKEN`
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
check_cli railway
|
|
251
|
+
check_env RAILWAY_TOKEN
|
|
252
|
+
|
|
253
|
+
if ! command -v railway &>/dev/null; then
|
|
254
|
+
brew install railway
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
if [ -n "$RAILWAY_TOKEN" ]; then
|
|
258
|
+
RAILWAY_TOKEN="$RAILWAY_TOKEN" railway whoami
|
|
259
|
+
echo "✅ Railway authenticated"
|
|
260
|
+
else
|
|
261
|
+
echo "❌ RAILWAY_TOKEN not set in .env"
|
|
262
|
+
echo "→ Create at: https://railway.app/account/tokens"
|
|
263
|
+
echo "→ Add to .env: RAILWAY_TOKEN=..."
|
|
264
|
+
fi
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
### SERVICE: heroku
|
|
270
|
+
|
|
271
|
+
**Required env vars:** `HEROKU_API_KEY`
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
check_cli heroku
|
|
275
|
+
check_env HEROKU_API_KEY
|
|
276
|
+
|
|
277
|
+
if ! command -v heroku &>/dev/null; then
|
|
278
|
+
brew tap heroku/brew && brew install heroku
|
|
279
|
+
fi
|
|
280
|
+
|
|
281
|
+
if [ -n "$HEROKU_API_KEY" ]; then
|
|
282
|
+
HEROKU_API_KEY="$HEROKU_API_KEY" heroku auth:whoami
|
|
283
|
+
echo "✅ Heroku authenticated"
|
|
284
|
+
else
|
|
285
|
+
echo "❌ HEROKU_API_KEY not set in .env"
|
|
286
|
+
echo "→ Get at: https://dashboard.heroku.com/account (API Key section)"
|
|
287
|
+
echo "→ Add to .env: HEROKU_API_KEY=..."
|
|
288
|
+
fi
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
### SERVICE: flyio
|
|
294
|
+
|
|
295
|
+
**Required env vars:** `FLY_API_TOKEN`
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
check_cli fly
|
|
299
|
+
check_env FLY_API_TOKEN
|
|
300
|
+
|
|
301
|
+
if ! command -v fly &>/dev/null; then
|
|
302
|
+
brew install flyctl
|
|
303
|
+
fi
|
|
304
|
+
|
|
305
|
+
if [ -n "$FLY_API_TOKEN" ]; then
|
|
306
|
+
FLY_API_TOKEN="$FLY_API_TOKEN" fly auth whoami
|
|
307
|
+
echo "✅ Fly.io authenticated"
|
|
308
|
+
else
|
|
309
|
+
echo "❌ FLY_API_TOKEN not set in .env"
|
|
310
|
+
echo "→ Create at: https://fly.io/user/personal_access_tokens"
|
|
311
|
+
echo "→ Add to .env: FLY_API_TOKEN=..."
|
|
312
|
+
fi
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
### SERVICE: supabase
|
|
318
|
+
|
|
319
|
+
**Required env vars:** `SUPABASE_ACCESS_TOKEN`
|
|
320
|
+
**Optional:** `SUPABASE_PROJECT_REF` · `SUPABASE_DB_PASSWORD`
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
check_cli supabase
|
|
324
|
+
check_env SUPABASE_ACCESS_TOKEN
|
|
325
|
+
|
|
326
|
+
if ! command -v supabase &>/dev/null; then
|
|
327
|
+
brew install supabase/tap/supabase
|
|
328
|
+
fi
|
|
329
|
+
|
|
330
|
+
if [ -n "$SUPABASE_ACCESS_TOKEN" ]; then
|
|
331
|
+
supabase login --token "$SUPABASE_ACCESS_TOKEN"
|
|
332
|
+
supabase projects list
|
|
333
|
+
echo "✅ Supabase authenticated"
|
|
334
|
+
else
|
|
335
|
+
echo "❌ SUPABASE_ACCESS_TOKEN not set in .env"
|
|
336
|
+
echo "→ Create at: https://supabase.com/dashboard/account/tokens"
|
|
337
|
+
echo "→ Add to .env: SUPABASE_ACCESS_TOKEN=..."
|
|
338
|
+
fi
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
### SERVICE: planetscale
|
|
344
|
+
|
|
345
|
+
**Required env vars:** `PLANETSCALE_SERVICE_TOKEN` · `PLANETSCALE_SERVICE_TOKEN_ID` · `PLANETSCALE_ORG`
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
check_cli pscale
|
|
349
|
+
check_env PLANETSCALE_SERVICE_TOKEN
|
|
350
|
+
check_env PLANETSCALE_SERVICE_TOKEN_ID
|
|
351
|
+
check_env PLANETSCALE_ORG
|
|
352
|
+
|
|
353
|
+
if ! command -v pscale &>/dev/null; then
|
|
354
|
+
brew install planetscale/tap/pscale
|
|
355
|
+
fi
|
|
356
|
+
|
|
357
|
+
if [ -n "$PLANETSCALE_SERVICE_TOKEN" ] && [ -n "$PLANETSCALE_SERVICE_TOKEN_ID" ]; then
|
|
358
|
+
pscale org list \
|
|
359
|
+
--service-token "$PLANETSCALE_SERVICE_TOKEN" \
|
|
360
|
+
--service-token-id "$PLANETSCALE_SERVICE_TOKEN_ID"
|
|
361
|
+
echo "✅ PlanetScale authenticated"
|
|
362
|
+
else
|
|
363
|
+
echo "❌ PlanetScale credentials not set in .env"
|
|
364
|
+
echo "→ Create service token at: https://app.planetscale.com/[org]/settings/service-tokens"
|
|
365
|
+
echo "→ Add to .env: PLANETSCALE_SERVICE_TOKEN=... PLANETSCALE_SERVICE_TOKEN_ID=... PLANETSCALE_ORG=..."
|
|
366
|
+
fi
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
### SERVICE: firebase
|
|
372
|
+
|
|
373
|
+
**Required env vars:** `FIREBASE_TOKEN` · `FIREBASE_PROJECT_ID`
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
check_cli firebase
|
|
377
|
+
check_env FIREBASE_TOKEN
|
|
378
|
+
check_env FIREBASE_PROJECT_ID
|
|
379
|
+
|
|
380
|
+
if ! command -v firebase &>/dev/null; then
|
|
381
|
+
npm install -g firebase-tools
|
|
382
|
+
fi
|
|
383
|
+
|
|
384
|
+
if [ -n "$FIREBASE_TOKEN" ]; then
|
|
385
|
+
firebase projects:list --token "$FIREBASE_TOKEN"
|
|
386
|
+
firebase use "$FIREBASE_PROJECT_ID" --token "$FIREBASE_TOKEN"
|
|
387
|
+
echo "✅ Firebase authenticated"
|
|
388
|
+
else
|
|
389
|
+
echo "❌ FIREBASE_TOKEN not set in .env"
|
|
390
|
+
echo "→ Generate with: firebase login:ci"
|
|
391
|
+
echo "→ Add to .env: FIREBASE_TOKEN=... FIREBASE_PROJECT_ID=..."
|
|
392
|
+
fi
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
### SERVICE: stripe
|
|
398
|
+
|
|
399
|
+
**Required env vars:** `STRIPE_SECRET_KEY`
|
|
400
|
+
**Optional:** `STRIPE_PUBLISHABLE_KEY` · `STRIPE_WEBHOOK_SECRET`
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
check_cli stripe
|
|
404
|
+
check_env STRIPE_SECRET_KEY
|
|
405
|
+
|
|
406
|
+
if ! command -v stripe &>/dev/null; then
|
|
407
|
+
brew install stripe/stripe-cli/stripe
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
if [ -n "$STRIPE_SECRET_KEY" ]; then
|
|
411
|
+
stripe config --api-key "$STRIPE_SECRET_KEY"
|
|
412
|
+
stripe whoami
|
|
413
|
+
echo "✅ Stripe authenticated"
|
|
414
|
+
else
|
|
415
|
+
echo "❌ STRIPE_SECRET_KEY not set in .env"
|
|
416
|
+
echo "→ Get at: https://dashboard.stripe.com/apikeys"
|
|
417
|
+
echo "→ Add to .env: STRIPE_SECRET_KEY=sk_live_... (or sk_test_... for dev)"
|
|
418
|
+
fi
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
423
|
+
### SERVICE: cloudflare
|
|
424
|
+
|
|
425
|
+
**Required env vars:** `CLOUDFLARE_API_TOKEN`
|
|
426
|
+
**Optional:** `CLOUDFLARE_ACCOUNT_ID` · `CLOUDFLARE_ZONE_ID`
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
check_cli wrangler
|
|
430
|
+
check_env CLOUDFLARE_API_TOKEN
|
|
431
|
+
check_env CLOUDFLARE_ACCOUNT_ID
|
|
432
|
+
|
|
433
|
+
if ! command -v wrangler &>/dev/null; then
|
|
434
|
+
npm install -g wrangler
|
|
435
|
+
fi
|
|
436
|
+
|
|
437
|
+
if [ -n "$CLOUDFLARE_API_TOKEN" ]; then
|
|
438
|
+
# wrangler uses CLOUDFLARE_API_TOKEN env var automatically
|
|
439
|
+
CLOUDFLARE_API_TOKEN="$CLOUDFLARE_API_TOKEN" wrangler whoami
|
|
440
|
+
echo "✅ Cloudflare authenticated"
|
|
441
|
+
else
|
|
442
|
+
echo "❌ CLOUDFLARE_API_TOKEN not set in .env"
|
|
443
|
+
echo "→ Create at: https://dash.cloudflare.com/profile/api-tokens"
|
|
444
|
+
echo "→ Add to .env: CLOUDFLARE_API_TOKEN=... CLOUDFLARE_ACCOUNT_ID=..."
|
|
445
|
+
fi
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
### SERVICE: docker
|
|
451
|
+
|
|
452
|
+
**Required env vars:** `DOCKER_USERNAME` · `DOCKER_TOKEN`
|
|
453
|
+
**Optional:** `DOCKER_REGISTRY` (defaults to Docker Hub)
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
check_cli docker
|
|
457
|
+
check_env DOCKER_USERNAME
|
|
458
|
+
check_env DOCKER_TOKEN
|
|
459
|
+
|
|
460
|
+
if ! command -v docker &>/dev/null; then
|
|
461
|
+
echo "Docker Desktop not found — install from: https://www.docker.com/products/docker-desktop"
|
|
462
|
+
exit 1
|
|
463
|
+
fi
|
|
464
|
+
|
|
465
|
+
if [ -n "$DOCKER_USERNAME" ] && [ -n "$DOCKER_TOKEN" ]; then
|
|
466
|
+
REGISTRY="${DOCKER_REGISTRY:-docker.io}"
|
|
467
|
+
echo "$DOCKER_TOKEN" | docker login "$REGISTRY" --username "$DOCKER_USERNAME" --password-stdin
|
|
468
|
+
echo "✅ Docker authenticated to $REGISTRY"
|
|
469
|
+
else
|
|
470
|
+
echo "❌ Docker credentials not set in .env"
|
|
471
|
+
echo "→ Create access token at: https://hub.docker.com/settings/security"
|
|
472
|
+
echo "→ Add to .env: DOCKER_USERNAME=... DOCKER_TOKEN=..."
|
|
473
|
+
fi
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
### SERVICE: terraform
|
|
479
|
+
|
|
480
|
+
**Required env vars:** none (uses cloud provider creds already configured)
|
|
481
|
+
**Optional:** `TF_TOKEN_app_terraform_io` (for Terraform Cloud)
|
|
482
|
+
|
|
483
|
+
```bash
|
|
484
|
+
check_cli terraform
|
|
485
|
+
|
|
486
|
+
if ! command -v terraform &>/dev/null; then
|
|
487
|
+
brew install terraform
|
|
488
|
+
fi
|
|
489
|
+
|
|
490
|
+
terraform version
|
|
491
|
+
terraform validate 2>/dev/null && echo "✅ Terraform config valid" || echo "No terraform config in current directory"
|
|
492
|
+
|
|
493
|
+
# Terraform Cloud auth (if token set)
|
|
494
|
+
if [ -n "$TF_TOKEN_app_terraform_io" ]; then
|
|
495
|
+
echo "Terraform Cloud token detected — writing to ~/.terraform.d/credentials.tfrc.json"
|
|
496
|
+
mkdir -p ~/.terraform.d
|
|
497
|
+
cat > ~/.terraform.d/credentials.tfrc.json <<EOF
|
|
498
|
+
{
|
|
499
|
+
"credentials": {
|
|
500
|
+
"app.terraform.io": {
|
|
501
|
+
"token": "$TF_TOKEN_app_terraform_io"
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
EOF
|
|
506
|
+
echo "✅ Terraform Cloud authenticated"
|
|
507
|
+
fi
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
### SERVICE: sentry
|
|
513
|
+
|
|
514
|
+
**Required env vars:** `SENTRY_AUTH_TOKEN` · `SENTRY_ORG`
|
|
515
|
+
**Optional:** `SENTRY_PROJECT` · `SENTRY_URL` (for self-hosted)
|
|
516
|
+
|
|
517
|
+
```bash
|
|
518
|
+
check_cli sentry-cli
|
|
519
|
+
check_env SENTRY_AUTH_TOKEN
|
|
520
|
+
check_env SENTRY_ORG
|
|
521
|
+
|
|
522
|
+
if ! command -v sentry-cli &>/dev/null; then
|
|
523
|
+
brew install getsentry/tools/sentry-cli
|
|
524
|
+
fi
|
|
525
|
+
|
|
526
|
+
if [ -n "$SENTRY_AUTH_TOKEN" ]; then
|
|
527
|
+
SENTRY_AUTH_TOKEN="$SENTRY_AUTH_TOKEN" sentry-cli info
|
|
528
|
+
echo "✅ Sentry authenticated"
|
|
529
|
+
else
|
|
530
|
+
echo "❌ SENTRY_AUTH_TOKEN not set in .env"
|
|
531
|
+
echo "→ Create at: https://sentry.io/settings/account/api/auth-tokens/"
|
|
532
|
+
echo "→ Add to .env: SENTRY_AUTH_TOKEN=... SENTRY_ORG=my-org SENTRY_PROJECT=my-project"
|
|
533
|
+
fi
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
---
|
|
537
|
+
|
|
538
|
+
### SERVICE: datadog
|
|
539
|
+
|
|
540
|
+
**Required env vars:** `DD_API_KEY` · `DD_APP_KEY`
|
|
541
|
+
**Optional:** `DD_SITE` (defaults to datadoghq.com)
|
|
542
|
+
|
|
543
|
+
```bash
|
|
544
|
+
check_cli datadog-ci
|
|
545
|
+
check_env DD_API_KEY
|
|
546
|
+
check_env DD_APP_KEY
|
|
547
|
+
|
|
548
|
+
if ! command -v datadog-ci &>/dev/null; then
|
|
549
|
+
npm install -g @datadog/datadog-ci
|
|
550
|
+
fi
|
|
551
|
+
|
|
552
|
+
if [ -n "$DD_API_KEY" ]; then
|
|
553
|
+
DD_API_KEY="$DD_API_KEY" DD_APP_KEY="$DD_APP_KEY" \
|
|
554
|
+
datadog-ci synthetics run-tests --help &>/dev/null \
|
|
555
|
+
&& echo "✅ Datadog CI authenticated" \
|
|
556
|
+
|| echo "✅ Datadog credentials set (validation requires a test suite)"
|
|
557
|
+
else
|
|
558
|
+
echo "❌ DD_API_KEY not set in .env"
|
|
559
|
+
echo "→ Get at: https://app.datadoghq.com/organization-settings/api-keys"
|
|
560
|
+
echo "→ Add to .env: DD_API_KEY=... DD_APP_KEY=... DD_SITE=datadoghq.com"
|
|
561
|
+
fi
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
### SERVICE: jira
|
|
567
|
+
|
|
568
|
+
**Required env vars:** `JIRA_URL` · `JIRA_USER_EMAIL` · `JIRA_API_TOKEN`
|
|
569
|
+
**Optional:** `JIRA_PROJECT_KEY`
|
|
570
|
+
|
|
571
|
+
```bash
|
|
572
|
+
check_env JIRA_URL
|
|
573
|
+
check_env JIRA_USER_EMAIL
|
|
574
|
+
check_env JIRA_API_TOKEN
|
|
575
|
+
|
|
576
|
+
# go-jira CLI
|
|
577
|
+
if ! command -v jira &>/dev/null; then
|
|
578
|
+
brew install go-jira
|
|
579
|
+
fi
|
|
580
|
+
|
|
581
|
+
if [ -n "$JIRA_URL" ] && [ -n "$JIRA_API_TOKEN" ]; then
|
|
582
|
+
# Write go-jira config
|
|
583
|
+
mkdir -p ~/.jira.d
|
|
584
|
+
cat > ~/.jira.d/config.yml <<EOF
|
|
585
|
+
endpoint: ${JIRA_URL}
|
|
586
|
+
user: ${JIRA_USER_EMAIL}
|
|
587
|
+
login: ${JIRA_USER_EMAIL}
|
|
588
|
+
password-source: keyring
|
|
589
|
+
EOF
|
|
590
|
+
# Test via API
|
|
591
|
+
curl -sf -u "${JIRA_USER_EMAIL}:${JIRA_API_TOKEN}" \
|
|
592
|
+
"${JIRA_URL}/rest/api/3/myself" | python3 -c "import sys,json; u=json.load(sys.stdin); print('✅ Jira authenticated as', u['displayName'])"
|
|
593
|
+
else
|
|
594
|
+
echo "❌ Jira credentials not set in .env"
|
|
595
|
+
echo "→ Create API token at: https://id.atlassian.com/manage-profile/security/api-tokens"
|
|
596
|
+
echo "→ Add to .env: JIRA_URL=https://your-org.atlassian.net JIRA_USER_EMAIL=... JIRA_API_TOKEN=..."
|
|
597
|
+
fi
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
### SERVICE: linear
|
|
603
|
+
|
|
604
|
+
**Required env vars:** `LINEAR_API_KEY`
|
|
605
|
+
|
|
606
|
+
```bash
|
|
607
|
+
check_env LINEAR_API_KEY
|
|
608
|
+
|
|
609
|
+
if [ -n "$LINEAR_API_KEY" ]; then
|
|
610
|
+
# Test via GraphQL API
|
|
611
|
+
RESULT=$(curl -sf -X POST https://api.linear.app/graphql \
|
|
612
|
+
-H "Authorization: $LINEAR_API_KEY" \
|
|
613
|
+
-H "Content-Type: application/json" \
|
|
614
|
+
-d '{"query":"{ viewer { name email } }"}')
|
|
615
|
+
echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); v=d['data']['viewer']; print('✅ Linear authenticated as', v['name'], '(' + v['email'] + ')')"
|
|
616
|
+
else
|
|
617
|
+
echo "❌ LINEAR_API_KEY not set in .env"
|
|
618
|
+
echo "→ Create at: https://linear.app/settings/api"
|
|
619
|
+
echo "→ Add to .env: LINEAR_API_KEY=lin_api_..."
|
|
620
|
+
fi
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
---
|
|
624
|
+
|
|
625
|
+
### SERVICE: slack
|
|
626
|
+
|
|
627
|
+
**Required env vars:** `SLACK_BOT_TOKEN`
|
|
628
|
+
**Optional:** `SLACK_TEAM_ID` · `SLACK_SIGNING_SECRET`
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
check_env SLACK_BOT_TOKEN
|
|
632
|
+
|
|
633
|
+
if [ -n "$SLACK_BOT_TOKEN" ]; then
|
|
634
|
+
RESULT=$(curl -sf -X POST https://slack.com/api/auth.test \
|
|
635
|
+
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
|
|
636
|
+
-H "Content-Type: application/json")
|
|
637
|
+
echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print('✅ Slack authenticated — team:', d.get('team','?'), '| bot:', d.get('user','?')) if d.get('ok') else print('❌ Slack auth failed:', d.get('error','unknown'))"
|
|
638
|
+
else
|
|
639
|
+
echo "❌ SLACK_BOT_TOKEN not set in .env"
|
|
640
|
+
echo "→ Create a Slack app and get Bot Token at: https://api.slack.com/apps"
|
|
641
|
+
echo "→ Add to .env: SLACK_BOT_TOKEN=xoxb-..."
|
|
642
|
+
fi
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
---
|
|
646
|
+
|
|
647
|
+
### SERVICE: notion
|
|
648
|
+
|
|
649
|
+
**Required env vars:** `NOTION_TOKEN`
|
|
650
|
+
**Optional:** `NOTION_DATABASE_ID`
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
check_env NOTION_TOKEN
|
|
654
|
+
|
|
655
|
+
if [ -n "$NOTION_TOKEN" ]; then
|
|
656
|
+
RESULT=$(curl -sf https://api.notion.com/v1/users/me \
|
|
657
|
+
-H "Authorization: Bearer $NOTION_TOKEN" \
|
|
658
|
+
-H "Notion-Version: 2022-06-28")
|
|
659
|
+
echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print('✅ Notion authenticated as', d.get('name','?'))" 2>/dev/null || echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print('✅ Notion authenticated — bot:', d.get('bot',{}).get('workspace_name','?'))"
|
|
660
|
+
else
|
|
661
|
+
echo "❌ NOTION_TOKEN not set in .env"
|
|
662
|
+
echo "→ Create an integration at: https://www.notion.so/my-integrations"
|
|
663
|
+
echo "→ Add to .env: NOTION_TOKEN=secret_..."
|
|
664
|
+
fi
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
### SERVICE: npm
|
|
670
|
+
|
|
671
|
+
**Required env vars:** `NPM_TOKEN`
|
|
672
|
+
|
|
673
|
+
```bash
|
|
674
|
+
check_cli npm
|
|
675
|
+
check_env NPM_TOKEN
|
|
676
|
+
|
|
677
|
+
if [ -n "$NPM_TOKEN" ]; then
|
|
678
|
+
npm set //registry.npmjs.org/:_authToken "$NPM_TOKEN"
|
|
679
|
+
npm whoami
|
|
680
|
+
echo "✅ npm authenticated"
|
|
681
|
+
else
|
|
682
|
+
echo "❌ NPM_TOKEN not set in .env"
|
|
683
|
+
echo "→ Create at: https://www.npmjs.com/settings/[username]/tokens"
|
|
684
|
+
echo "→ Add to .env: NPM_TOKEN=npm_..."
|
|
685
|
+
fi
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
### SERVICE: pypi
|
|
691
|
+
|
|
692
|
+
**Required env vars:** `PYPI_TOKEN`
|
|
693
|
+
**Optional:** `PYPI_USERNAME` (defaults to __token__)
|
|
694
|
+
|
|
695
|
+
```bash
|
|
696
|
+
check_cli twine
|
|
697
|
+
check_env PYPI_TOKEN
|
|
698
|
+
|
|
699
|
+
if ! command -v twine &>/dev/null; then
|
|
700
|
+
pip install twine --quiet
|
|
701
|
+
fi
|
|
702
|
+
|
|
703
|
+
if [ -n "$PYPI_TOKEN" ]; then
|
|
704
|
+
# Write ~/.pypirc
|
|
705
|
+
cat > ~/.pypirc <<EOF
|
|
706
|
+
[distutils]
|
|
707
|
+
index-servers = pypi
|
|
708
|
+
|
|
709
|
+
[pypi]
|
|
710
|
+
username = __token__
|
|
711
|
+
password = ${PYPI_TOKEN}
|
|
712
|
+
EOF
|
|
713
|
+
chmod 600 ~/.pypirc
|
|
714
|
+
echo "✅ PyPI credentials written to ~/.pypirc"
|
|
715
|
+
twine check --help &>/dev/null && echo "✅ twine available"
|
|
716
|
+
else
|
|
717
|
+
echo "❌ PYPI_TOKEN not set in .env"
|
|
718
|
+
echo "→ Create at: https://pypi.org/manage/account/token/"
|
|
719
|
+
echo "→ Add to .env: PYPI_TOKEN=pypi-..."
|
|
720
|
+
fi
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
725
|
+
### SERVICE: digitalocean
|
|
726
|
+
|
|
727
|
+
**Required env vars:** `DIGITALOCEAN_ACCESS_TOKEN`
|
|
728
|
+
|
|
729
|
+
```bash
|
|
730
|
+
check_cli doctl
|
|
731
|
+
check_env DIGITALOCEAN_ACCESS_TOKEN
|
|
732
|
+
|
|
733
|
+
if ! command -v doctl &>/dev/null; then
|
|
734
|
+
brew install doctl
|
|
735
|
+
fi
|
|
736
|
+
|
|
737
|
+
if [ -n "$DIGITALOCEAN_ACCESS_TOKEN" ]; then
|
|
738
|
+
doctl auth init --access-token "$DIGITALOCEAN_ACCESS_TOKEN"
|
|
739
|
+
doctl account get
|
|
740
|
+
echo "✅ DigitalOcean authenticated"
|
|
741
|
+
else
|
|
742
|
+
echo "❌ DIGITALOCEAN_ACCESS_TOKEN not set in .env"
|
|
743
|
+
echo "→ Create at: https://cloud.digitalocean.com/account/api/tokens"
|
|
744
|
+
echo "→ Add to .env: DIGITALOCEAN_ACCESS_TOKEN=dop_v1_..."
|
|
745
|
+
fi
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
### SERVICE: render
|
|
751
|
+
|
|
752
|
+
**Required env vars:** `RENDER_API_KEY`
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
check_env RENDER_API_KEY
|
|
756
|
+
|
|
757
|
+
if [ -n "$RENDER_API_KEY" ]; then
|
|
758
|
+
RESULT=$(curl -sf https://api.render.com/v1/owners \
|
|
759
|
+
-H "Accept: application/json" \
|
|
760
|
+
-H "Authorization: Bearer $RENDER_API_KEY")
|
|
761
|
+
echo "$RESULT" | python3 -c "import sys,json; d=json.load(sys.stdin); print('✅ Render authenticated — owners:', ', '.join(o['owner']['name'] for o in d))" 2>/dev/null || echo "✅ Render API key accepted"
|
|
762
|
+
else
|
|
763
|
+
echo "❌ RENDER_API_KEY not set in .env"
|
|
764
|
+
echo "→ Create at: https://dashboard.render.com/u/settings#api-keys"
|
|
765
|
+
echo "→ Add to .env: RENDER_API_KEY=rnd_..."
|
|
766
|
+
fi
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
---
|
|
770
|
+
|
|
771
|
+
### SERVICE: mongodb
|
|
772
|
+
|
|
773
|
+
**Required env vars:** `MONGODB_ATLAS_PUBLIC_KEY` · `MONGODB_ATLAS_PRIVATE_KEY` · `MONGODB_ATLAS_ORG_ID`
|
|
774
|
+
|
|
775
|
+
```bash
|
|
776
|
+
check_cli atlas
|
|
777
|
+
check_env MONGODB_ATLAS_PUBLIC_KEY
|
|
778
|
+
check_env MONGODB_ATLAS_PRIVATE_KEY
|
|
779
|
+
|
|
780
|
+
if ! command -v atlas &>/dev/null; then
|
|
781
|
+
brew install mongodb-atlas-cli
|
|
782
|
+
fi
|
|
783
|
+
|
|
784
|
+
if [ -n "$MONGODB_ATLAS_PUBLIC_KEY" ] && [ -n "$MONGODB_ATLAS_PRIVATE_KEY" ]; then
|
|
785
|
+
atlas config set public_api_key "$MONGODB_ATLAS_PUBLIC_KEY"
|
|
786
|
+
atlas config set private_api_key "$MONGODB_ATLAS_PRIVATE_KEY"
|
|
787
|
+
[ -n "$MONGODB_ATLAS_ORG_ID" ] && atlas config set org_id "$MONGODB_ATLAS_ORG_ID"
|
|
788
|
+
atlas auth whoami
|
|
789
|
+
echo "✅ MongoDB Atlas authenticated"
|
|
790
|
+
else
|
|
791
|
+
echo "❌ MongoDB Atlas credentials not set in .env"
|
|
792
|
+
echo "→ Create programmatic API keys at: https://cloud.mongodb.com/v2#/org/[orgId]/settings/apiKeys"
|
|
793
|
+
echo "→ Add to .env: MONGODB_ATLAS_PUBLIC_KEY=... MONGODB_ATLAS_PRIVATE_KEY=... MONGODB_ATLAS_ORG_ID=..."
|
|
794
|
+
fi
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
## Phase 3 — Status Dashboard (no-arg mode)
|
|
800
|
+
|
|
801
|
+
When `/connect` is called with no argument, run status checks for ALL services and print this summary:
|
|
802
|
+
|
|
803
|
+
```bash
|
|
804
|
+
echo ""
|
|
805
|
+
echo "╔══════════════════════════════════════════════════════════════════╗"
|
|
806
|
+
echo "║ SAAS CONNECTION STATUS ║"
|
|
807
|
+
echo "╠══════════════════════════════════════════════════════════════════╣"
|
|
808
|
+
|
|
809
|
+
check_service() {
|
|
810
|
+
local name="$1"; local cli="$2"; local envvar="$3"
|
|
811
|
+
local cli_ok=false; local env_ok=false
|
|
812
|
+
command -v "$cli" &>/dev/null 2>&1 && cli_ok=true
|
|
813
|
+
[ -n "${!envvar}" ] && env_ok=true
|
|
814
|
+
if $cli_ok && $env_ok; then
|
|
815
|
+
printf "║ ✅ %-18s CLI: %-8s Token: %-20s ║\n" "$name" "ok" "set"
|
|
816
|
+
elif $env_ok; then
|
|
817
|
+
printf "║ ⚠️ %-18s CLI: %-8s Token: %-20s ║\n" "$name" "missing" "set"
|
|
818
|
+
elif $cli_ok; then
|
|
819
|
+
printf "║ ⚠️ %-18s CLI: %-8s Token: %-20s ║\n" "$name" "ok" "not set"
|
|
820
|
+
else
|
|
821
|
+
printf "║ ❌ %-18s CLI: %-8s Token: %-20s ║\n" "$name" "missing" "not set"
|
|
822
|
+
fi
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
check_service "GitHub" gh GITHUB_TOKEN
|
|
826
|
+
check_service "AWS" aws AWS_ACCESS_KEY_ID
|
|
827
|
+
check_service "GCP" gcloud GCP_PROJECT_ID
|
|
828
|
+
check_service "Azure" az AZURE_CLIENT_ID
|
|
829
|
+
check_service "Vercel" vercel VERCEL_TOKEN
|
|
830
|
+
check_service "Netlify" netlify NETLIFY_AUTH_TOKEN
|
|
831
|
+
check_service "Railway" railway RAILWAY_TOKEN
|
|
832
|
+
check_service "Heroku" heroku HEROKU_API_KEY
|
|
833
|
+
check_service "Fly.io" fly FLY_API_TOKEN
|
|
834
|
+
check_service "Supabase" supabase SUPABASE_ACCESS_TOKEN
|
|
835
|
+
check_service "PlanetScale" pscale PLANETSCALE_SERVICE_TOKEN
|
|
836
|
+
check_service "Firebase" firebase FIREBASE_TOKEN
|
|
837
|
+
check_service "Stripe" stripe STRIPE_SECRET_KEY
|
|
838
|
+
check_service "Cloudflare" wrangler CLOUDFLARE_API_TOKEN
|
|
839
|
+
check_service "Docker" docker DOCKER_TOKEN
|
|
840
|
+
check_service "Terraform" terraform TF_TOKEN_app_terraform_io
|
|
841
|
+
check_service "Sentry" sentry-cli SENTRY_AUTH_TOKEN
|
|
842
|
+
check_service "Datadog" datadog-ci DD_API_KEY
|
|
843
|
+
check_service "Jira" jira JIRA_API_TOKEN
|
|
844
|
+
check_service "Linear" curl LINEAR_API_KEY
|
|
845
|
+
check_service "Slack" curl SLACK_BOT_TOKEN
|
|
846
|
+
check_service "Notion" curl NOTION_TOKEN
|
|
847
|
+
check_service "npm" npm NPM_TOKEN
|
|
848
|
+
check_service "PyPI" twine PYPI_TOKEN
|
|
849
|
+
check_service "DigitalOcean" doctl DIGITALOCEAN_ACCESS_TOKEN
|
|
850
|
+
check_service "Render" curl RENDER_API_KEY
|
|
851
|
+
check_service "MongoDB Atlas" atlas MONGODB_ATLAS_PUBLIC_KEY
|
|
852
|
+
|
|
853
|
+
echo "╠══════════════════════════════════════════════════════════════════╣"
|
|
854
|
+
echo "║ Run: /connect <service> to connect any service ║"
|
|
855
|
+
echo "║ Edit .env to add missing credentials ║"
|
|
856
|
+
echo "╚══════════════════════════════════════════════════════════════════╝"
|
|
857
|
+
```
|
|
858
|
+
|
|
859
|
+
---
|
|
860
|
+
|
|
861
|
+
## Phase 4 — Hook guidance
|
|
862
|
+
|
|
863
|
+
After a successful connection, suggest the user add this to their shell profile to auto-load `.env` on project entry:
|
|
864
|
+
|
|
865
|
+
```bash
|
|
866
|
+
# ~/.zshrc or ~/.bashrc — auto-load .env when entering a project directory
|
|
867
|
+
autoload_env() {
|
|
868
|
+
local env_file="$PWD/.env"
|
|
869
|
+
[ -f "$env_file" ] && [ -r "$env_file" ] && set -a && source "$env_file" && set +a
|
|
870
|
+
}
|
|
871
|
+
# Add to PROMPT_COMMAND (bash) or chpwd hook (zsh)
|
|
872
|
+
# zsh: add_zsh_hook chpwd autoload_env
|
|
873
|
+
# bash: PROMPT_COMMAND="autoload_env; $PROMPT_COMMAND"
|
|
874
|
+
```
|
|
875
|
+
|
|
876
|
+
And suggest adding Claude Code hook in `.claude/settings.json` to warn on missing credentials:
|
|
877
|
+
|
|
878
|
+
```json
|
|
879
|
+
{
|
|
880
|
+
"hooks": {
|
|
881
|
+
"PreToolUse": [
|
|
882
|
+
{
|
|
883
|
+
"matcher": "Bash",
|
|
884
|
+
"hooks": [
|
|
885
|
+
{
|
|
886
|
+
"type": "command",
|
|
887
|
+
"command": "bash -c 'if [ ! -f .env ] && grep -qE \"(aws|gcloud|stripe|supabase|vercel)\" <<< \"$CLAUDE_TOOL_INPUT\" 2>/dev/null; then echo \"WARNING: No .env file found. Run /connect to set up credentials.\"; fi'"
|
|
888
|
+
}
|
|
889
|
+
]
|
|
890
|
+
}
|
|
891
|
+
]
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
```
|