Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: absorb ecosystem skill folders and expose skills back - #488

Merged
pedronauck merged 23 commits into
mainfrom
skills-source
Aug 26, 2026
Merged

feat: absorb ecosystem skill folders and expose skills back#488
pedronauck merged 23 commits into
mainfrom
skills-source

Conversation

@pedronauck

Copy link
Copy Markdown
Member

What & why

CompozyOS could only see skills stored in its own folders (.compozy/skills in a workspace, the CompozyOS home skills folder globally). Meanwhile the agent-tool ecosystem settled on shared folder conventions — .agents/skills in a project and ~/.agents/skills for the user, read natively by most agent CLIs, plus per-tool homes such as Claude Code's .claude/skills. Anyone running CompozyOS next to another agent tool already owned a skill library that CompozyOS simply could not read. The reverse was equally broken: a skill authored or installed in CompozyOS was invisible to every other tool.

This PR makes the boundary two-way.

Reading in. The universal agents convention is scanned by default, so an existing skill library is available in the / picker on first launch with zero setup. Operators pick which further conventions to scan — curated presets plus arbitrary folders of their own — per installation, per profile, per workspace. Changes take effect on the running daemon in seconds, no restart.

Writing out. A skill with a real folder on disk can be exposed into an enabled convention as a per-skill link. One canonical body, no copies to drift. Removing the skill removes the links; editing it in place keeps them; a link CompozyOS did not create is never touched.

Absorbed skills are full citizens, not second-class imports: same content verification on every load, same enable/disable, same collision audit trail, same / picker, same invocation path, same budgets. They carry a discreet origin label wherever skills are listed so their provenance stays visible.

Spec and tasks: .compozy/tasks/skill-sources (tasks 01–09, ADR-001…ADR-017).


Product behavior

Source presets. A curated, daemon-known table of folder conventions. v1 ships three:

Preset Workspace folder Global folder Default
compozy <ws>/.compozy/skills CompozyOS home skills always on, not configurable
agents <ws>/.agents/skills ~/.agents/skills on
claude <ws>/.claude/skills ~/.claude/skills off

compozy never appears in the configurable selection — the marketplace installs there, so disabling it would break install and create flows. An empty selection is valid and means "Compozy folders only". An unknown preset name is a validation error that names the valid slugs and the closest match; it is never treated as a path.

Custom folders. Free-form directories scanned as skills-only sources, for layouts no preset covers. Absolute and ~-relative paths at user and profile scope; workspace scopes additionally accept workspace-relative paths. A folder that resolves to an already-active root is refused, naming the source that already owns it.

Live apply. A saved source change reaches every surface within two refresh intervals. Both keys are classified Live in the lifecycle matrix, and surfaces report the apply semantics from daemon truth rather than hardcoding them.

Diagnostics are never silent. Per-root scan caps still hold, but a capped root is now flagged truncated in every management surface instead of only writing a log line. Name collisions record every losing definition in an inspectable audit trail. Links that dangle, cycle, or escape a trusted folder are skipped with a per-entry reason.

Ecosystem frontmatter is quiet. Definition fields the ecosystem standardized but CompozyOS does not act on (license, compatibility, allowed-tools, and the known Claude Code superset) are accepted without warnings. They stay inert — recognized, never executed. Genuinely unknown fields still warn.


Architecture and root resolution

Discovery keeps one system rather than growing a parallel one. The three scan paths that previously joined hardcoded folder names now consume resolved root specs.

Eight-tier precedence (higher wins on collision, every shadow audited):

bundled → marketplace → user → profile → additional → workspace → workspace-profile → agent-local

Workspace-level pattern roots map to the workspace tiers, global-level roots to the user tier, and custom folders to additional. Intra-tier order follows list order with the compozy root loaded last so it wins ties. No new tier was introduced — Source is a tier string that ripples through resource records, shadows, and the web source field.

Stable identity. RootID derives from (resource_scope, profile_id, workspace_id, root_kind, canonical_dir). Stable IDs own cache identity — never profile names or display slugs — and generations include profile configuration.

One physical skill appears exactly once, no matter how many links point at it: identity is the resolved real location. First-level links inside a source root are followed; anything that escapes a trusted location, dangles, or cycles is skipped with a diagnostic. Containment is tested against real temporary filesystems, including the macOS /private/var realpath quirk.

Every non-bundled skill passes content verification on every load, regardless of which source it came from. Critical findings block that skill. A skill absorbed from ~/.agents/skills is exactly as trusted as one in the CompozyOS home folder — both are local user files — and marketplace allowlists still gate only marketplace-tier content.


Configuration lifecycle and live apply

Two new keys in the [skills] block:

[skills]
# Folder conventions to scan besides Compozy's own (always active).
# Valid presets: "agents" (default on), "claude".
sources = ["agents"]

# Extra skills-only directories. Absolute or ~ paths at user/profile scope;
# workspace configs may also use workspace-relative paths.
custom_sources = []

Four config layers — user → profile → workspace → workspace-profile — with per-key tri-state semantics:

  • absent → inherit from the layer above;
  • present with an array → replace the whole list for that key;
  • present but empty → disable configured non-Compozy roots for that key.

sources and custom_sources override independently. Removing an override restores inheritance, and surfaces report which layer owns the effective value. Runtime mutation covers user, profile, and workspace; the repository workspace-profile layer stays read-only by design.

Go's plain *[]string cannot tell "absent" from "null" on the wire, so the request type uses an explicit presence-aware wrapper (OptionalStringList{Present, Null, Value}) with a custom UnmarshalJSON, parsed by one shared decoder used by both HTTP and UDS — the two transports are byte-identical. Plain *[]string survives only in the TOML overlay model, where JSON-null has no meaning.

Live apply mechanics. The watcher's roots provider re-derives roots from current configuration, profile-keyed caches invalidate, and resources republish in the same change. That last part matters: after resource authority hands over, the filesystem scan is bypassed, so configured roots must flow through the global and workspace discovery entry points or absorbed skills would vanish on the first resource sync. An integration test pins it.


Discovery, identity, dedup, diagnostics, and events

The sources read model reports, per resolved root: path, existence, readability, skill count, truncation, and the skipped-link reasons. Collisions surface the winner and every shadowed definition.

Three durable events cover the configuration path:

  • skills.sources.applied — carries every effective preset and custom root for the generation;
  • skills.sources.apply_failed;
  • skills.sources.superseded.

Five cover the exposure path:

  • skills.exposure.created, skills.exposure.removed, skills.exposure.broken_detected, skills.exposure.cleanup_failed, skills.exposure.operation_failed.

