melaya 0.1.4 → 0.2.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.
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Melaya
4
+ # Templates API — create, manage, share, and assign pipeline templates.
5
+ #
6
+ # Templates bundle a pipeline definition into a reusable, shareable artifact.
7
+ # Visibility levels: private → team → community → assigned.
8
+ #
9
+ # Maps to:
10
+ # /api/v1/private/user-templates/* — CRUD + share + assignments
11
+ # /api/v1/private/templates/* — global/validated lists
12
+ #
13
+ # @example
14
+ # templates = melaya.templates.list
15
+ # t = melaya.templates.save(name: "My report", payload: { steps: [] })
16
+ # melaya.templates.share(t["id"], "team")
17
+ # melaya.templates.delete(t["id"])
18
+ class TemplatesAPI
19
+ def initialize(http)
20
+ @http = http
21
+ end
22
+
23
+ # GET /api/v1/private/user-templates
24
+ # List all templates visible to the caller (own + team + community + assigned).
25
+ def list
26
+ @http.get("/api/v1/private/user-templates")
27
+ end
28
+
29
+ # GET /api/v1/private/templates/global
30
+ # List all community-visibility (global) templates.
31
+ def list_global
32
+ @http.get("/api/v1/private/templates/global")
33
+ end
34
+
35
+ # GET /api/v1/private/templates/validated
36
+ # List IDs of all validated (platform-approved) templates.
37
+ def list_validated
38
+ @http.get("/api/v1/private/templates/validated")
39
+ end
40
+
41
+ # POST /api/v1/private/user-templates
42
+ # Create a new private user template.
43
+ # @param name [String]
44
+ # @param payload [Hash]
45
+ # @param description [String, nil]
46
+ # @param category [String, nil]
47
+ def save(name:, payload:, description: nil, category: nil)
48
+ body = compact(
49
+ "name" => name,
50
+ "payload" => payload,
51
+ "description" => description,
52
+ "category" => category
53
+ )
54
+ @http.post("/api/v1/private/user-templates", body)
55
+ end
56
+
57
+ # PATCH /api/v1/private/user-templates/:id
58
+ # Update name/description/category/payload of a private user template.
59
+ # @param template_id [String]
60
+ # @param body [Hash]
61
+ def update(template_id, body = {})
62
+ @http.patch("/api/v1/private/user-templates/#{enc(template_id)}", body)
63
+ end
64
+
65
+ # POST /api/v1/private/user-templates/:sourceId/duplicate
66
+ # Duplicate a readable template into the caller's private library.
67
+ # @param template_id [String] the source template to copy
68
+ # @param new_name [String, nil]
69
+ def duplicate(template_id, new_name: nil)
70
+ body = new_name ? { "newName" => new_name } : nil
71
+ @http.post("/api/v1/private/user-templates/#{enc(template_id)}/duplicate", body)
72
+ end
73
+
74
+ # DELETE /api/v1/private/user-templates/:id
75
+ # Delete (or soft-demote if shared) a template.
76
+ # @param template_id [String]
77
+ def delete(template_id)
78
+ @http.delete("/api/v1/private/user-templates/#{enc(template_id)}")
79
+ end
80
+
81
+ # PUT /api/v1/private/user-templates/:id/visibility
82
+ # Change the visibility of a template.
83
+ # @param template_id [String]
84
+ # @param visibility [String] "private", "team", "community", or "assigned"
85
+ def share(template_id, visibility)
86
+ @http.put("/api/v1/private/user-templates/#{enc(template_id)}/visibility",
87
+ "visibility" => visibility)
88
+ end
89
+
90
+ # GET /api/v1/private/user-templates/share-targets
91
+ # List projects the caller is a member of (for the share target picker UI).
92
+ def share_targets
93
+ @http.get("/api/v1/private/user-templates/share-targets")
94
+ end
95
+
96
+ # ── Assignments ────────────────────────────────────────────────────────────
97
+
98
+ # GET /api/v1/private/user-templates/:templateId/assignments
99
+ # List all assignments (users / projects) for a template.
100
+ # @param template_id [String]
101
+ def list_assignments(template_id)
102
+ @http.get("/api/v1/private/user-templates/#{enc(template_id)}/assignments")
103
+ end
104
+
105
+ # POST /api/v1/private/user-templates/:templateId/assignments
106
+ # Assign a template to a user or project.
107
+ # Provide exactly one of +user_id:+ or +project_id:+ (both UUIDs);
108
+ # the server rejects requests carrying both or neither.
109
+ # @param template_id [String]
110
+ # @param user_id [String, nil] target user UUID
111
+ # @param project_id [String, nil] target project UUID
112
+ def assign(template_id, user_id: nil, project_id: nil)
113
+ @http.post("/api/v1/private/user-templates/#{enc(template_id)}/assignments",
114
+ assignment_target(user_id, project_id))
115
+ end
116
+
117
+ # DELETE /api/v1/private/user-templates/:templateId/assignments
118
+ # Remove an assignment from a template.
119
+ # Provide exactly one of +user_id:+ or +project_id:+ (both UUIDs).
120
+ # The target is sent as query params — the server ignores DELETE
121
+ # request bodies.
122
+ # @param template_id [String]
123
+ # @param user_id [String, nil] target user UUID
124
+ # @param project_id [String, nil] target project UUID
125
+ def unassign(template_id, user_id: nil, project_id: nil)
126
+ @http.delete("/api/v1/private/user-templates/#{enc(template_id)}/assignments",
127
+ assignment_target(user_id, project_id))
128
+ end
129
+
130
+ private
131
+
132
+ # Exactly one of user_id / project_id must be given.
133
+ def assignment_target(user_id, project_id)
134
+ if user_id.nil? == project_id.nil?
135
+ raise ArgumentError, "Melaya: provide exactly one of user_id: or project_id:"
136
+ end
137
+ user_id ? { "userId" => user_id } : { "projectId" => project_id }
138
+ end
139
+
140
+ def enc(s)
141
+ URI.encode_www_form_component(s.to_s)
142
+ end
143
+
144
+ def compact(hash)
145
+ hash.reject { |_, v| v.nil? }
146
+ end
147
+ end
148
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Melaya
4
- VERSION = "0.1.4"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/melaya.rb CHANGED
@@ -3,6 +3,8 @@
3
3
  require_relative "melaya/version"
