brainiac 0.0.4 → 0.0.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 +4 -4
- data/Gemfile.lock +2 -2
- data/bin/brainiac +249 -4
- data/bin/brainiac-completion.bash +10 -4
- data/lib/brainiac/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: 5d349dd4297beb2e1970aaff969c468ea088cc58142391e738f0dbefa7736fcb
|
|
4
|
+
data.tar.gz: 79b008e8823b2c4289f48a4356e4bd9271c5d3564518ec9bd42f24c460870822
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2c7b7448242a508c1cbb3d58c1d4a8cea72218d886fc2db60c9c5a2913ad8737300ef3cd897a44333af4cbad44dc92d046f8e3ca20cb792edb552868ea6a4d4
|
|
7
|
+
data.tar.gz: b0a838dbd6b1ab90f65004cc4f420eb87632c2a8e60ee95e456f9e6bede3a7184a1130981740024166936730eb7df5ff4d7a3365d65315d7e3a871514b9b6d72
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
brainiac (0.0.
|
|
4
|
+
brainiac (0.0.5)
|
|
5
5
|
puma (~> 7.2)
|
|
6
6
|
rackup (~> 2.3)
|
|
7
7
|
sinatra (~> 4.1)
|
|
@@ -90,7 +90,7 @@ DEPENDENCIES
|
|
|
90
90
|
CHECKSUMS
|
|
91
91
|
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
|
|
92
92
|
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
|
|
93
|
-
brainiac (0.0.
|
|
93
|
+
brainiac (0.0.5)
|
|
94
94
|
event_emitter (0.2.6) sha256=c72697bd5cce9d36594be1972c17f1c9a573236f44303a4d1d548080364e1391
|
|
95
95
|
json (2.19.9) sha256=9b9025b7cdddafa38d316eca0b2358488e42d417045c1b90d216a9fefe46b79a
|
|
96
96
|
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
|
data/bin/brainiac
CHANGED
|
@@ -1436,23 +1436,179 @@ when "agent"
|
|
|
1436
1436
|
end
|
|
1437
1437
|
end
|
|
1438
1438
|
|
|
1439
|
+
when "create", "add"
|
|
1440
|
+
name = ARGV.shift
|
|
1441
|
+
unless name
|
|
1442
|
+
puts "Usage: brainiac agent create <name> [options]"
|
|
1443
|
+
puts ""
|
|
1444
|
+
puts "Options:"
|
|
1445
|
+
puts " --local Mark agent as local (dispatches on this machine)"
|
|
1446
|
+
puts " --role <role> Assign a role (repeatable)"
|
|
1447
|
+
puts " --cli <provider> Set CLI provider (default: kiro)"
|
|
1448
|
+
puts " --persona <text> Create a persona style file with this description"
|
|
1449
|
+
puts ""
|
|
1450
|
+
puts "If no options are given and stdin is a terminal, interactive mode is used."
|
|
1451
|
+
puts ""
|
|
1452
|
+
puts "Examples:"
|
|
1453
|
+
puts " brainiac agent create SecurityBot --local --role code-reviewer"
|
|
1454
|
+
puts " brainiac agent create Jane --role general-engineer --cli grok"
|
|
1455
|
+
puts " brainiac agent create Avon --persona \"Dry wit, sardonic, brilliant\""
|
|
1456
|
+
puts " brainiac agent create MyAgent # interactive"
|
|
1457
|
+
exit 1
|
|
1458
|
+
end
|
|
1459
|
+
|
|
1460
|
+
agent_key = name.downcase.gsub(/[^a-z0-9-]/, "-")
|
|
1461
|
+
registry = File.exist?(agent_registry_file) ? JSON.parse(File.read(agent_registry_file)) : {}
|
|
1462
|
+
|
|
1463
|
+
if registry[agent_key]
|
|
1464
|
+
puts "Agent '#{name}' already exists. Use 'brainiac agent #{agent_key} show' to view."
|
|
1465
|
+
exit 1
|
|
1466
|
+
end
|
|
1467
|
+
|
|
1468
|
+
local = false
|
|
1469
|
+
roles = []
|
|
1470
|
+
cli_provider = nil
|
|
1471
|
+
persona_text = nil
|
|
1472
|
+
|
|
1473
|
+
if ARGV.any?
|
|
1474
|
+
# Flag mode
|
|
1475
|
+
while ARGV.any?
|
|
1476
|
+
case ARGV[0]
|
|
1477
|
+
when "--local"
|
|
1478
|
+
ARGV.shift
|
|
1479
|
+
local = true
|
|
1480
|
+
when "--role"
|
|
1481
|
+
ARGV.shift
|
|
1482
|
+
roles << ARGV.shift
|
|
1483
|
+
when "--cli"
|
|
1484
|
+
ARGV.shift
|
|
1485
|
+
cli_provider = ARGV.shift
|
|
1486
|
+
when "--persona"
|
|
1487
|
+
ARGV.shift
|
|
1488
|
+
persona_text = ARGV.shift
|
|
1489
|
+
else
|
|
1490
|
+
puts "Unknown option: #{ARGV[0]}"
|
|
1491
|
+
exit 1
|
|
1492
|
+
end
|
|
1493
|
+
end
|
|
1494
|
+
elsif $stdin.tty?
|
|
1495
|
+
# Interactive mode
|
|
1496
|
+
puts "Creating agent '#{name}' (#{agent_key})"
|
|
1497
|
+
puts ""
|
|
1498
|
+
|
|
1499
|
+
print "Local (dispatches on this machine)? [y/N]: "
|
|
1500
|
+
local = $stdin.gets.chomp.downcase.start_with?("y")
|
|
1501
|
+
|
|
1502
|
+
# Show available CLI providers
|
|
1503
|
+
providers_dir = File.join(BRAINIAC_DIR, "cli-providers")
|
|
1504
|
+
available_providers = Dir.exist?(providers_dir) ? Dir.glob(File.join(providers_dir, "*.json")).map { |f| File.basename(f, ".json") } : []
|
|
1505
|
+
hint = available_providers.any? ? " (#{available_providers.join(", ")})" : ""
|
|
1506
|
+
print "CLI provider#{hint} [kiro]: "
|
|
1507
|
+
input = $stdin.gets.chomp
|
|
1508
|
+
cli_provider = input.empty? ? nil : input
|
|
1509
|
+
|
|
1510
|
+
# Show available roles
|
|
1511
|
+
roles_dir = File.join(BRAINIAC_DIR, "roles")
|
|
1512
|
+
available_roles = Dir.exist?(roles_dir) ? Dir.glob(File.join(roles_dir, "*.md")).map { |f| File.basename(f, ".md") } : []
|
|
1513
|
+
hint = available_roles.any? ? " (#{available_roles.join(", ")})" : ""
|
|
1514
|
+
print "Roles#{hint} (comma-separated) []: "
|
|
1515
|
+
input = $stdin.gets.chomp
|
|
1516
|
+
roles = input.empty? ? [] : input.split(",").map(&:strip)
|
|
1517
|
+
|
|
1518
|
+
print "Persona description (tone/style, or blank to skip) []: "
|
|
1519
|
+
input = $stdin.gets.chomp
|
|
1520
|
+
persona_text = input.empty? ? nil : input
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1523
|
+
entry = { "fizzy_name" => name }
|
|
1524
|
+
entry["local"] = true if local
|
|
1525
|
+
entry["cli_provider"] = cli_provider if cli_provider
|
|
1526
|
+
entry["role"] = roles.size == 1 ? roles.first : roles if roles.any?
|
|
1527
|
+
|
|
1528
|
+
registry[agent_key] = entry
|
|
1529
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1530
|
+
puts "✓ Created agent '#{name}' (#{agent_key})"
|
|
1531
|
+
puts " Local: #{local}" if local
|
|
1532
|
+
puts " Role: #{roles.join(", ")}" if roles.any?
|
|
1533
|
+
puts " CLI: #{cli_provider}" if cli_provider
|
|
1534
|
+
|
|
1535
|
+
# Create persona directory and style file if requested
|
|
1536
|
+
if persona_text
|
|
1537
|
+
persona_dir = File.join(BRAINIAC_DIR, "brain", "persona", agent_key)
|
|
1538
|
+
FileUtils.mkdir_p(persona_dir)
|
|
1539
|
+
persona_file = File.join(persona_dir, "style.md")
|
|
1540
|
+
unless File.exist?(persona_file)
|
|
1541
|
+
File.write(persona_file, <<~MD)
|
|
1542
|
+
---
|
|
1543
|
+
name: #{agent_key}-style
|
|
1544
|
+
description: Persona voice for #{name}.
|
|
1545
|
+
---
|
|
1546
|
+
# #{name} — Persona
|
|
1547
|
+
#{persona_text}
|
|
1548
|
+
MD
|
|
1549
|
+
puts " Persona: #{persona_file}"
|
|
1550
|
+
end
|
|
1551
|
+
end
|
|
1552
|
+
|
|
1553
|
+
# Initialize brain (qmd collections) for local agents
|
|
1554
|
+
if local
|
|
1555
|
+
puts ""
|
|
1556
|
+
brain_init(name)
|
|
1557
|
+
end
|
|
1558
|
+
|
|
1559
|
+
when "remove", "delete", "rm"
|
|
1560
|
+
name = ARGV.shift
|
|
1561
|
+
unless name
|
|
1562
|
+
puts "Usage: brainiac agent remove <name>"
|
|
1563
|
+
exit 1
|
|
1564
|
+
end
|
|
1565
|
+
|
|
1566
|
+
agent_key = name.downcase.gsub(/[^a-z0-9-]/, "-")
|
|
1567
|
+
registry = File.exist?(agent_registry_file) ? JSON.parse(File.read(agent_registry_file)) : {}
|
|
1568
|
+
|
|
1569
|
+
unless registry[agent_key]
|
|
1570
|
+
puts "Agent '#{name}' not found in registry."
|
|
1571
|
+
exit 1
|
|
1572
|
+
end
|
|
1573
|
+
|
|
1574
|
+
display = registry[agent_key]["fizzy_name"] || name
|
|
1575
|
+
registry.delete(agent_key)
|
|
1576
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1577
|
+
puts "✓ Removed agent '#{display}' (#{agent_key}) from registry"
|
|
1578
|
+
puts " Note: Persona files at ~/.brainiac/brain/persona/#{agent_key}/ were not deleted."
|
|
1579
|
+
|
|
1439
1580
|
when nil
|
|
1440
1581
|
puts <<~HELP
|
|
1441
1582
|
Usage: brainiac agent <name> <command> [args]
|
|
1442
1583
|
brainiac agent list
|
|
1584
|
+
brainiac agent create <name> [options]
|
|
1585
|
+
brainiac agent remove <name>
|
|
1443
1586
|
|
|
1444
1587
|
Commands:
|
|
1445
1588
|
list List all agents in the registry
|
|
1589
|
+
create <name> [options] Add a new agent to the registry
|
|
1590
|
+
remove <name> Remove an agent from the registry
|
|
1446
1591
|
<name> show Show agent configuration (tokens redacted)
|
|
1592
|
+
<name> set <field> <value> Update a config field (local, cli, role, persona, fizzy_name)
|
|
1447
1593
|
<name> env <KEY> <VALUE> Set an env var for an agent
|
|
1448
1594
|
<name> env List env vars for an agent
|
|
1449
1595
|
<name> env --delete <KEY> Remove an env var from an agent
|
|
1450
1596
|
|
|
1597
|
+
Create options (or interactive if no flags given):
|
|
1598
|
+
--local Mark agent as local (dispatches on this machine)
|
|
1599
|
+
--role <role> Assign a role (repeatable)
|
|
1600
|
+
--cli <provider> Set CLI provider (default: kiro)
|
|
1601
|
+
--persona <text> Create a persona style file
|
|
1602
|
+
|
|
1451
1603
|
Examples:
|
|
1604
|
+
brainiac agent create SecurityBot --local --role code-reviewer
|
|
1605
|
+
brainiac agent create Jane --cli grok
|
|
1606
|
+
brainiac agent create MyAgent # interactive mode
|
|
1607
|
+
brainiac agent remove SecurityBot
|
|
1608
|
+
brainiac agent galen set local true
|
|
1609
|
+
brainiac agent galen set persona "Dry, sardonic"
|
|
1610
|
+
brainiac agent galen set role code-reviewer,general-engineer
|
|
1452
1611
|
brainiac agent galen env FIZZY_TOKEN fizzy_abc123
|
|
1453
|
-
brainiac agent galen env DISCORD_BOT_TOKEN Bot_xyz789
|
|
1454
|
-
brainiac agent galen env
|
|
1455
|
-
brainiac agent galen env --delete DISCORD_BOT_TOKEN
|
|
1456
1612
|
brainiac agent galen show
|
|
1457
1613
|
HELP
|
|
1458
1614
|
|
|
@@ -1522,9 +1678,98 @@ when "agent"
|
|
|
1522
1678
|
puts "✓ Set #{var_name} for #{agent_cmd}"
|
|
1523
1679
|
end
|
|
1524
1680
|
|
|
1681
|
+
when "set"
|
|
1682
|
+
field = ARGV.shift
|
|
1683
|
+
value = ARGV.shift
|
|
1684
|
+
unless field
|
|
1685
|
+
puts "Usage: brainiac agent #{agent_cmd} set <field> <value>"
|
|
1686
|
+
puts ""
|
|
1687
|
+
puts "Fields:"
|
|
1688
|
+
puts " local <true|false> Set local dispatch flag"
|
|
1689
|
+
puts " cli <provider> Set CLI provider"
|
|
1690
|
+
puts " role <roles> Set roles (comma-separated, or 'none' to clear)"
|
|
1691
|
+
puts " persona <text> Set/update persona style file"
|
|
1692
|
+
puts " fizzy_name <name> Set display name for Fizzy @mentions"
|
|
1693
|
+
exit 1
|
|
1694
|
+
end
|
|
1695
|
+
|
|
1696
|
+
registry = File.exist?(agent_registry_file) ? JSON.parse(File.read(agent_registry_file)) : {}
|
|
1697
|
+
unless registry[agent_key]
|
|
1698
|
+
puts "Agent '#{agent_cmd}' not found in registry."
|
|
1699
|
+
exit 1
|
|
1700
|
+
end
|
|
1701
|
+
|
|
1702
|
+
case field
|
|
1703
|
+
when "local"
|
|
1704
|
+
if value == "true"
|
|
1705
|
+
registry[agent_key]["local"] = true
|
|
1706
|
+
else
|
|
1707
|
+
registry[agent_key].delete("local")
|
|
1708
|
+
end
|
|
1709
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1710
|
+
puts "✓ Set local=#{value} for #{agent_cmd}"
|
|
1711
|
+
|
|
1712
|
+
when "cli"
|
|
1713
|
+
unless value
|
|
1714
|
+
puts "Usage: brainiac agent #{agent_cmd} set cli <provider>"
|
|
1715
|
+
exit 1
|
|
1716
|
+
end
|
|
1717
|
+
registry[agent_key]["cli_provider"] = value
|
|
1718
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1719
|
+
puts "✓ Set cli_provider=#{value} for #{agent_cmd}"
|
|
1720
|
+
|
|
1721
|
+
when "role"
|
|
1722
|
+
unless value
|
|
1723
|
+
puts "Usage: brainiac agent #{agent_cmd} set role <roles|none>"
|
|
1724
|
+
exit 1
|
|
1725
|
+
end
|
|
1726
|
+
if value == "none"
|
|
1727
|
+
registry[agent_key].delete("role")
|
|
1728
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1729
|
+
puts "✓ Set role for #{agent_cmd}"
|
|
1730
|
+
next
|
|
1731
|
+
end
|
|
1732
|
+
roles = value.split(",").map(&:strip)
|
|
1733
|
+
registry[agent_key]["role"] = roles.size == 1 ? roles.first : roles
|
|
1734
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1735
|
+
puts "✓ Set role for #{agent_cmd}"
|
|
1736
|
+
|
|
1737
|
+
when "persona"
|
|
1738
|
+
unless value
|
|
1739
|
+
puts "Usage: brainiac agent #{agent_cmd} set persona <text>"
|
|
1740
|
+
exit 1
|
|
1741
|
+
end
|
|
1742
|
+
persona_dir = File.join(BRAINIAC_DIR, "brain", "persona", agent_key)
|
|
1743
|
+
FileUtils.mkdir_p(persona_dir)
|
|
1744
|
+
persona_file = File.join(persona_dir, "style.md")
|
|
1745
|
+
display = registry[agent_key]["fizzy_name"] || agent_cmd.capitalize
|
|
1746
|
+
File.write(persona_file, <<~MD)
|
|
1747
|
+
---
|
|
1748
|
+
name: #{agent_key}-style
|
|
1749
|
+
description: Persona voice for #{display}.
|
|
1750
|
+
---
|
|
1751
|
+
# #{display} — Persona
|
|
1752
|
+
#{value}
|
|
1753
|
+
MD
|
|
1754
|
+
puts "✓ Wrote persona to #{persona_file}"
|
|
1755
|
+
|
|
1756
|
+
when "fizzy_name"
|
|
1757
|
+
unless value
|
|
1758
|
+
puts "Usage: brainiac agent #{agent_cmd} set fizzy_name <name>"
|
|
1759
|
+
exit 1
|
|
1760
|
+
end
|
|
1761
|
+
registry[agent_key]["fizzy_name"] = value
|
|
1762
|
+
File.write(agent_registry_file, JSON.pretty_generate(registry))
|
|
1763
|
+
puts "✓ Set fizzy_name=#{value} for #{agent_cmd}"
|
|
1764
|
+
|
|
1765
|
+
else
|
|
1766
|
+
puts "Unknown field '#{field}'. Available: local, cli, role, persona, fizzy_name"
|
|
1767
|
+
exit 1
|
|
1768
|
+
end
|
|
1769
|
+
|
|
1525
1770
|
else
|
|
1526
1771
|
puts "Unknown subcommand '#{sub}' for agent '#{agent_cmd}'."
|
|
1527
|
-
puts "Available: show, env"
|
|
1772
|
+
puts "Available: show, env, set"
|
|
1528
1773
|
exit 1
|
|
1529
1774
|
end
|
|
1530
1775
|
end
|
|
@@ -73,13 +73,19 @@ _brainiac() {
|
|
|
73
73
|
agent)
|
|
74
74
|
case $cword in
|
|
75
75
|
2)
|
|
76
|
-
COMPREPLY=($(compgen -W "list $(_brainiac_agents)" -- "$cur"))
|
|
76
|
+
COMPREPLY=($(compgen -W "list create remove $(_brainiac_agents)" -- "$cur"))
|
|
77
77
|
;;
|
|
78
78
|
3)
|
|
79
79
|
local agent_name="${words[2]}"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
case "$agent_name" in
|
|
81
|
+
list|remove|delete|rm) ;;
|
|
82
|
+
create|add)
|
|
83
|
+
COMPREPLY=($(compgen -W "--local --role --cli --persona" -- "$cur"))
|
|
84
|
+
;;
|
|
85
|
+
*)
|
|
86
|
+
COMPREPLY=($(compgen -W "show env" -- "$cur"))
|
|
87
|
+
;;
|
|
88
|
+
esac
|
|
83
89
|
;;
|
|
84
90
|
4)
|
|
85
91
|
local subcmd="${words[3]}"
|
data/lib/brainiac/version.rb
CHANGED