From 01ee9ecf57ab16fb251306f6e30cff58f9e13c1c Mon Sep 17 00:00:00 2001 From: Jurie Smit Date: Tue, 31 Mar 2026 23:24:31 +0200 Subject: [PATCH] feat(jetbrains): add Junie context integration and IDE onboarding docs - Add optional Junie dependency in plugin.xml (loaded only when Junie is installed) - Add junie.xml descriptor registering RetortWorkspaceContextService - Implement RetortWorkspaceContextService to build phase/task/teams context block - Rename CI workflow to "JetBrains Plugin", add workflow_dispatch trigger - Add docs/onboarding/ with per-IDE guides (VS Code, JetBrains, Zed) and overview Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/pycharm.yml | 5 +- docs/onboarding/README.md | 41 +++++ docs/onboarding/jetbrains.md | 142 ++++++++++++++++++ docs/onboarding/vscode.md | 87 +++++++++++ docs/onboarding/zed.md | 76 ++++++++++ extensions/pycharm/build.gradle.kts | 13 +- .../junie/RetortWorkspaceContextService.kt | 94 ++++++++++++ .../src/main/resources/META-INF/junie.xml | 21 +++ .../src/main/resources/META-INF/plugin.xml | 10 +- 9 files changed, 483 insertions(+), 6 deletions(-) create mode 100644 docs/onboarding/README.md create mode 100644 docs/onboarding/jetbrains.md create mode 100644 docs/onboarding/vscode.md create mode 100644 docs/onboarding/zed.md create mode 100644 extensions/pycharm/src/main/kotlin/com/phoenixvc/retort/junie/RetortWorkspaceContextService.kt create mode 100644 extensions/pycharm/src/main/resources/META-INF/junie.xml diff --git a/.github/workflows/pycharm.yml b/.github/workflows/pycharm.yml index 3eb2660..7dd4987 100644 --- a/.github/workflows/pycharm.yml +++ b/.github/workflows/pycharm.yml @@ -1,10 +1,11 @@ -name: PyCharm Plugin +name: JetBrains Plugin on: push: paths: ['extensions/pycharm/**'] pull_request: paths: ['extensions/pycharm/**'] + workflow_dispatch: jobs: build: @@ -21,6 +22,6 @@ jobs: working-directory: extensions/pycharm run: ./gradlew buildPlugin - - name: Verify plugin + - name: Verify plugin (PyCharm + Rider) working-directory: extensions/pycharm run: ./gradlew verifyPlugin diff --git a/docs/onboarding/README.md b/docs/onboarding/README.md new file mode 100644 index 0000000..5a70104 --- /dev/null +++ b/docs/onboarding/README.md @@ -0,0 +1,41 @@ +# Retort IDE Plugin — Onboarding Overview + +Retort ships editor extensions for three IDEs. Each integrates with the +[Retort framework](https://github.com/phoenixvc/retort) running in your terminal, +surfacing commands, status, and (where supported) AI context injection directly +inside your editor. + +| IDE | Extension | Status | +|-----|-----------|--------| +| [VS Code](vscode.md) | VSIX via Marketplace / manual | Available | +| [JetBrains](jetbrains.md) | Plugin via Marketplace / local install | Available | +| [Zed](zed.md) | Extension via Zed extension registry | Available | + +## Prerequisites + +All extensions require Retort to be installed in your project: + +```bash +# Verify Retort is present +cat .agentkit/spec/project.yaml # must exist +pnpm -C .agentkit retort:sync # ensure generated files are up-to-date +``` + +The extension activates automatically when `.agentkit/` is detected at the +workspace root. No manual configuration is needed for basic usage. + +## Common Features Across All IDEs + +| Feature | VS Code | JetBrains | Zed | +|---------|---------|-----------|-----| +| Command palette | ✓ | ✓ | ✓ (slash commands) | +| Project tool window / sidebar | ✓ | ✓ | — | +| Status bar widget | ✓ | ✓ | — | +| Junie / AI context injection | — | ✓ (optional) | — | + +## Quick Links + +- [VS Code onboarding](vscode.md) +- [JetBrains onboarding](jetbrains.md) — covers PyCharm, IntelliJ IDEA, Rider +- [Zed onboarding](zed.md) +- [Junie integration details](jetbrains.md#junie-integration) diff --git a/docs/onboarding/jetbrains.md b/docs/onboarding/jetbrains.md new file mode 100644 index 0000000..9e40395 --- /dev/null +++ b/docs/onboarding/jetbrains.md @@ -0,0 +1,142 @@ +# Retort — JetBrains Plugin + +The JetBrains plugin works across PyCharm, IntelliJ IDEA, Rider, and any +other IDE built on the IntelliJ platform (build 233+). It provides a command +palette, project tool window, and status bar widget. Optionally, when the +[Junie](https://www.jetbrains.com/junie/) AI plugin is installed, Retort +injects active team and task context into every Junie AI session. + +## Requirements + +- IntelliJ-based IDE build `233` or later (2023.3+), up to `251.*` + - PyCharm 2023.3+ + - IntelliJ IDEA 2023.3+ + - Rider 2023.3+ +- Retort installed in the project (`.agentkit/spec/project.yaml` must exist) +- Gradle / JDK 17+ (for building from source only) + +## Installation + +### From JetBrains Marketplace (recommended) + +1. Open your IDE. +2. Go to **Settings → Plugins → Marketplace**. +3. Search for **Retort**. +4. Click **Install** and restart the IDE when prompted. + +### Manual / dev install + +```bash +cd extensions/pycharm +./gradlew buildPlugin # produces build/distributions/retort-*.zip +``` + +Then in the IDE: **Settings → Plugins → ⚙ → Install Plugin from Disk…** and +select the generated `.zip`. + +### Building and running in a sandbox IDE + +```bash +cd extensions/pycharm +./gradlew runIde # launches a sandboxed IDE with the plugin pre-installed +``` + +## Activation + +The plugin activates for any project that contains `.agentkit/` at its root. +No manual configuration is required. + +## Available Commands + +Access via **Tools → Retort** in the menu bar, or press +`Shift+Ctrl+Alt+R` (Windows/Linux) / `Shift+Cmd+Alt+R` (macOS) to open the +**Run Command...** picker. + +| Menu Item | Description | +|-----------|-------------| +| Sync Configs | Regenerate all AI tool configs from spec | +| Run Check | Lint + typecheck + tests | +| Health Check | Full repo health check | +| Orchestrate | Master coordinator — assess, plan, delegate | +| Plan | Structured implementation planning | +| Discover | Scan repo structure and tech stacks | +| Validate | Validate spec against schema | +| Show Backlog | Show consolidated backlog | +| Handoff | Generate session handoff document | +| Preflight | Pre-ship delivery checks | +| Security Scan | Security audit | +| Project Status | Unified PM dashboard | +| **Run Command...** | Choose and run any Retort command | + +## Tool Window + +The **Retort** panel (right side bar) shows: + +- Active orchestration phase +- In-progress tasks from `.claude/state/tasks/` +- Quick-launch buttons for common commands + +## Status Bar Widget + +A widget on the right of the status bar shows the active phase. Click it to +open the command picker. + +## Junie Integration + +> **Status:** The Junie third-party context API is not yet public. The +> integration is pre-wired and will activate automatically once JetBrains +> publishes a stable extension point. + +When both the Retort plugin and [Junie](https://plugins.jetbrains.com/plugin/24367-junie) +are installed, Retort registers a workspace context provider that injects: + +- The active orchestration **phase** (Discovery / Planning / Implementation / Validation / Ship) +- **In-progress task titles** from `.claude/state/tasks/` +- The path to the **teams file** (`.agentkit/spec/teams.yaml` or `AGENT_TEAMS.md`) + +This context block is prepended to each Junie AI session so the assistant is +immediately aware of what the team is working on and which slash commands are +available. + +### How the optional dependency works + +The Junie integration is declared as an optional plugin dependency in +`META-INF/plugin.xml`: + +```xml +com.intellij.junie +``` + +- If Junie is **not** installed the `junie.xml` descriptor is never loaded and + no Junie classes are referenced — the plugin works exactly as before. +- If Junie **is** installed, `RetortWorkspaceContextService` is registered as a + project service and wired to Junie's context provider once JetBrains publishes + the stable API. + +### Enabling context injection manually (until API is public) + +Until the official `JunieContextProvider` extension point ships you can copy the +context string into a Junie session manually: + +1. Open the **Retort** tool window. +2. Click **Copy Workspace Context** (shows active phase + tasks). +3. Paste into the Junie chat as the first message. + +## Troubleshooting + +**Plugin not activating** +: Ensure `.agentkit/spec/project.yaml` exists at the project root. + Check **Help → Show Log in Explorer/Finder** for `RetortPlugin` log lines. + +**Junie section missing in tool window** +: The Junie section only renders when Junie is installed. Install it via + **Settings → Plugins → Marketplace → Junie**. + +**`gradlew buildPlugin` fails with SDK error** +: Run `./gradlew wrapper` to refresh the Gradle wrapper, then check that a + JDK 17+ is configured in **File → Project Structure → SDKs**. + +**Build fails: `until-build` compatibility** +: The plugin targets builds up to `251.*`. If your IDE build is newer, update + `until-build` in `plugin.xml` and `intellijPlatform { ... }` in + `build.gradle.kts`, then rebuild. diff --git a/docs/onboarding/vscode.md b/docs/onboarding/vscode.md new file mode 100644 index 0000000..fc09229 --- /dev/null +++ b/docs/onboarding/vscode.md @@ -0,0 +1,87 @@ +# Retort — VS Code Extension + +The VS Code extension surfaces Retort commands in the command palette, +a sidebar view, and a status bar widget. It activates automatically when +a `.agentkit/` directory is present at the workspace root. + +## Requirements + +- VS Code `^1.85.0` +- Retort installed in the project (`.agentkit/spec/project.yaml` must exist) + +## Installation + +### From the Marketplace (recommended) + +1. Open VS Code. +2. Press `Ctrl+Shift+X` to open the Extensions panel. +3. Search for **Retort** (publisher: `phoenixvc`). +4. Click **Install**. + +### Manual / dev install + +```bash +cd extensions/vscode +pnpm install +pnpm run build # compiles to out/extension.js +``` + +Then in VS Code: **Extensions → ⋯ → Install from VSIX...** and select +`extensions/vscode/retort-*.vsix` (produced by `pnpm run package`). + +## Activation + +The extension activates when VS Code opens a workspace that contains `.agentkit/` +at the root (`activationEvents: ["workspaceContains:.agentkit"]`). No manual +enable step is required. + +## Available Commands + +Open the Command Palette (`Ctrl+Shift+P`) and type **Retort** to see all commands: + +| Command | Description | +|---------|-------------| +| `Retort: Sync Configs` | Regenerate AI tool configs from spec | +| `Retort: Run Check` | Lint + typecheck + tests | +| `Retort: Health Check` | Full repo health check | +| `Retort: Orchestrate` | Master coordinator — assess, plan, delegate | +| `Retort: Plan` | Structured implementation planning | +| `Retort: Discover` | Scan repo structure and tech stacks | +| `Retort: Validate` | Validate spec against schema | +| `Retort: Show Backlog` | Show consolidated backlog | +| `Retort: Handoff` | Generate session handoff document | +| `Retort: Preflight` | Pre-ship delivery checks | +| `Retort: Security Scan` | Security audit | +| `Retort: Project Status` | Unified PM dashboard | +| `Retort: Run Command...` | Choose and run any Retort command | + +## Keyboard Shortcut + +`Shift+Ctrl+Alt+R` — opens the **Run Command...** picker. + +## Sidebar + +The Retort sidebar view (Activity Bar icon) shows: + +- Active orchestration phase +- In-progress tasks from `.claude/state/tasks/` +- Quick-launch buttons for common commands + +## Status Bar + +A status bar item on the right shows the active phase (e.g. `Retort: Implementation`). +Click it to open the command picker. + +## Troubleshooting + +**Extension not activating** +: Ensure `.agentkit/spec/project.yaml` exists. The extension only activates when + `.agentkit/` is present at the workspace root — not in a subdirectory. + +**Commands not found in terminal** +: The extension runs Retort in VS Code's integrated terminal. Ensure `pnpm` is + on your `PATH`. Check `Extensions → Retort → Output` for error details. + +**Sidebar is empty** +: Run `Retort: Sync Configs` once to generate state files. The sidebar reads + `.claude/state/` which is created on first sync. diff --git a/docs/onboarding/zed.md b/docs/onboarding/zed.md new file mode 100644 index 0000000..b5e213e --- /dev/null +++ b/docs/onboarding/zed.md @@ -0,0 +1,76 @@ +# Retort — Zed Extension + +The Zed extension adds Retort slash commands to Zed's AI assistant panel. +It is implemented as a Rust `slash_command` extension. + +## Requirements + +- [Zed](https://zed.dev) stable or nightly +- Retort installed in the project (`.agentkit/spec/project.yaml` must exist) +- Rust toolchain (for building from source only) + +## Installation + +### From the Zed Extension Registry (recommended) + +1. Open Zed. +2. Press `Cmd+Shift+X` (macOS) / `Ctrl+Shift+X` (Linux) to open extensions. +3. Search for **Retort**. +4. Click **Install**. + +### Manual / dev install + +```bash +cd extensions/zed +cargo build --release +``` + +Then in Zed: **Extensions → Install Dev Extension** and point to the +`extensions/zed` directory. + +## Available Slash Commands + +Type `/` in the Zed AI assistant panel to see the Retort commands: + +| Command | Description | +|---------|-------------| +| `/retort-status` | Show active Retort agents and task status | +| `/retort-teams` | List Retort agent teams | +| `/retort-backlog` | Show open Retort backlog items | +| `/retort-sync` | Instructions to run `retort sync` | + +## Usage Example + +``` +/retort-status +# → Returns current phase, in-progress tasks, and team roster + +/retort-teams +# → Lists all configured agent teams with their scope + +/retort-backlog +# → Shows open items from AGENT_BACKLOG.md +``` + +## Limitations + +Compared to the VS Code and JetBrains extensions, the Zed extension is +intentionally minimal — Zed's extension API currently supports slash commands +only. There is no sidebar panel or status bar widget. + +As Zed's extension API matures, additional surface areas (status bar, sidebar) +will be added. + +## Troubleshooting + +**Commands not appearing** +: Ensure the extension is installed and Zed has been restarted. Slash commands + appear only when the AI assistant panel is open (`Cmd+?` or **View → AI Assistant**). + +**`cargo build` fails** +: Ensure Rust stable is installed (`rustup update stable`). The extension uses + the `zed_extension_api` crate — check `Cargo.toml` for the pinned version. + +**Output is empty** +: The extension reads `.claude/state/` files. Run `retort sync` in the terminal + first to generate state files, then retry the slash command. diff --git a/extensions/pycharm/build.gradle.kts b/extensions/pycharm/build.gradle.kts index 107b4c6..1a84fcc 100644 --- a/extensions/pycharm/build.gradle.kts +++ b/extensions/pycharm/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType + plugins { id("org.jetbrains.intellij.platform") version "2.2.1" id("org.jetbrains.kotlin.jvm") version "2.0.21" @@ -15,7 +17,8 @@ repositories { dependencies { intellijPlatform { - // Targets PyCharm Community; swap to "PC" for Professional or "IU" for IntelliJ Ultimate + // Targets PyCharm Community for development; plugin.xml declares platform-level + // compatibility so it also runs on Rider, IntelliJ IDEA, and other JetBrains IDEs. pycharmCommunity("2024.3") bundledPlugins("com.intellij.modules.python") pluginVerifier() @@ -32,6 +35,14 @@ intellijPlatform { } } + pluginVerification { + ides { + // Verify against both PyCharm Community and Rider to ensure cross-IDE compatibility + ide(IntelliJPlatformType.PyCharmCommunity, "2024.3") + ide(IntelliJPlatformType.Rider, "2024.3") + } + } + signing { // Set via env vars RETORT_CHAIN_CRT / RETORT_PRIVATE_KEY in CI certificateChainFile = providers.environmentVariable("RETORT_CHAIN_CRT") diff --git a/extensions/pycharm/src/main/kotlin/com/phoenixvc/retort/junie/RetortWorkspaceContextService.kt b/extensions/pycharm/src/main/kotlin/com/phoenixvc/retort/junie/RetortWorkspaceContextService.kt new file mode 100644 index 0000000..e174a45 --- /dev/null +++ b/extensions/pycharm/src/main/kotlin/com/phoenixvc/retort/junie/RetortWorkspaceContextService.kt @@ -0,0 +1,94 @@ +package com.phoenixvc.retort.junie + +import com.intellij.openapi.components.Service +import com.intellij.openapi.project.Project +import java.io.File + +/** + * Reads Retort workspace state and formats it as a Junie context block. + * + * This service is registered in junie.xml (loaded only when Junie is installed). + * + * TODO: Once JetBrains publishes a stable `com.intellij.junie.ext.JunieContextProvider` + * extension point, implement that interface here so Retort context is automatically + * injected into every Junie AI session. + * + * Usage (when Junie API is available): + * val service = project.getService(RetortWorkspaceContextService::class.java) + * val context = service.buildContext() // inject into Junie session + */ +@Service(Service.Level.PROJECT) +class RetortWorkspaceContextService(private val project: Project) { + + /** + * Returns a markdown-formatted context block describing the active Retort workspace: + * - Active orchestration phase + * - In-progress tasks + * - Team roster (from .agentkit/spec/teams.yaml or AGENT_TEAMS.md) + */ + fun buildContext(): String { + val root = project.basePath ?: return "" + val sections = mutableListOf() + + // Orchestration phase + val sessionFile = File(root, ".claude/state/orchestrator.json") + if (sessionFile.exists()) { + try { + val text = sessionFile.readText() + val phaseMatch = Regex(""""phase"\s*:\s*(\d+)""").find(text) + val phase = phaseMatch?.groupValues?.get(1)?.toIntOrNull() + if (phase != null) { + val phaseName = PHASE_NAMES[phase] ?: "Phase $phase" + sections += "**Active phase:** $phaseName" + } + } catch (_: Exception) { /* ignore */ } + } + + // In-progress tasks + val tasksDir = File(root, ".claude/state/tasks") + if (tasksDir.isDirectory) { + val inProgress = tasksDir.listFiles { f -> f.extension == "json" } + ?.mapNotNull { f -> + try { + val text = f.readText() + if (text.contains(""""status":"working"""") || text.contains(""""status":"accepted"""")) { + Regex(""""title"\s*:\s*"([^"]+)"""").find(text)?.groupValues?.get(1) + } else null + } catch (_: Exception) { null } + } + ?: emptyList() + + if (inProgress.isNotEmpty()) { + sections += "**In-progress tasks:**\n" + inProgress.joinToString("\n") { "- $it" } + } + } + + // Teams + val teamsYaml = sequenceOf( + ".agentkit/spec/teams.yaml", + ".agentkit/spec/AGENT_TEAMS.yaml", + "AGENT_TEAMS.md", + ).map { File(root, it) }.firstOrNull { it.exists() } + + if (teamsYaml != null) { + sections += "**Retort teams file:** `${teamsYaml.name}` (use `/team-` commands to delegate work)" + } + + if (sections.isEmpty()) return "" + + return buildString { + appendLine("") + sections.forEach { appendLine(it).appendLine() } + }.trim() + } + + companion object { + private val PHASE_NAMES = mapOf( + 1 to "Discovery", + 2 to "Planning", + 3 to "Implementation", + 4 to "Validation", + 5 to "Ship", + ) + } +} diff --git a/extensions/pycharm/src/main/resources/META-INF/junie.xml b/extensions/pycharm/src/main/resources/META-INF/junie.xml new file mode 100644 index 0000000..4450a55 --- /dev/null +++ b/extensions/pycharm/src/main/resources/META-INF/junie.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/extensions/pycharm/src/main/resources/META-INF/plugin.xml b/extensions/pycharm/src/main/resources/META-INF/plugin.xml index 445439a..37113b9 100644 --- a/extensions/pycharm/src/main/resources/META-INF/plugin.xml +++ b/extensions/pycharm/src/main/resources/META-INF/plugin.xml @@ -4,18 +4,22 @@ 0.1.0 PhoenixVC + AI agent orchestration for JetBrains IDEs — PyCharm, IntelliJ IDEA, Rider, and more.
Provides a command palette, project tool window, and status bar widget - for the Retort framework. + for the Retort framework.

+ When Junie is installed, Retort injects active team and task context into AI sessions. ]]>
0.1.0 — Initial release. ]]> - + com.intellij.modules.platform + + com.intellij.junie +