baid 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 83bacc2e8f9264fa7203aa6b9c9d1ded8a18974c63c72fbd3ef4f0e0ae6f7a76
4
+ data.tar.gz: '094836c43eab0251dc04fc8738b3b885b57cda69edb7197704c123a40d0450c1'
5
+ SHA512:
6
+ metadata.gz: 2f39c86e23698bd6883c23521050f745ffbea60547c235a5d0bcb7083f575b8ef77361faac640169354403fdfbdcb77071352ce5330773b892faccc355420d68
7
+ data.tar.gz: b392ac3a82514828f91f3eb59cc77699b8c3842cbdefca33969c9763ac528180e3396037420c390d50915936af9fa6f46c59fcdf9b47a0d7105854206b838111
data/bin/baid ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "baid"
5
+
6
+ Baid::CLI.start(ARGV)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ class AgentDetector
5
+ AGENTS = [
6
+ { name: "claude_code", marker: ".claude", config_path: ".mcp.json" },
7
+ { name: "cursor", marker: ".cursor", config_path: ".cursor/mcp.json" },
8
+ { name: "antigravity", marker: ".agent", config_path: ".agent/settings.json" },
9
+ { name: "opencode", marker: ".opencode", config_path: ".opencode/config.json" },
10
+ { name: "github_copilot", marker: ".vscode", config_path: ".vscode/mcp.json" },
11
+ { name: "gemini", marker: ".gemini", config_path: ".gemini/settings.json" },
12
+ { name: "codex", marker: ".codex", config_path: ".codex/config.toml" }
13
+ ].freeze
14
+
15
+ def self.detect(project_dir = ".")
16
+ AGENTS.select do |agent|
17
+ Dir.exist?(File.join(project_dir, agent[:marker]))
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ class ApiClient
5
+ BASE_URL = ENV.fetch("BAID_API_URL", "https://baid.dev")
6
+
7
+ def initialize(token: nil)
8
+ @token = token || Config.load_token
9
+ end
10
+
11
+ def get(path, params = {})
12
+ HTTParty.get("#{BASE_URL}/api#{path}",
13
+ query: params,
14
+ headers: auth_headers)
15
+ end
16
+
17
+ def post(path, body = {})
18
+ HTTParty.post("#{BASE_URL}/api#{path}",
19
+ body: body.to_json,
20
+ headers: auth_headers.merge("Content-Type" => "application/json"))
21
+ end
22
+
23
+ private
24
+
25
+ def auth_headers
26
+ { "Authorization" => "Bearer #{@token}" }
27
+ end
28
+ end
29
+ end
data/lib/baid/cli.rb ADDED
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ class CLI < Thor
5
+ desc "version", "Print the Baid CLI version"
6
+ def version
7
+ puts Baid::VERSION
8
+ end
9
+
10
+ desc "login", "Authenticate with BaidSkills"
11
+ def login
12
+ Commands::Login.new.execute
13
+ end
14
+
15
+ desc "logout", "Remove stored credentials"
16
+ def logout
17
+ Commands::Logout.new.execute
18
+ end
19
+
20
+ desc "whoami", "Show current user and workspace info"
21
+ def whoami
22
+ Commands::Whoami.new.execute
23
+ end
24
+
25
+ desc "init", "Initialize Baid in the current project"
26
+ def init
27
+ Commands::Init.new.execute
28
+ end
29
+
30
+ desc "reconfigure", "Remove and re-initialize Baid configuration"
31
+ def reconfigure
32
+ Commands::Reconfigure.new.execute
33
+ end
34
+
35
+ desc "install SKILL_NAME", "Install a skill into your project"
36
+ def install(skill_name)
37
+ Commands::Install.new.execute(skill_name)
38
+ end
39
+
40
+ desc "search QUERY", "Search for skills in the registry"
41
+ def search(query)
42
+ Commands::Search.new.execute(query)
43
+ end
44
+
45
+ desc "update", "Update all installed skills to latest versions"
46
+ def update
47
+ Commands::Update.new.execute
48
+ end
49
+
50
+ desc "skills SUBCOMMAND", "Manage workspace skills"
51
+ subcommand "skills", Class.new(Thor) {
52
+ namespace "skills"
53
+
54
+ desc "list [WORKSPACE]", "List skills in a workspace (defaults to active workspace)"
55
+ def list(workspace_slug = nil)
56
+ Commands::Skills.new.list(workspace_slug)
57
+ end
58
+
59
+ desc "show [WORKSPACE] SKILL_ID", "Show skill details"
60
+ def show(workspace_slug, skill_id = nil)
61
+ Commands::Skills.new.show(workspace_slug, skill_id)
62
+ end
63
+ }
64
+
65
+ desc "workspace SUBCOMMAND", "Manage workspaces"
66
+ subcommand "workspace", Class.new(Thor) {
67
+ namespace "workspace"
68
+
69
+ desc "list", "List all workspaces"
70
+ def list
71
+ Commands::Workspace.new.list
72
+ end
73
+
74
+ desc "switch SLUG", "Switch active workspace"
75
+ def switch(slug)
76
+ Commands::Workspace.new.switch(slug)
77
+ end
78
+ }
79
+ end
80
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Init
6
+ def initialize(project_dir: ".")
7
+ @project_dir = project_dir
8
+ end
9
+
10
+ def execute
11
+ agents = AgentDetector.detect(@project_dir)
12
+
13
+ if agents.empty?
14
+ puts "No agents detected in this project."
15
+ return
16
+ end
17
+
18
+ agents.each do |agent|
19
+ McpConfigurator.configure(agent, @project_dir)
20
+ puts "Configured MCP for #{agent[:name]}"
21
+ end
22
+
23
+ config_path = File.join(@project_dir, ".baid", "config.yml")
24
+ FileUtils.mkdir_p(File.dirname(config_path))
25
+ config = { "agents" => agents.map { |a| a[:name] }, "installed_skills" => [] }
26
+ File.write(config_path, config.to_yaml)
27
+
28
+ puts "Baid initialized with #{agents.length} agent(s)."
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Install
6
+ def initialize(project_dir: ".")
7
+ @project_dir = project_dir
8
+ end
9
+
10
+ def execute(skill_name)
11
+ client = ApiClient.new
12
+ response = client.get("/skills/resolve", name: skill_name)
13
+
14
+ if response.code != 200
15
+ puts "Skill '#{skill_name}' not found."
16
+ return
17
+ end
18
+
19
+ data = JSON.parse(response.body)
20
+ skill = data["skill"]
21
+
22
+ config = Config.load_project_config
23
+ agents = (config["agents"] || []).map do |name|
24
+ AgentDetector::AGENTS.find { |a| a[:name] == name }
25
+ end.compact
26
+
27
+ SkillWriter.write(skill, agents, @project_dir)
28
+
29
+ # Update installed_skills in config
30
+ config["installed_skills"] ||= []
31
+ config["installed_skills"] << skill["name"] unless config["installed_skills"].include?(skill["name"])
32
+ Config.save_project_config(config)
33
+
34
+ puts "Installed #{skill['name']}@#{skill['version']}"
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Login
6
+ def execute
7
+ response = HTTParty.post("#{ApiClient::BASE_URL}/api/auth/device",
8
+ headers: { "Content-Type" => "application/json" })
9
+
10
+ data = JSON.parse(response.body)
11
+ device_code = data["device_code"]
12
+ user_code = data["user_code"]
13
+ verification_uri = data["verification_uri"]
14
+ interval = data["interval"] || 5
15
+
16
+ puts "Open #{verification_uri} and enter code: #{user_code}"
17
+ open_browser(verification_uri)
18
+
19
+ token = poll_for_token(device_code, interval)
20
+ Config.save_token(token)
21
+ puts "Logged in successfully!"
22
+ end
23
+
24
+ private
25
+
26
+ def poll_for_token(device_code, interval)
27
+ loop do
28
+ response = HTTParty.post("#{ApiClient::BASE_URL}/api/auth/device/token",
29
+ body: { device_code: device_code }.to_json,
30
+ headers: { "Content-Type" => "application/json" })
31
+
32
+ data = JSON.parse(response.body)
33
+
34
+ if data["access_token"]
35
+ return data["access_token"]
36
+ elsif data["error"] == "authorization_pending"
37
+ sleep(interval)
38
+ else
39
+ raise "Authentication failed: #{data['error']}"
40
+ end
41
+ end
42
+ end
43
+
44
+ def open_browser(url)
45
+ system("open", url) || system("xdg-open", url)
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Logout
6
+ def execute
7
+ if File.exist?(Config::CREDENTIALS_FILE)
8
+ File.delete(Config::CREDENTIALS_FILE)
9
+ puts "Logged out successfully."
10
+ else
11
+ puts "Not logged in."
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Reconfigure
6
+ def initialize(project_dir: ".")
7
+ @project_dir = project_dir
8
+ end
9
+
10
+ def execute
11
+ puts "Reconfiguring Baid..."
12
+
13
+ # Remove existing baid entries from all agent configs
14
+ agents = AgentDetector.detect(@project_dir)
15
+ agents.each do |agent|
16
+ McpConfigurator.remove(agent, @project_dir)
17
+ end
18
+
19
+ # Remove .baid directory
20
+ baid_dir = File.join(@project_dir, ".baid")
21
+ FileUtils.rm_rf(baid_dir)
22
+
23
+ # Re-initialize
24
+ Init.new(project_dir: @project_dir).execute
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Search
6
+ def execute(query)
7
+ client = ApiClient.new
8
+ response = client.get("/skills/search", q: query)
9
+ data = JSON.parse(response.body)
10
+ skills = data["skills"] || []
11
+
12
+ if skills.empty?
13
+ puts "No skills found for '#{query}'."
14
+ return
15
+ end
16
+
17
+ puts format("%-25s %-40s %-10s %s", "NAME", "DESCRIPTION", "VERSION", "WORKSPACE")
18
+ puts "-" * 90
19
+ skills.each do |skill|
20
+ puts format("%-25s %-40s %-10s %s",
21
+ skill["name"],
22
+ (skill["description"] || "")[0..38],
23
+ skill["version"],
24
+ skill["workspace"])
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Skills
6
+ def list(workspace_slug = nil)
7
+ workspace_slug = resolve_workspace(workspace_slug)
8
+ return unless workspace_slug
9
+
10
+ client = ApiClient.new
11
+ response = client.get("/workspaces/#{workspace_slug}/skills")
12
+
13
+ unless response.code == 200
14
+ puts "Failed to fetch skills (#{response.code}). Check your token with `baid whoami`."
15
+ return
16
+ end
17
+
18
+ data = JSON.parse(response.body)
19
+ skills = data["skills"] || []
20
+
21
+ if skills.empty?
22
+ puts "No skills in workspace."
23
+ return
24
+ end
25
+
26
+ puts format("%-25s %-15s %s", "NAME", "SOURCE", "VERSION")
27
+ puts "-" * 50
28
+ skills.each do |skill|
29
+ puts format("%-25s %-15s %s", skill["name"], skill["source"], skill["latest_version"])
30
+ end
31
+ end
32
+
33
+ def show(workspace_slug, skill_id = nil)
34
+ # If called with one arg, treat it as skill_id and resolve workspace
35
+ if skill_id.nil?
36
+ skill_id = workspace_slug
37
+ workspace_slug = resolve_workspace(nil)
38
+ return unless workspace_slug
39
+ end
40
+
41
+ client = ApiClient.new
42
+ response = client.get("/workspaces/#{workspace_slug}/skills/#{skill_id}")
43
+
44
+ unless response.code == 200
45
+ puts "Failed to fetch skill (#{response.code}). Check your token with `baid whoami`."
46
+ return
47
+ end
48
+
49
+ data = JSON.parse(response.body)
50
+
51
+ puts "Name: #{data['name']}"
52
+ puts "Description: #{data['description']}"
53
+ puts "Source: #{data['source']}"
54
+ puts "Version: #{data['latest_version']}"
55
+ puts "Agents: #{(data['agents'] || []).join(', ')}"
56
+ end
57
+
58
+ private
59
+
60
+ def resolve_workspace(workspace_slug)
61
+ return workspace_slug if workspace_slug
62
+
63
+ slug = Config.load_active_workspace
64
+ return slug if slug
65
+
66
+ token = Config.load_token
67
+ unless token
68
+ puts "Not logged in. Run `baid login` first."
69
+ return nil
70
+ end
71
+
72
+ # Fall back to first workspace from whoami
73
+ client = ApiClient.new
74
+ response = client.get("/whoami")
75
+ if response.code == 200
76
+ data = JSON.parse(response.body)
77
+ ws = data["workspace"]
78
+ if ws && ws["slug"]
79
+ Config.save_active_workspace(ws["slug"])
80
+ return ws["slug"]
81
+ end
82
+ end
83
+
84
+ puts "No active workspace. Run `baid workspace switch SLUG` first."
85
+ nil
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Update
6
+ def initialize(project_dir: ".")
7
+ @project_dir = project_dir
8
+ end
9
+
10
+ def execute
11
+ config = Config.load_project_config
12
+ installed = config["installed_skills"] || []
13
+
14
+ if installed.empty?
15
+ puts "No skills installed."
16
+ return
17
+ end
18
+
19
+ client = ApiClient.new
20
+ agents = (config["agents"] || []).map do |name|
21
+ AgentDetector::AGENTS.find { |a| a[:name] == name }
22
+ end.compact
23
+
24
+ installed.each do |skill_name|
25
+ response = client.get("/skills/resolve", name: skill_name)
26
+ next if response.code != 200
27
+
28
+ data = JSON.parse(response.body)
29
+ SkillWriter.write(data["skill"], agents, @project_dir)
30
+ puts "Updated #{skill_name}@#{data['skill']['version']}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Whoami
6
+ def execute
7
+ token = Config.load_token
8
+ unless token
9
+ puts "Not logged in. Run `baid login` first."
10
+ return
11
+ end
12
+
13
+ client = ApiClient.new(token: token)
14
+ response = client.get("/whoami")
15
+
16
+ if response.code != 200
17
+ puts "Failed to fetch user info (#{response.code})."
18
+ return
19
+ end
20
+
21
+ data = JSON.parse(response.body)
22
+ user = data["user"]
23
+ workspace = data["workspace"]
24
+
25
+ puts "\e[32m✔\e[0m You are logged in to baid"
26
+ puts "User: #{user['name']} (#{user['email']})"
27
+ puts "Workspace: #{workspace['name']} (#{workspace['slug']})" if workspace
28
+ puts "Run \e[36mbaid logout\e[0m to log out"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ module Commands
5
+ class Workspace
6
+ def list
7
+ client = ApiClient.new
8
+ response = client.get("/workspaces")
9
+ data = JSON.parse(response.body)
10
+ workspaces = data["workspaces"] || []
11
+
12
+ if workspaces.empty?
13
+ puts "No workspaces found."
14
+ return
15
+ end
16
+
17
+ puts format("%-25s %-25s %s", "NAME", "SLUG", "ROLE")
18
+ puts "-" * 60
19
+ workspaces.each do |ws|
20
+ puts format("%-25s %-25s %s", ws["name"], ws["slug"], ws["role"])
21
+ end
22
+ end
23
+
24
+ def switch(slug)
25
+ FileUtils.mkdir_p(Config::CONFIG_DIR)
26
+ File.write(Config::ACTIVE_WORKSPACE_FILE, slug)
27
+ puts "Switched to workspace '#{slug}'."
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ class Config
5
+ CONFIG_DIR = File.expand_path("~/.baid")
6
+ CREDENTIALS_FILE = File.join(CONFIG_DIR, "credentials")
7
+ ACTIVE_WORKSPACE_FILE = File.join(CONFIG_DIR, "active_workspace")
8
+ PROJECT_CONFIG = ".baid/config.yml"
9
+
10
+ def self.load_token
11
+ return nil unless File.exist?(CREDENTIALS_FILE)
12
+
13
+ File.read(CREDENTIALS_FILE).strip
14
+ end
15
+
16
+ def self.save_token(token)
17
+ FileUtils.mkdir_p(CONFIG_DIR)
18
+ File.write(CREDENTIALS_FILE, token)
19
+ FileUtils.chmod(0o600, CREDENTIALS_FILE)
20
+ end
21
+
22
+ def self.load_active_workspace
23
+ return nil unless File.exist?(ACTIVE_WORKSPACE_FILE)
24
+
25
+ File.read(ACTIVE_WORKSPACE_FILE).strip.then { |s| s.empty? ? nil : s }
26
+ end
27
+
28
+ def self.save_active_workspace(slug)
29
+ FileUtils.mkdir_p(CONFIG_DIR)
30
+ File.write(ACTIVE_WORKSPACE_FILE, slug)
31
+ end
32
+
33
+ def self.load_project_config
34
+ return {} unless File.exist?(PROJECT_CONFIG)
35
+
36
+ YAML.safe_load(File.read(PROJECT_CONFIG)) || {}
37
+ end
38
+
39
+ def self.save_project_config(config)
40
+ FileUtils.mkdir_p(File.dirname(PROJECT_CONFIG))
41
+ File.write(PROJECT_CONFIG, config.to_yaml)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ class McpConfigurator
5
+ BAID_MCP_ENTRY = {
6
+ "command" => "npx",
7
+ "args" => ["-y", "@baid/mcp-server"],
8
+ "env" => {}
9
+ }.freeze
10
+
11
+ def self.configure(agent, project_dir = ".")
12
+ config_path = File.join(project_dir, agent[:config_path])
13
+ FileUtils.mkdir_p(File.dirname(config_path))
14
+
15
+ config = load_config(config_path)
16
+ config["mcpServers"] ||= {}
17
+ config["mcpServers"]["baid"] = BAID_MCP_ENTRY.dup
18
+
19
+ File.write(config_path, JSON.pretty_generate(config))
20
+ end
21
+
22
+ def self.remove(agent, project_dir = ".")
23
+ config_path = File.join(project_dir, agent[:config_path])
24
+ return unless File.exist?(config_path)
25
+
26
+ config = load_config(config_path)
27
+ config["mcpServers"]&.delete("baid")
28
+
29
+ File.write(config_path, JSON.pretty_generate(config))
30
+ end
31
+
32
+ def self.load_config(path)
33
+ return {} unless File.exist?(path)
34
+
35
+ JSON.parse(File.read(path))
36
+ rescue JSON::ParserError
37
+ {}
38
+ end
39
+
40
+ private_class_method :load_config
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Baid
4
+ class SkillWriter
5
+ AGENT_PATHS = {
6
+ "claude_code" => proc { |name| File.join(".claude", "skills", "#{name}.md") },
7
+ "cursor" => proc { |name| File.join(".cursor", "rules", "#{name}.md") },
8
+ "antigravity" => proc { |name| File.join(".agent", "skills", name, "SKILL.md") },
9
+ "opencode" => proc { |name| File.join(".opencode", "rules", "#{name}.md") }
10
+ }.freeze
11
+
12
+ def self.write(skill_data, agents, project_dir = ".")
13
+ name = skill_data["name"]
14
+ content = skill_data["content"]
15
+
16
+ agents.each do |agent|
17
+ path_proc = AGENT_PATHS[agent[:name]]
18
+ next unless path_proc
19
+
20
+ relative_path = path_proc.call(name)
21
+ full_path = File.join(project_dir, relative_path)
22
+ FileUtils.mkdir_p(File.dirname(full_path))
23
+
24
+ file_content = if agent[:name] == "antigravity"
25
+ frontmatter = { "name" => name, "version" => skill_data["version"] }.to_yaml
26
+ "#{frontmatter}---\n\n#{content}"
27
+ else
28
+ content
29
+ end
30
+
31
+ File.write(full_path, file_content)
32
+ end
33
+ end
34
+
35
+ def self.remove(name, agents, project_dir = ".")
36
+ agents.each do |agent|
37
+ path_proc = AGENT_PATHS[agent[:name]]
38
+ next unless path_proc
39
+
40
+ full_path = File.join(project_dir, path_proc.call(name))
41
+ FileUtils.rm_f(full_path)
42
+
43
+ # Clean up empty parent directories for antigravity
44
+ if agent[:name] == "antigravity"
45
+ parent = File.dirname(full_path)
46
+ FileUtils.rm_rf(parent) if Dir.exist?(parent) && Dir.empty?(parent)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
data/lib/baid.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+ require "httparty"
5
+ require "json"
6
+ require "yaml"
7
+ require "fileutils"
8
+
9
+ module Baid
10
+ VERSION = "0.1.0"
11
+ end
12
+
13
+ require_relative "baid/config"
14
+ require_relative "baid/api_client"
15
+ require_relative "baid/agent_detector"
16
+ require_relative "baid/mcp_configurator"
17
+ require_relative "baid/commands/login"
18
+ require_relative "baid/commands/logout"
19
+ require_relative "baid/commands/whoami"
20
+ require_relative "baid/skill_writer"
21
+ require_relative "baid/commands/init"
22
+ require_relative "baid/commands/reconfigure"
23
+ require_relative "baid/commands/install"
24
+ require_relative "baid/commands/search"
25
+ require_relative "baid/commands/update"
26
+ require_relative "baid/commands/skills"
27
+ require_relative "baid/commands/workspace"
28
+ require_relative "baid/cli"
metadata ADDED
@@ -0,0 +1,140 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: baid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Baid Team
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: thor
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.3'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.3'
26
+ - !ruby/object:Gem::Dependency
27
+ name: httparty
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.21'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.21'
40
+ - !ruby/object:Gem::Dependency
41
+ name: tty-prompt
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.23'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.23'
54
+ - !ruby/object:Gem::Dependency
55
+ name: tty-spinner
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.9'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.9'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '3.12'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.12'
82
+ - !ruby/object:Gem::Dependency
83
+ name: webmock
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.18'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.18'
96
+ executables:
97
+ - baid
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - bin/baid
102
+ - lib/baid.rb
103
+ - lib/baid/agent_detector.rb
104
+ - lib/baid/api_client.rb
105
+ - lib/baid/cli.rb
106
+ - lib/baid/commands/init.rb
107
+ - lib/baid/commands/install.rb
108
+ - lib/baid/commands/login.rb
109
+ - lib/baid/commands/logout.rb
110
+ - lib/baid/commands/reconfigure.rb
111
+ - lib/baid/commands/search.rb
112
+ - lib/baid/commands/skills.rb
113
+ - lib/baid/commands/update.rb
114
+ - lib/baid/commands/whoami.rb
115
+ - lib/baid/commands/workspace.rb
116
+ - lib/baid/config.rb
117
+ - lib/baid/mcp_configurator.rb
118
+ - lib/baid/skill_writer.rb
119
+ homepage: https://baid.dev
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: 3.2.0
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - ">="
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubygems_version: 3.6.9
138
+ specification_version: 4
139
+ summary: CLI for BaidSkills — AI agent skill management
140
+ test_files: []