4
4
  require_relative "melaya/errors"
5
5
  require_relative "melaya/http_client"
6
+
7
+ # ── Trading plane ──────────────────────────────────────────────────────────────
6
8
  require_relative "melaya/market"
7
9
  require_relative "melaya/account"
8
10
  require_relative "melaya/sim"
@@ -11,28 +13,86 @@ require_relative "melaya/backtest"
11
13
  require_relative "melaya/stream"
12
14
  require_relative "melaya/trade"
13
15
 
16
+ # ── Platform / agents plane ────────────────────────────────────────────────────
17
+ require_relative "melaya/auth"
18
+ require_relative "melaya/accounts"
19
+ require_relative "melaya/billing"
20
+ require_relative "melaya/runner"
21
+ require_relative "melaya/projects"
22
+ require_relative "melaya/pipelines"
23
+ require_relative "melaya/hitl"
24
+ require_relative "melaya/credentials"
25
+ require_relative "melaya/connectors"
26
+ require_relative "melaya/phone"
27
+ require_relative "melaya/team"
28
+ require_relative "melaya/templates"
29
+ require_relative "melaya/assistant"
30
+ require_relative "melaya/evals"
31
+ require_relative "melaya/bugs"
32
+ require_relative "melaya/events"
33
+
34
+ # ── Domain namespace groupings ─────────────────────────────────────────────────
35
+ require_relative "melaya/namespaces"
36
+
14
37
  module Melaya
