feat(achievements): Achievements Upgrades — filtering, CLI, export, curator dry-run - #18151
Closed
nosleepcassette wants to merge 2 commits into
Closed
feat(achievements): Achievements Upgrades — filtering, CLI, export, curator dry-run#18151nosleepcassette wants to merge 2 commits into
nosleepcassette wants to merge 2 commits into
Conversation
Four capability gaps addressed: 1. Filtering by completion state and evidence ordering 2. TUI and CLI interface (hermes achievements subcommand + /achievements slash command) 3. Achievement export (JSON/markdown/SVG) and agent communication 4. Dry-run mode for hermes curator Includes full implementation specs with code, file locations, test plans, and phased delivery order.
6-commit implementation plan with exact file locations, code patterns, dependency order, and verification steps. Covers backend filtering, export formatters, CLI/slash-command wiring, dashboard filter bar, curator dry-run, and integration testing.
Contributor
|
Closing — converting this spec-as-PR into a tracking issue since there's no runtime change to merge here. The four threads (achievements filtering, CLI + TUI, export formats, curator --dry-run) are now in #18472 where they can be discussed, picked up individually, and referenced by implementation PRs. Thanks @nosleepcassette — the spec is thorough and stays intact in this PR as the source document. |
1 task
1 task
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.
Achievements Upgrades
Summary
The achievements plugin currently lives entirely inside the web dashboard. There is no way to query, filter, sort, or export achievements from the CLI or from within a Hermes agent session. Completed achievements vanish from the default view, evidence is recorded but never surfaced meaningfully, and
hermes curatorhas no dry-run mode for safely previewing plugin operations before they mutate state. This PR addresses four capability gaps.1. Filtering by Completion State & Evidence Ordering
Problem
The
/achievementsendpoint returns every achievement in a flat list. The dashboard JS renders all states (unlocked, discovered, secret) in one stream with no server-side filtering or ordering. Thestate.jsonfile records per-achievementunlocked_attimestamps andevidenceblobs, but:?state=unlocked)/recent-unlocksendpoint is the only filtering path, and it only does reverse-chronological top-20Proposed Changes
Backend (
plugin_api.py)Add query parameters to
GET /achievements:stateunlocked,discovered,secret,allallcategoryDebugging Chaossort_byname,tier,progress,evidence,unlocked_atnameorderasc,descasc(desc forevidenceandunlocked_at)limitEvidence depth metric:
For tiered achievements, evidence depth = the raw
progressvalue (the underlying counter). For multi-condition achievements, evidence depth = the sum of per-requirement fulfillment percentages. This gives a meaningful "how much of this achievement's lifecycle have you traversed" number that makes sorting by evidence useful — you see your deepest commitments first.Dashboard frontend (
dist/index.js)Add a filter bar above the achievement grid:
achievementsresponse)Implementation Spec
Step 1: Refactor
/achievementshandler to accept query paramsFile:
plugins/hermes-achievements/dashboard/plugin_api.pyCurrent signature (line ~991):
New signature:
Note: FastAPI
Query()with regex validation keeps the param surface safe. If the dashboard is running without FastAPI (theAPIRouterstub at lines 16-23), the stub's.get()decorator just swallows the params — no breakage.Step 2: Extract filtering logic into a pure function
Add to
plugin_api.pyafterdisplay_achievement():Step 3: Wire into the endpoint
Replace the current
/achievementshandler body:Step 4: Add filter bar to dashboard frontend
File:
plugins/hermes-achievements/dashboard/dist/index.jsThe current
AchievementsPagecomponent fetches from/api/plugins/hermes-achievements/achievementswith no params and renders the full list. Patch:api():Step 5: Add tests
File:
plugins/hermes-achievements/tests/test_achievement_engine.py2. TUI & Command-Line Interface
Problem
The achievements plugin is currently web-dashboard-only. There is no CLI access. Users who live in the terminal (the core Hermes demographic) cannot check their badges, see progress toward an achievement, or review what sessions contributed evidence — without opening a browser. The plugin does not register any slash commands and has no
hermes achievementssubcommand.Proposed Changes
New CLI subcommand:
hermes achievementsNew slash command:
/achievementswith aliases/ach,/badgesTUI panel in the Ink TUI with category-grouped card view, keyboard navigation, and evidence drill-down.
Implementation Spec
Step 1: Create
hermes_cli/achievements_cmd.pyThis is the command handler for both
hermes achievements(CLI) and/achievements(slash command). It imports the engine directly — no HTTP needed.Step 2: Register the slash command
File:
hermes_cli/commands.pyAdd to
COMMAND_REGISTRY:Step 3: Register the
hermes achievementssubcommandFile:
cli.py(or whereverhermestop-level subcommands are dispatched — checkhermes_cli/for the argparse/click/fire wiring)Add a subcommand entry:
Step 4: TUI panel
File:
ui-tui/src/components/AchievementsPanel.tsx(new)This is the biggest piece and the one maps expressed interest in helping build. Scope TBD — the Ink TUI already has a tab system and a JSON-RPC client to the dashboard backend. The panel can:
/api/plugins/hermes-achievements/achievementson mountThis is a separate commit from the CLI work. The CLI and slash command ship first; the TUI panel follows.
3. Achievement Export & Agent Communication
Problem
Achievements are trapped in
state.jsonand the dashboard. There is no way to:Proposed Changes
Export endpoint and CLI command:
Formats:
jsonmarkdownsvgAgent communication: Compact
/achievements/summaryendpoint +agent_summary.jsoncontext file.Implementation Spec
Step 1: Add export formatters to
plugin_api.pyStep 2: Add
/exportendpointNote: need
from fastapi.responses import PlainTextResponse, JSONResponseat the top of the file (or stub them in the no-FastAPI fallback).Step 3: Add
/achievements/summaryendpoint for agent communicationStep 4: Write
agent_summary.jsonon rescanAdd to
_run_scan_and_update_cache(), after_SNAPSHOT_CACHEis set:And the helper:
Step 5: Create
hermes_cli/achievements_export.pyCLI handler for the
exportsubcommand:Step 6: Add export tests
4. Dry-Run Mode for
hermes curatorProblem
hermes curatormanages plugin lifecycle — install, update, enable, disable, remove. It currently has no dry-run mode. Any curator operation that modifies plugin state (updating an achievement catalog, resetting unlock state, toggling a plugin) takes effect immediately. For the achievements plugin specifically, acurator updatecould change achievement definitions (new badges, renamed IDs, shifted thresholds), which silently mutates unlock state. A bad update could reset progress or orphan unlocks.More broadly, every Hermes plugin that
curatormanages has the same risk: you can't preview what a curator operation will do before it does it. There is no--dry-runflag, no diff output, no "here's what would change" step.Proposed Changes
Add
--dry-runflag tohermes curator:When
--dry-runis passed, the curator precomputes the operation without executing, prints a structured preview, and exits without modifying state.Implementation Spec
Step 1: Add
--dry-runargument to curator parserFile:
hermes_cli/plugins_cmd.pyFind the argparse/click argument definitions for the curator subcommands. Add a
--dry-runflag to each mutating subcommand (install, update, enable, disable, remove):Step 2: Implement dry-run path for file operations
The core idea: every curator operation boils down to a sequence of file writes, config edits, and state transitions. A dry-run computes the same sequence but intercepts each mutation, records it, and skips the actual write.
Add a
DryRunRecorderclass:Step 3: Wire dry-run into each curator subcommand
The pattern is the same for each: if
--dry-runis set, create aDryRunRecorder, pass it through the operation logic instead of actually writing, then print the report and exit.Sketch for
curator update:Same pattern for install, enable, disable, remove.
Step 4: Plugin
dry_run_preview()hookPlugins can optionally define a
dry_run_preview(proposed_version, current_state)function in theirplugin_api.py:For the achievements plugin, implement
dry_run_preview():Note: A full implementation would also diff the proposed
ACHIEVEMENTSlist against the current one (new IDs, removed IDs, threshold changes). That requires downloading the proposed version'splugin_api.pyand parsing itsACHIEVEMENTSlist. This can be done as a follow-up — the initial implementation reports what it can from current state.Step 5: Exit codes
Step 6: Add dry-run tests
Implementation Order
hermes achievementssubcommand + TUI panel) — largest surface area, depends on 1 and 2Each phase is a separate commit with its own tests. The TUI panel is a separate PR that depends on phases 1-3 landing first.
Files Changed
plugins/hermes-achievements/dashboard/plugin_api.pyfilter_and_sort_achievements(), query params on/achievements, add/exportendpoint, add/achievements/summaryendpoint, add_build_agent_summary(), addexport_json/markdown/svg(), adddry_run_preview()hookplugins/hermes-achievements/dashboard/manifest.json0.4.0plugins/hermes-achievements/tests/test_achievement_engine.pyhermes_cli/commands.py/achievementsslash commandhermes_cli/achievements_cmd.pyhermes achievementssubcommand handler + Rich outputhermes_cli/achievements_export.pyhermes_cli/plugins_cmd.py--dry-runflag +DryRunRecorderto curator subcommandsui-tui/src/components/AchievementsPanel.tsxNon-Goals
ACHIEVEMENTSlist inplugin_api.py; a proper authoring UI is a separate PR