Skip to content

feat(skills): Codex unification — bring your skills, use them anywhere#2611

Merged
k11kirky merged 2 commits into
mainfrom
posthog-code/skills-07-codex
Jun 12, 2026
Merged

feat(skills): Codex unification — bring your skills, use them anywhere#2611
k11kirky merged 2 commits into
mainfrom
posthog-code/skills-07-codex

Conversation

@k11kirky

@k11kirky k11kirky commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Problem

Users who work in both PostHog Code and Codex have no way to access their Codex-authored skills from the Skills tab, and no way to bring those skills into their editable user skills collection. Similarly, skills created or installed in PostHog Code are invisible to Codex sessions.

Changes

New codex skill source

  • Added "codex" as a valid SkillSource type and wired it through the Zod schema, precedence ordering, source labels, and UI display config (using a Robot icon).
  • Codex skills appear in their own "Codex" section in the Skills view, between repo and bundled skills.
  • Codex skills are read-only in the UI.

Codex skill deduplication

  • Skills in ~/.agents/skills that were synced there by the official bundled pipeline, or mirrored out from the user's own skills, are hidden from the Codex section to avoid confusing duplicates. Only genuinely Codex-authored skills surface.

Import Codex skill

  • Added an "Import" button on the detail panel for Codex skills. Clicking it copies the skill into ~/.claude/skills, making it an ordinary editable user skill.
  • If a skill with the same name already exists locally, an overwrite confirmation dialog is shown before replacing it.
  • After import, the mirror takes ownership of the Codex copy so future user-skill mirrors carry edits back without duplicating or clobbering.
  • Added importCodex tRPC mutation and useImportCodexSkill hook.
  • Path validation ensures only skills inside the Codex skills directory can be imported.

User-to-Codex mirroring (codex-mirror.ts)

  • Introduced a one-way mirror that copies every user skill into ~/.agents/skills so skills created, edited, or installed in PostHog Code are available in Codex sessions.
  • A .posthog-mirror.json state file tracks which skills were placed there by the mirror, ensuring the mirror never overwrites Codex-native skills it didn't create.
  • Mirrors whose source skill has been deleted are cleaned up automatically.
  • Mirroring runs on startup and after each periodic skills update. Failures are logged as warnings and never interrupt the main skills pipeline.

How did you test this?

  • Added unit tests for mirrorUserSkillsToCodex covering: initial copy, collision avoidance, update propagation, deletion cleanup, and import ownership handoff.
  • Added unit tests for readCodexMirrorState covering missing and corrupt state files.
  • Added integration tests in skills.test.ts covering: listing codex skills with deduplication, importing a codex skill with mirror ownership, and rejection of paths outside the codex skills directory.

Automatic notifications

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

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

React Doctor could not complete this scan.

No React dependency found in /tmp/react-doctor-baseline-O8f8l7/package.json. Add "react" to dependencies (or peerDependencies) and re-run.

Reviewed by React Doctor for commit 7df61f0.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
Fix the following 3 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 3
packages/workspace-server/src/services/skills/skills.test.ts:189-192
**Test silently passes without executing assertions**

When `~/.claude/skills/codex-only` already exists on the developer's machine or CI runner, the test returns at line 192 without running any `expect` calls — the test is marked passing while nothing was verified. The root cause is that `importCodexSkill` hardcodes `path.join(os.homedir(), ".claude", "skills", name)` as the target, unlike the source side where `getCodexSkillsDir()` was extracted specifically to be mockable. Adding a parallel `getUserSkillsDir()` helper (mocked in tests to the temp directory the same way `getCodexSkillsDir` already is) would let this test run fully against the isolated temp dir, remove the early-return guard, and avoid writing to the real user filesystem during every test run.

### Issue 2 of 3
packages/ui/src/features/skills/SkillDetailPanel.tsx:177
**Fragile string-match gate for overwrite confirmation**

`message.includes("already exists")` ties the UI's overwrite flow to the exact wording of a backend error message. If the string in `skills.ts` is ever rephrased (e.g., "A skill with this name already exists"), this check silently falls through to the generic `toast.error` path — users never see the overwrite dialog and can't complete the import. Since tRPC is already in play here, throwing a `TRPCError` with a stable code (`CONFLICT`) and checking `error.data?.httpStatus === 409` (or a custom `code` field in the error data) on the client would make this contract explicit and refactoring-safe.

### Issue 3 of 3
packages/workspace-server/src/services/skills/skills.ts:464-490
**`mirroredNames` set is checked against both `skill.name` (display name) and `dirName` (directory name)**

The mirror state file stores directory basenames (confirmed by `addMirroredName` using `path.basename(resolved)` and `mirrorUserSkillsToCodex` tracking `name` from `findSkillDirs`). The extra `!mirroredNames.has(skill.name)` guard checks the display name (from SKILL.md frontmatter) against a set of directory names. If a Codex-only skill's frontmatter title happens to equal any mirrored directory name, it will be incorrectly hidden from the UI. Since the canonical key is the directory name, the `skill.name` check appears to be redundant and creates a false-positive suppression path.

Reviews (1): Last reviewed commit: "feat(skills): Codex unification — bring ..." | Re-trigger Greptile

Comment thread packages/workspace-server/src/services/skills/skills.test.ts
Comment thread packages/ui/src/features/skills/SkillDetailPanel.tsx
Comment thread packages/workspace-server/src/services/skills/skills.ts
@k11kirky k11kirky marked this pull request as ready for review June 11, 2026 13:56
Comment thread packages/workspace-server/src/services/skills/skills.ts
Comment thread packages/workspace-server/src/services/skills/skills.ts
Comment thread packages/workspace-server/src/services/posthog-plugin/codex-mirror.ts Outdated
k11kirky added a commit that referenced this pull request Jun 12, 2026
…rt tests hermetic

