thinkrailBLOCK
Vibe code with pi in a lightweight, real IDE that customises itself around the way you work — The Vibe You Need
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
ThinkRail is the agentic IDE that gets better every time you use it — learning your project through living specs today, and building its own capabilities tomorrow.
We built a rich interface around the `pi` coding agent, isolated work into separate workspaces, and gave the agent durable project knowledge through living specs and reusable skills. Next, we're adding full extension support, so ThinkRail can create the tools it needs based on how you actually work.
Website: thinkrail.ai · Blog: thinkrail.ai/blog
A `pi` session and the change it made, scoped to an isolated git-worktree workspace.
What you get
- Isolated workspaces. Open any git repo as a project and cut workspaces from it as
git worktrees,
each with its own branch and working directory. Agents work in parallel without touching your checkout; merge the good branch, delete the rest. You can also attach existing worktrees or explicitly work in the project folder itself. Finished and dormant workspaces settle onto a per-project shelf on their own — when their pull request merges or closes, or after a quiet week — and come back the moment you work in them.
- A real IDE around the agent. A splittable workbench of Monac
d2c17516c3b8OBSERVED · 2026-10-14Install
Commands as the repository documents them. They are shown, not run.
git clone <repo-url>
git clone https://github.com/JetBrains/thinkrail.git
Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| claude-code | mentioned | |
| codex | mentioned | |
| copilot | mentioned | |
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: asking-user-questions
description: "Use when composing an ask_user_question round inside a workflow, or when a workflow skill names it at a question step. Shared norms for the tool — not a workflow, nothing to execute."
---
# Asking User Questions
The workflow family's shared norms for `ask_user_question`: how to interview in rounds, what makes a
question worth asking, how to shape options, and how to degrade when answers don't come. Process
skills name this concept at the steps that ask; *when* to ask — and where the answers get recorded —
stays with the referencing skill.
## Interview in rounds until nothing is assumed
- Map the subject as a **design tree**: every decision branches into the decisions that hang off it.
The **frontier** is every open decision whose prerequisites are already settled — the questions you
can ask *now* without guessing at answers you haven't heard.
- One call = one **round** = the whole frontier, with no cap on its size. A question whose answer
depends on another question still open belongs to a *later* round, never the same one. Never split
independent questions across back-to-back calls.
- **The call blocks the current run.** Answers arrive as this tool's result. Don't keep working on the
blocked step or assume an answer until it arrives — seconds or days later. A composer message sent
while the card is open supersedes the round: the card closes unanswered and the message arrives as
the next user message, so treat it as the user's reply and re-ask only what still matters.
- After each round, recompute the frontier: answers settle branches, unblock their dependents, and
prune branches that no longer apply. Ask the next round; never pre-write later rounds.
- The interview is done when the frontier is empty — every branch visited, nothing material silently
assumed. Then continue the referencing skill's next step; there is no extra "are we aligned?" round
(the referencing skill's own gates still apply).
- Depth follows the work, not a quota: work with no open user decision gets zero rounds; a
decision-heavy change may take several.
## Facts are yours, decisions are theirs
- Never ask the user for a fact the workspace, the specs, or the web can answer. Look it up. When a
lookup is slow, start it in the background (a sub-agent, when the host offers one) and ask the rest
of the frontier meanwhile — only the questions downstream of that lookup wait.
- Every decision — scope, observable behavior, trade-offs the user will live with — goes to the user.
Picking an option yourself and moving on is answering your own question, not inferring.
- If candidate options differ only internally — identical observable behavior — it is not a user
decision: decide yourself and record the reasoning in the workflow's artifact.
## What makes a question worth asking
- **It changes the outcome.** Each answer leads somewhere different that the user will see or live
with. If every option ends in the same place, drop the question.
- **It is specific to this work.** Name the actual feature, screen, file, or user ("when a project is
renamed while collapsed..."), never a generic template question.
- **It probes what people silently assume.** Sweep the tree's usual blind spots: scope edges and
non-goals, empty / error / failure states, edge cases and limits, concurrency or multiple
instances, existing data and behavior that must migrate or stay, defaults, and who the work is for.
- **It surfaces tension.** A conflict with a recorded spec decision, an earlier answer, or the
request itself is asked about outright, quoting both sides.
- **It never re-asks.** Anything the request, a prior answer, or the specs already settled is
settled; build on it.
- **A concrete scenario beats an abstract principle.** Ask "a user drags a file onto a busy session —
queue it or reject it?", not "how should concurrency be handled?".
- If the question can't be settled by talking (how something should look or feel), show a concrete
artifact in `options[].preview` — a mockup, snippet, or config — instead of describing it.
## Options
- Recommended option first, label suffixed "(Recommended)", plus a one-line `recommendedReason` saying
why you recommend it over the alternatives (shown inline under the option as a `Why:` line).
- Every option: a concise label (1–5 words, ≤ 60 chars) + a description carrying the trade-off or
consequence of choosing it. Tailor options to the work at hand — never generic placeholders.
- Options must be **decidable by the asked user**: frame them as observable behavior or outcomes
("collapsing a project stays collapsed after a rename"), never as implementation mechanics
("semantic guard", "activation ref").
- Never author your own "Other", free-text, or escape options — the tool adds a free-text row to
every question and an always-available Skip, and reserved labels are rejected. This holds under
`multiSelect` too: the free-text row stays and is *additive* — a typed answer arrives alongside the
checked options, it does not replace them.
- `multiSelect: true` when several answers are valid at once (feature checklists); single-select when
confirming something or choosing one path.
- `options[].preview` (markdown) when a concrete artifact — code, a config, a mockup — is clearer
shown than described. Single-select only.
- `header` is a short chip, ≤ 16 characters.
## Confirming an inference
When you have inferred something and need a yes/adjust rather than an open answer: the inferred
statement *is* the question text, with "Looks right" as the first option (description: "accurate as
written") and a genuine rejection option second (e.g. "Off base — ask me directly"). Edits arrive
through the tool's automatic free-text row — do not author an edit option. Read the response as:
- **"Looks right"** → the inference holds; continue unchanged.
- **Free-text tweak** (one fact changes) → update that field only; don't rTrust audit
BLOCKgrade D · trust 63/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (6 observation(s))
- Network
- declared (3 observation(s))
- Shell
- declared (5 observation(s))
- Dependencies
- pinned
- Secrets in source
- found
Findings (25)
darwin: "ssh-add --apple-use-keychain ~/.ssh/id_ed25519",
linux: "ssh-add ~/.ssh/id_ed25519",
win32: "ssh-add $env:USERPROFILE\\.ssh\\id_ed25519",
return platform ? SSH_ADD_COMMAND[platform] : "ssh-add ~/.ssh/id_ed25519";
const origin = `http://127.0.0.1:${host.port}`;apiKey: "E2E_PROVIDER_SECRET_SENTINEL",
apiKey: "E2E_PROVIDER_SECRET_SENTINEL",
apiKey: "CONTEXT_PRIVATE_KEY_SENTINEL",
const TOKEN = "fixture-access-token";
apiKey: "private-fixture-sentinel",
"xoxb-1234-5678-abcdefgh",
const DEFAULT_STATIC_DIR = resolve(import.meta.dir, "../../web/dist");
expect(css).toContain('@source "../../../packages/ui";');expect(css).toContain('@source "../../../thinkrail-extensions/*/web/**/*.{ts,tsx}";');const ROOT = fileURLToPath(new URL("../../../", import.meta.url));import { longMarkdown } from "../../../../e2e/perf/longMarkdown";const origin = "http://127.0.0.1:24242";
setLayoutStateStorageForTests({ local, session }, "http://127.0.0.1:4311");setLayoutStateStorageForTests({ local, session }, "http://127.0.0.1:5099");"http://127.0.0.1:4311",
"--insecure",
"iVBORw0KGgoAAAANSUhEUgAAAKAAAABaBAMAAADN6EBhAAAALVBMVEURExgcJx1KfzF52UaN/0952kZKfzEcJx09Zyw9ZyxrvUAuSiUuSiVqvUBGeC8W2BlUAAAA4UlEQVRYw2NgGAWjYLAARmUXioFrOpKBLS7UABPg5nFSxTwXD7iBJdQx0EUAZmAKlQxUgBkYQiU
{"type":"message","id":"093d06a4","parentId":"45f5138f","timestamp":"2026-07-13T11:35:28.393Z","message":{"role":"assistant","content":[{"type":"thinking","thinking":"I need to look at the task file aconst binary = atob(payload.replaceAll(/\s/g, ""));
newly-created session share the host resolver (see `submodule-server-agent`). Favorites/recents arrive
Gates applied: no_behavioural_pass.
d2c17516c3b8full audit observations/trust-audit/skill/jetbrains__thinkrail.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-14 | d2c17516c3b8 | BLOCK | D | 63 | first audit |
Questions
What does the thinkrail skill do?
Vibe code with pi in a lightweight, real IDE that customises itself around the way you work — The Vibe You Need
Is thinkrail safe to install?
No — not without reading the findings first. The audit graded it D (63/100) and found 4 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What can thinkrail access on my machine?
The audit observed that it reaches the network, runs shell commands and reads or writes files. Each of those is consistent with what it says it does. Secrets in the source: found — see the findings.
Which assistants does thinkrail work with?
Its documentation mentions claude-code, codex, copilot and cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (d2c17516c3b8), read on 2026-10-14. The repository is watched, and a new audit runs when it changes — this is the first audit.