feat: show/copy + recommendations menu + stripped-env robustness — PR2#17
Merged
Conversation
Steg A of the recommended.json consumer's show/copy layer, on top of the read-only PR1 base. Adds the two contract actions the producer permits: - recommendations-template.sh <id> — print a pattern's command template (show) - recommendations-copy.sh <id> — copy that template to the clipboard (copy) Grounded in the producer's actual contract: allowed_actions is a FILE-WIDE field (['show','copy']), so action gating is one contract check (assert_action_allowed), not a per-pattern lookup — there is no per-pattern action list and no per-pattern reason field. The per-pattern guard stays visibility (risk_class), already enforced in PR1. Templates are shown/copied verbatim (placeholders unexpanded) and never executed: no schema.sh wrapper layer (parse.sh already holds the keys), no eval/exec/open/route — the only write is pbcopy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Steg B of the recommended.json consumer: a dedicated TUI menu, standalone and separate from mq-obsidian-menu.sh (vault navigation) by design. Wires the existing read-only flows — list, detail, template (show), copy — behind one surface, plus doctor. select.sh enforces the boundary: every selection resolves against the default-visible set (the same 12 patterns recommendations-list.sh shows), whether picked by number or typed as a literal id. Hidden/mutating patterns are refused in the menu flow (assert_selected_pattern_is_visible) — reachable only via the standalone CLI by exact id, never executed. The menu uses the shared mq-ui surface when present and degrades to plain printf otherwise. No execute/ route/launch surface: the only write is pbcopy (via clipboard.sh). Not wired into mq-main-menu.sh yet — that entry point is its own commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the dedicated recommendations menu reachable from the main TUI. Minimal
wiring only:
- source recommendations-menu.sh in the launcher (mirrors the obsidian block)
- main menu panel: slot 10 in the empty cell beside '9. MQ Obsidian'
- numeric dispatch 10) and text aliases (recommendations|recommend|rec)
-> recommendations_menu_main
No number shifts, no other refactors. The menu stays separate from
mq-obsidian-menu.sh; this only adds the entry point.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mqlaunch.sh runs as a non-login shell and inherits the caller's PATH without path_helper, so a stripped launch env (GUI, non-login shell, nested launcher) left /usr/bin and /opt/homebrew/bin off PATH — and the recommendations menu's jq check failed with "jq not found on PATH". Append the standard system + Homebrew dirs once at launcher start; only what is missing is added, so an inherited PATH is never clobbered. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The launcher PATH bootstrap doesn't cover every launch context, and assert_recommended_json runs inside $(...) so any PATH repair there dies with the subshell while the downstream jq renders run in the main shell — so the menu still failed with "jq not found" in a real TTY. Add rec_ensure_jq/rec_require_jq in resolve.sh: locate jq by absolute path (/opt/homebrew/bin, /usr/local/bin, /usr/bin, /bin) when it's not on PATH, prepend its dir, and have each entry point (the five command wrappers and the menu) call rec_require_jq in its own main shell before any jq use. The error now prints the active PATH for diagnosis. Belt-and-suspenders over the launcher fix; the feature no longer depends on launch-env PATH. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… jq) The launcher is being started in a sanitized environment that strips both PATH and the locale. Two visible failures traced to this: 1. jq not found / 'recommended.json is not valid JSON' — the live process emptied PATH mid-session (command -v jq and wc both came up empty), wiping the earlier PATH-prepend before the jq call ran. Fix: resolve jq to an absolute path once (REC_JQ) and route every jq call site through "$REC_JQ" instead of a bare jq, so it needs no PATH at all. 2. Ragged panel borders — with no UTF-8 locale the C locale byte-mangles the multi-byte box glyphs (─│┌┐) and byte-counts padding, skewing top vs bottom fill. Fix: set a UTF-8 locale in the launcher bootstrap when none is active (never overriding an existing UTF-8 locale). Verified from a fully stripped env (env -i, no PATH/LANG): jq resolves, the consumer reads the file, and the panel renders with aligned verticals. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Same class of failure as jq: pbcopy exists (/usr/bin/pbcopy) but the copy ran in a launcher context whose PATH was stripped, so 'command -v pbcopy' and the bare pbcopy call failed. Resolve pbcopy to an absolute path once (REC_PBCOPY) and invoke it directly, immune to the launcher emptying PATH. Verified: with PATH empty, copy still lands the template on the clipboard via /usr/bin/pbcopy. Co-Authored-By: Claude Opus 4.8 <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.
Stacked on PR1 (#16). Adds the contract's two actions, a dedicated TUI menu, the main-menu entry, and the launcher-robustness fixes the live TTY smoke surfaced.
Steg A — show/copy
recommendations-template.sh <id>(show) andrecommendations-copy.sh <id>(copy → clipboard).actions.sh(file-wide action gating —allowed_actionsis a single contract field, not per-pattern),clipboard.sh.Steg B — menu
terminal/menus/recommendations-menu.sh— dedicated, separate frommq-obsidian-menu.sh. Flows: list / detail / template / copy / doctor.select.sh— visible-set-only selection; hidden/mutating patterns are not reachable from the menu (refused byassert_selected_pattern_is_visible).recommendationsaliases (no number shifts).Stripped-env robustness (from live TTY findings)
The launcher was starting in a sanitized environment missing PATH and locale:
REC_JQ/REC_PBCOPY) — immune to PATH being emptied mid-session.Verified from a fully stripped
env -i(no PATH/LANG): jq resolves, the file reads, the panel renders with aligned verticals, copy lands on the clipboard.🤖 Generated with Claude Code