A coverage-matrix suite owns this event contract and fails when a lifecycle path forgets to emit.


Exposure lifecycle, ownership, and safety

Exposure needed to answer two questions the filesystem alone cannot: did we create this link? and did a link we created get deleted behind our back? Pure filesystem inference can prove neither. Treating records as truth drifts from reality. So: ownership is persisted, health is reconciled live from disk.

skill_exposures is a new side table keyed by (skill_name, owner_scope, workspace_id, target_slug) with a unique index on link_path, and a database-level CHECK that a user-scoped row has no workspace and a workspace-scoped row has one.

Rules the implementation enforces:

  • Only skills with a physical folder are exposable. Bundled skills have no on-disk home, and the error says exactly that.
  • User-owned skills expose only to user provider roots; workspace-owned skills only to that workspace's shared roots.
  • Profile- and workspace-profile-owned skills refuse with profile_skill_not_exposable before any record or link is written. That cut is deliberate for this MVP: per-profile provider homes do not exist yet, so there is no correct target to write to.
  • Re-exposing an existing healthy link is idempotent.
  • A name conflict at the target is an error, never an overwrite.
  • Removing a skill removes every link CompozyOS created for it. Updating a skill in place preserves them.
  • CompozyOS never removes a link it did not create, and never falls back to copying content when linking fails. A silent copy would create the drift this feature exists to prevent.
  • A multi-target expose that partially fails rolls back and reports rolled_back, with per-target cleanup errors when compensation itself could not complete.

Per-target error codes: skill_not_exposable, expose_target_disabled, expose_target_invalid, expose_name_conflict, expose_link_unsupported, expose_foreign_link, unsafe_skill_name.


Surface parity — CLI, HTTP, UDS, native tools, agents

Every capability is operable without the web UI, with structured output and deterministic errors.

CLI

  • compozy skill sources — enabled state, resolved locations, existence, per-source counts, truncation, skipped links. Reads the settings envelope; no new read route.
  • compozy skill expose <name> --to <target> / compozy skill unexpose
  • compozy skill create --expose
  • compozy config set|get|unset skills.sources|skills.custom_sources (comma and JSON forms)
  • compozy skill list / info / where gain origin and root provenance columns.

HTTP / UDS — the same methods registered on both transports, parsed once:

  • GET /api/settings/skills — extended envelope carrying the full sources read model.
  • PATCH /api/settings/skills — scope-specific request shapes; any non-source skills field at workspace scope returns 400 workspace_scope_field_forbidden. Validation errors: unknown_skill_source, duplicate_skill_source, invalid_source_path.
  • POST /api/skills/{name}/expose · POST /api/skills/{name}/unexpose — full success 200; any failure 409 with the single failure envelope plus per-target results. Unexpose results are per-target independent (idempotent removal, no rollback).
  • GET /api/skills/{name} — gains origin and exposures[]{target, path, status}.

Native toolscompozy__skill_list, compozy__skill_search, and compozy__skill_view consume the same shared DTOs, so origin (and exposures on view) appear without a bespoke path. Descriptors and schema digests were refreshed in the same change; the catalog fixture is updated.

Extension Host APIhandleSkillsList consumes the shared summary DTO and extension/contract/skills.go was updated in the same change.

Authorization split. Expose and unexpose are skill operations, so agent-scope callers may use them under the same gate as skill enable/disable. The two source configuration keys are user/profile/workspace policy and stay read-only at agent scope. Both keys are registered in the tool surface as agent-writable string slices at the scopes that own them.

Explicit no-impact: SkillRuntimeStatusPayload (compozy status) is untouched — the sources read model lives on the settings envelope only. Existing status tests verify it.


Managed-session suppression and command identity

If a session's provider already reads a folder natively, injecting those skills into its context again is pure waste. OpenClaw and Hermes read .agents/skills; Claude Code reads .claude/skills.

ACP cannot help here — the protocol carries no source paths at all, so dedup has to be resolved on our side. Each preset therefore declares which providers read its folders natively, and the harness policy filters skills whose winning copy lives in such a folder out of that session's injected context. The filter runs before the per-turn unchanged-hash check, and covers both injection points (the startup catalog section and the per-turn augmenter) together.

Suppression touches injected context and nothing else. The skill stays in the registry, the API, enable/disable, the shadow audit, the / picker, and — critically — an explicit /<skill> invocation always delivers it. An explicit user request always wins. An unknown provider suppresses nothing (fail-open). Every omission is visible in harness diagnostics. There is no configuration key for this: it is correct-by-default behavior.

Command identity. Each root emits a stable source ID. Without it, qualified command tokens collapse into each other and invocations get drift-rejected. Same-named skills from different sources stay separately addressable through their qualified forms — visible in the picker screenshot below, where agents:commit-hygiene and bare commit-hygiene are distinct rows.


Web

  • Settings › Skills — Sources section. One row per source: label, resolved paths, live skill count, and a switch (the always-on Compozy row shows a badge instead). Custom folders are added and removed beneath the table. Inherit/override state is shown per scope.
  • Session / picker — origin chips. Absorbed commands carry a neutral origin chip; native commands stay unlabeled.
  • Skill detail — Exposures panel. Current exposures with health and link path, an Unexpose action, and an "Expose to…" target picker limited to enabled, compatible targets.
  • Marketplace installed management continues to work across reloads.

No new @compozy/ui primitives were needed — the section reuses existing settings patterns and primitives.


Docs and the official Compozy skill

New pages: skills/sources.mdx, cli/skill/sources.mdx, cli/skill/expose.mdx, cli/skill/unexpose.mdx.

Updated: configuration/config-toml.mdx (section index, example block, field table), configuration/file-locations.mdx (location tables and tree), configuration/lifecycle-matrix.mdx (both keys as Live), configuration/skill-md.mdx, skills/index.mdx (discovery order and precedence), skills/skill-md.mdx, and the generated CLI reference.

agents/definitions.mdx and configuration/agent-md.mdx keep skills.extra_sources rejected for agent definitions — a different surface — and now point at the runtime skills.sources keys so the two are not confused.

Official skill: skills/compozy/references/configuration.md and references/tools-and-skills.md.

Instructions: internal/CLAUDE.md's five-layer precedence sentence is now the eight-tier one, with an explicit "never hardcode a root".


Schema and storage

