DARK-24: preserve tag-store and CLI changes - #34
Draft
cooper (czxtm) wants to merge 4 commits into
Draft
Conversation
- KeyAction::CycleStore added to keymap.rs with default Ctrl+I binding - SearchView.selected_store field (Option<String>) filters results by store - cycle_store() cycles None → first → ... → last → None - store_color() in theme.rs: 10-color palette, deterministic per-slug hash - Non-default store secrets colored distinctly in draw_results - Header shows colored filter pill when store filter is active - InfoMode set to always All (both health pills visible); cycle removed - SwitchStore handler sets selected_store from picker selection - App.selected_store preserved across fresh_search() calls - Autocomplete widget removed (hm-s12/hm-p3n) - Footer label: ^i info → ^i store (hm-3id) - Codegen design doc: docs/CODEGEN_DESIGN.md (hm-fcb) - bump-version.sh script (hm-0a2) Closes hm-3id, hm-ebs, hm-s12, hm-p3n, hm-5t6, hm-cqk, hm-bw5, hm-y3v, hm-661, hm-d3k, hm-0a2, hm-fcb hm-qlh implementation blocked on design approval (HARD-GATE)
Preserves existing working-copy changes for review during DARK-20.
Co-authored-by: multica-agent <github@multica.ai>
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved completion, reference parsing, and TUI store-filter issues remain.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds reference parsing, tag-definition storage, file/stdin secret handling, fuzzy completion, and TUI store filtering.
Changes:
- Adds parser and tag-store foundations.
- Updates CLI input handling and completions.
- Updates TUI filtering, documentation, release tooling, and tests.
File summaries
| File | Summary |
|---|---|
tests/integration/cli_test.rs |
Tests file input and stdin paths |
scripts/bump-version.sh |
Updates release version workflow |
rust/src/tui/widgets/secret_ref_autocomplete.rs |
Removes obsolete autocomplete widget |
rust/src/tui/widgets/mod.rs |
Unregisters removed widget |
rust/src/tui/views/search.rs |
Implements store filtering |
rust/src/tui/theme.rs |
Adds store colors |
rust/src/tui/keymap.rs |
Updates key bindings and help |
rust/src/tui/app.rs |
Adds store-filter state handling |
rust/src/remote/tag_store.rs |
Adds tag-definition persistence |
rust/src/remote/mod.rs |
Exposes tag storage |
rust/src/reference.rs |
Adds reference-expression parsing |
rust/src/error.rs |
Adds tag-storage errors |
rust/src/cli/set.rs |
Adds file-backed secret input |
rust/src/cli/get.rs |
Adds stdin path handling |
rust/src/cli/completions.rs |
Adds fuzzy path completion |
README.md |
Documents CLI and TUI changes |
docs/KEY_PROVIDERS_DESIGN.md |
Adds provider design proposal |
docs/CODEGEN_DESIGN.md |
Documents parser and tag storage |
docs/adr/0002-hard-error-on-duplicate-env-keys-under-tag-model.md |
Documents duplicate-key behavior |
docs/adr/0001-keep-last-wins-collapse-in-file-generators.md |
Records generator behavior |
CONTEXT.md |
Updates domain terminology |
CHANGELOG.md |
Records new functionality |
.gitignore |
Ignores local direnv overrides |
.envrc |
Loads optional local environment |
.beads/dolt-fsqlite-ns-gate |
Adds Beads gate marker |
Review details
Suppressed comments (6)
docs/adr/0002-hard-error-on-duplicate-env-keys-under-tag-model.md:24
- This ADR is marked accepted and says every consumer must hard-error on duplicate Env Keys, but the unchanged
generate/codegenloops still warn and keep the last value (for example,rust/src/cli/codegen.rs:165-174). Since this PR explicitly leaves runtime/codegen behavior unchanged, the accepted decision makes the repository's documented behavior contradictory; implement it in the consumers or mark it proposed/future until that migration lands.
A resolved Tag whose members produce the same Env Key is a hard error in
every consumer — `exec`, `generate`, `codegen` (sops materialization and
typed stubs alike). No consumer collapses duplicates. The error names
rust/src/cli/completions.rs:316
- Applying
--fuzzyto every secret-path subcommand changes the documented completion contract:docs/ARCHITECTURE.mdcurrently specifies fuzzy subsequence matching only forexecand exact-prefix matching for the other commands. Update that contract if this broad change is intentional, or retain the per-subcommand distinction.
for sub in SECRET_PATH_SUBCOMMANDS {
out.push_str(&format!(
"complete -c himitsu -n \"__fish_seen_subcommand_from {sub}\" -f -a \"(himitsu __complete-paths --fuzzy 2>/dev/null)\"\n"
rust/src/cli/completions.rs:316
- These Fish directives are gated only by
__fish_seen_subcommand_from, so secret-path candidates are offered for every token inset/write(including the secret value) and for option values, not just the positional path. Add an argument-position/flag-aware condition or a subcommand-specific helper before attaching__complete-paths.
for sub in SECRET_PATH_SUBCOMMANDS {
out.push_str(&format!(
"complete -c himitsu -n \"__fish_seen_subcommand_from {sub}\" -f -a \"(himitsu __complete-paths --fuzzy 2>/dev/null)\"\n"
rust/src/tui/keymap.rs:714
CycleStoreis now bound to Ctrl+I andhelp_rowsadds a livecycle store filterentry, but the search help still appends a static^irow describing the old header-status cycle. The help overlay will show two contradictory descriptions for the same key; remove or update the static row.
cycle_store: vec![ctrl('i')],
rust/src/tui/views/search.rs:472
- The contract immediately above says cycling is a no-op when there is only one store, but this branch still changes
NonetoSome(stores.first())for a one-store corpus, showing a filter pill and requiring another Ctrl+I to clear it. Guard the one-store case if the documented behavior is intended.
if stores.is_empty() {
rust/src/tui/views/search.rs:234
- This initializes
selected_storefromdefault_store, butApp::newstarts its persisted filter asNoneandfresh_searchoverwrites this value. Consequently the initial view can show only the configured default store while returning/rebuilding the view shows all stores; the field documentation also saysNoneis the default all-store state. Make the initialization source and intended default consistent.
selected_store: default_store,
- Files reviewed: 23/26 changed files
- Comments generated: 7
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| }; | ||
| out.push_str(&format!( | ||
| "complete -c himitsu -n \"__fish_seen_subcommand_from {sub}\" -f -a \"(himitsu __complete-paths {fuzzy_flag}2>/dev/null)\"\n" | ||
| "complete -c himitsu -n \"__fish_seen_subcommand_from {sub}\" -f -a \"(himitsu __complete-paths --fuzzy 2>/dev/null)\"\n" |
Comment on lines
+369
to
+374
| if let Some(prefix) = raw.strip_suffix('/') { | ||
| return Ok(ReferenceExpr::PathPrefix(normalize_path(prefix)?)); | ||
| } | ||
| if let Some(prefix) = raw.strip_suffix("/*") { | ||
| return Ok(ReferenceExpr::PathPrefix(normalize_path(prefix)?)); | ||
| } |
| pending_chord: Vec::new(), | ||
| pending_chord_deadline: None, | ||
| chord_breadcrumb_active: false, | ||
| selected_store: None, |
Comment on lines
+465
to
+471
| let stores: Vec<String> = self | ||
| .candidates | ||
| .iter() | ||
| .map(|r| r.store.clone()) | ||
| .collect::<std::collections::BTreeSet<_>>() | ||
| .into_iter() | ||
| .collect(); |
| - **Selector** — a query over secrets: `tag:pci`, `prod/*`, `tag:A+tag:B` | ||
| - **Reference** — a string that identifies a secret: path, qualified ref (`github:org/repo/path`), or selector | ||
| - **Tag** — a named group of secrets; the only grouping entity (replaces the former Output/env/label concept). A Tag lives in a Store, exactly like a Secret. Its members are the secrets tagged with it plus what the Tag's own references resolve to, counted once. A Tag groups secrets, never other Tags — shared membership is co-tagging. Referenced bare (`web-prod`) or explicitly (`tag:web-prod`). | ||
| - **Reference** — a string that identifies secrets. Bare: a path (`prod/api-key`), a path prefix (`prod/`), or a tag name (`web-prod`; a path beats a tag on name collision). Forced: `tag:web-prod`, `path:prod/api-key`, `regex:<pattern>` (anchored match over paths), or a qualified cross-store ref (`github:org/repo#path`). |
| `quit`, `help`, `command_palette`, `new_secret`, `switch_store`, | ||
| `copy_selected`, `copy_ref_selected`, `codegen` (legacy aliases: `outputs`, `envs`), | ||
| `collapse_paths`, `expand_paths`, `toggle_autocomplete`, `refine_tag`, | ||
| `collapse_paths`, `expand_paths`, `refine_tag`, |
| ("enter".into(), "open selection".into()), | ||
| ("backspace".into(), "delete char".into()), | ||
| ("i".into(), "cycle header status (info)".into()), | ||
| ("^i".into(), "cycle header status (info)".into()), |
cooper (czxtm)
marked this pull request as draft
September 10, 2026 05:55
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.
Parked after Cooper narrowed DARK-20 to pre-existing workspace issue work. This repository discovery has an audit-created tracking issue and is outside the active merge recommendation; source and validation below are preserved records.
Adds reference-expression parsing and tag-definition storage foundations, fuzzy completion, stdin path handling, file-based secret input, and store-filter UI changes. The parser/storage APIs remain separate from runtime resolution; key-provider and codegen designs are proposals. Retains Cooper’s two existing commits and the working-copy changes published under DARK-24/DARK-20.
Readiness cleanup removes two Clippy failures without changing generated Bash or Zsh completion behavior. On macOS at
c833567,cargo fmt --all -- --check,cargo clippy --workspace --all-targets --locked --offline -- -D warnings, andcargo test --workspace --locked --offlinepass: 730 tests in each lib/bin target and 161 integration tests; existing ignored tests unchanged. CI is running for the pushed fix. Validation used isolated test stores; no live secret-store operations.