fix(cli): Correct /tools display alignment and truncation - #116
Closed
Bartok9 wants to merge 1 commit into
Closed
Conversation
Fixes NousResearch#37 Issues fixed: 1. Header was off by 1 space (25+22+30=77 vs 78-char box interior) Changed to 28+22+28=78 for proper centering 2. Tool descriptions could overflow the 80-char terminal width Added truncation to 48 chars with '...' suffix The display now renders correctly on standard 80-column terminals.
Contributor
Author
|
Closing in favor of #109 which provides a more comprehensive fix handling all slash commands and wide characters. Great work @antoaenono! |
jarvis-stark-ops
added a commit
to 1Team-Engineering/hermes-agent
that referenced
this pull request
Jun 16, 2026
* feat(mcp): scaffold hermes-tools-mcp stdio server with initialize NousResearch#109 Minimal stdio JSON-RPC server that responds to MCP 'initialize' with the expected protocol version + capabilities. Tools surface comes in follow-up commits. Env-bound to (profile, project) scope. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(mcp): tools/list returns filtered Hermes tool surface NousResearch#109 Filters the live Hermes tool registry to the v1 surface defined in spec §4.1. Includes special hermes_set_task tool for per-turn task context updates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(mcp): tools/call dispatches to Hermes tool registry NousResearch#109 hermes_set_task updates per-turn task context (task_id, workspace). All other tools/call requests filter through ALLOWED_TOOLS, then dispatch via registry.dispatch() which handles both sync and async tools. Denied tools (kanban_dispatch etc.) return isError=true. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(kanban): add task_sessions table for relay scope tracking NousResearch#113 Per spec §4.7 — tracks (profile, project) → tmux session, claude session_id, FIFO path, MCP config path, project root, scope cwd, task count, timestamps. Helpers: upsert_session, get_session, touch_session, mark_compacted, evict_session, list_idle_sessions. * feat(relay): project derivation + task header builder NousResearch#114 derive_project maps a kanban workspace to its 'project' key: - scratch workspaces -> 'scratch' - git workspaces -> basename of git root - else raises ProviderError (B11: no silent default) build_task_header prepends '[task_id=... workspace=...]' to each user prompt so claude knows the current task without an MCP roundtrip. * feat(provider): register claude-code-relay ProviderProfile NousResearch#112 Registers the provider via the existing bundled-plugin pattern under plugins/model-providers/claude-code-relay/__init__.py. api_mode= 'claude_code_relay' is a new tag for the transport defined in the next commit. auth_type='none' because the claude binary handles its own OAuth — the relay just shells out. * feat(transport): scope spawn + send turn helpers NousResearch#112 ScopeContext bundles (profile, project, workspace). ensure_scope either finds a live tmux or invokes relay-spawn-scope.sh (writing the MCP config first). send_turn prepends the task header and relays through relay-send.sh, returning the captured response. Also added monkeypatch for derive_project_root in spawn test since tmp_path is not a git repo. * feat(transport): OpenAI-compat ChatCompletion response shape NousResearch#112 chat_completion() returns the standard OpenAI ChatCompletion object. Only the latest user message is forwarded — prior conversation rides on claude's in-session memory. Usage fields left null; /compact hook in next task captures /usage and backfills. * feat(kanban): /compact between-task hook for relay scopes NousResearch#115 After a task with provider=claude-code-relay completes or blocks, send /compact to its (profile, project) scope. Per B10, failures are logged but never block the completion. Records last_compacted_at on task_sessions. Also: add tasks.provider column to SCHEMA_SQL + additive ALTER migration; set conn.row_factory=sqlite3.Row in init_db test-fixture shortcut so complete_task works correctly in :memory: tests. Spike 2 (2026-06-15) confirmed /compact returns 'Not enough messages to compact' on short sessions; that's handled cleanly via the timeout in relay-send.sh slash-command extension. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(relay): idle-eviction cron step NousResearch#116 evict_idle_scopes deletes task_sessions rows whose last_used_at is older than HERMES_RELAY_IDLE_EVICT_SECS (default 86400 = 24h), and tears down the tmux session via relay-kill-scope.sh. Wire into nightly-hermes-maintenance follows separately. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(relay): boot-check that Hermes Stop hook is installed NousResearch#109 B3: Stop hook is mandatory for the relay to detect turn-end via FIFO. Boot-check raises ProviderError with installer path if the hook is missing — fail loud instead of silently hanging 180s per turn. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(relay): validate ScopeContext.profile + project against B8 regex Per code review on PR #20 — the shell relay-spawn-scope.sh validates ^[a-zA-Z0-9_-]+$ but Python-side _write_mcp_config writes /tmp/hermes-mcp-{slug}.json BEFORE invoking the shell. Slugs containing / or .. would have allowed path traversal out of /tmp. Add same regex check in ScopeContext.__post_init__. Closes B8 (spec §3). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(relay): chmod 0o600 on /tmp MCP config files Defense-in-depth: prevent workspace paths in the MCP config from leaking to other users sharing /tmp. Per code review on PR #20. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(kanban): honor HERMES_RELAY_BIN in /compact hook for consistency Transport reads HERMES_RELAY_BIN; the kanban_db /compact hook should too. Per code review on PR #20. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(relay): preserve task_sessions row when relay-kill-scope.sh fails Per code review on PR #20 — previously evicted the DB row even on kill failure, orphaning the tmux session with no record to retry. Now check rc; only evict DB row on rc=0. Failed scopes get retried on next cron tick. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(relay): log WARNING when relay-send exits 4 (Stop-hook timeout) Per code review on PR #20 — exit 4 means partial response, but callers had no signal. Add a logger.warning so operators see the partial in logs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Jarvis <jarvis@Kaipos-Mac-mini.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Meraniya
pushed a commit
to Meraniya/hermes-agent
that referenced
this pull request
Aug 6, 2026
* ci: add diff-scoped gitleaks secret scanning This repo had no secret scanning of any kind — no gitleaks/trufflehog workflow, no pre-commit config — while shipping 1Password and Bitwarden credential-bootstrap paths. supply-chain-audit.yml covers attack-pattern indicators only (.pth files, base64+exec) and is pull_request-scoped. The scan is diff-scoped: it never rescans history, so pre-existing placeholder credentials in test fixtures don't fire on unrelated changes. gitleaks is pinned by version and tarball SHA256; checkout is SHA-pinned per the dependency pinning policy. Two things worth flagging: gitleaks' stock ruleset has no Anthropic rule at all — a well-formed sk-ant-api03 canary passes straight through the default config. For an agent framework whose primary job is calling Claude, that is the most likely credential to leak, so anthropic-api-key, anthropic-admin-key and openrouter-api-key are added explicitly. OpenRouter otherwise falls to the entropy-based generic-api-key, which misses a key appearing without a nearby keyword. No committed credentials exist. A full-tree scan surfaced 647 findings in tracked files; all were triaged and all are benign — ~534 in two vendored upstream unsloth reference docs, the rest published OAuth client IDs, gemini-cli's public desktop client secret, Discord and Mattermost IDs in docs examples, and test fixtures. Verification: allowlist tuning takes the tracked tree 647 -> 82, all 82 residual being unmarked placeholders in tests/ that a diff scan never reaches. A canary with seven well-formed provider credentials is caught 7/7. End-to-end against the real CI command: clean commit exits 0, canary commit exits 1. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012689txgT12g2hjRczcUZi8 * docs(system-log): retract the RELEASE_v0.15.0.md finding All 13 RELEASE_*.md files landed in one commit (3beff00) — they are upstream NousResearch release notes vendored into this fork, not documents authored here. This fork's 0.15.0 is a local CVE bump, not an upstream release, so there is no missing artifact and authoring one would fabricate an upstream release document. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012689txgT12g2hjRczcUZi8 --------- Co-authored-by: Claude <noreply@anthropic.com>
Meraniya
pushed a commit
to Meraniya/hermes-agent
that referenced
this pull request
Aug 6, 2026
…ousResearch#126) Clears the two follow-ups named in NousResearch#116. .pre-commit-config.yaml runs the same gitleaks against the staged diff, pinned to the upstream repo at a commit SHA per the Dependency Pinning Policy. Opt-in — nothing runs until a contributor runs `pre-commit install`. CI remains the enforcement boundary; this only moves the check to where the remedy is an amend rather than a history rewrite plus a credential rotation. ci-auto-healer.yml drops from */30 to hourly at :23. The workflow_run triggers already fire the moment a watched workflow completes, so the cron is only a backstop for missed completion events. At */30 it ran ~48x/day almost always to print "No failed runs found", which is what buried the real Tests/Lint history in the run list during the scan that prompted this work. Off-minute is deliberate: :00 is GitHub's most contended scheduler slot. Verified the hook rather than just linting it: staged canary of seven well-formed provider credentials exits 1 and reports all seven, including the custom Anthropic and OpenRouter rules — confirming it reads .gitleaks.toml and not the built-in default. Clean tree exits 0. Both edited workflows re-parsed; the pinned rev came from `git ls-remote --tags`, not from memory. Claude-Session: https://claude.ai/code/session_012689txgT12g2hjRczcUZi8 Co-authored-by: Claude <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
Fixes #37
Issues Fixed
1. Header alignment off by 1 space
The header line had incorrect padding:
2. Tool descriptions overflow terminal width
On 80-column terminals, long descriptions would get cut off. Added truncation:
*(6 chars)-(3 chars)Descriptions longer than 48 chars are now truncated with
...Before
After
Testing