Skip to content

feat(config): add disabled_skills denylist for shared skill directories - #1983

Open
zicochaos wants to merge 4 commits into
MoonshotAI:mainfrom
zicochaos:feat/disabled-skills
Open

feat(config): add disabled_skills denylist for shared skill directories#1983
zicochaos wants to merge 4 commits into
MoonshotAI:mainfrom
zicochaos:feat/disabled-skills

Conversation

@zicochaos

Copy link
Copy Markdown

Related Issue

Resolve #1982

Problem

See linked issue. Shared skill directories (for example ~/.agents/skills/) often contain skills that should stay on disk for other tools but must not appear in Kimi's model listing, Skill tool, or slash menu. Existing levers are incomplete:

  • disableModelInvocation: true only blocks automatic model invocation
  • permission deny on Skill(...) can still leave the skill visible in listings

What changed

  • Add top-level disabled_skills in config.toml (case-insensitive name denylist, default [])
  • Apply the denylist in agent-core v1 and v2 skill registries / Skill tool activation
  • Add wire error code skill.disabled and config REST/protocol fields for the new setting
  • Document limits and pairing with Bash permission deny rules (EN + ZH)
  • Changeset (minor for @moonshot-ai/kimi-code)

Matching skills are fully hidden from Kimi surfaces while files remain on disk. /reload or a new session applies config changes. This only covers the Skill surface; shell reimplementation still needs permission deny rules when required.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: af63f9a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df3ca14c9c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
if (this.skillCatalog.catalog.isSkillDisabled(input.name)) {
throw new Error2(
ErrorCodes.SKILL_DISABLED,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Map disabled skill activation to a client error

When a disabled skill is activated through POST /sessions/{id}/skills/{name}:activate, this new ErrorCodes.SKILL_DISABLED path reaches packages/kap-server/src/routes/skills.ts's sendMappedError, which only handles SKILL_NOT_FOUND, SKILL_NAME_EMPTY, and SKILL_TYPE_UNSUPPORTED; the error is then rethrown to the global handler as 50001. A direct REST call or stale slash-menu entry for a disabled skill should return a deterministic client error instead of an internal error, so add this code to the route/error-code mapping.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Disabled activation now maps to the public non-activatable skill error (40912) instead of falling through to the internal error handler. The refreshed branch covers both the legacy service path and the kap-server route with regression tests.

Comment on lines +132 to +134
const disabledSkills =
this.config.get<DisabledSkillsConfig>(DISABLED_SKILLS_SECTION) ?? [];
const m = new InMemorySkillCatalog({ disabledSkills });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply disabled_skills to workspace skill listings

This wires disabled_skills into the session-scoped catalog, but the no-session workspace listing still composes its own catalog in packages/kap-server/src/routes/skills.ts with new InMemorySkillCatalog() and returns catalog.listSkills(). apps/kimi-web uses GET /workspaces/{id}/skills to pre-warm the onboarding composer's slash menu before a session exists, so disabled skills still appear there until the first session is created; pass the same config into that workspace catalog as well.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Session-less workspace skill listings now build the catalog with the configured disabled_skills denylist, matching the session-scoped catalog. The refreshed branch includes kap-server regression coverage for workspace listing and activation behavior.

@zicochaos
zicochaos force-pushed the feat/disabled-skills branch from d8e6864 to d409665 Compare July 22, 2026 20:11
@zicochaos

Copy link
Copy Markdown
Author

Rebuilt the branch on the current main and resolved the previous review findings. The update also keeps plugin session-start guidance, active-session skill listings, kap-server event schemas, and loaded web skill menus in sync when disabled_skills changes at runtime.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d409665b40

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

getSkillRoots(): readonly string[];
getSkippedByPolicy(): readonly SkippedSkill[];
getModelSkillListing(): string;
/** True when the skill name is listed in config `disabled_skills`. */

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep v2 comments in file headers only

In packages/agent-core-v2, the local guide only allows comments in the top-of-file module header, not beside interface members or functions. These newly added inline JSDoc comments in types.ts (and the matching option comment in registry.ts) put explanatory prose next to declarations, so they should be removed or folded into the module header to keep the v2 comment convention consistent.

AGENTS.md reference: packages/agent-core-v2/AGENTS.md:L11-L13

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The inline JSDoc comments were removed to preserve the agent-core-v2 header-only comment convention. The branch was also rebuilt on the current upstream main and its generated config manifest is up to date.

@zicochaos
zicochaos force-pushed the feat/disabled-skills branch from d409665 to 660af40 Compare July 25, 2026 02:08
@zicochaos

Copy link
Copy Markdown
Author

Rebuilt this PR on the current main after the 0.29.1 release. The update also closes runtime catalog-refresh races, keeps web skill caches synchronized after config changes, maps disabled activation consistently across REST/debug RPC, and regenerates the v2 config manifest.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 660af401e6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


if (event.type === 'configChanged') {
rawState.defaultModel = event.config.defaultModel ?? null;
void modelProvider.refreshLoadedSkills();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wait for catalog reload before refreshing cached skills

When a live v2 session has cached skills and a config patch changes extra_skill_dirs or merge_all_available_skills, this refresh can read and permanently cache the old catalog. In SessionSkillCatalogService, the config-source listener starts reloadSource() without awaiting it, while GET /sessions/{id}/skills waits only for the initial catalog.ready; the config route publishes event.config.changed immediately after config.set(). A slow directory scan therefore lets this request finish before the new contribution is merged, and the later catalog onDidChange is not forwarded to the web, so no second refresh repairs the cache. Publish/handle a post-catalog-refresh signal or make the listing wait for outstanding source reloads.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. The session skill listing endpoint now waits for outstanding async catalog reloads (extra_skill_dirs, merge_all_available_skills) before returning, instead of only awaiting the initial catalog ready promise. Deferred tests cover both config-triggered reload paths, so the web refresh no longer caches a stale listing.

@zicochaos
zicochaos force-pushed the feat/disabled-skills branch from 660af40 to 95b77e4 Compare July 25, 2026 16:55
@zicochaos

Copy link
Copy Markdown
Author

Addressed the latest review finding: session skill listings now drain in-flight catalog reloads before responding, which removes the stale web cache race after config changes.

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

zicochaos added a commit to zicochaos/kimi-code that referenced this pull request Jul 29, 2026
…odel/agentfile (MoonshotAI#2232)

Syncs 30 upstream commits. Upstream MoonshotAI#2232 ported custom agent files +
secondary-model binding to the v1 engine, covering the fork's exact-alias
subagent model selection (fb6d57c) and subagent model surfacing
(353a1c5) — so the fork's v1-side implementation is retired in favor of
upstream's:

- v1 collision files restored to upstream (agent/agent-swarm tools,
  subagent-host, tool registry, flags, docs); fork's v1
  subagent-model-directory.ts dropped as dead code
- TUI subagent model display deduplicated onto upstream's stats placement
  (agent-group, tool-call); fork's per-row model chip removed
- config schema/toml unions keep the fork's disabledSkills alongside
  upstream's extraAgentDirs
- footer quota readout ported onto upstream's slot-based footer
  (status_line); managed-usage rows adapted to upstream's structured
  ManagedUsageRow shape (window/name, no label)
- node-sdk getSessionWarnings passes pathClass for the fork's AGENTS.md
  include expansion
- state manifest regenerated

Fork-unique deltas kept: disabled_skills denylist (PR MoonshotAI#1983 upstream),
session-only default model, managed plan quota display, AGENTS.md include
expansion, v2-side subagent model selection, misc fixes.

Review follow-ups (PR #12):

- v1 subagent-host + node-sdk getSessionWarnings: thread
  agentsMdExpandIncludes through spawned-subagent and warning prompt
  contexts (with a subagent-host test covering include expansion)
- TUI: keep the status-derived subagent model when later events carry no
  model (subagent-event-handler, tool-call); AgentSwarm header shows a
  shared model only when all reported members agree (setMemberModel)
- kap-server subagentRosterTracker learns the model from
  agent.status.updated; kimi-web agentEventProjector projects it onto the
  task
- lint: drop useless spread in skillCatalogService; FORK.md + config docs
  note the v1 exact-alias retirement (v2-only)
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.

feat: allow hiding skills by name via config (disabled_skills)

1 participant