legionio 1.4.102 → 1.4.103

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d271552f43fd7cd244b7e22845d5f08b0a8adba77c159ae6054ab913f2cbea1
4
- data.tar.gz: 761a64ecc11ca421b45c8d618e8d2e7dc4dcf7d53c231b79e9bae805580d0ce5
3
+ metadata.gz: f036f54d059c1cdf1660a1ae08ed95b1fe97404d509123574508b9a6b36a1674
4
+ data.tar.gz: 616cacd65849dcdf73095f946df27c1afd9af68f9ee5f1b292ef53ee06f4554c
5
5
  SHA512:
6
- metadata.gz: 6fa6a1c07d50d1283608f175016ff4833f6518269bb5a5b5c9e0a5b8484bb5784918115648fd8ec64762a05676b3593f5c5fc27585ba5f6d1940b39bfc0466e7
7
- data.tar.gz: 03ab72c8a44c4c2a83146d343c8824bd9eaae5cd3cd4eb1bd6e31c843f9e2622e7e4dce306c19d34769e3e703ab6315cf469336c2a0515fcc7e604b0b7ab33fd
6
+ metadata.gz: 6681f51110762da3d76aa93b1e1ee2a92814c22e101842ef588f3a4d9492f585bdbf9bb4244df59c320c89d0dc992e17ba388b2ad56015a533fd7dec5411d378
7
+ data.tar.gz: ef6398f327e82cc91396d26fc855a6472eff22ee5f12e3ad225fbbbc06ee6df92912ef5c376dc9c0c838e0b6108bb3dbc7066f0372c820bb8e740d677fa70923
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Legion Changelog
2
2
 
3
+ ## [1.4.103] - 2026-03-21
4
+
5
+ ### Added
6
+ - `Legion::Team` module — team registry backed by settings (current, members, find, list)
7
+ - `Legion::Team::CostAttribution` — tags LLM request metadata with team and user context
8
+ - `legion team` CLI subcommand — list, show, current, set, create, add-member
9
+
3
10
  ## [1.4.102] - 2026-03-21
4
11
 
5
12
  ### Added
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Legion
6
+ module CLI
7
+ class Team < Thor
8
+ def self.exit_on_failure?
9
+ true
10
+ end
11
+
12
+ desc 'list', 'List all teams'
13
+ def list
14
+ require 'legion/settings'
15
+ require 'legion/team'
16
+ teams = Legion::Team.list
17
+ if teams.empty?
18
+ say 'No teams configured.', :yellow
19
+ return
20
+ end
21
+ say 'Teams', :green
22
+ say '-' * 20
23
+ teams.each { |t| say " #{t}" }
24
+ end
25
+
26
+ desc 'show TEAM', 'Show team details and members'
27
+ def show(name)
28
+ require 'legion/settings'
29
+ require 'legion/team'
30
+ team = Legion::Team.find(name)
31
+ if team.nil?
32
+ say "Team '#{name}' not found.", :red
33
+ return
34
+ end
35
+ say "Team: #{name}", :green
36
+ say '-' * 20
37
+ members = team[:members] || []
38
+ if members.empty?
39
+ say ' No members.'
40
+ else
41
+ members.each { |m| say " #{m}" }
42
+ end
43
+ end
44
+
45
+ desc 'current', 'Show the current active team'
46
+ def current
47
+ require 'legion/settings'
48
+ require 'legion/team'
49
+ say Legion::Team.current
50
+ end
51
+
52
+ desc 'set TEAM', 'Set the active team in settings'
53
+ def set(name)
54
+ require 'legion/settings'
55
+ require 'legion/team'
56
+ Legion::Settings.load unless Legion::Settings.instance_variable_get(:@loader)
57
+ Legion::Settings.loader.settings[:team] ||= {}
58
+ Legion::Settings.loader.settings[:team][:name] = name
59
+ say "Active team set to '#{name}'.", :green
60
+ end
61
+
62
+ desc 'create TEAM', 'Create a new team'
63
+ def create(name)
64
+ require 'legion/settings'
65
+ require 'legion/team'
66
+ Legion::Settings.load unless Legion::Settings.instance_variable_get(:@loader)
67
+ teams = Legion::Settings.loader.settings[:teams] || {}
68
+ if teams.key?(name.to_sym)
69
+ say "Team '#{name}' already exists.", :yellow
70
+ return
71
+ end
72
+ teams[name.to_sym] = { name: name, members: [] }
73
+ Legion::Settings.loader.settings[:teams] = teams
74
+ say "Team '#{name}' created.", :green
75
+ end
76
+
77
+ desc 'add-member TEAM USER', 'Add a member to a team'
78
+ map 'add-member' => :add_member
79
+ def add_member(team_name, user)
80
+ require 'legion/settings'
81
+ require 'legion/team'
82
+ Legion::Settings.load unless Legion::Settings.instance_variable_get(:@loader)
83
+ teams = Legion::Settings.loader.settings[:teams] || {}
84
+ sym = team_name.to_sym
85
+ unless teams.key?(sym)
86
+ say "Team '#{team_name}' not found.", :red
87
+ return
88
+ end
89
+ teams[sym][:members] ||= []
90
+ if teams[sym][:members].include?(user)
91
+ say "#{user} is already a member of '#{team_name}'.", :yellow
92
+ return
93
+ end
94
+ teams[sym][:members] << user
95
+ Legion::Settings.loader.settings[:teams] = teams
96
+ say "Added #{user} to team '#{team_name}'.", :green
97
+ end
98
+ end
99
+ end
100
+ end
data/lib/legion/cli.rb CHANGED
@@ -45,6 +45,7 @@ module Legion
45
45
  autoload :Image, 'legion/cli/image_command'
