fix: writers emit tags as JSON array frontmatter (skill/command/subagent)#202
Merged
tylergraydev merged 1 commit intoApr 22, 2026
Conversation
…ent) Mirrors the round-trip bug tylergraydev#200 caught for rule_writer: the DB reader for skills, commands, and sub-agents deserialises the `tags` column via `serde_json::from_str` (see `db/schema.rs:1727`, `:1860`, `:2009`), but the three corresponding writers silently dropped the `tags` field from frontmatter entirely. No live bug today — no scanner re-ingests these primitives — but once scanners do (and given the asymmetry tylergraydev#200 closed, that direction is likely), disk round-trip would either lose tags or, if someone shipped a comma-joined stopgap, silently corrupt them. Fixes: - skill_writer::generate_skill_markdown emits `tags: <json>` when non-empty - command_writer::generate_command_markdown emits `tags: <json>` when non-empty - subagent_writer::generate_subagent_markdown emits `tags: <json>` when non-empty Each writer gains two tests: one pinning the JSON-array shape, one pinning the empty-vec skip path. Full `cargo test --lib` passes. Not touched: `paths`, `allowed_tools`, `tools`, `skills`, `disallowed_tools` in the same writers still use comma-joined form. They have the same latent shape but are out of scope for this PR (would expand the diff; can land separately once their scanners exist and decide on a canonical form).
5 tasks
tylergraydev
pushed a commit
that referenced
this pull request
May 4, 2026
User-facing additions: - Model picker now uses Claude Code aliases (opus/sonnet/haiku/opusplan/best) with a 1M context toggle and a free-form "Other (custom model ID)" field for Bedrock ARNs / Vertex / Foundry IDs (#213). - Rules dropped into ~/.claude/rules/ or {project}/.claude/rules/ now show up in the UI via new global/project scanners (#200). Fixes: - Sync Config no longer wipes externally-managed configs (.mcp.json, claude.json, OpenCode/Copilot/Cursor/Gemini/Codex) — extends the #191 guard to all 7 writers and imports .mcp.json on project add (#204). - Skill/command/sub-agent writers emit `tags` as JSON arrays so they round-trip through the DB reader (#202). - PR builds from forks/Dependabot no longer fail on missing TAURI_SIGNING_PRIVATE_KEY (#203). - delete_rule_inner returns real DB errors instead of swallowing them as "row absent" (follow-up to #200). Internal: - Cargo clippy from 134 warnings to 0; CI now enforces -D warnings on --lib --tests (#205). All 1565 frontend tests and 2021 Rust tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #200. Closes the same round-trip failure class that PR caught for
rule_writer, applied to the three other flat-.mdwriters.The DB readers for skills, commands, and sub-agents deserialise the
tagscolumn viaserde_json::from_str— seedb/schema.rs:1727,:1860,:2009. The three matching writers silently droppedtagsfrom frontmatter entirely. No live corruption today because no scanner re-ingests these primitives — but given #200 closed the "every primitive has a disk scanner except rules" asymmetry, it's reasonable to assume scanners for skills/commands/agents will follow. At that point, disk round-trip would either lose tags or (if anyone ships a comma-joined stopgap) silently corrupt them the same way rule_writer did pre-#200.Changes
src-tauri/src/services/skill_writer.rsgenerate_skill_markdownemitstags: <json-array>when non-emptysrc-tauri/src/services/command_writer.rsgenerate_command_markdownemitstags: <json-array>when non-emptysrc-tauri/src/services/subagent_writer.rsgenerate_subagent_markdownemitstags: <json-array>when non-emptyEach writer gains two tests: one pins the JSON-array emission shape, one pins the empty-vec skip path.
No schema change, no new dependency, no public-API change.
Test plan
cargo fmt --checkpassescargo test --lib— full suite passes locally, 6 new tests addedcargo test --lib writer— 299/299 writer tests passNot in scope (intentionally)
paths,allowed_tools,tools,skills,disallowed_toolsin these same writers still use comma-joined form. Same latent round-trip shape, but expanding this PR would:Separate PRs when their scanners land.
Relation to #200
This PR branches from
main(not from the #200 branch) — zero file overlap with #200's diff. Safe to review and merge independently in either order.