fix(server): thread cwd through Claude capability probe (#2048)#2124
fix(server): thread cwd through Claude capability probe (#2048)#2124mvanhorn wants to merge 1 commit intopingdotgg:mainfrom
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 |
There was a problem hiding this comment.
🟢 Low Layers/ClaudeProvider.ts:791
The probeKey function includes cwd in the cache key format ${binaryPath}|${cwd ?? ""}, but the resolve callbacks in checkClaudeProviderStatus only receive binaryPath and never pass cwd. This means cwd is always undefined, the cache key is always ${binaryPath}|, and the SDK never receives the project directory for resolving .claude/skills/ commands despite the comment explaining this is the purpose (#2048).
const checkProvider = checkClaudeProviderStatus(
(binaryPath) =>
- Cache.get(subscriptionProbeCache, probeKey(binaryPath)).pipe(
+ Cache.get(subscriptionProbeCache, probeKey(binaryPath, /* TODO: get cwd from caller */)).pipe(
Effect.map((probe) => probe?.subscriptionType),
),
(binaryPath) =>
- Cache.get(subscriptionProbeCache, probeKey(binaryPath)).pipe(
+ Cache.get(subscriptionProbeCache, probeKey(binaryPath, /* TODO: get cwd from caller */)).pipe(
Effect.map((probe) => probe?.slashCommands),
),
).pipe(🤖 Copy this AI Prompt to have your agent fix this:
In file apps/server/src/provider/Layers/ClaudeProvider.ts around lines 791-803:
The `probeKey` function includes `cwd` in the cache key format `${binaryPath}|${cwd ?? ""}`, but the resolve callbacks in `checkClaudeProviderStatus` only receive `binaryPath` and never pass `cwd`. This means `cwd` is always `undefined`, the cache key is always `${binaryPath}|`, and the SDK never receives the project directory for resolving `.claude/skills/` commands despite the comment explaining this is the purpose (#2048).
Evidence trail:
- apps/server/src/provider/Layers/ClaudeProvider.ts line 789: `probeKey` definition includes `cwd` parameter
- apps/server/src/provider/Layers/ClaudeProvider.ts lines 521-525: `checkClaudeProviderStatus` callback signatures only accept `binaryPath`
- apps/server/src/provider/Layers/ClaudeProvider.ts lines 792-796: callbacks call `probeKey(binaryPath)` without `cwd`
- apps/server/src/provider/Layers/ClaudeProvider.ts lines 465-469: comment explains `cwd` is needed for `.claude/skills/` resolution (#2048)
ApprovabilityVerdict: Needs human review An unresolved review comment identifies that the fix may be incomplete - the You can customize Macroscope's approvability policy. Learn more. |
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
Low Risk
Low risk: localized changes to Claude provider probing and caching; behavior is unchanged unless a
cwdis supplied, with only a small memory/perf tradeoff from a larger cache.Overview
Updates the Claude provider’s SDK capability probe to accept an optional
cwdand pass it intoclaudeQuery, so project/local setting sources (and project-level slash commands like.claude/skills/) can be discovered correctly.Adjusts the subscription/slash-command probe cache to key by
binaryPath|cwdand increases capacity from 1 to 8, preventing cross-project cache collisions and reducing re-probes when switching between projects.Reviewed by Cursor Bugbot for commit e7bacee. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Thread
cwdthroughprobeClaudeCapabilitiesfor project-aware capability probingcwdparameter toprobeClaudeCapabilitiesin ClaudeProvider.ts, passing it to the Claude Agent SDK so project/local settings are resolved correctly during the probe.binaryPathtobinaryPath|cwdand increases cache capacity from 1 to 8 to support multiple working directories.(binaryPath, cwd)pair, so the same binary may be probed multiple times for different working directories.📊 Macroscope summarized e7bacee. 1 file reviewed, 1 issue evaluated, 0 issues filtered, 1 comment posted
🗂️ Filtered Issues