---
name: setup-project
description: Walk the user through creating a new PinAppAI project from scratch — pick or create a workspace, create the project, and emit the widget snippet they can paste into their site.
arguments: []
---
# Set up a new PinAppAI project

You're helping the user spin up a brand-new project. The flow:
**(workspace) → (project) → (widget snippet) → (optional reviewers)**.

Use the `get_me` tool first to learn what context the API key sits in.
That tells you the workspace + role; it shapes everything below.

## Step 1 — Confirm the workspace

Call `get_me`. From the result:

- **role = owner / admin / editor**: the API key can create projects in this
  workspace. Skip to Step 2.
- **role = viewer**: the API key cannot create projects. Tell the user
  they need to either (a) ask their workspace admin/owner to mint a new
  key for them, or (b) sign in to https://app.pinappai.com and create
  the project themselves. Stop here — there's nothing else MCP can do.

If the user wants the project in a DIFFERENT workspace than this key is
bound to, call `list_workspaces` and tell them which workspaces they're
already a member of. They can:

- Mint a key for that workspace at app.pinappai.com/api-keys, then re-run
  `/pinappai:setup-project` after restarting their MCP host with the new
  key. (The MCP can't switch keys mid-session.)
- Or call `create_workspace` here to spin up a fresh workspace — but the
  current key remains bound to the OLD workspace, so they'll still need
  to mint a key for the new one before the project setup can finish.

## Step 2 — Create the project

Don't interrogate the user field by field — DERIVE defaults from the
repo first, then confirm everything in ONE question:

- **slug**: from the site's domain (`astro.config` `site`, `CNAME`,
  `package.json` `homepage`, framework equivalents) with dots folded to
  hyphens (`bulut-ik.com` → `bulut-ik-com`); else from the repo
  directory name. Lowercase, hyphens only.
- **name**: the site/product name from config or README title; else
  Title-Case the slug.
- **allowed_origins**: the site's `https://` origin(s) from the same
  config sources. Include a localhost dev origin only if the user asks.

Present the derived trio in one block and ask: "Create the project with
these? Correct anything inline." A user answer like "slug is fine, call
it Bulut İK" adjusts just that field. Only when NOTHING is derivable
(bare repo, no config) fall back to asking for the three values.

Call `create_project({ slug, name, allowed_origins })`. The response
includes the embeddable `project_key` (a `pk_…` value — the project's
public widget key, distinct from the caller's `ppk_…` MCP credential
which is a privileged workspace key). The same value is also exposed
as `api_key` in the response for back-compat — same string, legacy
name; prefer `project_key` going forward.

If the response is 409 `slug_taken`, ask for a different slug.

## Step 3 — Emit the widget snippet

{{include: _shared/widget-snippet.md}}

Substitute the placeholder with the `project_key` returned by
`create_project` in Step 2. Place the snippet just before `</body>` in
the customer's base layout. If the user has a known framework (you've
seen Astro / Next / Hugo / etc. in the conversation), point at the
canonical layout file. **Do NOT echo the full `project_key` value in
chat output** — substitute it silently when writing to the file.

## Step 3b — Permissions-Policy audit

{{include: _shared/permissions-policy-audit.md}}

## Step 3c — Review link

{{include: _shared/review-link-offer.md}}

(You just created the project — `primary_origin` is necessarily unset,
and `allowed_origins` from Step 2 is the first candidate source.)

## Step 4 — Bootstrap the iteration boundary marker

This is the first time the boundary marker is being created in this repo. The
marker is the load-bearing piece of PinAppAI's iteration loop: every future
`/pinappai:apply` run overwrites it with that run's timestamp; every
`/changes/` regeneration reads it to scope the diff.

{{include: _shared/marker-write.md}}

Use the bootstrap variant (file doesn't exist yet → write with `note` field).
The bootstrap timestamp will be overwritten on the first
`/pinappai:apply` run; until then it just establishes the baseline.

### Also bind the repo to this project

Write `.pinappai/context.json` at the repo root with the project slug so
every future `/pinappai:*` prompt resolves the project automatically (no
arg prompts, no list-and-pick dialogs):

```json
{
  "project": "<slug>"
}
```

If `.pinappai/context.json` already exists (rare during setup, but
possible if a teammate populated stack / i18n fields ahead of you),
MERGE: preserve every existing key and add/overwrite only the `project`
field. Do not clobber unrelated fields like `framework`, `text_lives_in`,
i18n shape, etc.

If `.pinappai/` is gitignored or the working tree is read-only, skip the
write silently — the binding can be created on demand later by the first
`/pinappai:apply` run.

Both `.pinappai/last-applied.json` and `.pinappai/context.json` should
land in the same install commit (Step 7's landing-chooser handles the
commit mechanics).

## Step 5 — (Optional) Add external reviewers

External reviewers don't need PinAppAI accounts — they verify by email
OTP through the widget. To pre-allowlist specific people:

```
invite_reviewer({ project: "<slug>", email: "alice@example.com", name: "Alice" })
```

If the user prefers an open mode where any verified email on a CORS-
allowed origin can submit feedback, they can flip
`allow_anonymous_reviewers: true` via `update_project`. (Default is
false — recommended for staging-first rollouts.)

## Step 6 — Sanity-check

Call `get_project({ project: "<slug>" })` to confirm the project exists
and the allowed_origins shape matches what the user expects. If they
want to verify reviewers are listed, `list_reviewers({ project: "<slug>" })`.

That's the full setup — the widget is now waiting at the user's site.

## Step 7 — Land the install changes

The customer's working tree now has: the `<script>` tag added to their base
layout, `.pinappai/last-applied.json` with the bootstrap timestamp,
`.pinappai/context.json` bound to the project slug, and (if found and
approved in Step 3b) the Permissions-Policy relaxation. All of it commits
together as the install batch.

{{include: _shared/landing-chooser.md}}

For the suggested branch name, use `pinappai/install-YYYY-MM-DD-HHMM`. For the
suggested commit message: `chore: install PinAppAI feedback widget`.

{{include: _shared/output-language.md}}
