localvault 1.12.2 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/localvault/cli.rb +111 -2
- data/lib/localvault/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aa374ffc862a0591ab2936ea836ea4f04e96d3d86acd3591fb1b57ed91ea1253
|
|
4
|
+
data.tar.gz: f8ac6c6bd7e329d395801741f1c9e61f121339d5f05d013623faa6e2f7d255e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3cfb2aaccbfb4c0fc8882d6115dc3ca7ab8802f060601f3083ec9d1c36f76b1688ea2649eea70edaaf18d463f87e35605311a7a5492094f1e22d70326771b1ae
|
|
7
|
+
data.tar.gz: 874a4be548a5f7498d9fa520be60485f762df2f4ebe2e4612816b16617bf072cb1c735f73375ace33638c73d309d0a86c294095ea1c777ccfc57a3b9666b1eca
|
data/lib/localvault/cli.rb
CHANGED
|
@@ -116,14 +116,14 @@ module LocalVault
|
|
|
116
116
|
# disappearing from help.
|
|
117
117
|
HELP_SECTIONS = [
|
|
118
118
|
["GETTING STARTED", %w[login config init demo]],
|
|
119
|
-
["SECRETS", %w[set get show groups list delete import env exec]],
|
|
119
|
+
["SECRETS", %w[set get show reveal groups list delete import env exec]],
|
|
120
120
|
["VAULT MANAGEMENT", %w[vaults switch rekey unlock lock reset rename copy]],
|
|
121
121
|
["SYNC (requires localvault login)", %w[sync]],
|
|
122
122
|
["TEAM SHARING (requires localvault login)", %w[dashboard verify add remove team]],
|
|
123
123
|
["KEYS (X25519 identity for vault sharing)", %w[keys identity]],
|
|
124
124
|
["AI / MCP", %w[install-mcp mcp guard]],
|
|
125
125
|
["LEGACY SHARING (pre-v1.2 direct share, still works)", %w[keygen share receive revoke]],
|
|
126
|
-
["OTHER", %w[logout version doctor help]]
|
|
126
|
+
["OTHER", %w[logout version doctor upgrade help]]
|
|
127
127
|
].freeze
|
|
128
128
|
|
|
129
129
|
# One row per plain command; registered subcommands (sync, team, keys,
|
|
@@ -526,6 +526,29 @@ module LocalVault
|
|
|
526
526
|
abort_with "Wrong passphrase for vault '#{vault_name}'"
|
|
527
527
|
end
|
|
528
528
|
|
|
529
|
+
desc "reveal [GROUP]", "Show secrets with values unmasked (same as `show --reveal`)"
|
|
530
|
+
long_desc <<~DESC
|
|
531
|
+
Show secrets with their values unmasked. Identical to `show --reveal`, and
|
|
532
|
+
it takes the same options — `reveal` is simply the verb most people reach
|
|
533
|
+
for. A bare argument is treated as the group to show.
|
|
534
|
+
|
|
535
|
+
\x05 localvault reveal # every secret, unmasked
|
|
536
|
+
\x05 localvault reveal CLOUDFLARE # one group
|
|
537
|
+
\x05 localvault reveal --group CLOUDFLARE # the same thing
|
|
538
|
+
\x05 localvault reveal -p kuickr -v intellectaco
|
|
539
|
+
|
|
540
|
+
Plaintext output is still gated: it refuses to print values when stdout is
|
|
541
|
+
not a terminal, so a redirect or a pipe can't quietly capture secrets.
|
|
542
|
+
DESC
|
|
543
|
+
method_option :group, aliases: "-g", type: :string, lazy_default: GROUP_ALL_SENTINEL, desc: "Show all groups or one group by name"
|
|
544
|
+
method_option :project, aliases: "-p", type: :string, desc: "Show only this project group"
|
|
545
|
+
def reveal(group = nil)
|
|
546
|
+
merged = options.merge("reveal" => true)
|
|
547
|
+
merged["group"] = group if group && merged["project"].nil?
|
|
548
|
+
self.options = merged
|
|
549
|
+
show
|
|
550
|
+
end
|
|
551
|
+
|
|
529
552
|
desc "show", "Display secrets in a formatted table (masked by default)"
|
|
530
553
|
long_desc <<~DESC
|
|
531
554
|
Show secrets in the current vault. Values are masked by default.
|
|
@@ -1626,6 +1649,60 @@ module LocalVault
|
|
|
1626
1649
|
end
|
|
1627
1650
|
end
|
|
1628
1651
|
|
|
1652
|
+
desc "upgrade", "Upgrade localvault using whichever method installed it"
|
|
1653
|
+
long_desc <<~DESC
|
|
1654
|
+
Detect how this copy of localvault was installed and run the matching
|
|
1655
|
+
upgrade — Homebrew, RubyGems, or the install script.
|
|
1656
|
+
|
|
1657
|
+
\x05 localvault upgrade # detect and upgrade
|
|
1658
|
+
\x05 localvault upgrade --check # show what would run, change nothing
|
|
1659
|
+
|
|
1660
|
+
If more than one localvault is on PATH, an old copy can shadow the new one
|
|
1661
|
+
and the upgrade looks like it did nothing. This refuses to guess in that
|
|
1662
|
+
case and points you at `localvault doctor`.
|
|
1663
|
+
DESC
|
|
1664
|
+
method_option :check, type: :boolean, default: false, desc: "Print the upgrade command without running it"
|
|
1665
|
+
def upgrade
|
|
1666
|
+
paths = localvault_paths
|
|
1667
|
+
if paths.length > 1
|
|
1668
|
+
$stderr.puts "Error: multiple localvault executables are on PATH:"
|
|
1669
|
+
paths.each_with_index { |path, index| $stderr.puts " #{index + 1}. #{path}" }
|
|
1670
|
+
$stderr.puts "\nUpgrading now would leave a stale copy shadowing the new one."
|
|
1671
|
+
$stderr.puts "Run `localvault doctor`, remove the copies you don't want, then retry."
|
|
1672
|
+
return CommandStatus.error
|
|
1673
|
+
end
|
|
1674
|
+
|
|
1675
|
+
method, command = upgrade_method_for(paths.first)
|
|
1676
|
+
if method == :unknown
|
|
1677
|
+
$stderr.puts "Error: cannot tell how localvault was installed#{" (#{paths.first})" if paths.first}."
|
|
1678
|
+
$stderr.puts "Upgrade with whichever you used:"
|
|
1679
|
+
$stderr.puts " brew upgrade inventlist/tap/localvault"
|
|
1680
|
+
$stderr.puts " gem update localvault"
|
|
1681
|
+
$stderr.puts " curl -sSL https://inventlist.com/tools/localvault/install.sh | sh"
|
|
1682
|
+
return CommandStatus.error
|
|
1683
|
+
end
|
|
1684
|
+
|
|
1685
|
+
$stdout.puts "Installed via #{method} (#{paths.first})"
|
|
1686
|
+
$stdout.puts "Current version: #{VERSION}"
|
|
1687
|
+
$stdout.puts "Command: #{command}"
|
|
1688
|
+
|
|
1689
|
+
if options[:check]
|
|
1690
|
+
$stdout.puts "\n--check: nothing was run."
|
|
1691
|
+
return CommandStatus.ok
|
|
1692
|
+
end
|
|
1693
|
+
|
|
1694
|
+
$stdout.puts
|
|
1695
|
+
unless system(command)
|
|
1696
|
+
$stderr.puts "\nError: upgrade command failed. Run it yourself to see the full output:"
|
|
1697
|
+
$stderr.puts " #{command}"
|
|
1698
|
+
return CommandStatus.error
|
|
1699
|
+
end
|
|
1700
|
+
|
|
1701
|
+
$stdout.puts
|
|
1702
|
+
$stdout.puts "Done. Verify with: localvault version"
|
|
1703
|
+
CommandStatus.ok
|
|
1704
|
+
end
|
|
1705
|
+
|
|
1629
1706
|
def self.exit_on_failure?
|
|
1630
1707
|
false
|
|
1631
1708
|
end
|
|
@@ -2146,6 +2223,38 @@ module LocalVault
|
|
|
2146
2223
|
path.start_with?("/opt/homebrew/bin/", "/usr/local/bin/")
|
|
2147
2224
|
end
|
|
2148
2225
|
|
|
2226
|
+
# Which installer put this executable here, and how to upgrade it.
|
|
2227
|
+
#
|
|
2228
|
+
# The path alone can't decide: Homebrew and install.sh both land in
|
|
2229
|
+
# /usr/local/bin. Both write a wrapper naming their gem prefix, so read
|
|
2230
|
+
# that instead — a Cellar path means brew, ~/.localvault/runtime means the
|
|
2231
|
+
# install script.
|
|
2232
|
+
UPGRADE_COMMANDS = {
|
|
2233
|
+
brew: "brew upgrade inventlist/tap/localvault",
|
|
2234
|
+
gem: "gem update localvault",
|
|
2235
|
+
script: "curl -sSL https://inventlist.com/tools/localvault/install.sh | sh"
|
|
2236
|
+
}.freeze
|
|
2237
|
+
|
|
2238
|
+
def upgrade_method_for(path)
|
|
2239
|
+
method = detect_install_method(path)
|
|
2240
|
+
[method, UPGRADE_COMMANDS[method]]
|
|
2241
|
+
end
|
|
2242
|
+
|
|
2243
|
+
def detect_install_method(path)
|
|
2244
|
+
return :unknown if path.nil?
|
|
2245
|
+
return :brew if File.symlink?(path) && File.readlink(path).include?("/Cellar/")
|
|
2246
|
+
|
|
2247
|
+
wrapper = File.read(path, 2048)
|
|
2248
|
+
return :brew if wrapper.include?("/Cellar/")
|
|
2249
|
+
return :script if wrapper.include?("/.localvault/runtime")
|
|
2250
|
+
return :gem if path.include?("/shims/") || path.include?("/gems/")
|
|
2251
|
+
|
|
2252
|
+
:unknown
|
|
2253
|
+
rescue SystemCallError, ArgumentError
|
|
2254
|
+
# Binary or unreadable: fall back to the one thing the path does tell us.
|
|
2255
|
+
path.include?("/shims/") || path.include?("/gems/") ? :gem : :unknown
|
|
2256
|
+
end
|
|
2257
|
+
|
|
2149
2258
|
def cursor_settings_path
|
|
2150
2259
|
File.expand_path("~/.cursor/mcp.json")
|
|
2151
2260
|
end
|
data/lib/localvault/version.rb
CHANGED