Skip to content

fix(skills): allow symlinked local skills in cloud tasks - #3810

Merged
trunk-io[bot] merged 6 commits into
mainfrom
posthog-code/fix-symlinked-local-skill-bundles
Jul 27, 2026
Merged

fix(skills): allow symlinked local skills in cloud tasks#3810
trunk-io[bot] merged 6 commits into
mainfrom
posthog-code/fix-symlinked-local-skill-bundles

Conversation

@richardsolomou

@richardsolomou richardsolomou commented Jul 25, 2026

Copy link
Copy Markdown
Member

Problem

My local skills are managed through dotfiles and symlinked into the user skills directory. Cloud task setup rejected them before uploading the bundle. Path aliases also needed to retain their original repository ownership so they could not bundle a workspace root or files from another open repository.

Refs #1956

Changes

I allow explicitly selected symlinked skills only under the canonical user-owned Claude and Codex roots. Repository skills are validated against their lexical owner before user-root aliases into open workspaces are handled separately. Marketplace roots keep the symlink guard, and dependency expansion cannot follow a symlink without explicit selection.

How did you test this?

  • pnpm --filter @posthog/workspace-server exec vitest run src/services/skills/skills.test.ts (53 tests)
  • pnpm exec biome check packages/workspace-server/src/services/skills/skills.ts packages/workspace-server/src/services/skills/skills.test.ts
  • pnpm --filter @posthog/workspace-server typecheck

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Created with PostHog Code

Resolve trusted local skill roots before bundling while retaining repository containment checks.

Generated-By: PostHog Code
Task-Id: 5cf8bddc-dae4-4dc9-84fb-195b06f48068
@trunk-io

trunk-io Bot commented Jul 25, 2026

Copy link
Copy Markdown

😎 Merged directly without going through the merge queue, as the queue was empty and the PR was up to date with the target branch - details.

@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 3244e06.

@richardsolomou richardsolomou changed the title Allow symlinked local skills in cloud tasks fix(skills): allow symlinked local skills in cloud tasks Jul 25, 2026
Keep repository and marketplace skill roots protected while allowing user-managed dotfile symlinks.

Generated-By: PostHog Code
Task-Id: 5cf8bddc-dae4-4dc9-84fb-195b06f48068
@richardsolomou
richardsolomou marked this pull request as ready for review July 25, 2026 09:02
@richardsolomou
richardsolomou requested a review from a team July 25, 2026 09:02
Comment thread packages/workspace-server/src/services/skills/skills.ts Outdated
@veria-ai

veria-ai Bot commented Jul 25, 2026

Copy link
Copy Markdown

PR overview

All previously flagged issues have been addressed. No open security concerns remain on this pull request.

Security review

No open security issues remain on this pull request.

Fixed/addressed: 2 · PR risk: 0/10

@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "Restrict symlinked skills to user roots" | Re-trigger Greptile

Require explicit selection before dependency expansion follows a symlinked local skill.

Generated-By: PostHog Code
Task-Id: 5cf8bddc-dae4-4dc9-84fb-195b06f48068

@tatoalo tatoalo 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.

can we resolve realpath(path.dirname(skillDir)) before comparing against the user claude/codex roots, and select the owning folder in assertRepoSkillStaysInRepo the same way, so a skill that realpaths into an open folder always gets the repo check regardless of which alias addressed it? a ~/.claude/skills/hehe -> ~/work/some-repo silently uploads a whole working tree which I believe we might want to avoid

additionally, with ~/.claude/skills/{a,b,c} all symlinked into a dotfiles repo and a → b → c we have that each level costs another round trip, and the throw propagates out of loadCloudSkillBundlesuploadRunAttachments / uploadTaskStagedAttachments with no recovery, so the entire message send fails w/no attachments, no skills.
We have bundleLocalSkill that already permits these roots, the guard could use the same predicate so wecan refuse to follow an implicit symlinked dep when its parent is not a user claude/codex root, i.e. when bundling would fail anyway

Generated-By: PostHog Code
Task-Id: 5cf8bddc-dae4-4dc9-84fb-195b06f48068

Copy link
Copy Markdown
Member Author

updated this to compare the canonical user roots and apply the open-workspace containment check from the real skill path, so a ~/.claude/skills/hehe alias to the workspace root is rejected.

i kept explicit selection for implicit symlink dependencies. the resolver runs the dependency walk in one server call and bundles expanded refs concurrently, and attachment preparation stays fail-fast so we dont silently send a message without the selected context.

Comment thread packages/workspace-server/src/services/skills/skills.ts Outdated
@posthog

posthog Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

👋 Visual changes detected for this PR.

Review and approve in PostHog Visual Review

If these changes are unexpected, they may be caused by a flaky test or a broken snapshot on master. Don't approve — rerun the job or wait for a fix.

Generated-By: PostHog Code
Task-Id: 5cf8bddc-dae4-4dc9-84fb-195b06f48068
@richardsolomou
richardsolomou requested a review from tatoalo July 27, 2026 10:11
@trunk-io
trunk-io Bot merged commit 4ba879c into main Jul 27, 2026
32 checks passed
@trunk-io
trunk-io Bot deleted the posthog-code/fix-symlinked-local-skill-bundles branch July 27, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants