feat: convention-based skill queue registration via frontmatter#98
feat: convention-based skill queue registration via frontmatter#98
Conversation
Each skills/*.md file now declares its queue-action, queue-args, and optional queue-args-defaults/queue-required-args fields so the convention-based registry can discover the mapping automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add src/skill-queue-registry.ts: lazy-loaded registry that scans skills/*.md frontmatter to build action→command mappings. Exports resolveSkillCommand(), hasRegisteredAction(), clearSkillQueueCache(). - Refactor resolveQueueRequestCommand() in src/mag.ts to three-tier dispatch: pre-hooks (briefing/adopt-sessions), auto-discovered skill commands via registry, programmatic-only actions (message/adapter- followup/complete-task) in a reduced switch. - Add src/skill-queue-registry.test.ts: 26 tests covering all 14 existing actions, required-arg null guard, defaults, and cache. Adding a new queueable skill now requires only the template file. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
f6cfb3f to
011d714
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f6cfb3fd11
ℹ️ 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".
| const skillCommand = resolveSkillCommand(action, request); | ||
| if (skillCommand !== null) { | ||
| return skillCommand; |
There was a problem hiding this comment.
Restore fallback dispatch for known queue skill actions
This now hard-depends on resolveSkillCommand() succeeding for every non-programmatic queue action, but buildRegistry() returns an empty map whenever skills/ is missing or unreadable, so actions like briefing, draft-proposal, and verify-completion fall through and get dropped as unknown. That is a regression from the previous hardcoded switch behavior and can happen in binary-only or partial installs where skills is not colocated with the executable. Please keep a fallback mapping (or explicit fallbacks for existing actions) so queue dispatch still works when registry loading fails.
Useful? React with 👍 / 👎.
|
|
||
| /** Parse YAML frontmatter block from a Markdown file, or return null. */ | ||
| function parseFrontmatter(content: string): Record<string, unknown> | null { | ||
| const match = content.match(/^---\n([\s\S]*?)\n---/); |
There was a problem hiding this comment.
Parse frontmatter with CRLF-compatible delimiters
The frontmatter regex only matches LF line endings, so any skill file saved with CRLF (for example with core.autocrlf or Windows editors) will fail frontmatter parsing and never register its queue-action. In that environment, those queue requests are treated as unregistered and are dropped. Using a \r?\n-tolerant pattern avoids this platform-dependent dispatch failure.
Useful? React with 👍 / 👎.
Suggest Refactor — task-b5a884c0 (coder retrospective)What I'd do differently next time1. Validate the registry at startup, not silently at first useThe current design builds the registry lazily on the first 2. Use a typed frontmatter schema for skill filesRight now 3. Co-locate the
|
Summary
queue-actionfrontmatter field to all 14 queueable skill templatessrc/skill-queue-registry.tsmodule scans frontmatter and builds action→command mapresolveQueueRequestCommand()to use registry with hardcoded fallbacks for special casesTest plan
bun run typecheckpassesbun testpassesGenerated with Claude Code