15
- # The Melaya client.
38
+ # The unified Melaya client.
39
+ #
40
+ # Exposes every public endpoint in the Melaya REST API surface through three
41
+ # domain namespaces **and** flat module accessors (for backward compatibility).
42
+ #
43
+ # **Primary API — namespaced** (recommended):
44
+ #
45
+ # melaya.trading.market.ticker(...) # market data
46
+ # melaya.trading.strategies.create(...) # trading strategies
47
+ # melaya.agents.pipelines.list(...) # agent pipeline runs
48
+ # melaya.agents.hitl.pending # HITL approval queue
49
+ # melaya.platform.projects.list # platform projects
50
+ # melaya.platform.billing.subscription # billing
51
+ #
52
+ # **Flat accessors** (backward-compatible aliases):
53
+ #
54
+ # melaya.market.ticker(...) # same object as melaya.trading.market
55
+ # melaya.pipelines.list(...) # same object as melaya.agents.pipelines
56
+ # melaya.projects.list # same object as melaya.platform.projects
57
+ #
58
+ # **Namespace groupings**:
59
+ # - +trading+ — market, account, sim, strategies, backtest, stream, trade
60
+ # - +agents+ — pipelines (also +.runs+), hitl, assistant, phone, evals, models
61
+ # - +platform+ — projects, credentials, connectors, billing, team, templates,
62
+ # overview, runner, auth (also +.mfa+), accounts, bugs, events
63
+ #
64
+ # Authentication: pass your +mk_*+ platform API key via +api_key:+. Every REST call
65
+ # sends it as an Authorization: Bearer header. For session JWT workflows
66
+ # (login/refresh) construct the client with the JWT instead.
67
+ # Never log or expose the key — it is stored opaquely in the HTTP client.
16
68
  #
17
69
  # @example
18
70
  # require "melaya"
19
- # melaya = Melaya::Client.new(api_key: ENV["MK"])
20
71
  #
21
- # # Market data
22
- # t = melaya.market.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot")
72
+ # melaya = Melaya::Client.new(api_key: ENV["MELAYA_API_KEY"])
73
+ #
74
+ # # Namespaced — primary API
75
+ # t = melaya.trading.market.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot")
23
76
  # puts t["last"]
24
77
  #
25
- # # Paper strategy
26
- # result = melaya.strategies.create(
27
- # name: "my-bot", strategy_type: "custom", exchange: "binanceusdm",
28
- # symbol: "BTC/USDT:USDT", market: "FUTURES", dry_run: true,
29
- # params: { language: "rhai", definition: 'fn evaluate() { emit_long(param("qty")); }', qty: 0.001 }
30
- # )
31
- # sid = result["strategyId"]
32
- # melaya.strategies.stop(sid)
33
- # melaya.strategies.delete(sid)
78
+ # # Agent pipelines
79
+ # runs = melaya.agents.pipelines.list(project: "my-project", limit: 10)
80
+ # # or via the alias:
81
+ # runs = melaya.agents.runs.list(project: "my-project", limit: 10)
82
+ #
83
+ # # HITL approvals
84
+ # pending = melaya.agents.hitl.pending
85
+ # pending.each { |r| melaya.agents.hitl.approve(r["requestId"]) }
86
+ #
87
+ # # Platform
88
+ # projects = melaya.platform.projects.list
89
+ # melaya.platform.auth.login(username: "you@example.com", password: "s3cr3t")
90
+ #
91
+ # # Real-time events (Socket.IO) — also on platform namespace
92
+ # melaya.platform.events.on_run_update("run-123") { |e| puts e["event_type"] }
34
93
  class Client
35
- # REST market-data + reference endpoints (public plane).
94
+ # ── Trading plane ──────────────────────────────────────────────────────────
95
+ # REST market-data + reference endpoints (public + authenticated).
36
96
  attr_reader :market
