fix(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon
, '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(codex): discover project skills from workspace - #5335

Open
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills
Open

fix(codex): discover project skills from workspace#5335
t3-code[bot] wants to merge 1 commit into
mainfrom
t3code/codex-project-skills

Conversation

@t3-code

@t3-codet3-codeBot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

summary

  • discover codex skills against the active project or thread worktree
  • feed workspace-scoped skills into $ autocomplete
  • keep the global fallback while excluding repo skills discovered from the server launch directory
  • resolve workspace paths server-side instead of accepting arbitrary client paths

reproduction

  1. launch t3 code outside the target repository
  2. open a project containing .agents/skills/<name>/SKILL.md
  3. select codex and type $
  4. the project skill is now listed

tests

  • pnpm --filter t3 typecheck
  • pnpm --filter @t3tools/contracts typecheck
  • pnpm --filter @t3tools/client-runtime typecheck
  • pnpm --filter @t3tools/web typecheck
  • pnpm --dir apps/server exec vp test run src/server.test.ts -t "server.listProviderSkills"
  • pnpm --dir apps/server exec vp test run src/provider/Layers/ProviderRegistry.test.ts -t "cwd-scoped skill discovery"
  • pnpm lint
  • pnpm fmt:check

Note

Medium Risk
New WS RPC and Codex subprocess probes on composer interaction add latency and failure modes; cwd is server-resolved from project/thread shells rather than client paths, which limits path injection risk.

Overview
Fixes Codex $ autocomplete when T3 Code is launched outside the target repo by loading skills for the active project or thread worktree instead of only from the server’s launch directory.

Adds server.listProviderSkills (read scope): the server maps projectId / optional threadId to workspaceRoot or worktreePath, then calls provider listSkills(cwd). Codex runs a scoped skills/list probe against that cwd (10s timeout, fallback to cached global skills on failure). Full provider refresh still drops repo-scoped skills from the global snapshot so launch-dir repo skills don’t pollute the default list.

The web composer fetches skills via useProviderSkills when the skill menu is open, with short-lived caching for smoother UX; other providers without listSkills keep using snapshot skills.

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

Note

Discover project skills from workspace via server.listProviderSkills RPC

  • Adds a new server.listProviderSkills websocket RPC that resolves skills scoped to the active workspace root or worktree path, with auth requiring OrchestrationReadScope.
  • Implements listSkills(cwd) on the Codex provider driver in CodexDriver.ts, which spawns a short-lived app-server probe with a 10s timeout and falls back to snapshot skills on failure.
  • Refactors CodexProvider.ts to extract openCodexAppServerProbe as a reusable utility; snapshot skills now exclude repo-scoped entries.
  • The web ChatComposer fetches live provider skills via the new RPC when the skill trigger is active, caching results by environment/instance/project/thread and falling back to snapshot skills filtered to non-repo scope.
  • Risk: the 10s child-process timeout per listSkills call may add latency if the Codex app-server is slow to start.

Macroscope summarized 6df2036.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 4, 2026

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

One finding on error-log hygiene in the new Codex skill-discovery fallback. Everything else (subpath namespace imports, Effect.fn service methods, whole-channel Effect.catch, contract schemas, added focused tests) matches the conventions.

Posted via Macroscope — Effect Service Conventions

Effect.catch((error) =>
Effect.logWarning("Codex workspace skill discovery failed; using global skills.", {
cwd,
error: String(error),

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.

String(error) puts arbitrary error text into the log payload — the failure channel here includes CodexAppServerSpawnError, whose message carries the resolved binary/app-server command and underlying spawn output. Consider logging a normalized tag instead (the pattern used by the other provider layers, e.g. errorTag/causeErrorTag from @t3tools/shared/observability), keeping the real error only as cause.

- error: String(error),+ errorTag: errorTag(error),

Requires adding import { errorTag } from "@t3tools/shared/observability";.

Posted via Macroscope — Effect Service Conventions

@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 2 potential issues.

Fix All in Cursor

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

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

const isComposerMenuLoading =
composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending;
(composerTriggerKind === "path" && pathTriggerQuery.length > 0 && workspaceEntries.isPending) ||
(composerTriggerKind === "skill" && providerSkills.isPending && composerMenuItems.length === 0);

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.

Incomplete skill menu looks final

Medium Severity

The skill autocomplete menu ($) incorrectly shows only global skills as complete while project/repo-specific skills are still loading. This happens because the loading indicator is suppressed when fallback global skills are present, masking the pending state of the skill query.

Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

skills: parseCodexSkillsListResponse(skillsResponse, input.cwd),
skills: parseCodexSkillsListResponse(skillsResponse, input.cwd).filter(
(skill) => skill.scope !== "repo",
),

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.

Repo skill chips lost in timeline

Medium Severity

Repo-scoped skills are stripped from the Codex provider snapshot, but the message timeline still renders skill chips only from that snapshot. $repo tokens in history therefore stop turning into skill chips because timeline rendering was not switched to workspace-scoped skill discovery.

Additional Locations (1)
Fix in CursorFix in Web

Reviewed by Cursor Bugbot for commit 6df2036. Configure here.

@macroscopeapp

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR introduces a new feature for workspace-scoped skill discovery with new RPC endpoints and frontend integration. Additionally, there are unresolved review comments identifying potential bugs in loading state handling and timeline skill chip rendering that should be addressed.

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

@archiekd

Copy link
Copy Markdown

Does this work for claude project level skills as well?

@felix-exon

Copy link
Copy Markdown

waiting for this as well :P

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:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@archiekd@felix-exon