---
name: peaks-ide
description: Orchestrate peaks-loop's IDE-aware behavior (hooks + statusline + handle) for a user's specific IDE. Detects the current state (which IDE the user is on, what peaks has already installed), plans the install / switch / status / uninstall actions, and invokes the existing peaks CLI primitives. Triggers on `/peaks-ide`, "set up peaks for my IDE", "switch peaks to Trae", "what did peaks install", "uninstall peaks hooks". Sits between the user and `peaks hooks install` / `peaks statusline install` / `peaks hook handle` — those are the CLI primitives; this skill is the user-facing surface.
visibility: internal
---

<!-- peaks:loop-hygiene — HAND-MAINTAINED block, NOT generated; byte-identical in every SKILL.md, enforced by tests/unit/skills/loop-hygiene-block.test.ts. Edit one, edit all 23. -->

## Loop hygiene (every turn — MANDATORY)

**Skill header.** While this skill is active, open every turn with
`Peaks-Loop Skill: <skill> | Peaks-Loop Role: <role> | Peaks-Loop Gate: <gate> | Peaks-Loop Context: <ratio%> (<zone>) | Next: <one short action>`.
Every turn, not only the first — it is how the user knows which skill is driving.
`Role` and `Context` are machine facts: copy them from `peaks skill presence --json`
(`data.role`, `data.context.ratioPct`, `data.context.action`) — never invent them.

**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
ratio in one line if it helps, but never hand them the compaction step: asking the user to
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.

**Read before you edit.** Read a file before your first `Edit` / `Write` / `MultiEdit` on
it — the normal way to work here — for every path outside `.peaks/**` (source, tests, docs,
config); `.peaks/**` writes are exempt.

**Expect one denial per file anyway — and do NOT pre-empt it.** A `PreToolUse` gate (ECC's
"Fact-Forcing Gate") denies the FIRST edit a session makes to any given path, once, by
design. Reading does NOT prevent it: the gate keys on the path's first touch, not on whether
you read it. **Do not recite its four questions before every edit** — it asks when it wants
them, and reciting unprompted burns a round-trip per file for nothing. Answer only when a
denial actually arrives.

