JetBrains shipped ThinkRail as an IDE where agents can write their own capabilities instead of waiting for plugin updates. The project hit 5,016 stars and #1 on GitHub Trending (TypeScript) by combining isolated workspaces, living specs as durable project knowledge, and a skill system that lets the pi coding agent extend itself based on how you actually work.
This is not a wrapper around an LLM chat interface. ThinkRail is a full IDE built around agent-extensibility as a core feature. The agent can create tools, register them as reusable skills, and invoke them across workspace boundaries without breaking existing state.
ThinkRail runs on three layers:
The pi coding agent sits at the center. It decides when to invoke an existing skill versus writing a new one based on the task context and available specs.
Each workspace is a separate git worktree. The agent can:
This prevents a newly-created skill from corrupting the main branch or interfering with other active workspaces. If a skill fails, the worktree is disposable. You lose the experiment, not the project.
Traditional documentation goes stale. Living specs are different:
When the agent needs to create a new skill, it queries the spec registry for relevant context. The spec provides:
This makes specs a durable knowledge substrate instead of a brittle reference. The agent does not hallucinate tool signatures because the spec includes the actual contract.
The skill registry is a lookup table mapping task patterns to executable capabilities. When the agent receives a request, it:
| Condition | Action | Rationale |
|---|---|---|
| Exact skill match | Invoke existing skill | Reuse proven capability |
| Partial match + simple delta | Compose existing skills | Avoid redundant code |
| No match + spec exists | Generate new skill from spec | Leverage durable knowledge |
| No match + no spec | Prompt user for clarification | Prevent hallucinated tools |
| Skill fails in test | Rollback and log | Protect workspace state |
The registry does not blindly invoke. It checks workspace compatibility first. A skill written for a Node.js project will not run in a Python workspace, even if the task description matches.
Here is how the agent creates a new skill:
// Simplified skill generation flow
async function generateSkill(intent: string, workspace: Workspace): Promise<Skill> {
// 1. Query living specs for relevant context
const specs = await specRegistry.query(intent);
// 2. Generate skill code using spec patterns
const skillCode = await agent.generate({
intent,
specs,
workspace: workspace.context,
constraints: workspace.securityBoundaries
});
// 3. Test in isolated worktree
const testResult = await workspace.test(skillCode);
if (!testResult.success) {
throw new SkillGenerationError(testResult.errors);
}
// 4. Register skill with metadata
const skill = {
id: generateSkillId(intent),
code: skillCode,
metadata: {
createdAt: Date.now(),
workspace: workspace.id,
specs: specs.map(s => s.id),
testCoverage: testResult.coverage
}
};
await skillRegistry.register(skill);
return skill;
}
The key is step 3: testing in isolation. The agent does not register a skill until it passes tests in the worktree. This prevents broken tools from polluting the registry.
Agent-generated skills are powerful and risky. ThinkRail enforces three boundaries:
The agent cannot escalate privileges. If a skill needs network access, the user must update the spec to allow it. The agent can propose the change, but it cannot self-approve.
| Failure | Impact | Mitigation |
|---|---|---|
| Skill generates invalid code | Test fails, skill not registered | Worktree rollback |
| Skill passes tests but breaks in production | Workspace corruption | Git reset to pre-skill state |
| Skill conflicts with existing skill | Registry collision | Namespace isolation by workspace ID |
| Spec drift (code changes, spec does not) | Agent generates outdated skill | Spec validation on commit |
The most dangerous failure is spec drift. If the spec says a function takes two arguments but the actual implementation takes three, the agent will generate a broken skill. ThinkRail mitigates this with pre-commit hooks that validate specs against the codebase.
ThinkRail is adding full extension support next. This means:
The extension API will expose:
This turns ThinkRail into a platform, not just an IDE. You can build domain-specific skill libraries (e.g., "Kubernetes deployment skills" or "React component generation skills") and share them across teams.
The agent logs every skill invocation with:
This creates an audit trail. If a skill breaks something, you can replay the invocation in a fresh worktree and debug it without affecting the main branch.
The logs also feed back into the skill registry. If a skill consistently fails for certain input patterns, the agent can flag it for review or automatically deprecate it.
ThinkRail runs as a desktop Electron app. The agent backend is a Node.js process that:
The frontend is a React app that renders:
All state lives locally. There is no cloud dependency for core functionality. You can use your own LLM API keys (OpenAI, Anthropic, local models via Ollama).
Use ThinkRail when:
Avoid ThinkRail when:
The skill registry is the breakthrough. Most agentic IDEs treat the agent as a code generator. ThinkRail treats it as a capability builder. The agent does not just write code for you. It writes tools for itself, tests them, and adds them to its own toolkit. That is a different kind of automation.