37
97
  # Authenticated account reads: connected keys, tier limits, usage.
38
98
  attr_reader :account
@@ -44,29 +104,114 @@ module Melaya
44
104
  attr_reader :backtest
45
105
  # WebSocket streaming endpoints (public market data + private feeds).
46
106
  attr_reader :stream
47
- # Live trading — credentialed order placement and account state on a connected exchange. WARNING: real funds.
107
+ # Live trading — credentialed order placement on a connected exchange. WARNING: real funds.
48
108
  attr_reader :trade
49
109
 
50
- # @param api_key [String] your Melaya API key, prefixed +mk_+
51
- # @param base_url [String] override the REST base URL
52
- # @param ws_url [String] override the WebSocket base URL
53
- # @param verify_ssl [Boolean] set false to skip TLS verification (dev-box only).
54
- # Prefer using ENV["MELAYA_INSECURE_TLS"]="1" rather than passing this directly.
110
+ # ── Platform / agents plane ────────────────────────────────────────────────
111
+ # Auth: login, MFA, registration, password management, session tokens.
112
+ attr_reader :auth
113
+ # Account management: GDPR export, CEX key removal, profile updates.
114
+ attr_reader :accounts
115
+ # Billing: subscription, Stripe checkout/portal, pricing plans, credit balances.
116
+ attr_reader :billing
117
+ # Runner tokens: mint, list, revoke mel_run_ tokens.
118
+ attr_reader :runner
119
+ # Agent projects: create and list.
120
+ attr_reader :projects
121
+ # Pipeline runs, traces, schedules, and overview dashboard.
122
+ attr_reader :pipelines
123
+ # Human-in-the-loop approval queue: list pending, approve, reject.
124
+ attr_reader :hitl
125
+ # User-scoped credential storage (services, OAuth, env handles, models).
126
+ attr_reader :credentials
127
+ # Project-scoped connector credentials.
128
+ attr_reader :connectors
129
+ # Phone device control: pair, list, screen-tree, apps.
130
+ attr_reader :phone
131
+ # Project team management: members, roles, invite links.
132
+ attr_reader :team
133
+ # Pipeline templates: create, share, assign, and manage visibility.
134
+ attr_reader :templates
135
+ # Assistant onboarding profile (get + set).
136
+ attr_reader :assistant
137
+ # Agent evaluation runs and benchmarks.
138
+ attr_reader :evals
139
+ # Bug reports: submit, track, and comment.
140
+ attr_reader :bugs
141
+ # Platform real-time events over Socket.IO at /api/v1/events.
142
+ # Subscribe to run updates, init-phase progress, HITL notifications,
143
+ # and pipeline CRUD events. Opens a background polling thread.
144
+ attr_reader :events
145
+
146
+ # ── Domain namespace accessors (primary API) ───────────────────────────────
147
+
148
+ # Trading-plane namespace.
149
+ # Groups: market, account, sim, strategies, backtest, stream, trade.
150
+ #
151
+ # @return [TradingNamespace]
152
+ # @example
153
+ # melaya.trading.market.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot")
154
+ # melaya.trading.strategies.create(name: "bot", strategy_type: "custom", ...)
155
+ # melaya.trading.stream.ticker(exchange: "binance", symbol: "BTC/USDT", market: "spot") { |f| ... }
156
+ attr_reader :trading
157
+
158
+ # Agent-plane namespace.
159
+ # Groups: pipelines (alias: runs), hitl, assistant, phone, evals, models.
160
+ #
161
+ # @return [AgentsNamespace]
162
+ # @example
163
+ # melaya.agents.pipelines.list(project: "my-project")
164
+ # melaya.agents.runs.list(project: "my-project") # alias for pipelines
165
+ # melaya.agents.hitl.pending
166
+ # melaya.agents.assistant.get_profile
167
+ # melaya.agents.evals.list_runs
168
+ # melaya.agents.models.list_models(provider: "anthropic")
169
+ attr_reader :agents
170
+
171
+ # Platform-plane namespace.
172
+ # Groups: projects, credentials, connectors, billing, team, templates,
173
+ # overview, runner, auth (alias: mfa), accounts, bugs, events.
174
+ #
175
+ # @return [PlatformNamespace]
176
+ # @example
177
+ # melaya.platform.projects.list
178
+ # melaya.platform.billing.subscription
179
+ # melaya.platform.auth.login(username: "u", password: "p")
180
+ # melaya.platform.mfa.mfa_setup # alias for auth
181
+ # melaya.platform.credentials.set("openai", value: "sk-...")
182
+ # melaya.platform.events.on_run_update("run-123") { |e| puts e["event_type"] }
183
+ attr_reader :platform
184
+
185
+ # @param api_key [String] Melaya platform API key, prefixed +mk_+.
186
+ # Create one at melaya.org → Settings → API Keys. May also be a session
187
+ # JWT for auth-plane operations (login/refresh return a JWT).
188
+ # @param base_url [String] Override the REST base URL.
189
+ # @param ws_url [String] Override the WebSocket base URL.
190
+ # @param verify_ssl [Boolean] Retained for compatibility; false is rejected.
191
+ # @param connect_events [Boolean] If false, do not open a Socket.IO connection
192
+ # on construction. Call +events+ to connect lazily. Default: false (lazy).
55
193
  def initialize(api_key:, base_url: HttpClient::DEFAULT_BASE_URL,
56
- ws_url: StreamAPI::DEFAULT_WS_URL, verify_ssl: nil)
57
- raise ArgumentError, "Melaya: api_key is required (create one at melaya.org -> Settings -> API Keys)." \
58
- if api_key.nil? || api_key.empty?
59
- raise ArgumentError, "Melaya: API keys must be prefixed 'mk_'." \
60
- unless api_key.start_with?("mk_")
61
-
62
- ssl = if verify_ssl.nil?
63
- ENV["MELAYA_INSECURE_TLS"] != "1"
64
- else
65
- verify_ssl
194
+ ws_url: StreamAPI::DEFAULT_WS_URL,
195
+ verify_ssl: nil,
196
+ connect_events: false)
197
+ raise ArgumentError,
198
+ "Melaya: api_key is required (create one at melaya.org → Settings → API Keys)." \
199
+ if api_key.nil? || api_key.to_s.empty?
200
+ # Allow JWTs (which don't start with mk_) for auth-plane use cases
201
+ # while still guiding developers who forget the prefix.
202
+ if !api_key.to_s.start_with?("mk_") && !api_key.to_s.start_with?("ey")
203
+ raise ArgumentError,
204
+ "Melaya: API keys must be prefixed 'mk_' (or a Bearer JWT starting with 'ey')."
205
+ end
206
+
207
+ if verify_ssl == false
208
+ raise ArgumentError, "Melaya: TLS certificate verification cannot be disabled."
66
209
  end