**When one does arrive:** a denial is not a failure and the tool is not broken — your edit
was NOT applied. State the facts it asks for (importers, affected API, data schemas if any,
the user's verbatim instruction), then retry the SAME operation. The retry is allowed. Do not
switch tools, do not give up, do not retry blindly. One more thing worth knowing: an idle gap
of ~30 minutes clears the gate's "already passed" list, so a file you cleared earlier can be
denied again after a long pause. That is the gate resetting, not you regressing.
<!-- /peaks:loop-hygiene -->
---

# Peaks-Loop IDE Setup (peaks-ide)

`peaks-ide` is the **user-facing surface** for everything peaks-loop does that's IDE-aware. It does NOT introduce new CLI commands. It orchestrates the existing CLI primitives — `peaks hooks install`, `peaks statusline install`, `peaks hook handle` — based on the user's intent and the IDE the user is on.

**Why this exists (dev-preference red line):** "skill is primary, CLI is auxiliary." The behavior that only an LLM in a skill prompt would use ("detect which IDE the user is on", "plan the migration steps", "ask the user before destructive actions") lives in this SKILL.md, not in a new `peaks <cmd>`. The CLI commands stay as atomic primitives the skill composes.

**Slice #2 scope:** the first version supports Trae (alongside Claude Code, the only other adapter in slice #2's registry). Cursor / Codex / Qoder / Tongyi Lingma will land in slice #3+ — the skill will pick them up automatically because the underlying auto-detect (the `peaks project dashboard --json` flow internally calls `listAdapterIds()` via the `IdeRegistry`) registers them as the registry grows.

## Skill presence (MANDATORY first action)

```bash
peaks skill presence:set peaks-ide --project <repo> --mode <mode> --gate startup
peaks project memories --project <repo> --json  # load durable memory
```

The presence marker tells the global peaks status line that peaks-ide is orchestrating. The memory read pulls forward the slice #1 contract: `peaks <cmd> --project <path>` is the canonical project-root source; `process.env[adapter.envVar]` (e.g. `CLAUDE_PROJECT_DIR`, `TRAE_PROJECT_DIR`) is the env-var override for auto-detect.

## Step 1: detect current state

The skill's first move is to **read**, not to ask. Build a complete picture of the user's IDE environment before any AskUserQuestion.

```bash
# 1. What adapters are registered? (slice #2 ships with claude-code + trae)
peaks project dashboard --project <repo> --json

# 2. Is the user on Claude Code, Trae, or something else?
#    Check the cwd for adapter-specific directories:
ls -la <repo>/.claude 2>/dev/null && echo "claude-code detected"
ls -la <repo>/.trae 2>/dev/null && echo "trae detected"

# 3. Are peaks hooks already installed? For each candidate, read settings.json:
#    claude: <root>/.claude/settings.json
#    trae:   <root>/.trae/settings.json
peaks hooks status --project <repo> --json 2>/dev/null
peaks statusline status --project <repo> --json 2>/dev/null
```

The skill composes a 1-2 sentence **state summary** before asking anything:

> "I see you're on **Trae** (`.trae/` exists in the project root). peaks hooks are **not installed** yet. peaks statusline is **not installed** either. The `peaks hook handle` runtime is available as a CLI primitive — you don't need to install it separately; what needs installing is the settings.json entries that point to it."

The user gets a complete picture without having to answer any question. The next step only fires AskUserQuestion if intent is genuinely ambiguous.

## Step 2: AskUserQuestion (only if intent is ambiguous)

If the user typed `/peaks-ide` without context, the skill's intent is genuinely ambiguous. The four canonical intents are:

| Option | What it does |
|---|---|
| First-time install | Run `peaks hooks install` + `peaks statusline install` for the detected IDE |
| Switch to a different IDE | Detect current install, uninstall from old IDE, install on new IDE (e.g. Claude → Trae) |
| Show current status | Just print the state summary from Step 1; no side effects |
| Uninstall peaks hooks | Run `peaks hooks uninstall` + `peaks statusline uninstall` for the detected IDE |

**Default option is "Show current status"** — the cheapest action, and the user gets useful output even if they didn't know what they wanted. AskUserQuestion is the ONLY place this skill asks anything. All destructive paths (Switch, Uninstall) gate on user confirmation here.

## Step 3: plan & preview (dry-run)

Before any side effect, the skill prints the exact CLI invocations it will run. This is the "see before you leap" step.

```
Plan: First-time install for Trae (.trae/ detected in project root)

  1. peaks hooks install --project <repo>
     → writes a beforeToolCall hook entry to <root>/.trae/settings.json
       that points to `peaks hook handle --project "${TRAE_PROJECT_DIR}"`

  2. peaks statusline install --project <repo>
     → writes a statusLine field with command `peaks statusline`

  3. (no third command — `peaks hook handle` is the runtime; once the
     settings.json entries point to it, the user's Trae will invoke it
     on every PreToolUse event)

Verification: after install, re-run `peaks hooks status --project <repo>`
             to confirm the entries are present.

Proceed? (Y/n)
```

The plan MUST be human-readable. Don't run a side effect until the user confirms.

## Step 4: execute

For each step in the plan, invoke the CLI primitive. The skill does NOT call out to a hidden script — it runs the actual peaks CLI commands, so the user sees the same output they'd see typing the command themselves.

```bash
# Example: first-time Trae install
peaks hooks install --project <repo>
peaks statusline install --project <repo>

# After each command, check the exit code. If non-zero, STOP and report
# the failure to the user. The skill does NOT auto-rollback; the user
# decides what to do next.
```

For destructive paths (Switch, Uninstall), the skill uses a **transactional pattern**: it captures the current state, runs the destructive CLI, then runs the install CLI; if any step fails, it reports the partial state and lets the user decide.

## Step 5: audit log

Every successful execution writes one JSON line to `.peaks/_runtime/<sid>/ide-onboard.log`:

```json
{"timestamp":"2026-06-06T19:55:00Z","intent":"first-time-install","detected_ide":"trae","cli_invocations":["peaks hooks install --project <repo>","peaks statusline install --project <repo>"],"outcome":"success","session_id":"2026-06-06-session-22f08c"}
```

The audit log is **machine-readable** (so `peaks project dashboard` can read it and surface "you installed peaks for Trae on 2026-06-06") and **human-readable** (so the user can `cat` it to see the install history). The skill does NOT write the log file itself — it delegates to `peaks project dashboard` (the canonical log writer, per the dev-preference red line "skill-first for workflow, CLI-backed for gates / side effects"). The audit log writer is a CLI primitive, not a per-skill helper; the skill body MUST NOT introduce a new `peaks <cmd>` for the log writer. The thin helper that writes the log is `scripts/peaks-ide-audit-log.mjs`; see [audit-log-helper.md](references/audit-log-helper.md) for its CLI surface and contract.

## Boundaries

`peaks-ide` may:

- detect the current IDE (cwd + env var + settings.json)
- ask the user via AskUserQuestion (Step 2 only)
- preview the CLI invocations (Step 3)
- execute existing peaks CLI commands (Step 4)
- write a single line to the audit log (Step 5)

`peaks-ide` must NOT:

- introduce new `peaks <cmd>` CLI commands (dev-preference red line: "Default-no on new CLI commands")
- bypass the user's confirmation on destructive paths (Switch / Uninstall)
- write the settings.json directly (the CLI primitives own that)
- run other peaks skills (peaks-code, peaks-qa, etc.) — those are separate skills with their own scopes
- handle multi-IDE scenarios in slice #2 (e.g. "I use Claude at work and Trae at home" — the registry is single-IDE per session; a future slice could add multi-IDE)

## Reference: the CLI primitives the skill composes

- `peaks hooks install` / `peaks hooks uninstall` / `peaks hooks status` — adapter-driven; auto-detects IDE from env / stdin / cwd
- `peaks statusline install` / `peaks statusline uninstall` / `peaks statusline status` — same
- `peaks hook handle` — the runtime handler; not installed, just invoked
- `peaks project dashboard --json` — surfaces the current state summary
- `peaks skill runbook` — surfaces the peaks-ide skill body for inspection

## Next-step references

- The slice #1 RD artifact at `.peaks/_runtime/<sid>/rd/requests/002-2026-06-06-peaks-ide-skeleton.md` documents the slim `IdeAdapter` shape that the skill is built on.
- The slice #2 PRD at `.peaks/_runtime/<sid>/prd/requests/002-2026-06-06-trae-adapter-and-peaks-ide-skill.md` documents the 13 ACs this skill is part of.
- The slice #2 RD artifact (in flight) documents the implementation contract.

## Default runbook

The skill is invoked as `/peaks-ide` or via the natural-language triggers listed in the frontmatter. The runbook is the body of this SKILL.md (steps 1-5 plus the boundaries and reference sections above); the runbook-service extracts the section between this `## Default runbook` heading and the next `##` heading.

When the user types `/peaks-ide` (or "set up peaks for my IDE" / "switch peaks to Trae" / "what did peaks install" / "uninstall peaks hooks"), execute Steps 1 → 5 in order:

1. **Skill presence (MANDATORY first action)**: `peaks skill presence:set peaks-ide --project <repo> --gate startup` and `peaks project memories --project <repo> --json` (load durable memory).
2. **Detect current state** (Step 1 above): `peaks project dashboard --project <repo> --json` + `peaks hooks status --project <repo> --json` + `peaks statusline status --project <repo> --json` + `ls -la <repo>/.claude 2>/dev/null` + `ls -la <repo>/.trae 2>/dev/null`. Build a 1-2 sentence state summary.
3. **AskUserQuestion** (Step 2 above, only if intent is ambiguous). Default option: "Show current status". Destructive paths (Switch, Uninstall) gate on user confirmation here.
4. **Plan & preview** (Step 3 above): print the exact `peaks hooks install` / `peaks statusline install` invocations before running them. Wait for "Proceed? (Y/n)".
5. **Execute** (Step 4 above): run the `peaks hooks install` / `peaks statusline install` (or uninstall / status) commands. Stop on non-zero exit. Do not auto-rollback.
6. **Audit log** (Step 5 above): delegate the JSONL write to `peaks project dashboard` (the canonical log writer; per the dev-preference red line, the skill MUST NOT introduce a new CLI primitive for the log writer).

CLI primitives the skill composes (per the "Reference" section above): `peaks skill presence:set`, `peaks project memories`, `peaks project dashboard`, `peaks hooks install` / `uninstall` / `status`, `peaks statusline install` / `uninstall` / `status`, `peaks hook handle`, `peaks skill runbook`. The skill does NOT introduce any new `peaks <cmd>` command.