Two append-only migrations, allocated at execution time and serialized against the concurrent agent-comms schema work:

  • 00090_schema.sql — creates skill_exposures with non-empty CHECKs on every text column, owner_scope IN ('user','workspace'), the owner/workspace consistency CHECK, a unique index on link_path, and a unique index on (skill_name, owner_scope, COALESCE(workspace_id,''), target_slug).
  • 00091_schema.sql — drops the superseded idx_skill_exposures_skill_name.

The declarative schema fragment, atlas.sum, and sqlc output were regenerated with make codegen, and make codegen-check is green. No existing migration bytes, versions, or ordering were touched, and no boot-time schema repair was added. The fresh, reopen, ahead, integrity, and equivalence suites were extended.


Deep review

One full deep-review round over the complete branch diff:

Candidates 304
Reported 158
Suppressed 146 — intentional 70, speculative 43, phantom-knowledge 11, pre-existing 10, formatting 9, linter-overlap 2, duplicate 1
Canonical accepted 147 (38 defects + 109 advisories)
Resolved 147 / 147 — 0 open defects, 0 open advisories
Severity of accepted 3 critical · 22 major · 73 minor · 49 trivial
Coverage both lanes complete over 19,620 selected hunk lines, 317 files

Artifacts: .deep-review/skill-sources/ (remediation.json records every item as fixed).


QA

A targeted release-grade run in an isolated lab: non-default CompozyOS home, lab-scoped daemon port, lab-scoped UDS and tmux-bridge sockets, manifest-derived provider homes, and browser proxy configuration derived from the manifest rather than a hardcoded port.

20-scenario session matrix, all terminal, zero Pending/Skipped/Fail/Blocked across five personas — runtime administrator, delivery builder, returning session user, autonomous agent, and one in-persona real-scenario founder run. The real-scenario run released 11 declared tasks behind the scheduler barrier and reached all_terminal with no stall, and the independent task catalog matched task-detail reads.

Ten product defects found and fixed, each root-caused, contained, with a named regression suite and no product trade-off:

Bug Impact Regression proof
skill-source-profile-write-rejected Blocks-Completion settings core source-policy suite
workspace-skills-non-source-field-written Blocks-Completion native config + scope-validation suites
skill-detail-rejects-workspace-id Blocks-Completion skill detail registered-id suite
skill-source-event-omits-custom-roots Blocks-Completion settings diagnostics + generation fence
workspace-native-skill-missing Blocks-Completion registry root scope + E2E-011
expose-picker-crashes Blocks-Completion production-bundle E2E-011
skill-source-agent-write-doc-mismatch Trust-Damage native config classifier + documented replay
custom-source-stuck-pending Trust-Damage settings diagnostics + E2E-008
session-delete-return-race Trust-Damage session controller units + full Web E2E
namespaced-skill-label-collapses Trust-Damage command projection units + E2E-010

Two stale test assumptions were also corrected — skill inspectskill info, the legacy detail workspace query → workspace_id, and an ambiguous visible-text match → the exact command token. No retry, timeout, or assertion was weakened anywhere.

Automated lanes

Lane Result
Focused Go race tests Pass — settings diagnostics, workspace resource projection
Root Turbo web lint / typecheck / build Pass — zero warnings, zero errors
Root Turbo web unit suite Pass — 719 files, 6,346 tests
make test-e2e-runtime Pass — exit 0 on a fresh full rerun
make test-e2e-web Pass — 256 total: 253 passed, 3 intentional skips, 0 unexpected, 0 flaky
make gate-full Pass

Teardown. Both labs ended with teardown.json recording clean: true and zero surviving processes. Both strict evidence audits record verdict: pass with empty blockers.

Report: docs/qa/reports/2026-08-25-skill-sources.md. All 21 touched scenario files carry qa_status: pass.

One open item, out of scope for this branch. BUG-20260825-workspace-agent-unusable-for-sessions: the catalog advertises a workspace-profile agent that session new refuses. The playbook continued with global agents and the managed-skill canary passed, so this PR is unaffected — but the journey needs a product decision on profile-aware session resolution. The bug file records the options and recommends making session resolution consume the same workspace-profile layer the agent catalog already publishes.


Compozy Impact Audit

  • Native tools: compozy__skill_list, compozy__skill_search, and compozy__skill_view consume the shared skill DTOs, so payloads gain origin (and exposures on view); descriptors and schema digests were refreshed and internal/tools/builtin/testdata/native-tool-catalog.json regenerated in the same change. No tool ID, toolset, risk flag, capability gate, or availability diagnostic changed. CLI/API fallbacks are unchanged.
  • Extensibility and hooks: the resources.skills manifest path is unaffected and extension-published skills keep flowing through the resource store; the resource-authority handoff now republishes from discovery paths that carry configured roots, pinned by integration test. Extension Host API handleSkillsList and extension/contract/skills.go were updated together. No new hook events; absorbed skills' metadata.compozy.* declarations follow the exact rules of user-tier skills today. Config lifecycle adds two [skills] keys, both Live, both registered on the tool surface. The preset table is closed to extension registration in v1 (ADR-014). Checked and unchanged: bridge SDK types (no skill payloads), MCP sidecar lifecycle (per-skill declarations unchanged), network protocol (skills never cross the wire).
  • Workspace data isolation: skill catalog records are workspace-scoped, and RootID carries (resource_scope, profile_id, workspace_id, root_kind, canonical_dir) so cache identity cannot alias across workspaces or profiles. The registered workspace ID now survives publication, cache lookup, HTTP/UDS reads, marketplace queries, and session command projection — the QA run fixed two defects precisely here (skill-detail-rejects-workspace-id, workspace-native-skill-missing). skill_exposures rows are constrained at the database level so a workspace-scoped row must carry a workspace ID and a user-scoped row must not. Workspace-pattern roots resolve from the workspace root directory; global roots are global-tier by design. Two-workspace isolation is covered by integration test.
  • Official Compozy skill: skills/compozy/references/configuration.md (the two new keys and the write-scope policy) and references/tools-and-skills.md (discovery paths) were updated. No public command or tool ID changed beyond the skill inspectskill info rename listed below.

Breaking changes and delete targets

Removed in the same change — no aliases, no dual fields, no compatibility shims:

  • RegistryConfig.UserSkillsDir (a single scalar folder) → GlobalSkillRoots + GlobalAgentsDir; every reader updated.
  • WorkspaceDiscoveryRoot.SkillsDir()SkillsDirs(cfg); both callers updated.
  • Hardcoded workspace root joins in the workspace registry cache → resolved root specs.
  • globalAgentsDir()'s filepath.Dir derivation → an explicit configuration field (it broke the moment the scalar became a list).
  • compozy skill inspectcompozy skill info; the cli/skill/inspect.mdx page is gone.