210
+ ssl = true
67
211
 
68
212
  http = HttpClient.new(api_key: api_key, base_url: base_url, verify_ssl: ssl)
69
213
 
214
+ # Trading plane
70
215
  @market = MarketAPI.new(http)
71
216
  @account = AccountAPI.new(http)
72
217
  @sim = SimAPI.new(http)
@@ -74,6 +219,92 @@ module Melaya
74
219
  @backtest = BacktestAPI.new(http)
75
220
  @stream = StreamAPI.new(api_key, ws_url, http, verify_ssl: ssl)
76
221
  @trade = TradeAPI.new(http)
222
+
223
+ # Platform / agents plane
224
+ @auth = AuthAPI.new(http)
225
+ @accounts = AccountsAPI.new(http)
226
+ @billing = BillingAPI.new(http)
227
+ @runner = RunnerAPI.new(http)
228
+ @projects = ProjectsAPI.new(http)
229
+ @pipelines = PipelinesAPI.new(http)
230
+ @hitl = HitlAPI.new(http)
231
+ @credentials = CredentialsAPI.new(http)
232
+ @connectors = ConnectorsAPI.new(http)
233
+ @phone = PhoneAPI.new(http)
234
+ @team = TeamAPI.new(http)
235
+ @templates = TemplatesAPI.new(http)
236
+ @assistant = AssistantAPI.new(http)
237
+ @evals = EvalsAPI.new(http)
238
+ @bugs = BugsAPI.new(http)
239
+
240
+ if connect_events
241
+ @events = Events.new(api_key: api_key, base_url: base_url, verify_ssl: ssl)
242
+ else
243
+ @_events_api_key = api_key
244
+ @_events_base_url = base_url
245
+ @_events_verify_ssl = ssl
246
+ @events = nil
247
+ end
248
+
249
+ # ── Domain namespaces ────────────────────────────────────────────────────
250
+ # Each attribute is the SAME instance as the flat accessor — no copies,
251
+ # no extra HTTP clients.
252
+
253
+ @trading = TradingNamespace.new(
254
+ market: @market,
255
+ account: @account,
256
+ sim: @sim,
257
+ strategies: @strategies,
258
+ backtest: @backtest,
259
+ stream: @stream,
260
+ trade: @trade
261
+ )
262
+
263
+ @agents = AgentsNamespace.new(
264
+ pipelines: @pipelines,
265
+ hitl: @hitl,
266
+ assistant: @assistant,
267
+ phone: @phone,
268
+ evals: @evals,
269
+ # credentials#list_models is the canonical "models" surface; expose the
270
+ # full CredentialsAPI object here so callers can do agents.models.list_models(...)
271
+ models: @credentials
272
+ )
273
+
274
+ # Platform namespace: events slot uses a lazy proxy so the Socket.IO
275
+ # thread is still only started on first access (same as the flat #events).
276
+ platform_self = self
277
+ @platform = PlatformNamespace.new(
278
+ projects: @projects,
279
+ credentials: @credentials,
280
+ connectors: @connectors,
281
+ billing: @billing,
282
+ team: @team,
283
+ templates: @templates,
284
+ overview: @pipelines, # overview dashboard lives on PipelinesAPI
285
+ runner: @runner,
286
+ auth: @auth,
287
+ accounts: @accounts,
288
+ bugs: @bugs,
289
+ events: nil # filled lazily below
290
+ )
291
+
292
+ # Patch platform#events to delegate to the lazy flat accessor.
293
+ # We do this with a singleton method so PlatformNamespace remains a plain
294
+ # Struct (no subclassing required).
295
+ @platform.define_singleton_method(:events) { platform_self.events }
296
+ end
297
+
298
+ # Lazily initialize and return the events client.
299
+ # If +connect_events: true+ was passed to the constructor, returns the
300
+ # already-connected client. Otherwise creates and connects on first access.
301
+ # Also accessible as +melaya.platform.events+.
302
+ def events
303
+ @events ||= Events.new(
304
+ api_key: @_events_api_key,
305
+ base_url: @_events_base_url,
306
+ verify_ssl: @_events_verify_ssl
307
+ )
77
308
  end