Review feedback on #2610/#2611: the "already exists" overwrite detection
now keys off SKILL_EXISTS_MARKER in @posthog/shared, used verbatim by the
server messages and the UI matcher, so a reword cannot silently break the
overwrite dialog; getUserSkillsDir is mocked in skills.test.ts so the
codex-import and team-install tests run fully against temp dirs instead
of early-returning when the real home directory has a colliding skill.

Generated-By: PostHog Code
Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
@k11kirky k11kirky force-pushed the posthog-code/skills-06b-team-publish branch from a72917a to 975d78b Compare June 12, 2026 07:50
@k11kirky k11kirky force-pushed the posthog-code/skills-07-codex branch from 17de255 to 24695c3 Compare June 12, 2026 07:50
k11kirky added a commit that referenced this pull request Jun 12, 2026
…rt tests hermetic

Review feedback on #2610/#2611: the "already exists" overwrite detection
now keys off SKILL_EXISTS_MARKER in @posthog/shared, used verbatim by the
server messages and the UI matcher, so a reword cannot silently break the
overwrite dialog; getUserSkillsDir is mocked in skills.test.ts so the
codex-import and team-install tests run fully against temp dirs instead
of early-returning when the real home directory has a colliding skill.

Generated-By: PostHog Code
Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
@k11kirky k11kirky force-pushed the posthog-code/skills-07-codex branch from 24695c3 to bf96408 Compare June 12, 2026 08:19
@k11kirky k11kirky force-pushed the posthog-code/skills-06b-team-publish branch from 975d78b to eb09670 Compare June 12, 2026 08:19

k11kirky commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

k11kirky added a commit that referenced this pull request Jun 12, 2026
…rt tests hermetic

Review feedback on #2610/#2611: the "already exists" overwrite detection
now keys off SKILL_EXISTS_MARKER in @posthog/shared, used verbatim by the
server messages and the UI matcher, so a reword cannot silently break the
overwrite dialog; getUserSkillsDir is mocked in skills.test.ts so the
codex-import and team-install tests run fully against temp dirs instead
of early-returning when the real home directory has a colliding skill.

Generated-By: PostHog Code
Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
@k11kirky k11kirky force-pushed the posthog-code/skills-06b-team-publish branch from eb09670 to a188d67 Compare June 12, 2026 11:43
@k11kirky k11kirky force-pushed the posthog-code/skills-07-codex branch from bf96408 to 3f66898 Compare June 12, 2026 11:43
@k11kirky k11kirky changed the base branch from posthog-code/skills-06b-team-publish to graphite-base/2611 June 12, 2026 12:48
@k11kirky k11kirky changed the base branch from graphite-base/2611 to main June 12, 2026 13:01
Read (Codex -> tab):
- ~/.agents/skills becomes a discovery source with the new "codex"
  SkillSource (read-only; import to edit). Copies we are responsible
  for are hidden: bundled skills synced by the official pipeline and
  user skills mirrored out — what remains is genuinely the user's
  Codex-only skills.
- "Codex" group in the tab with an Import action that copies the
  directory into ~/.claude/skills (confirm-overwrite on collision).
  Import records the name in the mirror state, so future syncs carry
  the imported copy back without clobbering or duplicating.

Write (your skills -> Codex):
- mirrorUserSkillsToCodex one-way mirrors ~/.claude/skills into
  ~/.agents/skills next to the existing bundled sync (initialize +
  after each successful update; the update-skills saga itself is
  untouched). Mirrored names are tracked in
  ~/.agents/skills/.posthog-mirror.json.
- Safety rule: a codex skill we didn't put there is never overwritten;
  the collision skips and surfaces in the tab as a shadowing warning
  (user precedence beats codex in analyzeSkills). Mirrors whose source
  skill is gone are removed.

Unit tests cover the dedupe rules, mirror ownership/conflict/stale
removal, import guards, and corrupt state files.

Generated-By: PostHog Code
Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
…nks in the mirror

Review feedback on #2611: marketplace/team installs and skill CRUD now
trigger the Codex mirror immediately (fire-and-forget) instead of waiting
for the next periodic sync — this also makes deletes disappear from Codex
right away; mirror copies dereference symlinks so the mirrored skill is
self-contained, and one unreadable skill no longer breaks the rest of the
mirror.

Generated-By: PostHog Code
Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
@k11kirky k11kirky force-pushed the posthog-code/skills-07-codex branch from 3f66898 to 7df61f0 Compare June 12, 2026 13:02
@k11kirky k11kirky merged commit 759fffc into main Jun 12, 2026
24 checks passed
@k11kirky k11kirky deleted the posthog-code/skills-07-codex branch June 12, 2026 13:10
k11kirky added a commit that referenced this pull request Jun 12, 2026
…rt tests hermetic

Review feedback on #2610/#2611: the "already exists" overwrite detection
now keys off SKILL_EXISTS_MARKER in @posthog/shared, used verbatim by the
server messages and the UI matcher, so a reword cannot silently break the
overwrite dialog; getUserSkillsDir is mocked in skills.test.ts so the
codex-import and team-install tests run fully against temp dirs instead
of early-returning when the real home directory has a colliding skill.

Generated-By: PostHog Code
Task-Id: f4e84f1a-19c9-490c-9b98-47787a7dddcf
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.

3 participants