46
46
  autoload :Dataset, 'legion/cli/dataset_command'
47
47
  autoload :Cost, 'legion/cli/cost_command'
48
+ autoload :Team, 'legion/cli/team_command'
48
49
  autoload :Marketplace, 'legion/cli/marketplace_command'
49
50
  autoload :Notebook, 'legion/cli/notebook_command'
50
51
  autoload :Llm, 'legion/cli/llm_command'
@@ -250,6 +251,9 @@ module Legion
250
251
  desc 'cost', 'Cost visibility and reporting'
251
252
  subcommand 'cost', Legion::CLI::Cost
252
253
 
254
+ desc 'team SUBCOMMAND', 'Team and multi-user management'
255
+ subcommand 'team', Legion::CLI::Team
256
+
253
257
  desc 'marketplace', 'Extension marketplace (search, info, scan)'
254
258
  subcommand 'marketplace', Legion::CLI::Marketplace
255
259
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Legion
4
+ module Team
5
+ module CostAttribution
6
+ def self.tag(metadata = {})
7
+ metadata.merge(
8
+ team: Legion::Team.current,
9
+ user: Legion::Settings.dig(:team, :user) || ENV.fetch('USER', nil)
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'legion/team/cost_attribution'
4
+
5
+ module Legion
6
+ module Team
7
+ class << self
8
+ def current
9
+ Legion::Settings.dig(:team, :name) || 'default'
10
+ end
11
+
12
+ def members
13
+ Legion::Settings.dig(:team, :members) || []
14
+ end
15
+
16
+ def find(name)
17
+ teams = Legion::Settings[:teams] || {}
18
+ teams[name.to_sym]
19
+ end
20
+
21
+ def list
22
+ (Legion::Settings[:teams] || {}).keys.map(&:to_s)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Legion
4
- VERSION = '1.4.102'
4
+ VERSION = '1.4.103'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legionio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.102
4
+ version: 1.4.103
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -548,6 +548,7 @@ files:
548
548
  - lib/legion/cli/swarm_command.rb
549
549
  - lib/legion/cli/task.rb
550
550
  - lib/legion/cli/task_command.rb
551
+ - lib/legion/cli/team_command.rb
551
552
  - lib/legion/cli/telemetry_command.rb
552
553
  - lib/legion/cli/templates/core.json.erb
553
554
  - lib/legion/cli/theme.rb
@@ -618,6 +619,8 @@ files:
618
619
  - lib/legion/sandbox.rb
619
620
  - lib/legion/service.rb
620
621
  - lib/legion/supervision.rb
622
+ - lib/legion/team.rb
623
+ - lib/legion/team/cost_attribution.rb
621
624
  - lib/legion/telemetry.rb
622
625
  - lib/legion/telemetry/open_inference.rb
623
626
  - lib/legion/telemetry/safety_metrics.rb