78
309
  end
79
310
  end
data/melaya.gemspec CHANGED
@@ -8,15 +8,20 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Melaya"]
9
9
  spec.email = ["sdk@melaya.org"]
10
10
 
11
- spec.summary = "Official Ruby SDK for the Melaya unified market-data & trading API"
12
- spec.description = "Access 70+ exchanges via Melaya's normalized REST and WebSocket API. " \
13
- "Market data, strategies, backtesting, sim trading, and streaming."
11
+ spec.summary = "Official Ruby SDK for Melaya Agent Builder and Mobile Device Control"
12
+ spec.description = "Official Ruby SDK for Melaya Agent Builder and Mobile Device Control. Includes preview Melaya Trading namespaces that are not yet generally available."
14
13
  spec.homepage = "https://melaya.org"
15
- spec.license = "MIT"
14
+ spec.license = "Apache-2.0"
15
+
16
+ spec.metadata = {
17
+ "homepage_uri" => "https://melaya.org",
18
+ "source_code_uri" => "https://github.com/melaya-labs/melaya",
19
+ "changelog_uri" => "https://github.com/melaya-labs/melaya/blob/main/CHANGELOG.md"
20
+ }
16
21
 
17
22
  spec.required_ruby_version = ">= 3.0.0"
18
23
 
