Conversation
… filters, and context-mode integration - Redesign Console dashboard: 8 clickable stat cards (Projects, Sessions, Active, Memories, Extensions, Requirements, Specifications, Changes), Recent Specifications and Recent Memories cards - Flatten sidebar navigation: single nav list with inline ProjectFilter dropdowns per view - Add TopbarSpecs: active spec pills in top bar across all projects - Add notification navigation with project switching and clear-all support - Add session resume workflow: copy session ID, /resume deep-linking - Memory cards: show linked session, click to navigate, remove clutter - Cross-project APIs: /api/plans/active/all, /api/extensions?all=true - Project list from project_roots table (filtered to real git repos) - Update branding: Make Claude Code production-ready - Add context-mode integration for token-optimized context management - Update README, Docusaurus docs, and marketing site BREAKING CHANGE: Console UI completely restructured — sidebar flattened, project selector removed from sidebar and replaced with per-view inline filters, dashboard cards redesigned, PlanStatus and GitStatus widgets removed
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughThis PR repositions product messaging to "production-ready" across marketing and site text, documents and implements a new context-mode sandbox (FTS5-backed) for large-output tool handling, adds installer support to detect/install a context-mode plugin, and changes v3→v4 config migration to preserve user worktree preferences. Changes
Sequence Diagram(s)sequenceDiagram
participant User as User
participant Pilot as Pilot Shell (Hooks)
participant MCP as MCP context-mode
participant FTS as FTS5 DB
User->>Pilot: Submit large-output command
Pilot->>Pilot: PreToolUse hook intercepts and routes to context-mode
Pilot->>MCP: ctx_execute / ctx_fetch_and_index (sandboxed)
MCP->>FTS: Index summaries / extracted text (FTS5)
MCP-->>Pilot: Return summary/printed output
Pilot-->>User: Present condensed summary in session context
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Claude finished @maxritter's task in 2m 16s —— View job Code Review: feat: complete Console overhaul — v8.0.0
SummaryOverall a solid release. The context-mode integration is well-structured, the migration v4 fix is correct and well-documented, and test coverage for the new plugin installer is thorough. However, there are two bugs in Bugs1. Duplicate "Help" slide with wrong image in
|
| File | Count |
|---|---|
hooks.md title + description |
18 |
| README.md component table | 21 |
DeepDiveSection.tsx |
21 |
| PR description | 21 |
The hooks.md frontmatter needs updating: "18 hooks across 7 lifecycle events" → "21 hooks across 7 lifecycle events".
Observations (no action required)
installer/steps/config_migration.py — v4 retroactive fix is correct.
The logic is sound: existing users already past v4 are unaffected (their version is ≥ 4 so v4 won't re-run). Only users upgrading from v3 or earlier get the corrected behavior. The docstring explaining why the original implementation was wrong is clear.
install_context_mode_plugin() — solid implementation.
Proper early exit when claude isn't available, correct handling of JSON parse failures (falls through to fresh install rather than returning False), and the three-step flow (list → update OR marketplace-add → install) mirrors expected Claude CLI semantics.
Test coverage for install_context_mode_plugin is thorough — 7 cases cover the main paths including timeout, non-zero list exit, marketplace add failure, and the update path. One minor gap: no test covers the case where marketplace add succeeds but plugins install subsequently fails (should return False). Low risk given the existing coverage.
test_config_migration.py — test names updated accurately. The rename from test_enables_all_three_when_disabled to test_enables_reviewers_preserves_worktree correctly documents the changed contract, and the assertion change from is True → is False on worktreeSupport matches the fixed migration.
|
Claude finished @maxritter's task in 1m 7s —— View job Incremental Code Review — Push Delta
✅ Resolved Issues✅ Resolved — Duplicate "Help" slide ( ✅ Resolved — ✅ Resolved — Hook count inconsistency ( Still OpenNone — all previously reported issues are resolved. Observation (no action required)Hook count in tables vs. declared count — minor discrepancy All three bugs from the prior review are fixed. No new issues introduced by this push. |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (5)
.gitignore (1)
272-272: Line 272 duplicates an existing broader rule.
.env*.localis already covered by.env**(Line 240), so this new entry is redundant. Consider keeping one pattern to reduce.gitignorenoise.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.gitignore at line 272, Remove the redundant .env*.local entry from .gitignore because the broader pattern .env** already covers it; locate the duplicate pattern ".env*.local" and delete that line so only the broader ".env**" pattern remains to avoid noise and duplication.docs/site/src/pages/Index.tsx (2)
20-21: Redundant phrasing in SEO description.The description repeats concepts: it starts with "spec-driven plans, enforced tests, persistent knowledge" and ends with "Spec-driven plans. Enforced quality gates. Persistent knowledge." — this reads awkwardly. Consider streamlining.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/site/src/pages/Index.tsx` around lines 20 - 21, The SEO description string assigned to the description property in Index.tsx is redundant (it repeats "spec-driven plans, enforced tests, persistent knowledge" twice); update that description to a single, concise sentence that preserves the key benefits without repetition (e.g., combine into one phrase like "Spec-driven plans, enforced tests, and persistent knowledge — from requirements to production-ready code") so replace the current duplicated text in the description value accordingly.
73-74: SEO description has duplicate value propositions.Similar to the structured data, the SEO description contains near-duplicate phrases. If this is intentional for keyword optimization, consider adding a brief comment explaining the SEO strategy.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/site/src/pages/Index.tsx` around lines 73 - 74, The SEO description prop currently repeats similar value propositions; update the description string used in Index.tsx (the description prop next to title="Pilot Shell - Make Claude Code production-ready.") to remove duplicated phrases and consolidate into a concise, non-redundant sentence, or if duplication is intentional for SEO, add an inline comment above the description explaining the keyword strategy; ensure you edit the description value and/or add the explanatory comment in the same file near the title/description lines.docs/docusaurus/docs/features/console.md (1)
25-25: Use “bug fixes” for consistency in user-facing docs.At Line 25, replacing “bugfixes” with “bug fixes” would align with standard documentation wording.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docusaurus/docs/features/console.md` at line 25, Update the user-facing copy in the "**Memories**" table cell: change the word "bugfixes" to "bug fixes" so the sentence reads "Browsable observations — decisions, discoveries, bug fixes — with type filters and search."; edit the string in the docs/docusaurus/docs/features/console.md entry where the "**Memories**" description is defined.README.md (1)
452-457: Remove blank lines between blockquote entries.The current testimonial block has blank lines inside the quote block, which triggers markdownlint
MD028.Proposed fix
> "Spec-driven development in Pilot Shell is incredible. I'm so impressed that I have to resist the urge to fix every issue all at once." - > "Instead of just letting Claude Code run on its own, you've managed to make it work in a much more organized, consistent, and reliable way within a workflow, which I think is fantastic. What you've built is truly impressive." - > "I have fallen in love with Pilot and just can't stand the idea of having to go back to native Claude."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@README.md` around lines 452 - 457, The testimonial block in README.md contains blank lines between blockquote lines which triggers markdownlint MD028; remove the empty lines so each quoted line is contiguous (i.e., make the three lines starting with ">" a single continuous blockquote with no blank lines between them) and ensure any intended paragraph breaks use consecutive ">" lines rather than empty lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/docusaurus/docs/features/hooks.md`:
- Around line 4-9: The header and summary text in
docs/docusaurus/docs/features/hooks.md claiming "18 hooks across 7 lifecycle
events" is inconsistent with the tables (≈20 hooks) and other files
(DeepDiveSection.tsx and README.md which say "21 hooks"); audit the actual hook
list (including the two command-scoped Stop hooks called out on line 74) to
determine the true total, then update the human-readable counts so all three
places match; specifically change the header/description string in hooks.md (the
"18 hooks across 7 lifecycle events" lines) and any summary/count constants or
strings in DeepDiveSection.tsx and README.md to the reconciled number, and if
the discrepancy comes from omitted command-scoped hooks, either include them in
the tables or explicitly state they are excluded from the total.
In `@docs/site/src/components/ConsoleSection.tsx`:
- Around line 54-59: Remove the duplicate "Help" slide object in the slides
array inside the ConsoleSection component: delete the object with label "Help"
that uses src "/console/settings.png" and alt "Help view — embedded
documentation" so only the real Help slide remains (the one already defined
elsewhere); after removal confirm the slides array length matches the tab layout
(10 tabs) so ConsoleSection's tabs render correctly.
In `@docs/site/src/components/DeepDiveSection.tsx`:
- Around line 225-227: The copy in DeepDiveSection.tsx saying "21 hooks across 7
lifecycle events" is inconsistent with docs/docusaurus/docs/features/hooks.md
and the hooksPipeline array; open DeepDiveSection.tsx (component
DeepDiveSection) and align the copy and displayed lifecycle items with the
canonical hooks list by updating the hook count and lifecycle event list to
match hooksPipeline (or update hooksPipeline to include the missing
UserPromptSubmit and any missing hooks) so totals match (ensure hooksPipeline
includes UserPromptSubmit and the total hook count equals the number in
features/hooks.md), and update either features/hooks.md or hooksPipeline so both
the textual count and rendered lifecycle events (hooksPipeline) and the
DeepDiveSection text are consistent.
In `@installer/steps/dependencies.py`:
- Around line 424-428: The marketplace-add step using
_run_bash_with_retry("claude plugins marketplace add mksglu/context-mode")
should treat the CLI error that indicates the marketplace is already present as
non-fatal; change the failure handling to inspect the command output/error and
continue when it contains the actual message used by the tool (e.g., "already
installed" or at minimum "already") instead of the fragile "already" AND "exist"
check so retries become idempotent; update the logic around the marketplace add
call to detect that substring and return True/skip continuing installation
rather than returning False.
- Around line 406-415: The code calling subprocess.run and parsing the Claude
output should defensively validate the parsed JSON before accessing item.get;
update the block around result/plugins/already_installed in
steps/dependencies.py so that after plugins = json.loads(result.stdout) you
check isinstance(plugins, list) and that each item is a dict (or skip non-dict
items) before calling p.get("id"), and also include AttributeError in the except
tuple (i.e., except (subprocess.TimeoutExpired, json.JSONDecodeError, OSError,
AttributeError)) so unexpected JSON shapes don't raise an uncaught exception;
reference the variables/functions result, plugins, and already_installed when
making the changes.
In `@README.md`:
- Line 440: The README's "Hooks Pipeline" badge incorrectly states "21 hooks"
while pilot/hooks/hooks.json currently defines 15 hook commands across the 7
lifecycle events; update the README.md text for "Hooks Pipeline" to reflect the
actual hook count (15) or make it dynamic, and ensure the badge/string
referencing the hook count in the README (the line containing "21 hooks across 7
events") is changed to match the count found in pilot/hooks/hooks.json so the
documentation no longer drifts from the implementation.
---
Nitpick comments:
In @.gitignore:
- Line 272: Remove the redundant .env*.local entry from .gitignore because the
broader pattern .env** already covers it; locate the duplicate pattern
".env*.local" and delete that line so only the broader ".env**" pattern remains
to avoid noise and duplication.
In `@docs/docusaurus/docs/features/console.md`:
- Line 25: Update the user-facing copy in the "**Memories**" table cell: change
the word "bugfixes" to "bug fixes" so the sentence reads "Browsable observations
— decisions, discoveries, bug fixes — with type filters and search."; edit the
string in the docs/docusaurus/docs/features/console.md entry where the
"**Memories**" description is defined.
In `@docs/site/src/pages/Index.tsx`:
- Around line 20-21: The SEO description string assigned to the description
property in Index.tsx is redundant (it repeats "spec-driven plans, enforced
tests, persistent knowledge" twice); update that description to a single,
concise sentence that preserves the key benefits without repetition (e.g.,
combine into one phrase like "Spec-driven plans, enforced tests, and persistent
knowledge — from requirements to production-ready code") so replace the current
duplicated text in the description value accordingly.
- Around line 73-74: The SEO description prop currently repeats similar value
propositions; update the description string used in Index.tsx (the description
prop next to title="Pilot Shell - Make Claude Code production-ready.") to remove
duplicated phrases and consolidate into a concise, non-redundant sentence, or if
duplication is intentional for SEO, add an inline comment above the description
explaining the keyword strategy; ensure you edit the description value and/or
add the explanatory comment in the same file near the title/description lines.
In `@README.md`:
- Around line 452-457: The testimonial block in README.md contains blank lines
between blockquote lines which triggers markdownlint MD028; remove the empty
lines so each quoted line is contiguous (i.e., make the three lines starting
with ">" a single continuous blockquote with no blank lines between them) and
ensure any intended paragraph breaks use consecutive ">" lines rather than empty
lines.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0f6a952c-f200-4ad9-808c-8fbbaf1b2fcb
⛔ Files ignored due to path filters (75)
console/src/services/sqlite/notifications/store.tsis excluded by!console/**console/src/services/worker/PaginationHelper.tsis excluded by!console/**console/src/services/worker/http/routes/DataRoutes.tsis excluded by!console/**console/src/services/worker/http/routes/ExtensionRoutes.tsis excluded by!console/**console/src/services/worker/http/routes/NotificationRoutes.tsis excluded by!console/**console/src/services/worker/http/routes/PlanRoutes.tsis excluded by!console/**console/src/services/worker/http/routes/utils/planFileReader.tsis excluded by!console/**console/src/ui/viewer/components/NotificationBell.tsxis excluded by!console/**console/src/ui/viewer/components/ProjectFilter.tsxis excluded by!console/**console/src/ui/viewer/components/ui/Modal.tsxis excluded by!console/**console/src/ui/viewer/hooks/useExtensions.tsis excluded by!console/**console/src/ui/viewer/hooks/useNotifications.tsis excluded by!console/**console/src/ui/viewer/hooks/useRouter.tsis excluded by!console/**console/src/ui/viewer/hooks/useStats.tsis excluded by!console/**console/src/ui/viewer/layouts/Sidebar/SidebarFooter.tsxis excluded by!console/**console/src/ui/viewer/layouts/Sidebar/SidebarNav.tsxis excluded by!console/**console/src/ui/viewer/layouts/Sidebar/SidebarProjectSelector.tsxis excluded by!console/**console/src/ui/viewer/layouts/Sidebar/index.tsxis excluded by!console/**console/src/ui/viewer/layouts/Topbar/TopbarActions.tsxis excluded by!console/**console/src/ui/viewer/layouts/Topbar/TopbarSpecs.tsxis excluded by!console/**console/src/ui/viewer/layouts/Topbar/index.tsxis excluded by!console/**console/src/ui/viewer/views/Changes/index.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/PlanStatus.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/RecentActivity.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/RecentSessions.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/RecentSpecs.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/StatsCard.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/StatsGrid.tsxis excluded by!console/**console/src/ui/viewer/views/Dashboard/index.tsxis excluded by!console/**console/src/ui/viewer/views/Extensions/ExtensionsView.tsxis excluded by!console/**console/src/ui/viewer/views/Help/index.tsxis excluded by!console/**console/src/ui/viewer/views/Memories/MemoryCard.tsxis excluded by!console/**console/src/ui/viewer/views/Memories/index.tsxis excluded by!console/**console/src/ui/viewer/views/Requirements/index.tsxis excluded by!console/**console/src/ui/viewer/views/Sessions/SessionCard.tsxis excluded by!console/**console/src/ui/viewer/views/Sessions/index.tsxis excluded by!console/**console/src/ui/viewer/views/Settings/index.tsxis excluded by!console/**console/src/ui/viewer/views/Spec/index.tsxis excluded by!console/**console/src/ui/viewer/views/Usage/index.tsxis excluded by!console/**console/tests/ui/ChangesNavigation.test.tsis excluded by!console/**console/tests/ui/dashboard-project-filter.test.tsis excluded by!console/**console/tests/ui/notification-bell.test.tsis excluded by!console/**console/tests/ui/project-selector.test.tsis excluded by!console/**console/tests/ui/search-removal.test.tsis excluded by!console/**console/tests/ui/stats-grid-spec-cards.test.tsis excluded by!console/**console/tests/ui/use-stats-spec-metrics.test.tsis excluded by!console/**console/tests/worker/notification-routes.test.tsis excluded by!console/**console/tests/worker/plan-author-parsing.test.tsis excluded by!console/**console/tsconfig.jsonis excluded by!console/**docs/img/dashboard.pngis excluded by!**/*.pngdocs/img/extensions.pngis excluded by!**/*.pngdocs/img/specifications.pngis excluded by!**/*.pngdocs/site/public/console/changes.pngis excluded by!**/*.pngdocs/site/public/console/dashboard.pngis excluded by!**/*.pngdocs/site/public/console/extensions.pngis excluded by!**/*.pngdocs/site/public/console/help.pngis excluded by!**/*.pngdocs/site/public/console/memories.pngis excluded by!**/*.pngdocs/site/public/console/requirements.pngis excluded by!**/*.pngdocs/site/public/console/sessions.pngis excluded by!**/*.pngdocs/site/public/console/settings.pngis excluded by!**/*.pngdocs/site/public/console/specifications.pngis excluded by!**/*.pngdocs/site/public/console/usage.pngis excluded by!**/*.pnglauncher/statusline/formatter.pyis excluded by!launcher/**launcher/tests/unit/statusline/test_formatter.pyis excluded by!launcher/**pilot/rules/context-mode.mdis excluded by!pilot/**pilot/scripts/mcp-server.cjsis excluded by!pilot/**pilot/scripts/worker-service.cjsis excluded by!pilot/**pilot/ui/ExtensionsView.jsis excluded by!pilot/**pilot/ui/index.jsis excluded by!pilot/**pilot/ui/index2.jsis excluded by!pilot/**pilot/ui/index3.jsis excluded by!pilot/**pilot/ui/index4.jsis excluded by!pilot/**pilot/ui/index5.jsis excluded by!pilot/**pilot/ui/viewer-bundle.jsis excluded by!pilot/**pilot/ui/viewer.cssis excluded by!pilot/**
📒 Files selected for processing (23)
.gitignoreREADME.mddocs/docusaurus/docs/features/console.mddocs/docusaurus/docs/features/context-optimization.mddocs/docusaurus/docs/features/hooks.mddocs/docusaurus/docs/features/mcp-servers.mddocs/docusaurus/docs/features/open-source-tools.mddocs/docusaurus/docs/features/statusline.mddocs/docusaurus/docs/intro.mddocs/docusaurus/docusaurus.config.tsdocs/site/public/manifest.jsondocs/site/src/components/ConsoleSection.tsxdocs/site/src/components/DeepDiveSection.tsxdocs/site/src/components/Footer.tsxdocs/site/src/components/HeroSection.tsxdocs/site/src/components/Logo.tsxdocs/site/src/components/SEO.tsxdocs/site/src/components/TestimonialsSection.tsxdocs/site/src/pages/Index.tsxinstaller/steps/config_migration.pyinstaller/steps/dependencies.pyinstaller/tests/unit/steps/test_config_migration.pyinstaller/tests/unit/steps/test_dependencies.py
| description: 18 hooks across 7 lifecycle events — fire automatically at every stage | ||
| --- | ||
|
|
||
| # Hooks Pipeline | ||
|
|
||
| 15 hooks across 7 lifecycle events — quality enforcement on autopilot. | ||
| 18 hooks across 7 lifecycle events — quality enforcement on autopilot. |
There was a problem hiding this comment.
Hook count mismatch between claim and content.
The document claims "18 hooks across 7 lifecycle events" but the tables list approximately 20 hooks (plus 2 command-scoped Stop hooks mentioned on line 74). This also conflicts with DeepDiveSection.tsx and README.md which both claim "21 hooks."
Please reconcile the hook count across all documentation.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/docusaurus/docs/features/hooks.md` around lines 4 - 9, The header and
summary text in docs/docusaurus/docs/features/hooks.md claiming "18 hooks across
7 lifecycle events" is inconsistent with the tables (≈20 hooks) and other files
(DeepDiveSection.tsx and README.md which say "21 hooks"); audit the actual hook
list (including the two command-scoped Stop hooks called out on line 74) to
determine the true total, then update the human-readable counts so all three
places match; specifically change the header/description string in hooks.md (the
"18 hooks across 7 lifecycle events" lines) and any summary/count constants or
strings in DeepDiveSection.tsx and README.md to the reconciled number, and if
the discrepancy comes from omitted command-scoped hooks, either include them in
the tables or explicitly state they are excluded from the total.
| 21 hooks across 7 lifecycle events — fire automatically at every | ||
| stage | ||
| </p> |
There was a problem hiding this comment.
Hook count inconsistency across documentation.
This component claims "21 hooks across 7 lifecycle events" but docs/docusaurus/docs/features/hooks.md states "18 hooks across 7 lifecycle events" (lines 4 and 9). Additionally, the hooksPipeline array only displays 6 lifecycle events (missing UserPromptSubmit) with 16 total hooks listed.
Please reconcile these numbers across all documentation surfaces.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/site/src/components/DeepDiveSection.tsx` around lines 225 - 227, The
copy in DeepDiveSection.tsx saying "21 hooks across 7 lifecycle events" is
inconsistent with docs/docusaurus/docs/features/hooks.md and the hooksPipeline
array; open DeepDiveSection.tsx (component DeepDiveSection) and align the copy
and displayed lifecycle items with the canonical hooks list by updating the hook
count and lifecycle event list to match hooksPipeline (or update hooksPipeline
to include the missing UserPromptSubmit and any missing hooks) so totals match
(ensure hooksPipeline includes UserPromptSubmit and the total hook count equals
the number in features/hooks.md), and update either features/hooks.md or
hooksPipeline so both the textual count and rendered lifecycle events
(hooksPipeline) and the DeepDiveSection text are consistent.
| result = subprocess.run( | ||
| ["claude", "plugins", "list", "--json"], | ||
| capture_output=True, | ||
| text=True, | ||
| timeout=30, | ||
| ) | ||
| if result.returncode == 0 and result.stdout.strip(): | ||
| plugins = json.loads(result.stdout) | ||
| already_installed = any(p.get("id") == "context-mode@context-mode" for p in plugins) | ||
| except (subprocess.TimeoutExpired, json.JSONDecodeError, OSError): |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
What is the documented JSON response format for claude plugins list --json (array vs object with "plugins" key), and can you provide an official example output?
💡 Result:
Anthropic’s official Claude Code docs do not document any claude plugins list --json command, nor do they document (or provide an example of) a JSON schema for “list installed plugins” output (so there’s no official guidance on “array vs { plugins: ... }” for that command). The CLI plugin-management commands that are documented are under the singular claude plugin ... namespace (install/uninstall/enable/disable/update, etc.), and list is not included there. [1]
The only documented “list + --json” in the official plugin docs I can find is:
claude plugin marketplace list --json(“List all configured marketplaces…--jsonOutput as JSON”) — but the docs do not provide an example JSON output for this either. [2]
Therefore:
- Documented JSON format for
claude plugins list --json: not available in official docs (command not documented). [1] - Official example output: none published (and even the documented
claude plugin marketplace list --jsonlacks an official example output). [2]
Sources
- [1] Claude Code “Plugins reference” (CLI commands reference shows
claude plugin ...commands; noclaude plugins list) (docs.claude.com) - [2] Claude Code “Plugin marketplaces” (documents
claude plugin marketplace list --json, but no example output) (docs.claude.com)
Citations:
- 1: https://docs.claude.com/en/docs/claude-code/plugins-reference
- 2: https://docs.claude.com/en/docs/claude-code/plugin-marketplaces
🏁 Script executed:
# Find and examine the full install_context_mode_plugin function
fd -e py "dependencies.py" installer/ | head -1 | xargs -I {} sh -c 'wc -l {} && echo "---" && head -n 1 {}'Repository: maxritter/pilot-shell
Length of output: 168
🏁 Script executed:
# Read the install_context_mode_plugin function and surrounding context (approximately lines 395-433)
sed -n '390,440p' installer/steps/dependencies.pyRepository: maxritter/pilot-shell
Length of output: 1635
🏁 Script executed:
# Search for any tests related to this function
fd -e py "test" | xargs rg -l "install_context_mode_plugin|claude.*plugins.*list" 2>/dev/null | head -5Repository: maxritter/pilot-shell
Length of output: 112
🏁 Script executed:
# Search for any documentation or comments about the expected JSON format
rg -i "plugins.*list.*json|json.*schema|response.*format" installer/ -A 2 -B 2Repository: maxritter/pilot-shell
Length of output: 375
🏁 Script executed:
# Examine test file for context-mode plugin installation tests
cat -n installer/tests/unit/steps/test_dependencies.py | grep -A 30 -B 5 "install_context_mode\|plugins.*list"Repository: maxritter/pilot-shell
Length of output: 10815
🏁 Script executed:
# Search for any mock or fixture data showing JSON structure
rg -i "context-mode|plugins.*list" installer/tests/ -A 3 -B 1Repository: maxritter/pilot-shell
Length of output: 2313
🏁 Script executed:
# Check if there's any documentation about Claude CLI response formats
fd -e md -e txt -e rst . | xargs rg -l "claude.*plugins\|context-mode" 2>/dev/null | head -5Repository: maxritter/pilot-shell
Length of output: 47
🏁 Script executed:
# Look for any other references to "claude plugins" command in codebase
rg "claude.*plugins" installer/ --no-heading -B 2 -A 2Repository: maxritter/pilot-shell
Length of output: 1824
Add type validation and catch AttributeError from JSON parsing.
The exception handler at line 418 only catches (subprocess.TimeoutExpired, json.JSONDecodeError, OSError), but if claude plugins list --json returns an unexpected structure (e.g., a dict instead of a list), the .get("id") call on line 414 will raise AttributeError, which is not caught. This would cause an unhandled exception and abort the installation step.
Although test fixtures confirm the expected format is a JSON array, the code should validate the structure defensively since the Claude CLI response format is not officially documented.
Proposed fix
- if result.returncode == 0 and result.stdout.strip():
- plugins = json.loads(result.stdout)
- already_installed = any(p.get("id") == "context-mode@context-mode" for p in plugins)
+ if result.returncode == 0 and result.stdout.strip():
+ payload = json.loads(result.stdout)
+ if isinstance(payload, list):
+ plugins = payload
+ elif isinstance(payload, dict):
+ plugins = payload.get("plugins", [])
+ else:
+ plugins = []
+ already_installed = any(
+ isinstance(p, dict) and p.get("id") == "context-mode@context-mode"
+ for p in plugins
+ )📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = subprocess.run( | |
| ["claude", "plugins", "list", "--json"], | |
| capture_output=True, | |
| text=True, | |
| timeout=30, | |
| ) | |
| if result.returncode == 0 and result.stdout.strip(): | |
| plugins = json.loads(result.stdout) | |
| already_installed = any(p.get("id") == "context-mode@context-mode" for p in plugins) | |
| except (subprocess.TimeoutExpired, json.JSONDecodeError, OSError): | |
| result = subprocess.run( | |
| ["claude", "plugins", "list", "--json"], | |
| capture_output=True, | |
| text=True, | |
| timeout=30, | |
| ) | |
| if result.returncode == 0 and result.stdout.strip(): | |
| payload = json.loads(result.stdout) | |
| if isinstance(payload, list): | |
| plugins = payload | |
| elif isinstance(payload, dict): | |
| plugins = payload.get("plugins", []) | |
| else: | |
| plugins = [] | |
| already_installed = any( | |
| isinstance(p, dict) and p.get("id") == "context-mode@context-mode" | |
| for p in plugins | |
| ) | |
| except (subprocess.TimeoutExpired, json.JSONDecodeError, OSError): |
🧰 Tools
🪛 Ruff (0.15.9)
[error] 407-407: Starting a process with a partial executable path
(S607)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@installer/steps/dependencies.py` around lines 406 - 415, The code calling
subprocess.run and parsing the Claude output should defensively validate the
parsed JSON before accessing item.get; update the block around
result/plugins/already_installed in steps/dependencies.py so that after plugins
= json.loads(result.stdout) you check isinstance(plugins, list) and that each
item is a dict (or skip non-dict items) before calling p.get("id"), and also
include AttributeError in the except tuple (i.e., except
(subprocess.TimeoutExpired, json.JSONDecodeError, OSError, AttributeError)) so
unexpected JSON shapes don't raise an uncaught exception; reference the
variables/functions result, plugins, and already_installed when making the
changes.
| if not _run_bash_with_retry( | ||
| "claude plugins marketplace add mksglu/context-mode", | ||
| timeout=60, | ||
| ): | ||
| return False |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Does claude plugins marketplace add return a non-zero exit code when the marketplace is already added? If yes, what is the exact stderr text?
💡 Result:
Yes. The Claude Code CLI treats “already added” as an error and returns a non-zero exit code; people commonly wrap it by capturing 2>&1 and grepping for the error text. The only verbatim stderr substring I could find in public sources is that it includes:
Marketplace '<name>' ... already installed
…but I could not find a source that shows the full, exact stderr line (including any prefix like Error: / ✘, punctuation, or trailing guidance text). The Medium article and the associated justfile both only indicate matching on "already installed" and extracting the marketplace name from "Marketplace '<name>'" rather than quoting the complete stderr output. [1] [2]
🏁 Script executed:
# First, find the file and understand the context
fd -t f "dependencies.py" installer/Repository: maxritter/pilot-shell
Length of output: 144
🏁 Script executed:
# Search for the functions used in the code
rg "_run_bash_with_retry|_get_last_error" installer/ -B 2 -A 5Repository: maxritter/pilot-shell
Length of output: 50377
🏁 Script executed:
# Check the context around lines 424-428
fd -t f "dependencies.py" installer/ | head -1 | xargs wc -lRepository: maxritter/pilot-shell
Length of output: 100
🏁 Script executed:
# Read the context around lines 424-428
sed -n '400,450p' installer/steps/dependencies.pyRepository: maxritter/pilot-shell
Length of output: 1633
🏁 Script executed:
# Search for similar "already" error handling patterns in the codebase
rg "already" installer/ -B 2 -A 2 -iRepository: maxritter/pilot-shell
Length of output: 24383
🏁 Script executed:
# Look at the full function that contains lines 424-428
sed -n '380,450p' installer/steps/dependencies.pyRepository: maxritter/pilot-shell
Length of output: 2256
🏁 Script executed:
# Search for tests related to marketplace add already existing scenario
rg "marketplace.*already|already.*marketplace" installer/tests/ -i -B 2 -A 2Repository: maxritter/pilot-shell
Length of output: 635
🏁 Script executed:
# Check if there's a test for the "marketplace add fails because already exists" case
rg "fresh_install.*fails" installer/tests/ -A 10 | head -40Repository: maxritter/pilot-shell
Length of output: 1050
🏁 Script executed:
# Look for how errors are checked elsewhere in the codebase for similar patterns
rg "already.*in.*stderr\|already.*in.*error" installer/ -B 2 -A 2Repository: maxritter/pilot-shell
Length of output: 47
🏁 Script executed:
# Check the actual implementation of _run_bash_with_retry to understand error capture
sed -n '60,150p' installer/steps/dependencies.pyRepository: maxritter/pilot-shell
Length of output: 3044
Marketplace registration path is not safely idempotent.
When the marketplace is already registered but marketplace add returns non-zero on reruns, the function fails hard instead of continuing. Although the function checks plugin installation status and updates rather than re-adding, an edge case exists: if a previous run succeeded in adding the marketplace but failed during plugin install, a retry will fail at the marketplace add step.
The proposed fix's error-matching condition is fragile—it checks for both "already" and "exist", but the actual error message is Marketplace '<name>' ... already installed (which contains only "already", not "exist"). While the boolean logic still evaluates correctly (not False allows continuation), a more direct check is safer:
- if not _run_bash_with_retry(
+ if not _run_bash_with_retry(
"claude plugins marketplace add mksglu/context-mode",
timeout=60,
- ):
- return False
+ ):
+ err = _get_last_error().lower()
+ if "already" not in err:
+ return FalseThis explicitly checks for the actual error substring and is more resilient to future API changes.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@installer/steps/dependencies.py` around lines 424 - 428, The marketplace-add
step using _run_bash_with_retry("claude plugins marketplace add
mksglu/context-mode") should treat the CLI error that indicates the marketplace
is already present as non-fatal; change the failure handling to inspect the
command output/error and continue when it contains the actual message used by
the tool (e.g., "already installed" or at minimum "already") instead of the
fragile "already" AND "exist" check so retries become idempotent; update the
logic around the marketplace add call to detect that substring and return
True/skip continuing installation rather than returning False.
| | --- | --- | | ||
| | [**Hooks Pipeline**](https://pilot-shell.com/docs/features/hooks) | 15 hooks across 7 events — quality checks on every file edit (ruff, ESLint, go vet), TDD enforcement, token optimization via RTK (60–90% savings), memory capture, and session lifecycle management | | ||
| | [**Context Optimization**](https://pilot-shell.com/docs/features/context-optimization) | Lean context strategies — conditional rule loading, progressive skill disclosure, lazy MCP tool loading, RTK output compression. Compaction resilience for 200K windows | | ||
| | [**Hooks Pipeline**](https://pilot-shell.com/docs/features/hooks) | 21 hooks across 7 events — quality checks on every file edit (ruff, ESLint, go vet), TDD enforcement, token optimization via RTK (60–90% savings), context-mode sandbox routing, session continuity, memory capture, and session lifecycle management | |
There was a problem hiding this comment.
Hook count in README does not match the implemented hooks.
Line 440 says “21 hooks,” but pilot/hooks/hooks.json (Line 1-Line 152) currently defines 15 hook commands across the 7 lifecycle events. Please update the count to avoid documentation drift.
Proposed fix
-| [**Hooks Pipeline**](https://pilot-shell.com/docs/features/hooks) | 21 hooks across 7 events — quality checks on every file edit (ruff, ESLint, go vet), TDD enforcement, token optimization via RTK (60–90% savings), context-mode sandbox routing, session continuity, memory capture, and session lifecycle management |
+| [**Hooks Pipeline**](https://pilot-shell.com/docs/features/hooks) | 15 hooks across 7 events — quality checks on every file edit (ruff, ESLint, go vet), TDD enforcement, token optimization via RTK (60–90% savings), context-mode sandbox routing, session continuity, memory capture, and session lifecycle management |📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| | [**Hooks Pipeline**](https://pilot-shell.com/docs/features/hooks) | 21 hooks across 7 events — quality checks on every file edit (ruff, ESLint, go vet), TDD enforcement, token optimization via RTK (60–90% savings), context-mode sandbox routing, session continuity, memory capture, and session lifecycle management | | |
| | [**Hooks Pipeline**](https://pilot-shell.com/docs/features/hooks) | 15 hooks across 7 events — quality checks on every file edit (ruff, ESLint, go vet), TDD enforcement, token optimization via RTK (60–90% savings), context-mode sandbox routing, session continuity, memory capture, and session lifecycle management | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` at line 440, The README's "Hooks Pipeline" badge incorrectly
states "21 hooks" while pilot/hooks/hooks.json currently defines 15 hook
commands across the 7 lifecycle events; update the README.md text for "Hooks
Pipeline" to reflect the actual hook count (15) or make it dynamic, and ensure
the badge/string referencing the hook count in the README (the line containing
"21 hooks across 7 events") is changed to match the count found in
pilot/hooks/hooks.json so the documentation no longer drifts from the
implementation.
|
Claude finished @maxritter's task in 1m 5s —— View job Incremental Code Review — Push Delta
Changes in This PushBoth No new issues introduced. The version pin is a sound defensive measure for the documented Observation (no action required): The workflow YAML contains no inline comment explaining why the version is pinned. Future maintainers reading the file won't know it's a regression workaround rather than an intentional freeze. Adding a brief comment (e.g., Previously ResolvedAll three issues from the prior Claude review remain resolved:
Still Open (from prior reviews, no new detail)
|
# [8.0.0](v7.11.4...v8.0.0) (2026-04-08) ### Bug Fixes * pin Bun to 1.3.11 (1.2.15 lacks compression APIs, latest is unstable) ([2372ea7](2372ea7)) ### Features * add Pilot Bot — persistent automation agent with scheduled tasks, background jobs, and optional Telegram ([cab87f6](cab87f6)) * complete Console overhaul — v8.0.0 ([#126](#126)) ([bfa261f](bfa261f)) ### BREAKING CHANGES * Console UI completely restructured — sidebar flattened, project selector removed from sidebar and replaced with per-view inline filters, dashboard cards redesigned, PlanStatus and GitStatus widgets removed * fix: remove duplicate Help slide, update hooks count to 21 * fix: pin Bun to 1.2.15 in CI (latest has execSync regression on Linux)
|
🎉 This PR is included in version 8.0.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
# [8.0.0](v7.11.4...v8.0.0) (2026-04-08) ### Bug Fixes * pin Bun to 1.3.11 (1.2.15 lacks compression APIs, latest is unstable) ([2372ea7](2372ea7)) ### Features * add Pilot Bot — persistent automation agent with scheduled tasks, background jobs, and optional Telegram ([cab87f6](cab87f6)) * complete Console overhaul — v8.0.0 ([#126](#126)) ([bfa261f](bfa261f)) ### BREAKING CHANGES * Console UI completely restructured — sidebar flattened, project selector removed from sidebar and replaced with per-view inline filters, dashboard cards redesigned, PlanStatus and GitStatus widgets removed * fix: remove duplicate Help slide, update hooks count to 21 * fix: pin Bun to 1.2.15 in CI (latest has execSync regression on Linux)
Complete Console Overhaul
Dashboard
Navigation
Sessions
/resume <session-id>Memories
Notifications
APIs
/api/plans/active/all— cross-project spec aggregation/api/extensions?all=true— cross-project extension aggregation/api/notificationsDELETE — clear all notificationsBranding
context-mode Integration
Other
BREAKING CHANGE: Console UI completely restructured — sidebar flattened, project selector removed and replaced with per-view inline filters, dashboard cards redesigned, PlanStatus and GitStatus widgets removed.
Summary by CodeRabbit
New Features
Documentation
Chores
Tests