You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We’re migrating more agents from “prompt/command templates” toward “skills” (e.g. Codex). While doing this, I ran into a design tension that will likely become technical debt as more agents converge on skills.
Problem: hooks currently assume slash-command invocation
The extension hook system stores a command (e.g. speckit.plan) and HookExecutor.format_hook_message() renders it as a slash command:
Command: /{command}
To execute: /{command}
EXECUTE_COMMAND: {command}
That works for agents where invocation is /speckit.plan. But for skills-based agents the invocation syntax and the skill “name” can differ:
Kimi uses /skill:speckit.plan (dotted name, /skill: invocation)
So even if hooks are semantically “logical command IDs”, the UX/automation guidance becomes wrong as soon as the active agent isn’t slash-based.
Problem: skill name rules vs dotted names (Kimi)
The Agent Skills spec defines name as lowercase letters, numbers, and hyphens only (no dots), and it must match the directory name.
But Kimi’s current packaging/invocation convention uses dotted names (speckit.plan), which is incompatible with that spec. This means:
If we treat command as a “skill name”, dotted commands become problematic
If we treat command as a “logical ID”, then we need an agent-specific mapping layer
Observation: extensions are not “unrelated” to Codex
Extensions register commands into agent-specific directories at install time. For Codex, that means writing skill overrides into .agents/skills/<skill>/SKILL.md. This creates a direct dependency between extension command naming and the agent’s skill naming rules.
Hooks are separately registered into .specify/extensions.yml and then “shown” to the agent via formatted text. That formatting is currently slash-oriented, so it doesn’t adapt to Codex/Kimi skills invocation.
Proposal: split “command ID” from “agent invocation”
Treat extension/hook command as a stable logical command ID (recommend keep existing speckit.plan / speckit.tasks etc).
Add a mapping function to produce the invocation string based on active agent:
slash agents: /speckit.plan
Codex skills: $speckit-plan
Kimi skills: /skill:speckit.plan (or whatever Kimi requires)
Update hook message rendering to use that invocation string, not hard-coded /{command}.
Either:
Option A (minimal): keep hooks[].command (logical ID) and only change formatting per agent.
Option B (explicit): store command_id and compute/display invocation at runtime.
Open questions
Should the canonical identifier in manifests/hooks remain dotted (speckit.plan) as a logical ID, even if the “skill name” is hyphenated (speckit-plan) for standards compliance?
Should we move Kimi toward hyphen-only skill names for spec compliance, or treat Kimi as a deliberate exception and keep the mapping layer?
Where should “active agent” be sourced from for hook formatting (init options, detected directories, env var)?
Should hook output emit an agent-neutral token (e.g. EXECUTE_COMMAND) that downstream tooling maps, instead of embedding /... or $...?
Why this matters
As more agents converge on skills, anything that conflates:
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
We’re migrating more agents from “prompt/command templates” toward “skills” (e.g. Codex). While doing this, I ran into a design tension that will likely become technical debt as more agents converge on skills.
Problem: hooks currently assume slash-command invocation
The extension hook system stores a
command(e.g.speckit.plan) andHookExecutor.format_hook_message()renders it as a slash command:Command: /{command}To execute: /{command}EXECUTE_COMMAND: {command}That works for agents where invocation is
/speckit.plan. But for skills-based agents the invocation syntax and the skill “name” can differ:$speckit-plan(hyphenated skill name,$invocation)/skill:speckit.plan(dotted name,/skill:invocation)So even if hooks are semantically “logical command IDs”, the UX/automation guidance becomes wrong as soon as the active agent isn’t slash-based.
Problem: skill name rules vs dotted names (Kimi)
The Agent Skills spec defines
nameas lowercase letters, numbers, and hyphens only (no dots), and it must match the directory name.But Kimi’s current packaging/invocation convention uses dotted names (
speckit.plan), which is incompatible with that spec. This means:commandas a “skill name”, dotted commands become problematiccommandas a “logical ID”, then we need an agent-specific mapping layerObservation: extensions are not “unrelated” to Codex
Extensions register commands into agent-specific directories at install time. For Codex, that means writing skill overrides into
.agents/skills/<skill>/SKILL.md. This creates a direct dependency between extension command naming and the agent’s skill naming rules.Hooks are separately registered into
.specify/extensions.ymland then “shown” to the agent via formatted text. That formatting is currently slash-oriented, so it doesn’t adapt to Codex/Kimi skills invocation.Proposal: split “command ID” from “agent invocation”
commandas a stable logical command ID (recommend keep existingspeckit.plan/speckit.tasksetc)./speckit.plan$speckit-plan/skill:speckit.plan(or whatever Kimi requires)/{command}.Either:
hooks[].command(logical ID) and only change formatting per agent.command_idand compute/displayinvocationat runtime.Open questions
speckit.plan) as a logical ID, even if the “skill name” is hyphenated (speckit-plan) for standards compliance?EXECUTE_COMMAND) that downstream tooling maps, instead of embedding/...or$...?Why this matters
As more agents converge on skills, anything that conflates:
will become increasingly brittle.
Beta Was this translation helpful? Give feedback.
All reactions