19
- spec.files = Dir["lib/**/*.rb", "README.md", "melaya.gemspec"]
24
+ spec.files = Dir["lib/**/*.rb", "README.md", "LICENSE", "melaya.gemspec"]
20
25
  spec.require_paths = ["lib"]
21
26
 
22
27
  # stdlib only — no runtime gem dependencies
metadata CHANGED
@@ -1,40 +1,61 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: melaya
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Melaya
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-06-19 00:00:00.000000000 Z
11
+ date: 2026-07-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Access 70+ exchanges via Melaya's normalized REST and WebSocket API.
14
- Market data, strategies, backtesting, sim trading, and streaming.
13
+ description: Official Ruby SDK for Melaya Agent Builder and Mobile Device Control.
14
+ Includes preview Melaya Trading namespaces that are not yet generally available.
15
15
  email:
16
16
  - sdk@melaya.org
17
17
  executables: []
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - LICENSE
21
22
  - README.md
22
23
  - lib/melaya.rb
23
24
  - lib/melaya/account.rb
25
+ - lib/melaya/accounts.rb
26
+ - lib/melaya/assistant.rb
27
+ - lib/melaya/auth.rb
24
28
  - lib/melaya/backtest.rb
29
+ - lib/melaya/billing.rb
30
+ - lib/melaya/bugs.rb
31
+ - lib/melaya/connectors.rb
32
+ - lib/melaya/credentials.rb
25
33
  - lib/melaya/errors.rb
34
+ - lib/melaya/evals.rb
35
+ - lib/melaya/events.rb
36
+ - lib/melaya/hitl.rb
26
37
  - lib/melaya/http_client.rb
27
38
  - lib/melaya/market.rb
39
+ - lib/melaya/namespaces.rb
40
+ - lib/melaya/phone.rb
41
+ - lib/melaya/pipelines.rb
42
+ - lib/melaya/projects.rb
43
+ - lib/melaya/runner.rb
28
44
  - lib/melaya/sim.rb
29
45
  - lib/melaya/strategies.rb
30
46
  - lib/melaya/stream.rb
47
+ - lib/melaya/team.rb
48
+ - lib/melaya/templates.rb
31
49
  - lib/melaya/trade.rb
32
50
  - lib/melaya/version.rb
33
51
  - melaya.gemspec
34
52
  homepage: https://melaya.org
35
53
  licenses:
36
- - MIT
37
- metadata: {}
54
+ - Apache-2.0
55
+ metadata:
56
+ homepage_uri: https://melaya.org
57
+ source_code_uri: https://github.com/melaya-labs/melaya
58
+ changelog_uri: https://github.com/melaya-labs/melaya/blob/main/CHANGELOG.md
38
59
  post_install_message:
39
60
  rdoc_options: []
40
61
  require_paths:
@@ -53,5 +74,5 @@ requirements: []
53
74
  rubygems_version: 3.5.22
54
75
  signing_key:
55
76
  specification_version: 4
56
- summary: Official Ruby SDK for the Melaya unified market-data & trading API
77
+ summary: Official Ruby SDK for Melaya Agent Builder and Mobile Device Control
57
78
  test_files: []