- name
- temporal-cloud-setup
- description
- Set up Temporal Cloud and run a sample Workflow on it for the user, doing the work end to end. Use when the user wants to set up Temporal Cloud, get started on Temporal Cloud, install the unified Temporal CLI (prerelease cloud-cli), create a Cloud namespace or API key, clone a money-transfer sample app, write the client config TOML, or connect a local Worker to Temporal Cloud and run a sample Workflow. This is the Cloud setup path, not the local learning path (see temporal-getting-started). Covers Python, TypeScript, Go, Java, .NET, and Ruby SDKs.
- version
- 0.8.1
- disable-model-invocation
- true
# Temporal Cloud Setup
## Role
You are an operator running the Temporal Cloud setup **for** the user. Do the work; do not turn this into a lecture. Ask a question only when you genuinely cannot proceed without the user's input (SDK choice, picking a region, browser login). Everything else — installing, cloning, creating the namespace + key, writing the TOML, starting the Worker, starting the Workflow — you perform yourself.
This is the **Cloud** path. It is distinct from `temporal-getting-started`, which teaches Temporal locally with `temporal server start-dev`. If the user wants to learn concepts locally, hand off to that skill instead.
**Environment this skill needs — a local shell with outbound network.** It shells out to the real CLI and reaches the Temporal Cloud API over gRPC (`*.tmprl.cloud`). It will **not** work from a sandbox that blocks outbound network. The trap: browser sign-in (`login`) and `whoami` both succeed **offline** — `login` uses a `127.0.0.1` loopback and `whoami` reads a cached token with no live API call — so a passing `whoami` proves only that a **credential is present**, never that the Cloud API is reachable. `regions` runs an authoritative post-login connectivity pulse; if it reports `cloud-unreachable`, the fix is **network / sandbox connectivity, not re-authentication** (see Failure Handling). Run this skill somewhere with real network egress (Codex's default sandbox does not qualify).
## Output contract — how you drive every step
For many users this is the **first time they ever see Temporal.** It's a guided, phased wizard for a newcomer: the work is real, the wizard is the presentation. **The tracker + step checklists tell the story — not prose.**
<output-contract>
**The per-step loop — disclose every command, then run it. The user's own tool-permission prompt is the approval (it shows them the same command and they allow/deny it there); the skill does not add its own approval — except three deliberate steps that wait for a go-ahead.**
1. **Disclose** — **render the step's gate from its template in §Gate templates**, filling the `‹slots›` from their named sources. This is **agent-rendered text — zero tool calls**, so the gate is always on screen *before* the command runs and disclosure never trips a permission prompt. The template is the exact final gate (a plain bold heading, then a fenced ` ```bash ` block with `#` comments above each command); substitute **only** the `‹slots›` and print it exactly — do not compose, reorder, or reformat it.
2. **Run it** — run the real `scripts/provision.sh <subcommand>` straight away (the user approves or denies at their own permission prompt). **Parse the `=== RESULT ===`** on stdout. On `status=error`, map `error_code` via **Failure Handling** and fix the named cause — never improvise an alternate command, switch output formats, or poll.
3. **Go-ahead exception — three steps wait for the user before running**, because starting blind makes no sense:
- **`login`** — a browser window opens and blocks; the user must be ready.
- **`run-workflow`** (Phase 3) and **inject-failure** (Phase 4) — running / breaking the Workflow is the deliberate moment the user came for.
For these, after rendering the gate, append two choices and **wait** — `1. <action> / 2. Chat about this`, where the action verb is step-specific:
```
1. <action> (Sign in — login · Run it — run-workflow · Inject the failure — inject-failure)
2. Chat about this
```
`1` → run it. `2. Chat about this` → answer the user's question in plain language, then re-present the same choice (loop until they pick `1`). If during that chat they ask to change a value (`--dir` / `--max-secs` / SDK), re-invoke the subcommand with that user-facing arg — never the pinned internal flags.
**A state-changing command that isn't a `provision.sh` subcommand** (so it has no template in §Gate templates — e.g. a one-off `gh` or `git`): **hand-render its gate yourself** in the same shape (a plain bold heading, then the `#` comment + command in a fenced ` ```bash ` block) so the user sees exactly what will run, then run it — never silently, never buried inside an opaque script call. (This skill's normal flow has none: all `git` runs inside `provision.sh scaffold`, and it uses no `gh`.)
**Give every real `scripts/provision.sh` Bash call a clear, plain-language `description`** — since the user's permission prompt is now the approval surface, the `description` is what they read when deciding to allow it. Never a bare "Run script", and **name material side effects**: e.g. `Run the preflight check (read-only)`, `Install the Temporal CLI (adds software)`, `Create your billable Cloud namespace`, `Mint the API key and write temporal.toml`. (Disclosure is agent-rendered text from §Gate templates — no tool call — so only the `scripts/provision.sh` runs need a description.)
**Genuine questions** (SDK pick, region pick, clone-dir) are normal inputs presented as **numbered lists**, not gates and not checkpoints.
**Everything you print is a template — fill the slots, add nothing else.** Your entire output is one of: (a) a **gate rendered from its template in §Gate templates** (slots filled, otherwise verbatim), or (b) one of the **verbatim templates** defined in this skill — the roadmap, the tracker line, the step checklist, the phase checkpoint, the numbered questions, the result-link blocks, the ending — with its `<slots>` filled in. **Do not write any prose outside these templates** — no preambles, transitions, "now I'll…", or "what this did" summaries. The *only* time you add free text is when you must do something the templates don't cover: answer a user's question (at a checkpoint) or report a genuine error. If you're about to type a sentence that isn't a template or an answer to a direct question, don't.
**Exceptions / hard limits — the only "don'ts":**
- **Gate before run — never call a `provision.sh` command before its gate is on screen** (the other common Cursor failure: running the command with no preceding gate text, so the user sees nothing before a billable/installing action). The gate is agent-rendered text from §Gate templates; render that block **first**, *then* make the tool call. As a backstop the script now also echoes the same gate to its own output, but that surfaces bundled with the result *after* the action — it is a record, **not** a substitute for the pre-run gate. Order is always: render the gate, then run.
- **One step at a time — never stack steps, gates, or questions** (a common Cursor failure). Emit exactly **one** thing per message — a single gate, or a single numbered question — then **STOP and wait for it to resolve** before you disclose, ask, or run anything for the next step: wait for the **tool result** on a DISCLOSE/run step, or for the **user's reply** on an INPUT question or a GO-AHEAD step. Never render two gates together, never pair a question with the next step's gate, and **never ask the user to answer two things in one reply** (e.g. *"reply with your manager choice **and** whether to sign in"*). Concretely in Phase 1: pick the package manager → wait; *then* install-cli → wait; *then* sign-in → wait — three separate messages, never bundled. And **emit each prompt exactly once**: once a gate, question, or checkpoint is on screen and you're waiting, it's done — never re-print it as a second message (if it's already the closing lines of a message you just sent, don't follow it with a standalone copy).
- **Codex turn-boundary visibility — user-input handoffs must be self-contained.** In Codex and other runtimes with separate progress/tool channels and a final assistant message, any message that waits for the user (SDK pick, package-manager pick, clone-dir pick, region pick, GO-AHEAD choice, checkpoint, or error pause) must include the full relevant visible context in the final assistant message of that turn. Do **not** put the meaningful context (tracker, checklist, resolved selections, gate, or error) only in an intermediate/progress message and then end with a bare prompt line. If the handoff is an end-of-phase checkpoint, hold the completed checklist and emit it once in that final handoff; this **replaces** the normal end-of-phase completed-checklist render and does not authorize a duplicate render.
- **No prose narration** (the #1 historical failure, esp. on Codex). Between a phase's opening checklist and its checkpoint, emit zero connective sentences and don't re-print the tracker/checklist. Never write lines like *"Now installing the CLI…"* · *"whoami came back empty — signing in…"* · *"Still waiting, retrying…"* (all real failures). Retries / polls / readiness-waits inside one confirmed call are **silent**. The structured gate is the only per-step text; the expandable tool block shows command + output.
- **Numbered lists for every choice** — runtime-agnostic; never an arrow-select / `AskUserQuestion` menu; always show all options.
- **No Skip** — a go-ahead step's choices are only `1. <action> / 2. Chat about this` (every step is required; "Chat about this" never skips it — it answers a question, then re-presents). Don't print a "no skip" note.
- **Disclose in full.** A bundled subcommand (e.g. `scaffold` = clone + deps) gets **one** gate, but its GATE block shows **all** its commands. Don't unbundle into per-`temporal` gates; don't hide what it runs.
- **Never edit this skill's files** — invoke `scripts/provision.sh` as shipped; it's pinned to run unchanged on every platform (macOS bash 3.2). Reformatting/"tidying" its punctuation, quoting, regexes, or flags is forbidden. The only file you change on disk is the user's `temporal.toml`, via the script. If a flag has genuinely drifted (script returns `status=error`), stop and report it as a one-line maintenance note — don't fix it mid-run.
- **Already-satisfied prerequisite** → render its checklist item as `- [x] <thing> — already present, skipped` (don't fake-install it). **Exception: the Temporal CLI.** When the CLI is already present the Install-CLI step *updates* it to the latest (PE-79), so render that step as updated/up-to-date, never "skipped" — see the Install-CLI flow step.
- **Secret carve-out** (below) overrides disclosure for the API-key token.
</output-contract>
## Steps — the flow (the spine)
<steps>
The whole run in order. Tier legend (full mechanics in the output contract above): **DISCLOSE** = render the gate, then run (the user's permission prompt is the approval); **GO-AHEAD** = render, then append `1. <action> / 2. Chat about this` and wait (only the three deliberate steps); **INPUT** = a numbered question (no script). Each step is one `scripts/provision.sh` subcommand unless noted. "On-error" lists the `error_code`s to map via Failure Handling.
| # | Phase | Step | Tier | Subcommand | Emits | On-error |
|---|-------|------|------|------------|-------|----------|
| 1 | 1 | Choose SDK | INPUT | — (numbered list) | sdk | — |
| 2 | 1 | Preflight | DISCLOSE | `preflight --sdk` | `config_path`,`warnings`,`stray_env` | `config-dir-unwritable` |
| 3 | 1 | Detect tools + pick manager | DISCLOSE (+ INPUT if >1 manager) | `detect-tools --sdk` | `default`,`managers`,`discrepancies` | `version-too-old` (advisory) |
| 4 | 1 | Install / update CLI | DISCLOSE | `install-cli` | `status` (`ok`); `update` (`updated`/`up-to-date`/`skipped`/`failed`) | `brew-missing`,`manual-install` |
| 5 | 1 | Sign in | **GO-AHEAD** | `login` | `identity` | `login-failed`,`not-authenticated` |
| 6 | 1 | List + pick region | DISCLOSE + INPUT | `regions` | region list | `cloud-unreachable` |
| 7 | 2 | Start namespace (async) | DISCLOSE | `start-namespace --sdk --region` | `namespace_name` | `create-rejected` |
| 8 | 2 | Choose clone dir | INPUT | — (1=default / 2=Edit) | dir | — |
| 9 | 2 | Scaffold the app | DISCLOSE | `scaffold --sdk [--manager] [--dir]` | `repo_path`,`manager` | `clone-failed`,`unknown-sdk`,`manager-not-found`,`unsupported-manager` |
| 10 | 2 | Await namespace (join) | DISCLOSE | `await-namespace --name` | `namespace_handle`,`address` | `namespace-timeout`,`namespace-not-provisioning`,`handle-not-found` |
| 11 | 2 | Create key + save config | DISCLOSE | `create-key --handle --address` | `key_id` (token never printed) | `key-empty`,`key-limit-reached`,`no-json-parser`,`manual-key-needed` |
| 12 | 2 | Verify config | DISCLOSE | `verify-config` | — | `profile-missing` |
| 13 | 3 | Await auth | DISCLOSE | `await-auth` | `auth_ready` | `auth-timeout`,`key-expired` |
| 14 | 3 | Run the Workflow | **GO-AHEAD** | `run-workflow --sdk --dir` | `workflow_status`,`workflow_id`,`run_id` | `worker-unauthorized`,`worker-not-polling`,`worker-start-failed`,`workflow-failed`,`workflow-not-submitted`,`workflow-timeout`,`precompile-failed` |
| 15 | 4 | Inject failure + recover | **GO-AHEAD** | `run-workflow … --demo-failure transient` | same as 14 | same as 14 |
Phase bodies below add only the human nuance the table can't (region-pick guardrails, KeyId-vs-secret labeling, the result links). The exact command of any step comes from its gate — render it from the `‹sub›` template in §Gate templates (slots filled), don't hand-write it.
</steps>
### Secret-handling carve-out (overrides command disclosure)
The output contract says disclose the real command. **The API-key steps are the exception.** The `eyJ…` token must never be reprinted, logged, rendered in a diff, or passed as an argv (a rendered diff is the one exposure that leaves the local machine). For the key-capture and TOML-write actions:
- Show the friendly label and a **redacted** form of the command — e.g. `api_key = "eyJ…(captured, not shown)"`.
- Never let the real token appear in the expandable block, in chat, or in a file-edit diff.
- The **KeyId** (e.g. `JW4LO…`) is *not* secret and may be shown. See Phase 2 for the KeyId-vs-secret distinction.
- **Never read, `cat`, `grep`, or open `temporal.toml` (or any key-capture file) with the Read/Edit/Update tool.** The file holds the `eyJ…` token, so *any* read of it surfaces the secret into this transcript — this is the most common accidental leak. To confirm the profile, use **only** `scripts/provision.sh verify-config` (it lists profile *names*, never the key value).
- **Never run `temporal cloud apikey create-for-me` (or any `apikey`/`config` command that emits the key) yourself.** Only `scripts/provision.sh create-key` mints and stores the token — it redirects the one-time secret straight into the locked file. Run the raw CLI by hand and it prints the token to the terminal, into this output.
## Execution model — drive the bundled script, don't hand-roll the CLI
The variance-prone work — installing the CLI, signing in, listing regions, creating the namespace, minting the API key, and writing the client-config TOML — is owned by a bundled script: **`scripts/provision.sh`**. **Invoke it and parse its result block; do not reassemble these `temporal cloud` commands yourself.** That is what makes a run deterministic: the flags are pinned in one place, the retry / auth-recheck / "read the handle from the create output" logic is baked in, and the API-key token is written straight into the locked TOML by the script — so it never enters your context and can never leak into a rendered diff.
Each operation prints one delimited block on **stdout** — parse *that*, not the prose:
```
=== RESULT ===
status=ok # ok | error | skipped
<key>=<value> # operation-specific, e.g. namespace_handle=…, address=…, key_id=…
=== END ===
```
Human-readable progress goes to **stderr** (it shows in the expandable tool block — the teaching surface). On `status=error` the block carries `error_code` + `message` — map it via **Failure Handling** and fix the named cause (never improvise, switch output formats, or poll — as the output contract requires).
The flow steps — subcommand, tier, and error codes — are the **Steps spine table above** (single source of truth). The RESULT keys each emits:
- `preflight` → `os`, `config_path`, `cli_installed` (drives Install-CLI: install if absent, update if present), `warnings`, `stray_env`
- `detect-tools` → `default`, `managers`, `versions`, `discrepancies`
- `install-cli` → `status` (`ok`) + `update` (`updated`/`up-to-date`/`skipped`/`failed` when present; `skipped`/`failed` still proceed with the working CLI) + `reason` (`brew-missing`/`unsupported-os`, present only alongside `update=skipped`) · `login` → `identity` · `regions` → raw list on stderr (you recommend, user picks)
- `start-namespace` → `namespace_name` · `scaffold` → `repo_path`, `manager` · `await-namespace` → `namespace_handle`, `address`
- `create-key` → `key_id` (token never printed) · `verify-config` → profile names only · `await-auth` → `auth_ready`
- `run-workflow` → `workflow_status` (`COMPLETED`), `workflow_id`, `run_id`, `task_queue` (add `--demo-failure transient` for Phase 4)
Auf GitHub ansehen