---
name: dev-start
description: Launch SmartStack dev environment (backend + frontend + admin credentials)
argument-hint: "[--stop] [--restart] [--clean] [--reset] [--backend-only] [--frontend-only]"
allowed-tools: Bash, BashOutput, PowerShell
disable-model-invocation: true
---

`/dev-start` is a thin wrapper over the **deterministic `ss dev up` orchestrator**.
`ss dev up` runs the WHOLE workflow in ONE process — detect → (self-repair) →
ensure deps → (restart: stop + build) → launch detached → wait for readiness →
render the cartouche — driven by a tested state machine, NOT by you. You do **not**
chain `detect`/`start`/`wait`/`summary` by hand any more: you run one command and
relay its result.

## THE RULE — always output the cartouche, never a summary
**In every case where `ss dev up` returns a `cartouche`, that field IS your entire reply — output it VERBATIM, and nothing else before or instead of it.** It is forbidden to replace it with a hand-written status sentence ("Serveurs prêts", "servers ready", "c'est lancé", "à toi de tester"…). The user reads the GROUND TRUTH only from the box: per-side `✓ up` / `✗ DOWN`, `Health`, and every `⚠` CORS / port / FrontendUrl warning. A summary HIDES a DOWN side or a broken-CORS warning and makes the user think the app works when it does not — that is exactly the bug this rule exists to kill. Relay the rendered string as-is; never re-type, paraphrase, or pre-empt it.

## Important
- **Bash runs Git Bash (POSIX)** on Windows. Use `ss dev …` only — never `run_in_background`, never raw `dotnet run`/`npm run`. The CLI launches each server as a hidden, fully-detached process tree (WMI, outside the harness Job Object) that survives the session.
- Run `ss dev up <flags> --json` plain — do **not** pipe it through `jq`/`head`/etc. You parse the single JSON line yourself and then output its `cartouche` field verbatim.

## Routing — run ONE Bash command
Parse `$ARGUMENTS`:
- Contains `--stop` → `ss dev stop [--backend-only|--frontend-only] --json` → relay the JSON → DONE.
- Otherwise → `ss dev up <flags> --json`, passing through any of `--restart --clean --reset --backend-only --frontend-only` **verbatim**.

## Handle the result — read the JSON `status`
- **`"ok"`** → output the `cartouche` field **VERBATIM as your whole reply** (THE RULE above) — it carries URLs · database · admin login + real password · health · ⚠ warnings. DONE. A non-zero exit just means a side is DOWN — the box already shows it; **never restart/rebuild/loop because of it**, and never paper over it with "prêts".
- **`"error"`** → there is no cartouche (nothing launched). Print `message`; if `phase == "build"` also print `compiler_output` (the compiler tail). DONE.
- **`"needs_input"`** → dispatch on `reason`. Ask **ONE** `AskUserQuestion`, then re-enter (**at most ONCE** — a second non-`ok` is final):

  - **`reason: "seed_config"`** → **first launch on this branch**: `appsettings.Local.json` must be created with the SQL database **and the mandatory app admin login**. The CLI sends a `proposal` (`server`, `database`, `admin_email`, `admin_password` = a freshly generated strong password, `api_port`, `web_port`, `auth_mode: "windows"`). Show the four proposed values, header "Config locale":
     - **[1] Use these values** → run `reentry.configure` **verbatim** (it already carries the proposal, incl. `ensureDatabase:true`).
     - **[2] Customize** → ask which of `server` / `database` / `admin_email` / `admin_password` to change, collect the new value(s), then build ONE spec from the proposal with the overrides and run it:
       `ss dev configure --json --spec '{"apiPort":<proposal.api_port>,"webPort":<proposal.web_port>,"authMode":"windows","sqlServer":"<server>","sqlDatabase":"<database>","initialAdminEmail":"<admin_email>","initialAdminPassword":"<admin_password>","ensureDatabase":true}'`
     Parse `{ success }`; on `success:false` print `error` and STOP. Surface the DB outcome from `sql_probe` (`created` → "base créée", `existed` → "base existante", `available:false`/`reachable:false` → relay the `warnings[]`: the DB will be created at backend boot). Then run `reentry.then` (`ss dev up … --json`) and handle THAT result (`ok`/`error`). **Do not invent the password** — keep the proposed one unless the user gives one (it must stay ≥12 chars with upper/lower/digit/special, or `configure` rejects it).

  - **`reason: "mismatch" | "occupied"`** → a **PORT** decision (`mismatch` = api≠vite, `occupied` = ports taken by another branch's server). Header "Ports":
     1. Show `message` + the proposed free ports (`proposed_ports.api` / `.web`):
        - **[1] Use proposed** · **[2] Custom** — the user types 2 ports (accept a pattern like `21xx` → 2100/2101; if you can, verify free + distinct) · **[3] Manual edit** — print the file list ONCE and STOP (do **not** write the files yourself).
     2. Write the config with ONE Bash, filling the placeholders in `reentry.configure_ports_only`. Parse `{ success }`; on `success:false` print `error` and STOP.
     3. Run `reentry.then` (`ss dev up … --json`) and handle THAT result (terminal: `ok`/`error`).

## Notes
- **Idempotent / never-halt.** If our own servers are already up and the cache is fresh, `ss dev up` returns the cartouche in one shot. A foreign process squatting our port is rendered **DOWN, never ✓ up** (strong-identity check on the launched child PID), so it never silently reuses a stranger.
- **`--restart`** = stop → incremental `dotnet build` (fail-fast: a compile error returns `status:"error", phase:"build"` and nothing is launched) → relaunch → wait → cartouche. **`--clean`** = full `dotnet clean && build` + clears the Vite cache. `--frontend-only` skips the build/wait; `--backend-only` skips deps/Vite.
- **`appsettings.Local.json`** holds the connection string + JWT + the app admin login — on the **first run of a branch** `ss dev up` returns `needs_input` `reason:"seed_config"` so you **confirm/edit** the SQL server, database and admin login (a strong password is proposed) before the secret is written. After that one-time confirmation the file exists and `ss dev up` runs straight through. A non-default branch gets an **isolated DB** (`SmartStack_<branch>`); `ss dev configure --spec {…,"ensureDatabase":true}` creates it if missing (via `sqlcmd`; if absent/unreachable, the EF migrations applied at startup create it). The mandatory `Security.InitialAdmin` (login + strong password) is seeded here too, gitignored. `ss dev` also sweeps a port change through every URL in the file. You **never** hand-edit config files; `ss dev` writes them.
- **`FileStorage:BasePath` is auto-guaranteed (no prompt).** The template ships it empty and the platform fail-fasts on an empty value (`InvalidOperationException: FileStorage:BasePath is required` → 400 on `/api/administration/uiconfiguration/public/branding` + `/api/user/preferences/for-tenant/{id}` at boot). `ss dev` seeds an absolute dev default (`<apiDir>/app-files`, dir created) into the gitignored `appsettings.Local.json` when empty — both via `ss dev configure` and a pre-launch preflight in `ss dev up`. A custom value is preserved; prod config is untouched.
- Dev is **HTTP-only** (two ports, no https) — never propose an `httpsPort`.
