diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf6fdb..8fce039 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ All notable changes to qmax-code. Versions follow [Semantic Versioning](https://semver.org/). +## [1.17.1] - 2026-06-04 + +### Added +- `/skills` command surfaces the QA skill catalog from inside qmax-code: lists all 12 skills with their short description and a per-backend ✓/· install marker (Claude Code + Codex). `/skills install` (re)materializes the catalog into both `~/.claude/skills` and `~/.codex/skills` on demand. Previously the skills were only visible inside the spawned CLI sessions, with no way to see or manage them from qmax-code. + ## [1.17.0] - 2026-06-04 ### Added diff --git a/internal/repl/repl.go b/internal/repl/repl.go index 9047a41..7876c55 100644 --- a/internal/repl/repl.go +++ b/internal/repl/repl.go @@ -315,6 +315,12 @@ func Run(ag *agent.Agent, cliAgent agent.CLIAgent, quietMode bool, version strin case input == "/config": printConfigInfo(ag.AppConfig, term) continue + case input == "/skills": + setup.PrintSkillsStatus(term) + continue + case input == "/skills install": + setup.InstallSkillsBoth(term) + continue case input == "/set": handleSetCommand(input, ag, term) startCloudSession() diff --git a/internal/setup/orch.go b/internal/setup/orch.go index 6579523..63042f4 100644 --- a/internal/setup/orch.go +++ b/internal/setup/orch.go @@ -179,6 +179,49 @@ func InstallSkillsReport(backend string, term *tui.Terminal) { term.PrintSystem(fmt.Sprintf("Installed %d qmax QA skills into %s", len(res.Written), res.Dir)) } +// InstallSkillsBoth materializes the catalog into both CLI backends and reports +// each. Used by the `/skills install` command. +func InstallSkillsBoth(term *tui.Terminal) { + InstallSkillsReport("cc", term) + InstallSkillsReport("codex", term) +} + +// PrintSkillsStatus lists the qmax QA skill catalog and shows, per skill, +// whether it is currently materialized into the Claude Code and Codex skills +// directories. Backs the `/skills` command so the catalog is visible from +// inside qmax-code, even though the skills themselves run in the CLI backends. +func PrintSkillsStatus(term *tui.Terminal) { + home, err := os.UserHomeDir() + if err != nil { + term.PrintError(fmt.Sprintf("Could not locate home dir: %v", err)) + return + } + ccDir, _ := skills.SkillsDir(skills.BackendCC, home) + cxDir, _ := skills.SkillsDir(skills.BackendCodex, home) + + catalog := skills.SortedCatalog() + term.PrintSystem(fmt.Sprintf("qmax QA skills (%d) — installed in: cc = ~/.claude/skills · codex = ~/.codex/skills", len(catalog))) + for _, sk := range catalog { + cc := installMark(filepath.Join(ccDir, sk.Name, "SKILL.md")) + cx := installMark(filepath.Join(cxDir, sk.Name, "SKILL.md")) + desc := sk.ShortDescription + if desc == "" { + desc = sk.Description + } + fmt.Printf(" cc:%s codex:%s %s%-22s%s %s\n", cc, cx, tui.ColorBold, sk.Name, tui.ColorReset, desc) + } + term.PrintSystem("Skills load inside Claude Code / Codex sessions — auto-invoked by description, or `$name` in Codex.") + term.PrintSystem("Run /skills install to (re)install them into both backends now.") +} + +// installMark returns a check or cross depending on whether path exists. +func installMark(path string) string { + if _, err := os.Stat(path); err == nil { + return tui.ColorGreen + "✓" + tui.ColorReset + } + return tui.ColorDim + "·" + tui.ColorReset +} + // IsOrchSetupDone returns true if the qmax MCP entry already exists in the // CLI's config file. Used to skip the setup banner on subsequent launches. func IsOrchInstalled(backend string) bool { diff --git a/internal/tui/input.go b/internal/tui/input.go index f4789a4..083d672 100644 --- a/internal/tui/input.go +++ b/internal/tui/input.go @@ -33,6 +33,7 @@ var slashMenuItems = []SlashMenuItem{ {"/status", "Auth + session info"}, {"/cost", "Token usage + cost"}, {"/config", "Show config"}, + {"/skills", "List qmax QA skills + install status"}, {"/sessions", "List saved sessions"}, {"/resume", "Resume a session"}, {"/save", "Save current session"}, diff --git a/main.go b/main.go index 40b78dc..3fe5034 100644 --- a/main.go +++ b/main.go @@ -19,7 +19,7 @@ import ( ) // Version is set at build time via -ldflags "-X main.Version=x.y.z" -var Version = "1.17.0" +var Version = "1.17.1" const Name = "qmax-code"