fix(server): thread cwd through Claude capability probe (#2048)#2124
fix(server): thread cwd through Claude capability probe (#2048)#2124mvanhorn wants to merge 2 commits into
Conversation
probeClaudeCapabilities enables settingSources: ['user', 'project',
'local'] but never passed a cwd to the Claude Agent SDK. The SDK then
resolved the 'project' and 'local' sources against the T3 server
process cwd, not the user's active project, so project-level
.claude/skills/ was invisible in composer autocomplete even though
those skills still ran fine when typed manually.
Changes:
- probeClaudeCapabilities(binaryPath, cwd?) now forwards an optional
cwd into claudeQuery options. When undefined the SDK keeps its
previous behavior.
- subscriptionProbeCache key becomes '${binaryPath}|${cwd ?? ""}'
with capacity bumped to 8 so a handful of recent projects stay
cached without forcing re-probes on every project switch.
- Cache lookup parses the composite key back into (binaryPath, cwd)
before calling the probe.
The cache and the probe now support per-project cwds. The remaining
wire-up is at the caller of checkClaudeProviderStatus - the
subscriptionType and slashCommands lookup arrow functions still
receive only binaryPath. Threading the active session.cwd from
ProviderService (apps/server/src/provider/Layers/ProviderService.ts
already has session.cwd on hand) into those two lookups completes
the fix; happy to follow up in a separate PR if you'd like this one
kept tight to the probe layer.
Reporter @r3xsean has a 40-skill project-level .claude/skills/
setup and is a good candidate for verification once the caller is
wired through.
apps/server typecheck passes.
Fixes pingdotgg#2048
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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 |
ApprovabilityVerdict: Approved This is a straightforward bug fix that threads the workspace directory through the Claude capability probe so project-level slash commands resolve correctly. The changes are well-scoped, include clear documentation and unit tests, and don't touch any sensitive code paths. You can customize Macroscope's approvability policy. Learn more. |
Follow-up to the probe change earlier in this PR. probeKey accepted
an optional cwd but every call site passed undefined, so the cache
key collapsed to `${binaryPath}|` and the SDK never received the
active project directory — defeating the `.claude/skills/`
resolution the PR was supposed to enable.
- ClaudeProviderLive now resolves `cwd` once from `ServerConfig` at
layer construction and closes over it as `workspaceRoot`.
- Both Cache.get call sites pass `workspaceRoot` through the cache
key. The cache lookup already parses it back out and forwards it
into `probeClaudeCapabilities`.
- `probeKey` is renamed and exported as `claudeProbeCacheKey` so
the per-cwd contract is testable.
- Adds three unit tests covering distinct cwds, undefined/empty
equivalence, and distinct binaries.
ServerConfig.cwd is the same value serverRuntimeStartup already
treats as `workspaceRoot` (serverRuntimeStartup.ts:199), so no
new service surface is needed.
Refs pingdotgg#2048
|
Good catch. Fixed in 614529d. ClaudeProviderLive now resolves cwd from ServerConfig at layer construction and threads it into both Cache.get calls, so the cache key actually reflects the active workspace instead of always being Added three unit tests for the per-cwd key contract (distinct cwds, undefined/empty equivalence, distinct binaries). |
Summary
probeClaudeCapabilitiesenablessettingSources: ["user", "project", "local"]but never passed acwdto the Claude Agent SDK, so the SDK resolved the"project"and"local"sources against the T3 server process cwd rather than the user's active project. Project-level.claude/skills/was invisible in composer autocomplete even though those skills still executed when typed manually (#2048).Why this matters
From #2048 (@r3xsean, area:
apps/server):Tested on 0.0.17-nightly.20260415.45 with 40+ project-level skills.
Changes
apps/server/src/provider/Layers/ClaudeProvider.ts:probeClaudeCapabilities(binaryPath, cwd?)now takes an optionalcwdand spreads{ cwd }into theclaudeQueryoptions when set. Whencwdis undefined the SDK keeps its previous behavior.subscriptionProbeCachekey becomes${binaryPath}|${cwd ?? ""}. Capacity bumped from 1 to 8 so switching between projects doesn't force a re-probe each time (the probe talks to the SDK's init path, which is not free).lookupparses the composite key back into(binaryPath, cwd)before calling the probe.cwdcontract so future edits don't regress.What this PR does NOT do
The two arrow functions at lines 781-789 that feed
subscriptionTypeandslashCommandsintocheckClaudeProviderStatusstill receivebinaryPathonly. The final wire-up threadssession.cwdfromProviderService(which already has it on hand atapps/server/src/provider/Layers/ProviderService.ts:110) into those lookups.I'm happy to follow up with that caller change as a separate PR once this one lands and you confirm the shape of the probe is what you want. Keeping this PR tight to the probe layer so the diff is easy to review. If you'd prefer the wire-up in one PR, let me know and I'll expand.
Testing
cd apps/server && bun run typecheckpasses with exit 0.No behavior change when the caller still passes
undefinedfor cwd - the probe keeps its current fallback path.Request
@r3xsean on the thread has a 40-skill
.claude/skills/setup and reproduced the bug cleanly. Once the caller is wired, they're a good candidate for verification.Fixes #2048 (probe layer only - caller wire-up to follow).
This contribution was developed with AI assistance (Claude Code).
Note
Medium Risk
Behavior changes in Claude provider probing/caching (new
cwdhandling and multi-entry cache) could affect provider status/slash-command discovery if the workspace root or cache key parsing is incorrect.Overview
Fixes Claude capability probing to be project-aware by passing an optional
cwdintoprobeClaudeCapabilities, so the SDK resolvessettingSources: ['project','local']against the active workspace and includes.claude/skills/in initialization results.Updates the probe cache to key by
binaryPath|cwd(via newclaudeProbeCacheKey), increases cache capacity from 1→8, and adjusts cache lookup to parse the composite key; adds focused tests for the new cache-key behavior.Reviewed by Cursor Bugbot for commit 614529d. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Thread
cwdthrough Claude capability probe and key cache by workspace directorycwdparameter toprobeClaudeCapabilitiesin ClaudeProvider.ts, forwarding it toclaudeQueryso the Claude Agent SDK resolves project and local settings relative to the workspace root.claudeProbeCacheKey(binaryPath, cwd)to build composite cache keys, and increases the probe cache capacity from 1 to 8 entries so results are cached per binary+workspace combination.checkProviderto passworkspaceRootfromServerConfigwhen looking up or populating the cache.claudeProbeCacheKeycovering undefined and definedcwdcases.Macroscope summarized 614529d.