shapeup-cli 0.10.4 → 0.10.5

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: 0c09048590d2fb0edc18e5479d5d9a761c2d7360b165db1eb1de88887de2a1b6
4
- data.tar.gz: 4802cc019c1372cc91c8b1ea089f0a3b0af559e390a9cd54fadd85f1a293fde4
3
+ metadata.gz: a45ee37e8d065758ff406860f939921f4ddb7341bed82732cee1454ab2cde0c1
4
+ data.tar.gz: 9b8230e7e221798866fa6c1ca1fbe947f2aacef3a6ae03500a32cdfd494a08cd
5
5
  SHA512:
6
- metadata.gz: 5bb78243d2cf2cc5bb30bf303a6eded89088921f13901e8d128f54096701709aadd6c75b80bdf35aa55fc5c2e884720a527316f922eb16cf2b17b4a8959cf47c
7
- data.tar.gz: 632ab3fc5ecbcc4a753b79b92735509698ca9e04c8d823d6119616a12f30328d85142107594256f015db633631b590845ec80995ba0efaba6d5a213d16295bb0
6
+ metadata.gz: 03bb70e47f6b4322602c8e86d8e129ad153dc9e6f0596dd9fa54f6127f910a8fa428b51cd723c19389f4b2a31b698469afdc851c862a97390aa94f272af4bf63
7
+ data.tar.gz: 6eba12bf921de8b62efbda85d1d410ece152c11399872384ef54b9daae70adc64bc1ced1fcf8fb808cfb0e1343a2d506154d9db53ef6c6c39ed7a023c1fa4907
@@ -33,7 +33,9 @@ module ShapeupCli
33
33
  check_api_reachable,
34
34
  check_auth,
35
35
  check_org_access,
36
- check_claude_skill
36
+ check_claude_skills,
37
+ check_agent,
38
+ check_connector
37
39
  ]
38
40
 
39
41
  report(checks)
@@ -127,7 +129,7 @@ module ShapeupCli
127
129
  def check_auth
128
130
  return skip("auth", "no token to test") unless Config.token
129
131
 
130
- result = Output.extract_data(Client.new.call_tool("list_organisations"))
132
+ result = Output.extract_data(client.call_tool("list_organisations"))
131
133
  @organisations = result.is_a?(Hash) ? (result["organisations"] || []) : Array(result)
132
134
  pass "auth", "signed in, #{@organisations.length} organisation(s)"
133
135
  rescue Client::AuthError
@@ -149,15 +151,59 @@ module ShapeupCli
149
151
  end
150
152
  end
151
153
 
152
- def check_claude_skill
153
- installed = File.join(Dir.home, ".claude", "skills", "shapeup", "SKILL.md")
154
- return warn!("claude skill", "not installed", hint: "shapeup setup claude") unless File.exist?(installed)
154
+ def check_claude_skills
155
+ states = Setup::SKILL_NAMES.to_h do |name|
156
+ installed = File.join(Dir.home, ".claude", "skills", name, "SKILL.md")
157
+ current = File.exist?(installed) && File.read(installed) == File.read(File.join(Setup::SKILLS_DIR, name, "SKILL.md"))
158
+ [ name, File.exist?(installed) ? (current ? :current : :stale) : :missing ]
159
+ end
160
+
161
+ if states.values.all?(:current)
162
+ pass "claude skills", "#{states.keys.join(", ")} installed and current"
163
+ else
164
+ behind = states.reject { |_, state| state == :current }.map { |name, state| "#{name} #{state == :missing ? "not installed" : "stale"}" }
165
+ warn! "claude skills", behind.join(", "), hint: "shapeup setup claude"
166
+ end
167
+ end
168
+
169
+ def check_agent
170
+ return skip("agent", "auth not verified") unless @organisations && Config.organisation_id
171
+
172
+ mine = Output.extract_data(client.call_tool("list_my_agents", organisation: Config.organisation_id.to_s))
173
+ return pass("agent", "signed in as an agent") if mine["signed_in_as_agent"]
174
+
175
+ @agent = mine["agents"].first
176
+ return skip("agent", mine["can_add"] ? "you have no agent here" : "agents need a Pro organisation where you're a member") unless @agent
155
177
 
156
- if File.read(installed) == File.read(Setup::SKILL_SOURCE)
157
- pass "claude skill", "installed and current"
178
+ handle = @agent["name"]
179
+ profile = Config.profile(handle)
180
+ return warn!("agent", "@#{handle} isn't connected on this computer yet", hint: "/shapeup-connect in Claude Code") unless profile&.dig("token")
181
+
182
+ Client.new(host: profile["host"] || Config.host, token: profile["token"])
183
+ .call_tool("list_inbox", organisation: (profile["organisation_id"] || Config.organisation_id).to_s)
184
+ @connected_agent = handle
185
+ pass "agent", "@#{handle} signs in with profile '#{handle}'"
186
+ rescue Client::AuthError
187
+ fail! "agent", "@#{handle}'s saved token was rejected", hint: "/shapeup-connect in Claude Code"
188
+ rescue Client::ApiError => e
189
+ fail! "agent", e.message
190
+ end
191
+
192
+ def check_connector
193
+ return skip("connector", "no connected agent to listen for") unless @connected_agent
194
+
195
+ if connector_running_for?(@connected_agent)
196
+ pass "connector", "listening as @#{@connected_agent} on this computer"
158
197
  else
159
- warn! "claude skill", "installed but stale", hint: "shapeup setup claude"
198
+ warn! "connector", "not listening as @#{@connected_agent} on this computer", hint: "/shapeup-connect in Claude Code"
160
199
  end
200
+ rescue Errno::ENOENT
201
+ skip "connector", "can't check for running processes here"
202
+ end
203
+
204
+ def connector_running_for?(handle)
205
+ commands = IO.popen([ "pgrep", "-lf", "shapeup connect" ], err: File::NULL, &:readlines)
206
+ commands.any? { |command| command.match?(/--as @?#{Regexp.escape(handle)}\b/) || !command.include?("--as") }
161
207
  end
162
208
 
163
209
  def pass(name, message) = Check.new(name: name, status: :pass, message: message)
@@ -66,6 +66,10 @@ module ShapeupCli
66
66
  end
67
67
  end
68
68
 
69
+ def self.profile(name)
70
+ load_profiles_raw.dig("profiles", name)
71
+ end
72
+
69
73
  def self.current_profile
70
74
  data = load_profiles_raw
71
75
  name = ENV["SHAPEUP_PROFILE"] || data["default"]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ShapeupCli
4
- VERSION = "0.10.4"
4
+ VERSION = "0.10.5"
5
5
  end
@@ -134,7 +134,7 @@ Don't poll the inbox yourself. The connector does that.
134
134
 
135
135
  ## Handle a request, within seconds
136
136
 
137
- A `request` line carries `id`, `reason` (mentioned, assigned or watching), `issue`, `request`
137
+ A `request` line carries `id`, `reason` (mentioned, replied, assigned or watching), `issue`, `request`
138
138
  (the words that asked), `requester` and `reply_to`.
139
139
 
140
140
  1. **Acknowledge it.** When `request.comment_id` is set, react to it:
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shapeup-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.4
4
+ version: 0.10.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - ShapeUp