No data migration is required for users: the new keys have defaults (sources = ["agents"], custom_sources = []) and an absent key inherits. The default turns the universal convention on, which is the intended behavior change — an existing ~/.agents/skills library becomes visible on upgrade.


Risks and follow-ups

  • Double-load cost. A skill in a folder a provider also reads natively could otherwise land in context twice. Suppression handles it; per-tool presets additionally default off. The residual cost of a wrong provider mapping is context redundancy, not a correctness failure.
  • Traversal surface. Following links is new. Containment, dangling, cycle, and escape cases are covered on real temporary filesystems, and escapes outside trusted locations are skipped rather than followed.
  • Pathological folders. Pointing a custom source at a very large directory hits the per-root scan caps. That is now visible as truncated on every management surface instead of a silent log line.

Deferred, purely additive: further presets (codex, hermes, openclaw, cursor, opencode — one table row each), an ACP advertised-command confirmation signal for suppression, and custom folders as expose targets. Permanently out of scope: remote skill installation or sync, agent-definition discovery from new roots, extension-registered presets, content mirroring, and OpenClaw's bare project skills/ folder (it collides with ordinary repository folders, including this repo's own).


How you verified it

Command Result
make gate-full passmake gate-status reports full pass CURRENT-PASS, fingerprint 67ff910e25aad236ec92b7b747f04d4656933f88, log .cache/gate/logs/full-1787740522-77100.log
make codegen-check pass — all modules verified
make test-e2e-runtime exit 0 on a fresh full rerun
make test-e2e-web 256 total · 253 passed · 3 intentional skips · 0 unexpected · 0 flaky
Root Turbo web unit suite 719 files · 6,346 tests
Root Turbo lint / typecheck / build zero warnings, zero errors
Deep review round 1 147 / 147 accepted findings resolved
Isolated QA labs both strict audits verdict: pass, blockers: []; both teardown.json clean: true

Branch: 21 commits over merge-base f652f29a, 491 files, +28,172 / −2,805. Rebased onto main with no conflicts. Full local gate was run at this exact head; PR CI is the delivery gate.


Evidence

Settings › Skills — Sources section

Settings › Skills at user scope. Compozy is always on with no switch; Agents is on by default; Claude is available and off. A custom folder added as team-skills reports a live measured count ("1 skill") rather than sitting stuck at pending — the fix for custom-source-stuck-pending. The header reads "Saved · applied immediately", which is daemon truth for a Live key, not hardcoded copy. In this flow (E2E-008) adding the same folder a second time is refused, naming the source that already owns the root.

Session / picker with origin labels

The / picker in a live session. Built-in commands group first, then skills. The two skills absorbed from the agents convention carry an agents origin chip; native commands like compozy and cy-create-spec stay unlabeled. agents:commit-hygiene and bare commit-hygiene remain separate, individually invocable rows — the regression proof for namespaced-skill-label-collapses, where a qualified token used to collapse into its bare form.

Skill detail — active exposure

The exposure panel on a workspace-owned skill. One healthy exposure into the Agents convention, showing its status, its real link path, and an Unexpose action. The "Expose to…" picker lists only enabled, compatible targets. This panel is what expose-picker-crashes used to break before it could render.

Skill detail — foreign file at the target

The same panel when something CompozyOS did not create already occupies the target path. The row reads "another app's file is there" and no destructive action is offered — no Unexpose, no overwrite. This is the visible half of the rule that CompozyOS never removes a link it did not create.


Impact

Changes CLI commands (skill sources, skill expose, skill unexpose, skill create --expose, skill inspectskill info, origin columns on skill list|info|where), HTTP and UDS routes (extended settings envelope, two expose routes, origin + exposures[] on skill detail), config.toml keys (skills.sources, skills.custom_sources), the global database schema (skill_exposures), native tool payloads, the extension Host API skills contract, and web surfaces (Settings › Skills, / picker, skill detail, marketplace). Documentation in packages/site and the official skills/compozy/ skill are updated in this PR.


  • make gate passes locally (make gate-full, fingerprint 67ff910e25aad236ec92b7b747f04d4656933f88); this PR is delivered only after its required CI checks are green
  • New or changed behavior is covered by tests — unit, integration, runtime E2E, and web E2E, with a named regression suite for each of the ten QA defects
  • Written with Claude Opus under cy-loop-tasks; every gate, lane, and QA verdict above was executed and read back rather than assumed

🤖 Generated with Claude Code

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
compozy-site Ready Ready Preview Aug 26, 2026 6:25pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 357 files, which is 57 over the limit of 300.

To get a review, reduce the PR to 300 files or fewer by splitting it into smaller PRs or changing its base branch.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f199d274-4933-48a8-8df4-24e8ebb9168e

📥 Commits

Reviewing files that changed from the base of the PR and between 21d420d and cc11581.

