fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(server): discover Claude commands and skills per workspace - #7118

Closed
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery
Closed

fix(server): discover Claude commands and skills per workspace#7118
RaitP1 wants to merge 3 commits into
pingdotgg:mainfrom
RaitP1:feat/project-scoped-claude-discovery

Conversation

@RaitP1

@RaitP1RaitP1 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

What Changed

  • The composer now asks the server which commands and skills exist in the workspace it is about to send a turn to, instead of reading the single global list that ships with the provider snapshot.
  • The client sends ids, never a path. The server picks the directory itself: the thread's worktree when it has one, otherwise the project folder.
  • For Claude, the server runs the same capability probe and skill scan in that directory and keeps the answer for five minutes per workspace. A provider with nothing project-specific to report still answers from the global snapshot, so nothing else changes.
composer (web / mobile)
└─ useProviderWorkspaceCapabilities() apps/{web,mobile}/src/state/queries.ts
└─ serverEnvironment.providerWorkspaceCapabilities packages/client-runtime/src/state/server.ts
└─ WS RPC "server.listProviderWorkspaceCapabilities" packages/contracts/src/rpc.ts
└─ scope check apps/server/src/auth/RpcAuthorization.ts
└─ handler: resolve the cwd apps/server/src/ws.ts
└─ ProviderRegistry.listWorkspaceCapabilities()
└─ instance.listWorkspaceCapabilities(cwd) (optional)
└─ ClaudeDriver: probe + skill scan

Why

Commands and skills that live inside a project never appear in the / and $ menus, and every project shows the same list. Typing the command still works, because the thread itself runs in the project folder. Only the menus are wrong.

Discovery asks the directory the server process started in, not the project the user has open. In the desktop app those are never the same. The answer is then cached per provider, with nothing that records which project it came from, so opening another project cannot refresh it.

Left out on purpose: other providers keep their current behavior, and a probe that fails drops its cached entry instead of leaving a menu empty for the next five minutes.

Related: #4658. #4546 proposes the skills half of this, for the $ picker only.

Checklist

  • This PR is small and focused — one concern, the directory discovery reads
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — no visual change; the menus look the same and list the open project's entries. I can add a matched pair.
  • I included a video for animation/interaction changes — not applicable

Written by Claude Opus 5 in Claude Code, running inside T3 Code.


Note

Medium Risk
New read RPC and cwd resolution from projections affect composer discovery; Claude runs per-workspace probes with caching, but behavior falls back to snapshots for non-Claude providers and failed probes.

Overview
Workspace-scoped provider menus — Web and mobile composers no longer rely only on the global provider snapshot for / slash commands and $ skills. While those menus are open, they call useProviderWorkspaceCapabilities, which hits server.listProviderWorkspaceCapabilities with project/thread ids (no client paths).

Server resolution — The WS handler resolves cwd from the thread worktree when it belongs to the project, otherwise the project workspace root, then ProviderRegistry.listWorkspaceCapabilities. Drivers may implement listWorkspaceCapabilities(cwd); others keep snapshot lists.

ClaudeClaudeDriver probes capabilities and discovers skills in that cwd, caches per workspace (~5 minutes), and falls back to snapshot slash commands if the probe is empty.

Docs note that menus reflect the thread’s workspace folder.

Reviewed by Cursor Bugbot for commit 7c05f4e. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Discover Claude slash commands and skills per workspace in chat composers

  • Adds a new server.listProviderWorkspaceCapabilities RPC that resolves the workspace directory from the active thread's worktree path or project root, then queries the Claude provider for workspace-scoped slash commands and skills.
  • ClaudeDriver gains a listWorkspaceCapabilities(cwd) method backed by a capacity-8 cache, concurrently probing Claude capabilities and discovering skills, with fallback to the cached snapshot.
  • Web (ChatComposer) and mobile (ThreadComposer) composers call the new useProviderWorkspaceCapabilities hook when a slash-command or skill trigger is active, falling back to provider snapshot data if the query is unavailable.
  • Contract schemas, RPC group, client-runtime atoms, and RPC authorization scope are all updated to support the new endpoint.

Macroscope summarized 7c05f4e.

- Add server.listProviderWorkspaceCapabilities RPC that resolves slash commands and skills for a project's or thread's actual cwd (worktree when present), instead of the process-wide provider snapshot
- ClaudeDriver gains listWorkspaceCapabilities, caching per-cwd probes and skill discovery
- Web and mobile composers query workspace capabilities for the "/" and "$" menus, falling back to the provider snapshot when unavailable
- Document the workspace-scoped behavior in docs/user/providers-claude.md
@coderabbitai

coderabbitaiBot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b61acdbc-c0c9-4903-abb6-aa24cefd58b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actionsgithub-actionsBot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 15, 2026
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/server/src/ws.ts Outdated
Comment threadapps/web/src/state/queries.ts
@macroscopeapp

macroscopeappBot commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces new per-workspace discovery of Claude commands and skills, including a new RPC endpoint, client hooks, and caching logic. As a new feature that changes user-facing behavior (which commands/skills appear based on workspace), it warrants human review.

You can customize Macroscope's approvability policy. Learn more.

…empty list
A projection read error was swallowed and answered as an empty result, which
the client cached like real data, so one transient failure could blank the `/`
and `$` menus. The read now fails with OrchestrationGetSnapshotError, and the
composer keeps the snapshot list until it retries.
When no workspace resolves, the registry answers from the provider snapshot
rather than with an empty list, so an empty answer only ever means empty.
Drop the five-minute client stale time. The server already caches per
directory, so the default thirty seconds picks up a new worktree quickly and
costs a cache hit.

@cursorcursorBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 990e75a. Configure here.

Comment threadapps/server/src/ws.ts Outdated
…esolve
A thread id that is absent from the projection, or that belongs to another
project, forced the workspace to null and answered from the provider snapshot,
so the menus showed server-cwd entries for a project that had already resolved.
A new thread that has not projected yet hit this.
Use the project folder in that case, which is what omitting the thread id
already does. The snapshot now answers only when the project itself does not
resolve.
@RaitP1RaitP1 closed this by deleting the head repository Aug 20, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@RaitP1