⛔ Files ignored due to path filters (93)
  • .agents/skills/eng/eng-real-scenario-qa/scripts/observe-runtime.py is excluded by !.agents/**
  • .agents/skills/eng/eng-real-scenario-qa/scripts/test_observe_runtime.py is excluded by !.agents/**
  • bun.lock is excluded by !**/*.lock, !**/*.lock
  • docs/qa/automation-backlog/official-skill-doc-runtime-agreement.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-custom-source-stuck-pending.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-expose-picker-crashes.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-expose-preflight-misattributes-target.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-playbook-changelog-task-unsourced.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-skill-detail-rejects-workspace-id.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-skill-source-agent-write-doc-mismatch.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-skill-source-event-omits-custom-roots.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-skill-source-profile-write-rejected.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-workspace-agent-unusable-for-sessions.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-workspace-native-skill-missing.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260825-workspace-skills-non-source-field-written.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260826-namespaced-skill-label-collapses.md is excluded by !**/*.md
  • docs/qa/bugs/BUG-20260826-session-delete-return-race.md is excluded by !**/*.md
  • docs/qa/charters/CH-session-skill-catalog-budget.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-expose-lifecycle-trust.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-expose-web-repair.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-session-suppression-matrix.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-sources-agent-plane.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-sources-diagnostics-truth.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-sources-live-apply.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-sources-managed-session-canary.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-sources-repo-teammate.md is excluded by !**/*.md
  • docs/qa/charters/CH-skill-sources-settings-web.md is excluded by !**/*.md
  • docs/qa/journeys/J-absorb-skills-from-other-tools.md is excluded by !**/*.md
  • docs/qa/journeys/J-diagnose-skill-sources.md is excluded by !**/*.md
  • docs/qa/journeys/J-operate-skill-sources-headless.md is excluded by !**/*.md
  • docs/qa/journeys/J-share-skills-with-other-tools.md is excluded by !**/*.md
  • docs/qa/journeys/J-use-absorbed-skills-in-a-session.md is excluded by !**/*.md
  • docs/qa/reports/2026-08-25-skill-sources.md is excluded by !**/*.md
  • docs/qa/reports/2026-08-26-main-rebase-regressions.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-compozy-native-tool-invocation.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-compozy-official-skill-discovery.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-live-skill-source-reload.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-manage-skill-source-policy.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-managed-session-skill-loading.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-session-command-catalog-parity.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-session-composer-skill-chip.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-session-skill-catalog-budget.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-ecosystem-frontmatter-quiet.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-exposure-lifecycle.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-origin-attribution.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-session-source-injection.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-source-agent-parity.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-source-diagnostics-cli.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-source-observe-ledger.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-skill-source-symlink-containment.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-web-marketplace-installed-management.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-web-marketplace-skill-install.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-web-skill-expose-panel.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-web-skill-sources-settings.md is excluded by !**/*.md
  • docs/qa/scenarios/ET-workspace-skill-source-teammate.md is excluded by !**/*.md
  • docs/qa/scenarios/RT-014.md is excluded by !**/*.md
  • internal/CLAUDE.md is excluded by !**/*.md
  • internal/store/globaldb/schema/migrations/atlas.sum is excluded by !**/*.sum, !**/*.sum
  • internal/tools/builtin/testdata/native-tool-catalog.json is excluded by !**/*.json
  • openapi/compozy.json is excluded by !**/*.json
  • package.json is excluded by !**/*.json
  • packages/site/content/docs/agents/definitions.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/config/get.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/create.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/expose.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/index.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/info.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/list.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/meta.json is excluded by !**/*.json
  • packages/site/content/docs/cli/skill/sources.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/cli/skill/unexpose.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/configuration/agent-md.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/configuration/config-toml.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/configuration/file-locations.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/configuration/lifecycle-matrix.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/configuration/skill-md.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/skills/index.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/skills/meta.json is excluded by !**/*.json
  • packages/site/content/docs/skills/skill-md.mdx is excluded by !**/*.mdx
  • packages/site/content/docs/skills/sources.mdx is excluded by !**/*.mdx
  • sdk/typescript/src/generated/contracts.ts is excluded by !**/generated/**, !**/generated/**
  • skills/compozy/references/configuration.md is excluded by !**/*.md
  • skills/compozy/references/runtime-operations.md is excluded by !**/*.md
  • skills/compozy/references/tools-and-skills.md is excluded by !**/*.md
  • web/e2e/__tests__/marketplace.spec.ts is excluded by !web/e2e/**
  • web/e2e/__tests__/skill-sources.spec.ts is excluded by !web/e2e/**
  • web/e2e/fixtures/skill-source-selectors.ts is excluded by !**/fixtures/**, !web/e2e/**
  • web/e2e/fixtures/skill-sources.ts is excluded by !**/fixtures/**, !web/e2e/**
  • web/package.json is excluded by !**/*.json
  • web/src/generated/compozy-openapi.d.ts is excluded by !**/generated/**, !**/generated/**, !**/*.d.ts
  • web/src/systems/settings/components/stories/settings-skill-sources.stories.tsx is excluded by !**/*.stories.tsx
  • web/src/systems/settings/routes/settings-skills.stories.tsx is excluded by !**/*.stories.tsx
  • web/src/systems/skill/components/stories/skill-expose-panel.stories.tsx is excluded by !**/*.stories.tsx
📒 Files selected for processing (357)
  • desktop/e2e/_electron/__tests__/updates.spec.ts
  • internal/acp/prompt_stream_terminal.go
  • internal/api/contract/session_commands.go
  • internal/api/contract/session_runtime_payloads.go
  • internal/api/contract/settings_config_payloads.go
  • internal/api/contract/settings_mutations.go
  • internal/api/contract/settings_response_meta.go
  • internal/api/contract/settings_skill_source_status.go
  • internal/api/contract/settings_skill_sources.go
  • internal/api/contract/settings_test.go
  • internal/api/contract/skill_payloads.go
  • internal/api/core/authored_context_target.go
  • internal/api/core/base_handlers.go
  • internal/api/core/conversions_session_events.go
  • internal/api/core/conversions_settings_meta.go
  • internal/api/core/conversions_settings_runtime.go
  • internal/api/core/conversions_settings_sections.go
  • internal/api/core/conversions_settings_skill_sources.go
  • internal/api/core/conversions_settings_skills_mutation.go
  • internal/api/core/conversions_skills.go
  • internal/api/core/interfaces.go
  • internal/api/core/prompt_stream.go
  • internal/api/core/prompt_stream_emit.go
  • internal/api/core/prompt_stream_test.go
  • internal/api/core/session_commands.go
  • internal/api/core/session_input.go
  • internal/api/core/settings.go
  • internal/api/core/settings_feature_config.go
  • internal/api/core/settings_section_requests.go
  • internal/api/core/settings_skill_sources_errors.go
  • internal/api/core/settings_skill_sources_request.go
  • internal/api/core/settings_skills_update.go
  • internal/api/core/settings_test.go
  • internal/api/core/skill_exposure_dependencies.go
  • internal/api/core/skill_exposures.go
  • internal/api/core/skills.go
  • internal/api/core/skills_scope.go
  • internal/api/core/skills_test.go
  • internal/api/httpapi/handlers.go
  • internal/api/httpapi/handlers_test.go
  • internal/api/httpapi/routes.go
  • internal/api/spec/registry_settings_features.go
  • internal/api/spec/registry_skills.go
  • internal/api/spec/schema_customizers.go
  • internal/api/spec/schema_enum_registry.go
  • internal/api/spec/settings_test.go
  • internal/api/spec/skill_schema_enums.go
  • internal/api/spec/spec_test.go
  • internal/api/udsapi/handlers_test.go
  • internal/api/udsapi/routes.go
  • internal/api/udsapi/server_handlers.go
  • internal/api/udsapi/transport_parity_integration_test.go
  • internal/cli/agent_kernel.go
  • internal/cli/automation.go
  • internal/cli/client_api_errors.go
  • internal/cli/client_daemon_settings_types.go
  • internal/cli/client_query_values.go
  • internal/cli/client_resources_skills_hooks.go
  • internal/cli/client_session_prompt.go
  • internal/cli/client_settings_vault.go
  • internal/cli/client_test.go
  • internal/cli/cmd_palette_list.go
  • internal/cli/config.go
  • internal/cli/config_daemon_mutation.go
  • internal/cli/config_display.go
  • internal/cli/config_output.go
  • internal/cli/config_test.go
  • internal/cli/config_value_commands.go
  • internal/cli/extension_agent_plugin_output.go
  • internal/cli/gateway_output.go
  • internal/cli/helpers_test.go
  • internal/cli/loop.go
  • internal/cli/loop_runs_output.go
  • internal/cli/memory_runtime_output.go
  • internal/cli/output_labels.go
  • internal/cli/profile_output.go
  • internal/cli/profile_read_scope.go
  • internal/cli/provider_models.go
  • internal/cli/root.go
  • internal/cli/root_skill_exposure_errors.go
  • internal/cli/root_skill_source_errors.go
  • internal/cli/root_structured_error.go
  • internal/cli/skill.go
  • internal/cli/skill_commands.go
  • internal/cli/skill_commands_exposure.go
  • internal/cli/skill_commands_mutation.go
  • internal/cli/skill_daemon_test.go
  • internal/cli/skill_info.go
  • internal/cli/skill_items.go
  • internal/cli/skill_managed_guard.go
  • internal/cli/skill_marketplace.go
  • internal/cli/skill_marketplace_integration_test.go
  • internal/cli/skill_output.go
  • internal/cli/skill_output_exposure.go
  • internal/cli/skill_sources.go
  • internal/cli/skill_test.go
  • internal/cli/skill_workspace.go
  • internal/cli/skill_workspace_metadata.go
  • internal/cli/task.go
  • internal/cli/window_manager_common.go
  • internal/command/catalog.go
  • internal/command/command_test.go
  • internal/command/types.go
  • internal/config/agent.go
  • internal/config/agent_test.go
  • internal/config/config_clone.go
  • internal/config/config_extensions_sandbox.go
  • internal/config/config_marketplace_validation.go
  • internal/config/defaults.go
  • internal/config/home.go
  • internal/config/lifecycle/lifecycle.go
  • internal/config/lifecycle/lifecycle_test.go
  • internal/config/merge.go
  • internal/config/merge_features.go
  • internal/config/merge_load.go
  • internal/config/merge_test.go
  • internal/config/persistence_test.go
  • internal/config/skill_source_overlay.go
  • internal/config/skill_source_presets.go
  • internal/config/skill_source_roots.go
  • internal/config/skill_source_slugs.go
  • internal/config/skill_source_validation.go
  • internal/config/tool_surface.go
  • internal/config/tool_surface_security.go
  • internal/config/tool_surface_test.go
  • internal/config/write_scope_policy.go
  • internal/daemon/agent_skill_publisher.go
  • internal/daemon/agent_skill_resource_mapping.go
  • internal/daemon/agent_skill_resources_integration_test.go
  • internal/daemon/agent_skill_resources_test.go
  • internal/daemon/agent_skill_source_scopes.go
  • internal/daemon/agent_skill_sync_staged.go
  • internal/daemon/boot.go
  • internal/daemon/boot_finalize.go
  • internal/daemon/boot_profile_name_resolver.go
  • internal/daemon/boot_profiles.go
  • internal/daemon/boot_profiles_test.go
  • internal/daemon/boot_resource_watchers.go
  • internal/daemon/boot_runtime_foundation.go
  • internal/daemon/composed_assembler.go
  • internal/daemon/composed_assembler_test.go
  • internal/daemon/daemon.go
  • internal/daemon/daemon_acpmock_faults_integration_test.go
  • internal/daemon/daemon_extension_agent_fixture_e2e_integration_test.go
  • internal/daemon/daemon_integration_test.go
  • internal/daemon/daemon_test.go
  • internal/daemon/harness_context.go
  • internal/daemon/harness_context_diagnostics.go
  • internal/daemon/harness_context_integration_test.go
  • internal/daemon/harness_context_session.go
  • internal/daemon/harness_context_test.go
  • internal/daemon/harness_observability.go
  • internal/daemon/harness_reentry_decision.go
  • internal/daemon/loop_action_environment_integration_test.go
  • internal/daemon/native_tool_authored_paths.go
  • internal/daemon/native_tool_dependencies.go
  • internal/daemon/native_tool_registry_skills.go
  • internal/daemon/native_tools_dependencies_builder.go
  • internal/daemon/native_tools_test.go
  • internal/daemon/prompt_input_composite.go
  • internal/daemon/prompt_input_composite_augment.go
  • internal/daemon/prompt_input_composite_integration_test.go
  • internal/daemon/prompt_input_composite_message.go
  • internal/daemon/prompt_sections.go
  • internal/daemon/prompt_skills.go
  • internal/daemon/prompt_skills_test.go
  • internal/daemon/section_selector.go
  • internal/daemon/session_commands.go
  • internal/daemon/settings_runtime_applier.go
  • internal/daemon/settings_runtime_applier_test.go
  • internal/daemon/settings_runtime_failure.go
  • internal/daemon/settings_runtime_skills.go
  • internal/daemon/skill_injection_policy.go
  • internal/demoseed/seed_integration_test.go
  • internal/events/names.go
  • internal/events/registry_base.go
  • internal/extension/contract/skills.go
  • internal/extension/host_api_skills.go
  • internal/extension/host_api_test.go
  • internal/providerenv/env.go
  • internal/session/manager_start_runtime.go
  • internal/session/manager_start_session.go
  • internal/session/prompt_overlay.go
  • internal/session/provider_runtime_test.go
  • internal/session/resume_replay.go
  • internal/session/session.go
  • internal/session/session_info.go
  • internal/settings/config_apply_runtime.go
  • internal/settings/models.go
  • internal/settings/models_runtime.go
  • internal/settings/provider_model_active_config.go
  • internal/settings/section_build.go
  • internal/settings/section_diff.go
  • internal/settings/section_feature_apply.go
  • internal/settings/section_skill_sources.go
  • internal/settings/section_skills_update.go
  • internal/settings/sections.go
  • internal/settings/service.go
  • internal/settings/service_test.go
  • internal/settings/skill_diagnostics_test.go
  • internal/settings/skill_source_event_context.go
  • internal/skills/catalog.go
  • internal/skills/catalog_test.go
  • internal/skills/diagnostics.go
  • internal/skills/expose_cleanup.go
  • internal/skills/expose_events.go
  • internal/skills/expose_lifecycle.go
  • internal/skills/expose_manager.go
  • internal/skills/expose_operation.go
  • internal/skills/expose_path.go
  • internal/skills/expose_reconcile.go
  • internal/skills/expose_test.go
  • internal/skills/expose_types.go
  • internal/skills/expose_unexpose.go
  • internal/skills/loader.go
  • internal/skills/loader_test.go
  • internal/skills/marketplace/installed.go
  • internal/skills/marketplace/service.go
  • internal/skills/marketplace/service_lifecycle.go
  • internal/skills/marketplace/service_test.go
  • internal/skills/mcp_sidecar.go
  • internal/skills/perf_bench_test.go
  • internal/skills/registry.go
  • internal/skills/registry_agent.go
  • internal/skills/registry_command.go
  • internal/skills/registry_concurrency_test.go
  • internal/skills/registry_config_generation.go
  • internal/skills/registry_diagnostics.go
  • internal/skills/registry_diagnostics_test.go
  • internal/skills/registry_disabled_test.go
  • internal/skills/registry_discovery.go
  • internal/skills/registry_exposure_roots.go
  • internal/skills/registry_integration_test.go
  • internal/skills/registry_load.go
  • internal/skills/registry_marketplace_load_test.go
  • internal/skills/registry_resource_projection.go
  • internal/skills/registry_roots_test.go
  • internal/skills/registry_source.go
  • internal/skills/registry_test.go
  • internal/skills/registry_toggle.go
  • internal/skills/registry_workspace_cache.go
  • internal/skills/registry_workspace_projection.go
  • internal/skills/resource_spec.go
  • internal/skills/resource_test.go
  • internal/skills/shadows.go
  • internal/skills/source_events.go
  • internal/skills/source_status.go
  • internal/skills/types.go
  • internal/skills/watcher.go
  • internal/skills/watcher_sidecar_test.go
  • internal/skills/watcher_test.go
  • internal/skillscan/scan.go
  • internal/skillscan/scan_directory.go
  • internal/skillscan/scan_test.go
  • internal/store/failure.go
  • internal/store/globaldb/global_db_skill_exposure.go
  • internal/store/globaldb/global_db_skill_exposure_test.go
  • internal/store/globaldb/global_db_task_coordinator_intents.go
  • internal/store/globaldb/global_db_type.go
  • internal/store/globaldb/queries/skill_exposures.sql
  • internal/store/globaldb/repositories.go
  • internal/store/globaldb/schema/definitions/45_skill_exposures.sql
  • internal/store/globaldb/schema/definitions/99_workspace_scope_integrity.sql
  • internal/store/globaldb/schema/migrations/00090_schema.sql
  • internal/store/globaldb/schema/migrations/00091_schema.sql
  • internal/store/globaldb/skill_exposure_sqlc_mapping.go
  • internal/store/globaldb/sqlcgen/models.go
  • internal/store/globaldb/sqlcgen/skill_exposures.sql.go
  • internal/store/memv2_helpers_test.go
  • internal/store/skill_exposure.go
  • internal/testutil/acpmock/cmd/acpmock-driver/diagnostics.go
  • internal/testutil/acpmock/cmd/acpmock-driver/main.go
  • internal/testutil/acpmock/diagnostics.go
  • internal/testutil/acpmock/fixture_test.go
  • internal/testutil/acpmock/registration.go
  • internal/tools/builtin/builtin_test.go
  • internal/tools/builtin/skills.go
  • internal/workspace/resolver.go
  • internal/workspace/resolver_config_behavior_test.go
  • internal/workspace/resolver_skill_sources.go
  • internal/workspace/scanner.go
  • magefiles/defaults.go
  • sdk/go/contracts/types_023_gen.go
  • sdk/go/extension_describe_profiles.go
  • web/src/components/assistant-ui/__tests__/session-thread.test.tsx
  • web/src/components/assistant-ui/session-command-menu-model.ts
  • web/src/components/assistant-ui/session-composer-command-menu.tsx
  • web/src/hooks/routes/__tests__/use-session-page-controls.test.tsx
  • web/src/hooks/routes/use-session-page-controls.ts
  • web/src/routes/_app/settings/-skills-settings-page.tsx
  • web/src/storybook/__tests__/web-storybook-visual-contract.test.ts
  • web/src/systems/marketplace/components/__tests__/marketplace-components.test.tsx
  • web/src/systems/marketplace/components/__tests__/marketplace-detail-manage.test.tsx
  • web/src/systems/marketplace/components/marketplace-detail-skill-exposures.tsx
  • web/src/systems/marketplace/components/marketplace-detail-skill-installed.tsx
  • web/src/systems/marketplace/components/marketplace-installed-card.tsx
  • web/src/systems/marketplace/hooks/use-marketplace-detail-skill-manage.ts
  • web/src/systems/marketplace/hooks/use-marketplace-kind-page.ts
  • web/src/systems/os/apps/session/__tests__/session-window.test.tsx
  • web/src/systems/os/apps/session/hooks/use-session-window-controller.ts
  • web/src/systems/session/hooks/__tests__/use-session-actions.test.tsx
  • web/src/systems/session/hooks/__tests__/use-session-commands.test.ts
  • web/src/systems/session/hooks/use-session-actions.ts
  • web/src/systems/session/hooks/use-session-commands.ts
  • web/src/systems/settings/adapters/__tests__/settings-api.test.ts
  • web/src/systems/settings/adapters/settings-api-error.ts
  • web/src/systems/settings/adapters/settings-sections-api.ts
  • web/src/systems/settings/components/__tests__/settings-skill-custom-sources.test.tsx
  • web/src/systems/settings/components/__tests__/settings-skill-sources-section.test.tsx
  • web/src/systems/settings/components/index.ts
  • web/src/systems/settings/components/settings-disabled-skills-section.tsx
  • web/src/systems/settings/components/settings-skill-custom-sources.tsx
  • web/src/systems/settings/components/settings-skill-source-diagnostics.tsx
  • web/src/systems/settings/components/settings-skill-source-row.tsx
  • web/src/systems/settings/components/settings-skill-sources-section.tsx
  • web/src/systems/settings/components/settings-skills-engine-sections.tsx
  • web/src/systems/settings/components/settings-skills-install-policy-section.tsx
  • web/src/systems/settings/components/settings-skills-scope-selector.tsx
  • web/src/systems/settings/hooks/__tests__/use-settings-skills-page.test.tsx
  • web/src/systems/settings/hooks/settings-skills-draft-logic.ts
  • web/src/systems/settings/hooks/use-settings-skill-sources.ts
  • web/src/systems/settings/hooks/use-settings-skills-page.ts
  • web/src/systems/settings/hooks/use-settings-skills-scope.ts
  • web/src/systems/settings/index.ts
  • web/src/systems/settings/lib/query-keys.ts
  • web/src/systems/settings/lib/sections.ts
  • web/src/systems/settings/lib/settings-skills-save.ts
  • web/src/systems/settings/lib/skill-source-draft.ts
  • web/src/systems/settings/lib/skill-sources-view.ts
  • web/src/systems/settings/mocks/fixtures.ts
  • web/src/systems/settings/mocks/handlers.ts
  • web/src/systems/settings/mocks/index.ts
  • web/src/systems/settings/public-types.ts
  • web/src/systems/settings/types.ts
  • web/src/systems/skill/adapters/__tests__/skill-api.test.ts
  • web/src/systems/skill/adapters/skill-api.ts
  • web/src/systems/skill/components/__tests__/skill-expose-panel.test.tsx
  • web/src/systems/skill/components/skill-expose-panel.tsx
  • web/src/systems/skill/components/skill-expose-target-picker.tsx
  • web/src/systems/skill/hooks/__tests__/use-skill-actions.test.tsx
  • web/src/systems/skill/hooks/__tests__/use-skills.test.tsx
  • web/src/systems/skill/hooks/use-skill-actions.ts
  • web/src/systems/skill/hooks/use-skill-expose.ts
  • web/src/systems/skill/hooks/use-skill-exposures.ts
  • web/src/systems/skill/hooks/use-skills.ts
  • web/src/systems/skill/index.ts
  • web/src/systems/skill/lib/__tests__/query-keys.test.ts
  • web/src/systems/skill/lib/__tests__/query-options.test.ts
  • web/src/systems/skill/lib/__tests__/skill-formatters.test.ts
  • web/src/systems/skill/lib/query-keys.ts
  • web/src/systems/skill/lib/query-options.ts
  • web/src/systems/skill/lib/skill-exposure-view.ts
  • web/src/systems/skill/lib/skill-formatters.ts
  • web/src/systems/skill/mocks/fixtures.ts
  • web/src/systems/skill/mocks/handlers.ts
  • web/src/systems/skill/mocks/index.ts
  • web/src/systems/skill/types.ts

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

React Doctor found 1 new issue in 1 file · 1 error · score 83 / 100 (Needs work) · 0 fixed · vs main

Errors

Reviewed by React Doctor for commit cc11581. See inline comments for fixes.

pedronauck and others added 22 commits August 26, 2026 13:10
Checkpoint via cy-loop-tasks (iteration 3, phase B mode=tasks).

Focused verification: 4,604 tests passed; full gate deferred to the QA tail.

Co-Authored-By: Codex <[email protected]>
BUG-20260825-skill-source-profile-write-rejected

Setting or unsetting skills.sources / skills.custom_sources for a named
profile failed with `decode skills settings request: unknown field
"override"` on every transport, leaving the profile layer of the
four-layer source contract unreachable.

internal/settings.updateSkillsSection already accepts a
SkillSourcesOverride at ScopeProfile, and the CLI already sends it —
the presence-aware override is what gives `config unset` its
clear-and-inherit semantics. Only the shared API decoder was gated on
ScopeWorkspace, so profile bodies fell through to the config-only
branch and were rejected.

Offer the override shape to the exact-profile lane too, keeping the
workspace lane override-only and the user lane config-only. The
forbidden-field refusal keeps its `workspace_scope_field_forbidden`
code and now words its message for whichever scope raised it.

Co-Authored-By: Claude Opus 5 <[email protected]>
BUG-20260825-skill-source-agent-write-doc-mismatch

The official skill told agents that skills.sources and
skills.custom_sources are trust roots which compozy__config_set and
compozy__config_unset deny with config_trust_root_forbidden. Both tools
write both keys at user and workspace scope and report applied: true,
lifecycle: live; agent and profile scope refuse with
config_scope_not_allowed, and config_trust_root_forbidden is never
emitted for either key.

The runtime matches the binding spec, so the references were wrong.
Both paths sit in agentMutableConfigKinds and ClassifyToolConfigPath
returns on that lookup before the trust-root branch; the keys also
appear in skillsConfigPathIsTrustRoot, which is the unreachable branch
the original sentence was written from.

Correct both sentences and pin the classifier outcome in the canonical
tool-surface policy table so a future reordering cannot silently make
the corrected text wrong again. The missing doc-vs-runtime gate is
recorded in the QA automation backlog.

Co-Authored-By: Claude Opus 5 <[email protected]>
…utes

BUG-20260825-skill-detail-rejects-workspace-id

compozy skill info, skill where, skill expose and skill unexpose
refused every --workspace value, including the exact canonical ws_ id
workspace info prints, with "workspace_id must be the canonical
workspace id". GET /api/skills/{name} and the expose routes failed the
same way on HTTP and UDS, so no client could work around it.

canonicalResolvedWorkspaceID preferred ResolvedWorkspace.WorkspaceID,
which the resolver stamps with the durable identity from
<root>/.compozy/workspace.toml, over ResolvedWorkspace.ID, which holds
the registered ws_ id every public surface emits. The comparison
measured the caller's public id against an identity no public surface
ever hands out. The failing expose envelope echoed the public id at the
top level while rejecting that same string.

Prefer the registered id and fall back to the durable identity only for
a workspace resolved by path that has no registered id.

The existing coverage passed because its stub ResolvedWorkspace left
WorkspaceID empty, a shape production never has; the new subtest builds
both fields the way the resolver does.

Co-Authored-By: Claude Opus 5 <[email protected]>
@pedronauck
pedronauck marked this pull request as ready for review August 26, 2026 19:04
@greptile-apps

greptile-apps Bot commented Aug 26, 2026

Copy link
Copy Markdown

Too many files changed for review (450 files, 100 file limit).

Bypass the limit by tagging @greptile-apps to review.

<Button
data-testid={`${testId}-use-inherited`}
disabled={model.inheritPendingKey !== null}
onClick={() => model.useInherited(posture.key)}

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.

React Doctor · react-hooks-js/hooks (error)

This component misses React Compiler's automatic memoization & re-renders more than it should: Hooks must be called at the top level in the body of a function component or custom hook, and may not be called within function expressions. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning). Rewrite the flagged code so the compiler can optimize it.

Fix → Cannot call hook within a function expression.

Docs

@pedronauck
pedronauck merged commit fe19142 into main Aug 26, 2026
39 of 40 checks passed
@pedronauck
pedronauck deleted the skills-source branch August 26, 2026 19:16
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.

1 participant